Repository navigation
@solidjs/signals@2.0.0-rc.14
Pre-releasePatch Changes
-
0c550fd: A render effect still on screen while an action holds its removal follows the lane's re-derivation of a memo it reads, as its direct
latest()twin does (fuzzer adopted-staging case) -
ecb68a1: Binding slots: the fill runs once per occurrence, untracked, under the occurrence's owner — as a component body and a template-slot fill do. State created in the fill lives as long as the occurrence; a top-level read is a one-time read (dev:
STRICT_READ_UNTRACKED, naming the fill); getters are the reactive form. Handlers and refs are read once when an element binds and go throughassign, so events delegate, tuples bind and interactions wrap as in client JSX. On the server an array at a handler position is a dev finding (reasontuple) instead of being flattened; onlyrefmerges arrays. Template-slot fills are untracked on every render path and carry the same labelled warning.Breaking:
AttributeSlotis renamedBindingSlot, with no alias, and its return is constrained (SlotOutput<J>/SlotError<M>, both exported) so an array, DOM node, function, async value or$-prefixed key is a type error on both sides. The diagnostic codeATTRIBUTE_SLOT_POSITIONis renamedBINDING_SLOT_POSITION. The fill-shape finding also names async values. -
b07fed5: A born-held render effect re-run as lane work (a
latest()reader remounted during an action's hold) re-stages its value, so the commit applies the latest pass instead of the stale born-held one (fuzzer F13). -
21ff8f8: Infer
createEffectandcreateRenderEffectcompute results as const so inline tuple results retain their element types without a type argument oras const. -
1b9ceb6: Size audit (measurement branch): a derived store's derive reading a key (or container) a transaction holds through its draft — a user's write inside an action, held with it — joins that transaction, so the derive's whole result reveals with the action rather than key by key (core R31 / #3733: "under the transaction and revealed with it"; the
derived-write-then-derivation-3733action-hold pin). A user setter reading its own draft is no pass and joins nothing. -
fa371c3: Compare optimistic store writes against the committed backing frame of chained stores, so a writable derived store's held staging cannot suppress an optimistic override.
-
96c5e19: A derived store that returns rows from its own draft no longer recurses forever when its source refreshes: the projection draft wrapper resolves to its store proxy wherever the result carries it, so a retained row keeps its identity and stays readable, and an equivalent refresh doesn't re-notify its readers.
-
9a213bb: Derived writes apply first, then derivations re-run. A manual write to a writable derived value (
createSignal(fn),createStore(fn)) lands at once; when one of its sources changes — in the same update or later, inside or outside an action, across async holds — the function re-runs and receives the write asprev(or as the draft forcreateStore(fn)), and decides what to keep. A write on its own never re-runs the function.This reverses beta.11's same-tick precedence (#2692), where a write beat a source change in the same flush: a function that ignores
prevnow discards a write made in the same update as a source change, and a same-value write no longer holds against it. To keep a local value across source changes, carry it in the data as a flag the function honors. It also fixes #3733 (a write inside an action blocked later source changes for the whole hold, a regression since #2692) and supersedes the frame-scoped mask from #3740, whose changeset this replaces. -
721eb06: Attribution cost checks judge only what the scope's author can act on (#3739).
WIDE_SCOPE_DEPSno longer counts HMR plumbing sources (thesolid-js/refreshmemo per component instance), skips framework scopes marked with the new internal dev-only_wideoption (CONFIG_WIDE; not public API), and itswideDepsdefault rises from 30 to 200. The engine-sideHUGE_FAN_OUT(fanOut) no longer counts plumbing subscribers. The always-onHUGE_FAN_INand coreHUGE_FAN_OUT(2000) keep no exceptions. -
b07fed5: A render reader whose pass errored (NotReady included) before reaching a flight it read last time still holds that flight's transaction: a write no longer shows beside a reader still derived from the previous value while the flight is in the air (fuzzer F4).
-
bc51ada: A new async memo created over a held update now waits for it (#3800). A memo created while a transition holds a value, whose first pass reads that value and returns a promise, lands its first answer into the transition and reveals at its commit, as the same memo with a synchronous first answer already did. Before, the promise landed on its own and its readers showed the new value beside the rest of the page still on the old one. The transition never waits for the new memo's first load: if it lands after the transition commits, it is its own commit.
-
eaddda4: Fix false
GRAPH_GROWTHwarnings caused by the initial route declaration, which runs before page content mounts. The detector now compares completed visits while still emitting the initial graph record. -
d231b99: An optimistic store over a store reads a property the inner store's reconcile removed as
undefinedinstead of its last value (#3883) -
3086f1b: Fix an infinite flush loop ("Potential Infinite Loop Detected") when a
latest()-gatedShowmounts a freshLoadingunder an action hold: lane work that reads a node born staged is no longer re-queued to re-derive on a committed value it doesn't have. -
3c7631a: ABANDONED_FLIGHTS no longer fires for a frames slot arg that every re-shipped record re-reads while it is still pending (#3852). Dev builds mark the per-key slot-arg memo with an internal option that the check skips; the memo's flights are still recorded and still counted in
feedback(). -
09eadfe: A fresh
Loadingmounted over a held value shows its fallback in a flush too (#3540 under L2): a first pass a loading boundary that has not shown content catches is the boundary's, not the tick's, so the mount publishes and the content reveals at the commit. Content bound by a render effect under the boundary is collected, so the boundary no longer reveals empty content. -
be82cf3: Observe: one interaction frame per event, not per listener.
InteractionReftakes an optionalevent; frames with the sameeventre-enter one interaction record, which stays joinable for the event's dispatch and is recorded at the next task. The web runtime keys its frames by the DOM event, and@solidjs/webexportsdispatchAsInteraction(e, fn)so a listener outside the runtime (a router'sdocumentclick handler) joins the frame of the same event —fn()in production builds. One anchor click is now one interaction record carrying both theonClickwork and the navigation (#3754). -
fd9f381: Fix L2 lane regressions found by the semantic fuzzer: a lane dissolving with a node still in flight marks it as committed beneath published inputs, so a mount or verdict reader observes the flight instead of being served a value that tears against them; a correction of a blocked lane drops the re-guess runs it parked instead of releasing them; and a lane pass's pending propagation no longer lists a born-held or mid-pass mainline render effect on the lane, so a mount over a memo of a lane flight is born held, control and content together.
-
b07fed5: A landing whose commits dispose a zombie re-judges the transactions parked at the same seam: a write held only because that zombie observed its flight now lands with the commit that disposes it instead of staying unpublished until an unrelated flush (fuzzer F3).
-
fff1615: A lane now holds through a
Loadingboundary showing content: a boundary output forwarding its tree's pending counts as a frame reader, solatest()no longer reveals beside the boundary's stale content (A33). An output that never committed — a mount the frame has not revealed — holds nothing. A corrected guess that never showed is void at the correction: untracked reads return the committed value (A18 amendment, 2026-10-05). -
11e9fb6: An element an optimistic guess mounts now lands together with its bindings (#3835). A first pass created by a guess's lane reads as the lane's, not just routes as it: a binding the lane mounts reads a write the action still holds as the screen (its committed value) and re-derives when the action lands. Before, a binding inside a memo the lane created was born held while the memo's element showed, so
<div>Hello</div>appeared without itsstyleuntil the action finished; directly under the lane pass the binding showed the held value early instead. -
11e9fb6: A
Loadingmounted by an optimistic write over a flight shows its fallback again (#3835's seat regressed it). Lane work with no committed value yet reads a pending flight the way a mainline mount's memo does: it enters and throws, so the boundary it mounts catches the pending (A29's boundary exemption), instead of being served the flight's committed value. A render effect is still a stale reader of a held flight (rule 3). Approach and tests from #3843 by @brenelz. -
b0bad02: A lane's node inside a held frame stays the lane's:
holdFrameno longer re-lists a verdict reader (or a derivation of a guess) created under a held pass on the frame's transaction, where the landing nulled its transaction with its lane value still on and the next read of it crashed (laneRead→txOf(null),REACTIVITY_HALTED) — aLoadingoverlatest(x), or a memo ofisPending(() => x()), unmounted and remounted whilexis held (fuzzer F7a/F7b; A15 #3698: lane work never makes its node transaction work). -
0c550fd: A mainline mount whose child reads a lane derivation in flight shows the child as a stale reader beside its mount control, whether or not the lane is held (fuzzer F8)
-
2317623: Fix a render effect a lane took over from a held transaction: it keeps running as the lane's work while it waits on the lane's flight, and drops the hold when it leaves the lane (#3766).
-
4f67697: Breaking: only
onfollowed by an uppercase letter (onClick,onPointerDown) is an event handler. Lowercaseon*names (onclick,onmouseover) are plain attributes everywhere:- Both compilers compile
onclick={expr}like any other attribute (setAttribute, reactive whenexpris dynamic) instead of binding a delegated or native event, and SSR renders it as an escaped attribute instead of dropping it. A leftover 1.xon:click={fn}is likewise a plain namespaced attribute (it previously compiled toaddEventListener(":click", fn)). @solidjs/webspread/assignset lowercaseon*keys as attributes, the server spread walk renders them, anduseHeadapplies lowercaseon*attributes (camelCase handler names stay skipped).ssrAttributeescapes a function value instead of interpolating its source raw.@solidjs/htmland@solidjs/helements wrap a function passed to a lowercaseon*in a getter like any other attribute; onlyonXxxandrefare exempt.@solidjs/htmlcomponents follow@solidjs/h's rule: every zero-argument function prop,onXxxhandlers andrefincluded, is a getter, so a component handler must declare its event argument (onClick=${e => …}).- New dev-only check
LOWERCASE_EVENT_ATTRIBUTE(added to theDiagnosticCodeunion): warns once per attribute name when a function is set on a lowercaseon*(oron:) attribute, naming the camelCase handler to use.
- Both compilers compile
-
2317623: Fix an optimistic store over a derived store hiding its update after an action's local write to the same row: the row a held write staged is no longer guessed over the container's slot (#3796).
-
d1309ad: Resolve a writable derived store's retained draft row to its store proxy when an optimistic store chained over it writes, so the optimistic write to that row shows while its action is pending (#3859).
-
924d909: A store fold's presence notification (
insubscribers) now diffs the old and new presence of each observed key before writing the node, as the value notification already does (#3743).setSignaljoins a held node's transaction before its equality gate (A34 (1): a write to a held node is a proposal, the same value or another), so areconcile()outside an action that had deleted an observed key — the incoming snapshot leaving it absent too — made the whole tick the action's: an unrelateda.valuestayed stale until the action settled. A real presence change still notifies and still proposes on a held node.The adoption's diff base now materializes a nested prototype-overlay draft (a wide owned record) before it is taken: through the overlay's prototype a key the draft had deleted still read as present, so the presence skip fired on a real deletion and a reconcile restoring the key never re-proposed on the held leaf (it committed the draft's
undefinedbeside a backing that had the key).Two optimistic-store fixes the diff uncovered: a container carrying an arrangement guess is now told of an arrangement change whether or not anything subscribes to the container (for a guessed container the write is the landing that judges the guess — before, only the unconditional presence write reached the lane, so a newer question's rows landing beneath an optimistic push published beside it when the reader subscribed to leaves only); and an older truth re-based under an arrangement guess no longer re-stages a slot whose row the committed backing already shows by key, nor an unchanged
length(a spurious frame for leaf-only readers). -
6be6c51: Remove the empty carved module reexport that caused TS2306 during the Signals build.
-
7acc039: A render effect created while an action holds a value it reads no longer runs its callback when a later pass re-stages it before the action lands (#3802). That run passed
undefinedas the value, because the effect had nothing committed yet, so compiled JSX bindings threw and halted reactivity. The effect now runs once, at the commit that lands the action, with the latest staged value. -
bde4299: The seam (
settle) no longer pays the effect-queue merge on a plain flush — nothing parked, no lane reveal, no landing: this flush's runs are the queue as they stand instead of aconcatcopy, a parked flush stashes its runs in place, and the per-flush list resets run only when a list is non-empty. About 100 ns less fixed cost per flush (−11% on a 20k-key store commit, −45% on a one-signal flush), with the effect order of every other seam unchanged. -
1b9ceb6: Size audit (measurement branch):
affects()rebuilt on the L2 hold model as ruled (A24 (4), the #2893 audit) — a declared in-flight change that lights upisPendingon the marked accessor and its derivations for the surrounding transaction's lifetime; never a hold, never an entanglement, never a suspension. A count on the node, listed with its scope; coverage pull-derived at probe time; verdict readers re-derived at registration and release. The store targets return with the stores. Also:GlobalQueue's hook statics aredeclare static(type-only) — they emitted asstatic X;on every bundle. -
1b9ceb6: Attribution on the L2 hold model: the observe-tier engine is fed from the rebuilt lane and verdict layers again (hold census — blockers, optimistic/affects/isPending/latest acknowledgements; optimistic reverts labelled superseded vs reverted; loading-boundary fallback show/hide records; run posture). A lane derivation's first landing no longer trips the dev
SETTLE_WALK_UNINITIALIZED_SOURCEtripwire. -
1b9ceb6: Size audit (measurement branch): the reactive engine rebuilt on the L2 hold model — transactions as the one hold relationship (membership,
blocked, frame reads, born-held), with lanes (createOptimistic), verdicts (isPending/latest), boundaries (createLoadingBoundary/createErrorBoundary),createRevealOrderandactionrebuilt on it as modules behindGlobalQueuehooks; stores,affects()and the attribution engine carved out pending their own steps. Every step is measured on the whole size suite and recorded indocumentation/plans/size-reduction-carve-step1.md(§1–§28), with the maintainer's rulings that decided each behavior. Checkpoint before the §28 replay of the lane layer. -
1b9ceb6: Size audit (measurement branch): carve the lane layer —
createOptimistic's write,isPending,latest— ahead of its rebuild from the §28 principles (documentation/plans/size-reduction-carve-step1.md). The layer measured 1775 B br on+ isPending/latestand 1809 B br on the live page as built. -
1b9ceb6: Size audit (measurement branch): the lane layer rebuilt from the §28 principles (S0 skeleton). A node's value lives in one of three places —
_valuethe committed truth,_pendingValuea transaction's staging,_x._lanethe lane's value — and the lane transaction carries the shown/held state (_shown,_held); the seat of a pass is its node's; leaves read the screen; the body-end correction runs at the seam with one more pure round so its re-derivations are the parent's; a dissolving lane retires the void world's flights. RemovesCONFIG_LANE_HELD,CONFIG_HELD_TRUTH,REACTIVE_VERDICT_RERUNand the seam-time value swap. Fixes #3409 (indicators of a body-end correction clear together) and the #3698 held-lane children case. Design and results indocumentation/plans/size-reduction-carve-step1.md§28. -
1b9ceb6: Size audit (measurement branch): §28 S1 — holds and seams on the rebuilt lane layer. A render effect reading a lane flight that has never shown waits on it in its own frame and reads the landed answer at the landing (A15 LANE, #3334); a zombie's say is moot only for the transaction that disposes it (#3463); a lane-derived value committed at a dissolve publishes its inputs (#3648); a boundary re-armed through a display-ahead read swaps as the lane's from the head (#3540); any stale reader of a flight holds it, lane work included (V5/A17).
-
1b9ceb6: Size audit (measurement branch): §28 S2 — verdicts and consolidation on the rebuilt lane layer. The verdict watchers merge into the lane layer's staged-readers list (one seam, one rule: a pass that read this flush's staging as the screen re-derives if the frame parks); one
staleReaderregistration shared by frame reads, lane reads and verdict routes;dissolveLanerestructured by outcome, every guess of a dissolving lane re-homed with its truth. No behavior change; 0 pins moved. -
1b9ceb6: Size audit (measurement branch): the spec pass.
SPEC-ASYNC-SEMANTICS.mdgains "The hold model — L2 (2026-10-04)" — the carve's rulings in the spec's voice, the 2026-10-03 re-pins, and a mechanism note (the per-rule "Mechanism (index, 2026-09-14/15)" paragraphs describe the pre-L2 implementation; the L2 module map is the cross-reference) — with dated amendments on A18, A19, A22, A29 and A34.INTERNALS-ASYNC-STATE.mdgains "0. L2 — the hold model: what replaced §1–§4".RULES-INDEX.mdregenerated; plan-section citations insrc/comments are writtenplan sec. N. Comment-only in source. -
1b9ceb6: Size audit (measurement branch): §41.4 benchmark fixes. A plain pass already marked as having read this flush's staging reads an unheld container staging directly — the per-key "did this key change" question is asked once per pass, not once per key (a
mapArrayover 1k shifted rows asked it 1k times; store array opssplice/shift/unshift/reverse/pushon 1k proxied rows now at parity withnext). At the fold, a child whose parent was adopted whole no longer re-resolves its slot by an O(rows)indexOfthat cannot hit (the slot already holds the child's new backing). -
1b9ceb6: Size audit (measurement branch): §41 benchmark fixes. A derived store's family settle walk runs only after a wake (
fam.woke), not on every sync commit — a 1k-row derived store's no-op re-derive was walking every leaf (14× the fork). A value read under a staging asks only whether the key's value or presence changed (readSource(target, key, shape)); descriptor readers and hold decisions keep the full enumerability/accessor test, as does any container with accessors seen. Keyed reconcile of 1k rows read bymapArrayin the staging flush: 2.5× faster. -
1b9ceb6: Size audit (measurement branch): §41.5 — the container node's escape hatch (Q-A). A store staging gets its container node only when something can read the frame through it: a structural subscriber, lane work, a creation-time pass, or a derive a transaction holds. Otherwise the backing swap and the fold queue are the whole staging — nothing is allocated, queued or swept per container — and when a flush parks, the seam materializes and holds the node for every node-less staging (
_storePark), so a never-read key of a held container still reads committed until the landing (pinned). The fold queue itself no longer allocates per batch: a reusable list plus a weak map of pre-batch backings written in place (a dbmon tick's ~7000 containers cost ~540 KB of map table per tick before). dbmon-deep tick 1.17–1.19× → 1.08–1.13× by the harness's own method; node parity. -
1b9ceb6: Size audit (measurement branch): the fold queue records a pre-batch backing only for adoptions (whose backing swaps eagerly), in a weak map written in place batch after batch; a draft's pre-batch backing is its own committed backing, so nothing is recorded for it — 2000 fresh one-key stores per flush had cost 2000 weak-map insertions and ran at 2×
next(CodSpeed'sfresh storesbench). The two rare moves of a draft's backing mid-batch (a privatization, a draft over an adopted raw) are kept in small per-batch maps. -
1b9ceb6: Size audit (measurement branch): §40 S3c — projection verdict windows and family pending on L2; the promise-delivery readers by posture. A probe answered before the flush had a transaction re-runs at the seam even when a later read routed its pass into the verdict lane (
REACTIVE_PROBE_UNANSWERED); a render effect already observing a derive's flight keeps pulling it on re-run (the frame's hold is not dropped with its flight still up); the post-pass family wake fires only for a flight this pass registered (#3181); a derive's rejection reaches its leaves' readers (handleAsyncgains anonError(error, pending)seam;errorFamily).wakeFamilystamps leaves with the derive as a pending source and propagates through core's ownpropagateStatus(split out ofnotifyStatus): branch recovery stays pending through another path, pending render effects are held by the frame. Arefresh()during a non-quiet flight does not launder the new question; a quiet flight's landing writes are quiet through their reveal on stores.resolve/until/refresh's waiter deliver their own transaction's frame and, over a foreign hold, the committed view at its commit (#3482/#3490). The descriptor trap reads the backing the container's frame serves (#3706). Four pins re-ruled onto L2 / signal parity (plan §40.2): A22-3, #3662 step 1, #3585 never-resolving case, #3038 companion walk. -
1b9ceb6: One provenance test for a derivation's landing and a written landing alike (
stale); signal/store twin pins for the overlapping-actions and kanban shapes. -
1b9ceb6: Optimistic stores: a landing is judged against the guess of the question it answers. Another action's landing beneath a guess is held beneath it (the truth for the commit), the guess keeps showing, and the guess's own landing judges it; an arrangement guess on a keyed list is re-based over the held truth by key (order from the guess, rows from the truth, new rows appended, rows the setter removed stay removed). Two overlapping list edits confirming out of order no longer snap back. A corrected lane that had shown keeps the runs it queued this round; a chained view's guess reverts against the inner store's live value.
-
1b9ceb6: Stores on L2, S1: plain
createStorereturns (snapshot,deep,storePath,isWrappable,markRaw,$TRACK/$TARGET/$PROXY/$RECORD,storeIsShallow). A store is a tree of L2 nodes: one-literal slot nodes (slotSignal) for leaves, presence, deep witness and the container node — the$TRACKnode given a value, whose staging is the pending backing, so the scheduler owns the backing's lifetime. Core: the slot-node sweep dispatch and the store commit hook;_devWindowsbecomes an observe-literal slot;mapArrayreads$TRACKagain. Derived stores, projections, reconcile and optimistic stores return on later steps. -
1b9ceb6: Stores on L2, S2: plain stores under holds. Every leaf read is core's
read()(the hold rules — frame reads, joins, A28 — come from core, tracked or not); nodes are born from the two frames and held by the container's transaction only for keys the batch changed (#3706); structural reads take the container's frame; a setter's returned replacement is staged, not eager. Core:read()'s held arm now applies to untracked reads by a pass (a derivation of a held write is never published mainline — A29/A15). -
1b9ceb6: Stores on L2, S3a:
createProjection,createStore(fn, seed)andreconcilereturn. The firewall is projection-only and lives in the store: every read through a projection pulls the derive first (coreread()of it — untracked when settled, so nothing subscribes to the derive; tracked while a flight is up, so readers observe it as a memo's would); pending propagates to leaf readers by core's own dependent rule and settles at the landing; a derive's continuation writes join its hold; the creation run commits directly; adoption is eager with the container node keeping the committed frame. Core: the self-registered-flight probe inrecomputeis restored (projection-only, carved by mistake); an untracked verdict read of an uninitialized pending node links its reader asread()does. Derived-store manual writes follow A34 rule B (re-pinned). -
1b9ceb6: Stores on L2, S3b: holds on derived stores. A pass reading a key a held batch left unchanged reads committed and holds no one (#3706); a mainline setter above a held adoption publishes mainline for the keys the hold did not change (#3688); a user write to a key whose staging is a held derivation becomes the draft's prior state and the hold re-derives over it (A34 (3), #3612 —
CONFIG_MANUAL_WRITEdiscriminates a user's proposal from the derive's derivation). -
1b9ceb6: Stores on L2, S4: optimistic stores on lanes. A user write to an optimistic store is a guess on the written key's node (presence and container arrangement guesses alongside), shown under the action's hold, confirmed or corrected by a landing beneath it, dissolved at settle — no store-side layer or backup snapshots. The committed backing is never touched by a guess. Reads compose per key through the nodes; a guess over an in-flight derive stands in for the flight (A17). Chained views (
createOptimisticStore(base)) keep their links on the inner store's truth. A user'sreconcileon an optimistic family writes the draft. The optimistic machinery is late-bound: a plain store does not carry the lane layer. Core: a slot node's flight is its family's derive (_slotFlight); an untracked read inside lane work derives from the lane; a pass that joined a hold before its first lane read is re-derived on the screen; linked lanes are judged byblocked; a supersession resolves the lane's merged parent. -
1b9ceb6: Store size pass after S4: the write override is a live binding (no accessor call on the
gethot path); the optimistic draft and its set-aside staging live in the optimistic module; one predicate for the lane-view composition sites. Behavior unchanged. -
1b9ceb6: Stores on L2, S5: the store half of
affects()—affects(store)marks the record's carrier and every live node under it,affects(record, key)the slot's leaf; coverage by raw identity (captured proxies, chained views, cross-family raws), nodes born in the window inherit the mark, untracked probes are witnessed. Ambient marks whose flush parks join its transaction; one over a node whose own flight is up (a declared reload) lives to the landing.StoreNodeis exported again (the L2 target's shape). -
1b9ceb6: Stores on L2, S-U:
merge/omitand the merge/omit view machinery (utils.ts) are back unchanged; the carve has no stubs left. -
1a3f87f: Store fold queue: the pre-batch committed backing is recorded beside the queued target and released with the drain. The weak map it replaces kept every container's last adopted-away backing alive until its next adoption — for a keyed reconcile, the previous tick's whole tree promoted out of the nursery every tick (the saturated listened-paths and reconcile-tree shapes ran 10–15% over
nexton that alone); for a store adopted once, the old tree for the store's lifetime. The per-batch side maps for mid-batch privatizations and drafts over adoptions fold into the same record. -
5622be8:
UNSTABLE_MEMO_OUTPUTcompares symbol-keyed properties too, so a memo returning a fresh symbol-keyed box each run (asdynamicdoes for an in-flight promise) is no longer reported as new-but-equivalent. -
11e9fb6: A mount made by a verdict reader stays mainline (#3851). Inside an action,
<Show when={latest(x) > 0}>opens at once, but a<Loading>it mounts used to showcontent 1beside the committedx = 0: the content's first pass was staged in the verdict lane its creator was in, and in the action's own flush it read the stagedxbefore the seam held it. A first pass now takes its creator's lane only for an optimistic lane (head and tail of its pass alike); a mount a verdict lane makes whose first pass reads a staging of a flush with a transaction is born held like one that read a held node (other new memos do not join the transaction by being created); and verdict-lane work that read the frame's stagings re-derives on the committed world when the frame stays parked. The boundary shows its fallback andcontent 1at the landing. -
b07fed5: A memo pulled by an
isPending/latestprobe computes as its own pass, outside the probe's window: it no longer caches the committed input in place of a flushed write (fuzzer F10), or reads an uninitialized input asundefinedinstead of suspending (F11). -
b0bad02: A verdict reader that reveals a flight nobody holds registers it with the frame (A15 first observer, #3458):
observeFlightholds the flight's node in the frame's transaction, so the transaction waits for the landing instead of holding nothing, landing at its own seam and re-deriving the reader into the same observation every flush ("Potential Infinite Loop Detected") — an action whose body-end write re-asks an async memo as its verdict lane's work, revealed to alatest()reader the action adopted (fuzzer F12), or any memo re-asked unobserved and then revealed to a reader usinglatest()/isPending(). -
b07fed5: An
isPendingreader of an async memo settles when the memo's flight lands equal to its committed value: the settle walk re-derives the verdict reader instead of leaving ittrue(fuzzer F9). -
b0c8489: A re-run that commits
undefinedis no longer counted as waste. A projection that mutates its draft or reconciles a returned value, or a memo that does its work by writing a signal, has no output to compare, so its re-runs were reported as pure cost.RerunEvent.changednow reportstruefor these runs (as it already did for side-effect-only effects), soWASTED_RECOMPUTEno longer fires for them andcosts().wastedMs,expectNoWasteand the performance tracks stop counting them as wasted.