docs/plans/2026-04-15-slate-v2-decoration-wave-11-execution.md
Execute Wave 11 from the decoration roadmap: indexed or child-scoped projection recompute.
projectRange(...) calldocs/shared/agent-tiers.md is missing in this repopackages/slate/src/range-projection.tspackages/slate-react/src/projection-store.tspackages/slate/src/range-projection.tspackages/slate-react/src/projection-store.tspackages/slate-react/src/decoration-sources.tspackages/slate-react/src/annotation-store.tspackages/slate-react/src/widget-store.tspackages/slate-react/src/hooks/use-slate-range-ref-projection-store.tsxpackages/slate-react/src/hooks/use-slate-projections.tsxpackages/slate-react/src/index.tspackages/slate-react/test/projections-and-selection-contract.tsx
scripts/benchmarks/browser/react/rerender-breadth.tsxscripts/benchmarks/browser/replacement/huge-document-overlays.mjssite/examples/ts/huge-document.tsxdocs/walkthroughs/09-performance.mddocs/libraries/slate-react/hooks.mdpnpm installpnpm turbo build --filter=./packages/slate --filter=./packages/slate-reactpnpm turbo typecheck --filter=./packages/slate --filter=./packages/slate-reactpnpm lint:fixpnpm --filter slate-react test → 101 passedpnpm exec mocha --require ./config/babel/register.cjs ./packages/slate/test/snapshot-contract.ts
→ 188 passingpnpm exec tsc --project site/tsconfig.json --noEmit15 passedREACT_BREADTH_BENCH_ITERATIONS=1 REACT_BREADTH_SELECTION_OPS=2 pnpm bench:react:rerender-breadth:local
→ recompute counters emitted in JSONREPLACEMENT_BENCH_ITERATIONS=1 REPLACEMENT_HUGE_BLOCKS=200 pnpm bench:replacement:huge-document:overlays:local
→ overlay / annotation / widget recompute counters emitted in JSONlsp_diagnostics on affected Slate / slate-react / benchmark / example
files → 0 errorspackages/slate-react/src/projection-store.tsSnapshotChange
touches one of their previously projected runtime ids, or when dirtiness is
broad/unknownpackages/slate-react/test/projections-and-selection-contract.tsx
→ multi-text projections reproject touched interior runtime ids even when the range is unchangedSnapshotChange, but passed that refresh into the inner projection
store without a reason override, so the inner external dirtiness gate
could skip the recompute entirelypackages/slate-react/src/projection-store.tspackages/slate-react/src/decoration-sources.tspackages/slate-react/src/annotation-store.tspackages/slate-react/test/projections-and-selection-contract.tsx
→ decoration source stores preserve multi-text projection correctness across touched interior runtime ids1221111222210.89mspackages/slate-react/src/projection-store.tspackages/slate-react/test/projections-and-selection-contract.tsx
→ projection store updates runtime slice order when overlapping projection order changespackages/slate-react/src/projection-store.tspackages/slate-react/test/projections-and-selection-contract.tsx
→ invalid cached projections reproject when later text changes make the range validpackages/slate-react/src/annotation-store.tspackages/slate-react/test/annotation-store-contract.tsx
→ annotation projection store reprojects touched interior runtime ids even when the resolved range is unchangedAPPROVEDpnpm turbo build --filter=./packages/slate --filter=./packages/slate-reactpnpm turbo typecheck --filter=./packages/slate --filter=./packages/slate-reactpnpm lint:fixpnpm --filter slate-react test → 103 passedpnpm exec mocha --require ./config/babel/register.cjs ./packages/slate/test/snapshot-contract.ts
→ 188 passingpnpm exec tsc --project site/tsconfig.json --noEmitREACT_BREADTH_BENCH_ITERATIONS=1 REACT_BREADTH_SELECTION_OPS=2 pnpm bench:react:rerender-breadth:localREPLACEMENT_BENCH_ITERATIONS=1 REPLACEMENT_HUGE_BLOCKS=200 pnpm bench:replacement:huge-document:overlays:localuse-slate-projections.tsx no longer matched the expanded
SlateProjectionStore interface
getMetrics() implementationuseEffect was missing from the rerender-breadth importsgetMetrics()