Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add update hook for core primitives #578

Closed
artalar opened this issue Jun 3, 2023 · 3 comments
Closed

Add update hook for core primitives #578

artalar opened this issue Jun 3, 2023 · 3 comments

Comments

@artalar
Copy link
Owner

artalar commented Jun 3, 2023

Currently we have only one public method to hook an update of atom or action call - onUpdate from reatom/hooks. There are few DX problems with that:

  1. onUpdate have two overloads for atom and action with different behaviour (callback parameters), it could be not obvious especially for an action, coz "update" and "action call" is not connected semantically.
  2. onUpdate call made the whole graph hot and could produce memory leaks in rare cases (dynamic fabric on top of a shared state + forgetting about unsubscribe)
  3. If you need to hook an update / call just for a log the extra import and neediness of it deletion is not handy. For example, you have an atom and want to log the state during debug - you should import and write onUpdate(anAtom, console.log), BUT after this line deletion you should fix imports too - extra work for a temporal debug.
  4. There could be a rare cases when dependent update hooks just don't work (the first spy on an atom which was just changed...)
  5. onUpdate is a super common feature and one of the common tools to build almost anything with Reatom, it is strange that this API stored in a different package.

The proposal: add the same hook to all atoms and actions of the core package.

export interface Atom<State = any> {
  __reatom: AtomProto<State>
  pipe: Pipe<this>

  onChange: (cb: (newState: State, prevState: State) => void) => Unsubscribe
}

export interface Action<Params extends any[] = any[], Payload = any>
  extends Atom<Array<{ params: Params; payload: Payload }>> {
  (ctx: Ctx, ...params: Params): Payload

  onCall: (cb: (payload: Payload, params: Params) => void) => Unsubscribe
}

The overhead would be only around 0.1KB!

CleanShot 2023-06-03 at 08 18 44@2x
@artalar artalar changed the title Add public update hook Add update hook for core primitives Jun 3, 2023
@BANOnotIT
Copy link
Collaborator

Action inherit onChange. What semantic will be if I do someAction.onChange((...args) => console.log(args))?

@artalar
Copy link
Owner Author

artalar commented Jun 4, 2023

@BANOnotIT onChange will work the same as the internal update hook - the list of action calls during transaction includes the last one. We will not show this in any place of documentations, so I think it will be Ok.

@artalar
Copy link
Owner Author

artalar commented Jul 7, 2023

released

@artalar artalar closed this as completed Jul 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants