makeGet is the simplest:
const makeGet =
(target: any, args: any[], selector: (...args: any[]) => any) =>
(customSelector?: (...args: any[]) => any) => {
const { value: selectedValue, depsList } = callAndTrackDeps(
{ trackDeps: !target._meta.depsList },
() => selector(...args),
)
target._meta.depsList ??= depsList
const value = (customSelector ?? identity)(selectedValue)
return value
}
basically, here's what the user would do with the library/what the api looks like:
const myStore = store(() => {
const counter = atom(1)
const multiply = select((factor: number) => counter.get() * factor)
return {counter, double}
})
myStore.multiply(2).get()
myStore.multiply(2).use()
then store reads the _meta field from counter and double, and does conditional logic based on that (and also the field is used in type scenarios where I want to restrict what object/function can be returned, which is why I can't just omit it from the type)
and you can imagine that the function passed to select could be generic (the above works as long as it's not generic)