Repository navigation
Spike: replace @glimmer/validator with alien-signals - #21668
Draft
NullVoxPopuli-ai-agent wants to merge 5 commits into
Draft
NullVoxPopuli-ai-agent wants to merge 5 commits into
NullVoxPopuli-ai-agent wants to merge 5 commits into
Conversation
This is a spike. It removes the @glimmer/validator package. The new private package @glimmer/signals builds on alien-signals/system. - References and createCache are computed nodes of the graph. - Each cache group of the VM is a frame node. A render has a root frame. - A destroyed block or render removes its links from the tags. - A cache without a subscriber keeps a list of tags and a revision, not links. - updateTag uses a watcher node that forwards writes to the tag. - Classic computed properties and observers keep revision snapshots. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
No tag has a revision number, and valueForTag and validateTag are gone. Each caller that held a tag and a revision now owns a subscriber node: - a classic computed property and an alias, in the meta of the object - an observer - the arguments of a curly component - a modifier opcode - ArrayProxy for its arranged content A cache always has links to its tags. A cache that loses its last subscriber removes its links and runs again on the next read, as a computed of alien-signals does. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The package is no longer an entrypoint, so it is not in ember-addon.renamed-modules and no app or addon can import it. - The benchmark app builds its cell on tracked() from @glimmer/tracking. The control build of the perf job uses main, which has no @glimmer/signals. - The smoke test for a v1 addon imports @glimmer/destroyable. - The smoke test for the object tag reads it through a cache. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- A classic computed property is one node: its property tag. The tag links to the tags that the getter or the dependent keys read, and a stale bit on the tag says if the cached value is valid. Meta keeps only a flag that a value is cached. - trackInto(tag, fn) runs fn with the tag as the subscriber. It replaces track() followed by updateTag(). - A Tag is one node or an array of tags. combine() is gone. - track() returns a frame. beginTrackFrame and endTrackFrame are gone. - A tag that follows other tags never stops propagate. A new subscriber clears its flags, and the stale bit keeps the fact. - The tag of an argument is its reference. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The rebase brought in the tests that main added for the tracker pool. A frame of this spike returns a frame node, not a tag, so: - the two tests that compare the result of a frame with a tag are gone. They test the tracker that this spike deletes. - the other tests use the `watch` and `isValid` helpers of this file. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
NullVoxPopuli-ai-agent
force-pushed
the
nvp/spike-alien-signals
branch
from
October 7, 2026 17:27
539b452 to
5745741
Compare
This branch has not been deployed
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.
Spike. Not for merge. It answers one question: what does Ember look like when
alien-signalsreplaces@glimmer/validator?Try it:
git fetch origin pull/21668/head && pnpm install && pnpm test:wipResult
packages/@glimmer/validatoris deleted. Every export is treated as private.valueForTag,validateTag,CURRENT_TAG, andVOLATILE_TAGdo not exist.packages/@glimmer/signalsbuilds onalien-signals/system(link,unlink,propagate). "Is this still valid?" is a flag check on a node.@glimmer/signalsis private. It is not inrenamed-modules, and no app or addon can import it.mainof 2026-10-07. After the rebase, the full suite passes in development mode: 9534 tests, 0 failures. Production mode did not run again. It passed before the rebase with 9306 tests.57457412c6. It ports the tests thatmaingained for the tracker pool of Pool the trackers of tracking frames #21663, and removes two that test the tracker that this spike deletes.@ember/-internals/glimmer: +2.4 kB raw, +0.9 kB brotli againstmain.Speed of the reactive core
Benchmark: ember-reactivity-bench, Node 24.20, weighted geometric mean of 20 cases, plain
alien-signals= 1.0x, lower is faster.maintracked(value)creation does not change (17 µs per 1000, 6.6x of a plain signal). That cost is inTrackedValue, not in the graph.Rendering numbers (rere-benchmark against
main) are not here yet.How it maps
createCacheJumpIfNotModifiedOpcode+ tag + revision)createTag,createUpdatableTag,tagFor(tag, revision)pair in a callerwatchTag,isFrameStale)MetaisTagFresh)track(fn)thenupdateTag(tag, result)trackInto(tag, fn): the tag is the subscriber of the runcombine(tags)writeCount(), only for "did any write occur"Callers that held a
(tag, revision)pair and now own a subscriber: observers, the curly component manager, modifier opcodes,ArrayProxy.What alien-signals does not cover
Links hold subscribers strongly.
A tag keeps every node that subscribes to it. The validator had no back link, so the garbage collector did all the work. Now an owner must remove links:
unwatched).alien-signals.EmberObjectreleases the watchers of its tags on destroy.Still open:
@computed,@aliasor@dependentKeyCompathas no destroy hook. Its watcher stays linked until its sources die.checkDirtydoes not stop on a cycle.Two classic computed properties can depend on each other, so their tags link to each other.
propagatestops on such a cycle. The spike has no walk over dependencies that can pass a tag two times.A stale node stops
propagate.A subscriber with no function to run again cannot refresh a stale cache below it. Such a subscriber links to the leaf tags directly.
A tag that follows other tags has no function at all. A new subscriber clears the flags of such a tag, and a stale bit on the tag keeps the fact that a write reached it.
Behavior that stays the same
notifyPropertyChangewith the same value still updates the consumers.checkDirtyis therefore not in use.scheduleRevalidateruns for each write.Behavior that changes
@glimmer/validatoris no longer an importable module ofember-source, and nothing replaces it. An addon that imports it breaks.@cachedgetter or a helper runs again after its last subscriber goes away, for example when its block leaves the DOM and comes back. Before, it kept its value if its tags did not change.alien-signals3.2.1 is a new bundled dependency.Not done
TagNodeclass serves all kinds, so a leaf tag has unused fields.internal-docs/still name the validator.Tests added:
packages/@glimmer/signals/test/graph-test.ts(frames, caches,updateTag) andintegration-tests/test/graph-links-test.ts(a removed block and a destroyed render leave no link). Tests that usedvalueForTag/validateTagnow use a subscriber.🤖 Generated with Claude Code