Open PalmZE opened 2 years ago
@PalmZE Looks interesting, I'll try to book some time today to digest this.
In the meantime, I'm not a big fan of this
, how about turning the methods into functions taking current mutable state as an argument?
Solid's implementation also looks nice and in fact it's much more composable
Ok, I played a bit with immer
and came up with this solution https://github.com/raveclassic/frp-ts/pull/54
@PalmZE I don't think mixing methods with Atom
interface is a good idea as it leads to possible name clashes (e.g. we might want to add a subscribe
, set
etc. methods which would overwrite original methods defined for Atom
). Instead, I suggest working with method records directly. Still, you can create a bunch of methods and mix them into resulting Atom
by hand.
interface Dog {
name: string;
}
interface House {
dog: Dog;
}
interface AppState {
house: House;
}
const initialState: AppState = { house: { dog: { name: 'Fido' } } };
const storeState = newAtom(initialState)
const storeMethods = produceMany(storeState, {
renameTheDog: (newName: string) => state => {
state.house.dog.name = newName
}
})
const store = { ...storeState, ...storeMethods }
store.renameTheDog('Odif');
Btw, any ideas for a better name for produceMany
?
@raveclassic looks nice 👍
as for a better name, some ideas:
Anyway, I guess jsdoc explaining that the API uses immer internally will do
I love this concept! I thought immer would fit well here :)
produceMany
is similar to immer naming and looks nice
But I agree with PalmZE that we can choose any name
@raveclassic Might as well try making a variant with a reducer like approach?
const dispatch = newAtomReducer(state, (draft, action: Actions) => {
if (action.type === "toggle") {
const todo = draft.find((todo) => todo.id === action.id)
todo.done = !todo.done
}
})
dispatch({ type: "toggle", id: "1" })
@raveclassic, hi!
Would you accept the below feature as a separate frp-ts package\addition to the core package?
Internally it will use immer to support concise mutation syntax.
Motivation
I find it convenient to group store\vm state into a single object and expose a single atom in the API. This leads to some boilerplate when you need to modify parts of the state. Immer helps a lot, but we still need to use modify calls. This change simplifies this use case.
Besides, some libraries provide this out of the box (SolidJS as example).