diff --git a/.changeset/frames-bind-tier.md b/.changeset/frames-bind-tier.md new file mode 100644 index 000000000..8e9ffcba3 --- /dev/null +++ b/.changeset/frames-bind-tier.md @@ -0,0 +1,5 @@ +--- +"@solidjs/web": patch +--- + +frames: the binding-slot tier (`@solidjs/web/frames/bind`, `@experimental`) — the `_s:*` marker parsers, consumer discovery, the morph's owned-position arms, the per-frame consumer sets and the fill's binding leave the eager frames client as a lazy chunk; `assign` leaves with them. A marker met while the tier is absent holds the frame under frames-rulings 3.1 (hydration-done waits; the install's flush binds). The delegated-event replay window is closed by a bare ` _hk` the server stamps on each document-face element with an `_s:on:*` position (4 bytes each, nothing else stamped): the tier marks the element completed at the bind and drains the queue, so a click before or during the hold reaches the bound handler. Data occurrences now mount with the current record. diff --git a/.changeset/frames-drop-dead-slot-nodes-writes.md b/.changeset/frames-drop-dead-slot-nodes-writes.md new file mode 100644 index 000000000..40533e896 --- /dev/null +++ b/.changeset/frames-drop-dead-slot-nodes-writes.md @@ -0,0 +1,5 @@ +--- +"@solidjs/web": patch +--- + +frames: drop the three dead `#slotNodes` writes for data occurrences — the only reader (the zombie check) skips data occurrences, so the consumer-element arrays were built and never read diff --git a/.changeset/frames-trace-update-site-wait.md b/.changeset/frames-trace-update-site-wait.md new file mode 100644 index 000000000..144db25cb --- /dev/null +++ b/.changeset/frames-trace-update-site-wait.md @@ -0,0 +1,5 @@ +--- +"@solidjs/web": patch +--- + +frames: the trace tier's update-site wait. A MOUNTED occurrence's new slot record whose args carry a `{ $tr }` container-trace marker while the trace tier is absent (a live slot op minting the page's first trace after the shell, a refetch adding a projection arg) now stays pending in the store: the live binding keeps the args it shows, the tier load starts, and the install's flush applies the record as an args change with the marker materialized. Before, `#syncSlots` guarded only the fresh mount (`needsTrace`) and the regions tier at the update site (`needsRegions`), so such a record was pushed into the live binding raw — the marker read as the value. Mirrors the regions tier's update-site wait. diff --git a/documentation/plans/frames-savings-pass.md b/documentation/plans/frames-savings-pass.md index 6faf90633..3fa31cea3 100644 --- a/documentation/plans/frames-savings-pass.md +++ b/documentation/plans/frames-savings-pass.md @@ -88,9 +88,13 @@ _or_ acting without it is a bounded delay with the right thing on screen meanwhile. For every runtime tier: the exact race, the symptom if it were lost, the mechanism that bounds it, and the pin that proves it. "3.1 participant" means the hold registers as a pending boundary through -`initBoundaryResume` (ruling 3.1 / 3.2 — hydration-done waits for it, the -event-replay window stays open); "runtime wait" means a post-first-flush -buffer with no hydration involvement. +`initBoundaryResume` (ruling 3.1 / 3.2 — hydration-done waits for it); +"runtime wait" means a post-first-flush buffer with no hydration +involvement. **A 3.1 hold does not keep the delegated-event replay window +open** (corrected at C6, below): the bootstrap queues an event only under +a not-yet-completed `_hk` element, and a server component's interior has +none (it renders under NoHydration) — the window an element needs is its +own stamp. | tier | the race (what arrives before what) | symptom if lost | bound | class | pin | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -99,7 +103,7 @@ buffer with no hydration involvement. | **traces** (S1 re-based) | an adopt-time record whose literal args carry a `{ $tr, $ta }` marker — or a `data` chunk whose node tree holds the trace plugin's node — before `container-trace.js` (the materializer + the store engine) has loaded. | the fill runs with an inert marker object (`TypeError` or wrong content); on the codec face the chunk decodes a marker instead of a container. | **announce + hold.** Document: the server knows it serialized a trace (the serializer stamps it) → `modulepreload` at t = 0 + the `sc:tiers` record; the occurrence is **held** (S1's `#argsUnprepared` → the general held set) with its server interior on screen, the mount being the hydration attach; it mounts with the record it was held on (S1 commit 3). Codec: `prepareData` scans the node tree and awaits the tier before the chunk decodes (S1 as built; the header flag makes the scan a confirmation). The claim reads the snapshot; the backlog lands after done (3.6 (iii), S1 commit 3). | **3.1 participant** (document face: the hold is an adopt-time occurrence deferred — registers through `initBoundaryResume`, A2) | **existing (S1):** `frames-container-lazy-codec` (loads before decode / loads nothing), `frames-container-lazy-document` (held with the interior on screen, then mounted), `hydration/welcome-status-lazy` (claims in place, no key misses), `container-trace-hold-{id-determinism, interruption, record-retention, snapshot}`. **Re-pin:** `container-trace-hold-hydration-end` under 3.1 — _hydration waits for the load; the mount claims before done_ (rulings 3.1 "Consequences"). | | **regions** | a `slot:` record naming a `{$frame}` ref — or a `data-fid` region element inside adopted content — before `tier-regions.js` has loaded. | the fill receives the raw `{$frame}` ref (wrong content); an occluded region cannot mount from the store. | **announce + hold.** The sink knows at render it passed server content as a prop (`{$frame}` minted) → announced. Adopt path: the occurrence is held in the same set as traces (its interior stays on screen; `#resolveArgs` runs after the load). Stream path: the record stays pending in the store until the load's flush (buffer). | **3.1 participant** on the adopt path; runtime wait on the stream path | **existing:** `frames-regions-*`, the lifecycle matrix's region rows. **New:** `tier-regions-hold.spec` — adopt-time `{$frame}` occurrence held, interior intact, mounts after the load with the held record; a stream record with a region ref applies after the load; hydration-done waits (3.1). | | **assets** | a `reveal` for a segment whose `seg::assets` record names stylesheets (or `waitForStyles`) before `tier-assets.js` has loaded. Stream face only — the document face keeps the core's `$dfs`. | **without a bound: FOUC** — the segment reveals unstyled, then the sheet lands. With the bound: the fallback stays on screen longer. | **announce + reveal-readiness term.** The sink knows at render that a fragment is style-gated → announced in the header; `#segmentReady` gains one term: "the segment's `assets` record names styles **and** the tier is not resident → not ready". The fallback — the server's `` outcome — stays; the reveal happens at max(tier load, stylesheet load), and the stylesheet's own load dominates on every network. A segment without stylesheets never waits. Modules / preloads are not reveal-gating today and stay so. **Built (2026-10-06, C5, and its follow-up the same day):** the term is `(assets.styles | | assets.inlineStyles) && !tierReady("assets")?.gate(assets.styles | | [], this)`in`#segmentReady`— a segment whose record carries stylesheets **or inline styles** holds while the tier is absent (the inline`