Repository navigation
feat(node)!: add per-node measurement - #47
Merged
Merged
Conversation
hyfdev
marked this pull request as ready for review
August 17, 2026 16:43
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.
Summary
TaffyTree.setMeasure(node, measure | undefined)for persistent per-node measurementcomputeLayout({ root, availableSpace, measure? })and remove the publiccomputeLayoutWithMeasuremethod and options typegetStyleprovider creation, or Node-API/WASI entrysetMeasureand always use the unifiedcomputeLayoutpath without a global fallbackBehavior
Measurement dispatch is:
The raw native fast path remains active only when the tree has no configured per-node callbacks and the call has no fallback. A non-
undefined, non-function fallback throwsTypeErrorbefore native computation.Every
setMeasurecall, including replacement with the same function and clearing, updates native metadata first and dirties the node before committing the JavaScript map. Context and measure presence remain independent, and removal/clear release retained callbacks.Global fallback identity and presence are deliberately not part of Taffy's cache key. Adding, removing, or changing a fallback requires dirtying every potentially affected leaf;
markDirty(root)does not clear descendant caches. A focused regression test protects this behavior.Breaking change
becomes:
ComputeLayoutWithMeasureOptionsis replaced byComputeLayoutOptions<TContext>, whosemeasureproperty is optional.Callback evidence
One coding-agent-chat initial layout contains 51 measured text leaves and 115 fixed leaves:
The 1,032 real measured requests are unchanged; per-node marking removes all 230 fixed-leaf JavaScript entries. Diagnostic instrumentation was removed.
Benchmarks
Three matched local rounds on Node v24.19.0, using the unchanged coding-agent-chat initial-layout transaction:
@taffyjs/node@taffyjs/wasmbenchmarks/results/published.jsonis unchanged.Validation
vp check: formatting, lint, and types passed with zero warningsvp run check: Rust 11, native binding 45,@taffyjs/node214, Yoga 557 passed / 85 expected failures / 17 skippedvp run check:wasm: WASI public API 214, Yoga-Wasm 557 passed / 85 expected failures / 17 skipped, plus browser, package, type, and website checksFixes #44