Skip to content

Instantly share code, notes, and snippets.

@DavidWells
Last active March 16, 2022 09:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DavidWells/dbb1a628b003e6a521f35bf49b5b688a to your computer and use it in GitHub Desktop.
Save DavidWells/dbb1a628b003e6a521f35bf49b5b688a to your computer and use it in GitHub Desktop.
State management via JS proxy
// via https://twitter.com/judicael_andria/status/1501643071494180868
/* usage
createStore({
context: {
initialize state here
},
actions: {
add: (context, event) => {}
}
})
*/
function createStore({ context, actions }) {
const proxy = new Proxy(context, {
get: (obj, prop) => {
if (obj[prop] == undefined) {
throw new Error(`${String(prop)} doesn't exist on the target object`);
} else {
return Reflect.get(obj, prop);
}
},
set: (obj, prop, value) => {
return Reflect.set(obj, prop, value);
}
});
return {
context: Object.freeze(proxy),
actions,
};
}
const personsStore = createStore({
context: {
user: {
username: "Judicael",
age: 23,
}
},
actions: {
add: (context, event) => {
const { username, age } = context.user;
console.log('add username', username)
console.log('add age', age)
context.user.username = event.username
}
}
})
const { age, username } = personsStore.context.user;
console.log('username', username)
console.log('age', age)
personsStore.actions.add(personsStore.context, { username: 'bill' })
console.log('user', personsStore.context.user)
/*
// usage
createStore({
context: {
initialize state here
},
actions: {
add: (context, event) => {
}
}
})
*/
interface ICreateStoreProps<T, K> {
context: T;
actions?: K;
}
function createStore<
T extends Record<string, any>,
K extends Record<string, (context: T, event: Record<string, any>) => void>
>({ context, actions }: ICreateStoreProps<T, K>) {
type ContextType = typeof context;
const proxy = new Proxy(context, {
get: (obj: ContextType, prop: string) => {
if (obj[prop] == undefined) {
throw new Error(`${String(prop)} doesn't exist on the target object`);
} else {
return Reflect.get(obj, prop);
}
}
set: (obj: ContextType, prop, value) => {
return Reflect.set(obj, prop, value);
}
});
return {
context: Object.freeze(proxy),
actions,
}
}
const personsStore = createStore({
context: {
user: {
username: "Judicael",
age: 23,
}
},
actions: {
add: (context, event) => {
const { username, age } = context.user;
console.log({ username, age });
}
}
});
const { age, username } = personsStore.context.user;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment