Lazy computed-signals in Haptic Wire#1
Merged
tsugabloom merged 21 commits intohaptic-wfrom Apr 21, 2021
Merged
Conversation
…y own initializer"
…turn ... } }` syntax
…onsistent naming. 1578gz.
tsugabloom
commented
Apr 16, 2021
tsugabloom
commented
Apr 16, 2021
| // Token is set but never deleted since it's a WeakMap | ||
| reactorTokenMap.set($, wR); | ||
| adopt(wR, () => wR.fn($)); | ||
| saved = adopt(wR, () => wR.fn($)); |
Owner
Author
There was a problem hiding this comment.
This change also has reactors return a value. They're not () => void anymore.
tsugabloom
commented
Apr 16, 2021
tsugabloom
commented
Apr 16, 2021
| wireSignals as wS, | ||
| wireReactor, | ||
| wireReactor as wR, | ||
| reactorRegistry, |
Owner
Author
There was a problem hiding this comment.
I'll be adding this back into a haptic/w/dev or maybe a haptic/dev bundle
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This implements lazy computeds. Similar to the computeds found in Sinuous but these are lazy, explicitly defined, and are true
WireSignalfunctions. They're defined with aWireReactor, but unlike a reactor, they don't evaluate on each signal write.A computed-signal is a normal signal backed by a reactor (called a computed-reactor). This is a pairing.
It's different than:
This runs every write, even if no one is reading/observing
data.countPlusOne. This is because awRis an observer, so as far as Haptic can tell, it's worth executing. With computed-signals, the computed-reactor isn't worth executing unless it has observers aka a non-computed reactor.When a signal inside a computed updates, the signal marks the computed as stale rather than executing it. When it is finally executed, it uses this stale flag to cache the calculation. This leads to the least amount of work performed.
TypeScript #43683 helped me figure out the API design. There are notes directly in the code about the reasoning and why I thought it was worth it to settle on the version that (unfortunately) requires manually specifying the reactor return type - it's the best of many not great options due to limitations in the TS compiler.
If I cut out
when()andsvg()utilities, and import wR & wS into the main bundle, the size is 1570b min+gz for haptic and 805b min+gz for only haptic/w. This is everything, so hopefully I can keep Haptic around 1.6kb. The down side is this PR adds a lot of complexity. Wire was originally really nicely coupled - two paired functions that share a bit of global state and some helper methods. This shoves a new type of function into the definitions of both signals and reactors: it's not a third type, it's teaching them both to do a new dance. This adds a lot of new code branches and checks. Still, I think it's worth it because I've been chasing lazy computeds for at least a year in Sinuous.