kaoD 3 days ago

Interesting! Will give it a try.

I like how you properly used useSyncExternalStore and AbortController for signaling. Always a good sign seeing good use of APIs.

(EDIT) Quick question: will computed values be lazy and cached? I'm worried changing an atom could trigger a huge cascade of changes (most of which will not even be observed) but also that expensive values could get thrown away once not observed anymore (even if briefly, think e.g. a quick remount) but also that it might get cached for too long (or never discarded).

How is all this handled internally?

(EDIT2) I'm reading through the README and the rationale/comparison with Jotai looks very solid. I'm really impressed. Kudos.

  • e7h4n 3 days ago

    Thank you for your question. This is a crucial part of CCState, and I plan to include this answer directly in the documentation.

    In short, a Computed atom is lazy if it's not directly or indirectly subscribed to. Otherwise, it will recalculate immediately when any of its dependencies change.

    For example, consider A(Computed) -> B(Computed) -> C(State):

    - If no atoms are subscribed to, updates to C will have a lazy effect on both A and B

    - If A is subscribed to, C's updates will synchronously trigger recalculations of both B and A, then notify A's subscribers

    - If B is subscribed, C's updates will synchronously trigger B's recalculation and notify B's subscribers, while A remains unaffected

    This is the current behavior almost identical to Jotai's implementation.

    However, while writing this answer, I realized this could potentially be simpler. Jotai's design choice stems from its notification mechanism, which performs distinct events. This means Jotai must re-evaluate immediately after a set operation to determine whether to notify its subscribers. This is one of Jotai's "magic" features, but in CCState, I try to avoid such magic. CCState doesn't perform event deduplication during notifications (though we might consider providing some higher-order functions later, but this won't be part of the core design). Therefore, perhaps CCState could make Computed evaluations always lazy.

    [EDIT]: As long as subscriber notifications are synchronous, Computed atoms must be recalculated synchronously. Otherwise, dependency analysis will have issues. I've written two test cases, https://codesandbox.io/p/sandbox/t2vl2m

    [EDIT 2]: I've added the relevant behaviors to the documentation. I hope I've explained it clearly. https://github.com/e7h4n/ccstate?tab=readme-ov-file#when-com...

  • aidos 3 days ago

    Mobx has similar patterns with the computeds. They allow you to have a little more control over their lifecycle. The general rule is that they’re kept alive until they’re no longer observed but you can pass a flag to keep them around even when they’re not needed.