@solidjs/signals 2.0.0-rc.1 → 2.0.0-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/dist/dev-shared.js +7138 -0
  2. package/dist/dev.attribution.js +3307 -0
  3. package/dist/dev.js +5691 -4491
  4. package/dist/observe/affects.js +129 -0
  5. package/dist/observe/attribution.js +7 -0
  6. package/dist/observe/boundaries.js +793 -0
  7. package/dist/observe/core/action.js +177 -0
  8. package/dist/observe/core/async.js +849 -0
  9. package/dist/observe/core/attribution-costs.js +66 -0
  10. package/dist/observe/core/attribution-feedback.js +280 -0
  11. package/dist/observe/core/attribution-hooks.js +83 -0
  12. package/dist/observe/core/attribution-queries.js +43 -0
  13. package/dist/observe/core/attribution.js +2904 -0
  14. package/dist/observe/core/constants.js +283 -0
  15. package/dist/{types-cjs/core/context.d.cts → observe/core/context.js} +37 -12
  16. package/dist/observe/core/core.js +1999 -0
  17. package/dist/observe/core/dev.js +343 -0
  18. package/dist/observe/core/effect.js +200 -0
  19. package/dist/observe/core/error-hooks.js +71 -0
  20. package/dist/observe/core/error.js +80 -0
  21. package/dist/observe/core/external.js +98 -0
  22. package/dist/observe/core/graph.js +155 -0
  23. package/dist/observe/core/heap.js +147 -0
  24. package/dist/observe/core/invariants.js +45 -0
  25. package/dist/observe/core/lanes.js +205 -0
  26. package/dist/observe/core/optimistic.js +627 -0
  27. package/dist/observe/core/owner.js +353 -0
  28. package/dist/observe/core/scheduler.js +1547 -0
  29. package/dist/observe/core/verdict.js +674 -0
  30. package/dist/observe/index.js +59 -0
  31. package/dist/observe/map.js +484 -0
  32. package/dist/observe/signals.js +731 -0
  33. package/dist/observe/store/index.js +44 -0
  34. package/dist/observe/store/next/optimistic.js +717 -0
  35. package/dist/observe/store/next/projection.js +266 -0
  36. package/dist/observe/store/next/reconcile.js +375 -0
  37. package/dist/observe/store/next/store.js +2480 -0
  38. package/dist/observe/store/next/target.js +51 -0
  39. package/dist/observe/store/store.js +331 -0
  40. package/dist/observe/store/storePath.js +103 -0
  41. package/dist/observe/store/utils.js +1070 -0
  42. package/dist/prod/affects.js +10 -9
  43. package/dist/prod/attribution.js +45 -0
  44. package/dist/prod/boundaries.js +388 -178
  45. package/dist/prod/core/action.js +65 -37
  46. package/dist/prod/core/async.js +378 -163
  47. package/dist/prod/core/attribution-hooks.js +3 -0
  48. package/dist/prod/core/constants.js +186 -1
  49. package/dist/prod/core/context.js +10 -16
  50. package/dist/prod/core/core.js +1546 -416
  51. package/dist/prod/core/dev.js +18 -1
  52. package/dist/prod/core/effect.js +119 -79
  53. package/dist/prod/core/error-hooks.js +71 -0
  54. package/dist/prod/core/error.js +13 -1
  55. package/dist/prod/core/external.js +4 -4
  56. package/dist/prod/core/graph.js +105 -54
  57. package/dist/prod/core/heap.js +72 -65
  58. package/dist/prod/core/invariants.js +3 -2
  59. package/dist/prod/core/lanes.js +117 -52
  60. package/dist/prod/core/optimistic.js +458 -104
  61. package/dist/prod/core/owner.js +131 -84
  62. package/dist/prod/core/scheduler.js +998 -241
  63. package/dist/prod/core/verdict.js +417 -112
  64. package/dist/prod/index.js +20 -8
  65. package/dist/prod/map.js +312 -151
  66. package/dist/prod/signals.js +363 -32
  67. package/dist/prod/store/index.js +2 -0
  68. package/dist/prod/store/next/optimistic.js +530 -197
  69. package/dist/prod/store/next/projection.js +142 -57
  70. package/dist/prod/store/next/reconcile.js +149 -103
  71. package/dist/prod/store/next/store.js +1470 -346
  72. package/dist/prod/store/next/target.js +40 -9
  73. package/dist/prod/store/store.js +23 -19
  74. package/dist/prod/store/utils.js +997 -130
  75. package/dist/types/attribution.d.ts +19 -0
  76. package/dist/types/attribution.prod.d.ts +22 -0
  77. package/dist/types/boundaries.d.ts +78 -5
  78. package/dist/types/core/action.d.ts +12 -5
  79. package/dist/types/core/async.d.ts +3 -1
  80. package/dist/types/core/attribution-costs.d.ts +35 -0
  81. package/dist/types/core/attribution-feedback.d.ts +133 -0
  82. package/dist/types/core/attribution-hooks.d.ts +304 -0
  83. package/dist/types/core/attribution-queries.d.ts +24 -0
  84. package/dist/types/core/attribution.d.ts +892 -0
  85. package/dist/types/core/constants.d.ts +179 -0
  86. package/dist/types/core/core.d.ts +299 -25
  87. package/dist/types/core/dev.d.ts +421 -8
  88. package/dist/types/core/effect.d.ts +8 -1
  89. package/dist/types/core/error-hooks.d.ts +71 -0
  90. package/dist/types/core/error.d.ts +9 -0
  91. package/dist/types/core/graph.d.ts +23 -0
  92. package/dist/types/core/heap.d.ts +5 -3
  93. package/dist/types/core/index.d.ts +6 -3
  94. package/dist/types/core/invariants.d.ts +5 -1
  95. package/dist/types/core/lanes.d.ts +51 -19
  96. package/dist/types/core/owner.d.ts +15 -3
  97. package/dist/types/core/scheduler.d.ts +248 -1
  98. package/dist/types/core/types.d.ts +124 -41
  99. package/dist/types/index.d.ts +18 -5
  100. package/dist/types/map.d.ts +2 -0
  101. package/dist/types/signals.d.ts +145 -13
  102. package/dist/types/store/index.d.ts +7 -6
  103. package/dist/types/store/next/optimistic.d.ts +18 -13
  104. package/dist/types/store/next/projection.d.ts +5 -2
  105. package/dist/types/store/next/reconcile.d.ts +7 -0
  106. package/dist/types/store/next/store.d.ts +83 -11
  107. package/dist/types/store/next/target.d.ts +108 -11
  108. package/dist/types/store/store.d.ts +20 -11
  109. package/dist/types/store/utils.d.ts +188 -0
  110. package/package.json +31 -26
  111. package/dist/node.cjs +0 -8137
  112. package/dist/types/store/optimistic.d.ts +0 -45
  113. package/dist/types/store/projection.d.ts +0 -70
  114. package/dist/types/store/reconcile.d.ts +0 -46
  115. package/dist/types-cjs/affects.d.cts +0 -47
  116. package/dist/types-cjs/boundaries.d.cts +0 -175
  117. package/dist/types-cjs/core/action.d.cts +0 -64
  118. package/dist/types-cjs/core/async.d.cts +0 -21
  119. package/dist/types-cjs/core/constants.d.cts +0 -71
  120. package/dist/types-cjs/core/core.d.cts +0 -156
  121. package/dist/types-cjs/core/dev.d.cts +0 -64
  122. package/dist/types-cjs/core/effect.d.cts +0 -30
  123. package/dist/types-cjs/core/error.d.cts +0 -47
  124. package/dist/types-cjs/core/external.d.cts +0 -15
  125. package/dist/types-cjs/core/graph.d.cts +0 -5
  126. package/dist/types-cjs/core/heap.d.cts +0 -22
  127. package/dist/types-cjs/core/index.d.cts +0 -13
  128. package/dist/types-cjs/core/invariants.d.cts +0 -59
  129. package/dist/types-cjs/core/lanes.d.cts +0 -56
  130. package/dist/types-cjs/core/optimistic.d.cts +0 -6
  131. package/dist/types-cjs/core/owner.d.cts +0 -124
  132. package/dist/types-cjs/core/scheduler.d.cts +0 -172
  133. package/dist/types-cjs/core/types.d.cts +0 -148
  134. package/dist/types-cjs/core/verdict.d.cts +0 -2
  135. package/dist/types-cjs/index.d.cts +0 -10
  136. package/dist/types-cjs/map.d.cts +0 -69
  137. package/dist/types-cjs/package.json +0 -3
  138. package/dist/types-cjs/signals.d.cts +0 -624
  139. package/dist/types-cjs/store/index.d.cts +0 -19
  140. package/dist/types-cjs/store/next/optimistic.d.cts +0 -20
  141. package/dist/types-cjs/store/next/projection.d.cts +0 -24
  142. package/dist/types-cjs/store/next/reconcile.d.cts +0 -3
  143. package/dist/types-cjs/store/next/store.d.cts +0 -71
  144. package/dist/types-cjs/store/next/target.d.cts +0 -99
  145. package/dist/types-cjs/store/optimistic.d.cts +0 -45
  146. package/dist/types-cjs/store/projection.d.cts +0 -70
  147. package/dist/types-cjs/store/reconcile.d.cts +0 -46
  148. package/dist/types-cjs/store/store.d.cts +0 -138
  149. package/dist/types-cjs/store/storePath.d.cts +0 -58
  150. package/dist/types-cjs/store/utils.d.cts +0 -74
@@ -0,0 +1,3 @@
1
+ let attrHooks = null;
2
+
3
+ export { attrHooks };
@@ -30,6 +30,15 @@ const REACTIVE_MANUAL_WRITE = 1 << 10;
30
30
  * pending window does not read as pending (question-scoped pending model).
31
31
  */ const REACTIVE_REASK = 1 << 11;
32
32
 
33
+ /**
34
+ * A dependency write landed while this subscriber was mid-recompute — a
35
+ * nested pull committed beneath one of its reads (#3037). The heap refuses
36
+ * RECOMPUTING nodes, so recompute's tail consumes this latch and reschedules:
37
+ * values the pass read before the nested commit are stale. Only set for
38
+ * links validated this pass (gen-current): a write to an untouched link is
39
+ * either re-read later in the pass (fresh) or trimmed with it (not a dep).
40
+ */ const REACTIVE_MISSED_WAKE = 1 << 12;
41
+
33
42
  // Static configuration bits packed into Owner/Computed/Signal _config.
34
43
  const CONFIG_OWNED_WRITE = 1 << 0;
35
44
 
@@ -45,6 +54,179 @@ const CONFIG_AUTO_DISPOSE = 1 << 5;
45
54
 
46
55
  const CONFIG_SYNC = 1 << 6;
47
56
 
57
+ // Presence bits (stage-3 hot-path monomorphism, DESIGN-PATCH-CHANNEL §11b):
58
+ // optional per-node slots (_overrideValue, _pendingSignal/_latestValueComputed,
59
+ // _snapshotValue, _optimisticLane) are NOT part of every node's hidden class —
60
+ // reading a missing property defeats V8's inline caches on the hottest write/
61
+ // notify loops. These bits live on the always-present `_config` so hot paths
62
+ // pay one monomorphic masked read and only touch the optional field when its
63
+ // installer flagged it. Bits are STICKY ("may be set") — the guarded field
64
+ // read remains authoritative.
65
+ const CONFIG_OPTIMISTIC = 1 << 7;
66
+
67
+ const CONFIG_HAS_COMPANIONS = 1 << 8;
68
+
69
+ const CONFIG_HAS_SNAPSHOT = 1 << 9;
70
+
71
+ const CONFIG_HAS_LANE = 1 << 10;
72
+
73
+ /** Set on a FIREWALL computed when any of its child signals creates an
74
+ * isPending()/latest() companion. Gates the post-recompute child-companion
75
+ * walk (#3038): a store computed's `_child` chain holds one node per
76
+ * materialized leaf, so walking it unconditionally makes every update cost
77
+ * O(all leaves ever read). Sticky — set at companion creation, never
78
+ * cleared; sync-only apps never set it and never pay the walk. */ const CONFIG_CHILD_COMPANIONS = 1 << 11;
79
+
80
+ /** Set on a computed when its first firewall child signal is installed
81
+ * (projection machinery). Gates markNode's firewall-children walk with one
82
+ * masked read of the always-present _config — the walk's old `_child` read
83
+ * moved into the cold extension (§12), and an unconditional `_x` deref per
84
+ * marked node measurably taxed the propagation hot path (diamond -22%). */ const CONFIG_FW_CHILDREN = 1 << 12;
85
+
86
+ /** Authoritative-view reader (`until()`): while this node computes, reads
87
+ * dodge active optimistic OVERRIDES only — the predicate must observe
88
+ * arriving truth, never the caller's own tentative writes (which would
89
+ * trivially satisfy it). Everything else reads normally, INCLUDING
90
+ * transition-staged `_pendingValue`: staged data is authoritative (optimism
91
+ * lives only in override slots), and a hold that refused staged reads would
92
+ * deadlock on data the open transaction itself is holding (a refresh the
93
+ * action issued lands staged and cannot commit until the hold releases).
94
+ * read() checks the bit on the reading computation (`context`) directly — no
95
+ * ambient flag — so a shared computed the predicate pulls recomputes as
96
+ * itself (no bit) under the normal view, and its cache never forks. */ const CONFIG_AUTHORITATIVE_READ = 1 << 13;
97
+
98
+ /** Sticky mark: an authoritative-view reader read this node PAST an active
99
+ * override. The ack shape — an authoritative arrival EQUAL to the override —
100
+ * rides paths that are deliberately silent under A17 (every ordinary reader
101
+ * sees the override, so an equal landing changes nothing for them). A marked
102
+ * node notifies those readers on such paths anyway, so the landed truth is
103
+ * seen without re-firing ordinary subscribers. Never cleared — only nodes an
104
+ * until() predicate observed mid-override pay. */ const CONFIG_AUTHORITATIVE_OBSERVED = 1 << 14;
105
+
106
+ /** Promise-delivery effect (resolve()/until()): commits its computed value
107
+ * directly even when recomputing under its own held transition. These
108
+ * effects deliver applies on a microtask (#2930) instead of the stashed
109
+ * effect queues, so the value must ride the same immediate schedule — a
110
+ * staged value with an immediate apply delivers stale state (resolve) or
111
+ * deadlocks the hold (until). Safe because the node is a private leaf: no
112
+ * subscriber reads an effect's value, only its own apply does. */ const CONFIG_DIRECT_COMMIT = 1 << 15;
113
+
114
+ /** Fresh-pull reader (awaitable `refresh()`'s waiter effect): a read of a
115
+ * dirty source recomputes it inline even when the height gate defers to the
116
+ * flush. Closes the same-flush ordering race where a waiter created
117
+ * alongside a refresh() mark read the PRE-re-ask value as settled and
118
+ * delivered stale; with the pull, the waiter either parks on the re-ask's
119
+ * pending window (async — woken by the settle walk, which runs on every
120
+ * landing including equal-value ones) or serves its sync answer. resolve()
121
+ * deliberately keeps that race — its contract is "first settled value"
122
+ * (#2930), not "next quiescent state". */ const CONFIG_FRESH_READ = 1 << 16;
123
+
124
+ /** HELD truth (#3164): this node's staged `_pendingValue` is confirming
125
+ * truth riding a transaction that retains optimism, revealed only at that
126
+ * transaction's settle. Two arming sites, one meaning: the store fold
127
+ * (a landing staged into the retaining transaction) and until()'s
128
+ * flip-entanglement (a foreign carrier's staged write, stolen when it
129
+ * flipped the awaited predicate truthy). Override-covered nodes never
130
+ * arm: the override is their display and its revert their notification
131
+ * (A17).
132
+ *
133
+ * To a DERIVING reader the truth is a staged value like any other: a memo
134
+ * or user effect served it enters the transaction and is held with it
135
+ * (A29), so a pass that composes it with a superseded override's truth
136
+ * composes ONE staged world — never staged truth beside committed
137
+ * neighbours (#3568: the mask served the retaining transaction's own pass
138
+ * the landed `length` through the override while the rows past it stayed
139
+ * committed, and `<For>` walked into a hole). Stale readers of a foreign
140
+ * transaction keep committed through the stale-of-foreign clause,
141
+ * untracked reads keep committed (Rule 1), and latest() and until()'s
142
+ * predicate tunnel through — the exemption that keeps holds deadlock-free.
143
+ *
144
+ * The one reader the mark gates is a LANE pass, owning transaction or not
145
+ * (ruled 2026-09-22, superseding #3589's owner exemption): a lane applies
146
+ * its frame display-ahead at the park, so a lane pass served the truth
147
+ * would paint the confirmation beside the optimism it confirms —
148
+ * `saving=true` beside the saved row, a frame no timeline contains
149
+ * (GabbeV's union tear). It keeps committed and is re-run by the reveal's
150
+ * post-revert wake. A lane under the retaining transaction owns its
151
+ * overrides and its lane cargo (`ownsLane`), not the transaction's
152
+ * confirming truth. Cleared at commit (the commit IS the reveal);
153
+ * subscribers masked during the hold are woken by finalizePureQueue's
154
+ * post-revert pass. */ const CONFIG_HELD_TRUTH = 1 << 17;
155
+
156
+ /** SLOT node (store leaf): created through `slotSignal` with `_host`/`_key`
157
+ * backrefs baked into the literal. The unobserved sweep dispatches these to
158
+ * the ONE shared hook (`setSlotUnobserved`) instead of a per-node closure
159
+ * held in a per-node extension — store mounts materialize one signal per
160
+ * touched leaf, so per-node allocations (options object, equals closure,
161
+ * unobserved closure, NodeExtension) were the measured create-floor bytes
162
+ * (warm dbmon profile: store node machinery ~36% + GC ~29%). */ const CONFIG_SLOT_NODE = 1 << 18;
163
+
164
+ /** Optimistic node whose own source arrived with a value DIFFERENT from its
165
+ * active override (A18 supersession, #3331). The override survives only as
166
+ * the displayed value — untracked reads and the applied frame keep it until
167
+ * the owning transaction commits — while the graph has already moved to the
168
+ * staged truth in `_pendingValue`: tracked readers see it and the corrected
169
+ * cascade is that transaction's held work. Set by the two own-source write
170
+ * paths (asyncWrite, transition-held recompute); cleared by a fresh optimistic
171
+ * write (a new override re-masks) and by the revert. */ const CONFIG_OVERRIDE_SUPERSEDED = 1 << 19;
172
+
173
+ /** HELD children (#3404): this node's `_firstChild` chain (and `_disposal`
174
+ * list) was built by a recompute whose result has not committed — a staged
175
+ * value, a pending window, or a run under a held transaction. A later
176
+ * recompute may tear those children down immediately: nothing observable
177
+ * was ever built on them. Unset, the children belong to the committed frame
178
+ * and a recompute defers them as zombies (`_pendingFirstChild`) until this
179
+ * node commits — regardless of whether the recompute runs under a
180
+ * transaction. A parked node (status propagation stamps `_transition`
181
+ * without recomputing) recomputed when its source lands otherwise disposed
182
+ * its committed children mid-hold, running their cleanups before the
183
+ * transaction's atomic reveal. Cleared by `commitPendingNode`. */ const CONFIG_HELD_CHILDREN = 1 << 20;
184
+
185
+ /** The frame parked in `_pendingFirstChild` / `_pendingDisposal` is a LANE
186
+ * frame (#3662, A15 lanes corollary): an effect's lane pass direct-commits,
187
+ * so the frame it replaces leaves the screen when the lane's queue applies
188
+ * the run (A30) — not at the action's commit like #3404's transaction
189
+ * zombies, and not at the pass (a held lane defers the run). Drained by the
190
+ * lane's render entry the parking site pushed ahead of the new frame's
191
+ * effects (cleanups before side effects), by `commitPendingNode` if a hold
192
+ * commits the node first, or with the owner's death. While set the parked
193
+ * frame is not a hold (the node is not queued or stamped for it), a
194
+ * superseding pass disposes the never-shown live children on the spot, and a
195
+ * lane-channel dirty on a member is cancelled (`laneZombie`). Effects only: a
196
+ * memo's lane pass publishes an override (A17, #3479). */ const CONFIG_LANE_FRAME = 1 << 26;
197
+
198
+ /** In-flight async node whose inputs were PUBLISHED while it was pending: a
199
+ * batch or transaction committed with the node still `STATUS_PENDING` (an
200
+ * unobserved flight, #3305), so the inputs are on screen and the node's
201
+ * committed `_value` is stale against them. Governs read()'s reveal
202
+ * carve-out: a stale (render) reader in some OTHER transaction may show a
203
+ * foreign-held pending node's committed value — parallel transactions, no
204
+ * entanglement — only while that value is coherent with the visible frame,
205
+ * i.e. while the flight's inputs are themselves held (unpublished) and not
206
+ * lane-revealed. Set by `commitPendingNodes`; cleared when the node next
207
+ * enters pending fresh (a new flight from a settled state). */ const CONFIG_INPUTS_PUBLISHED = 1 << 21;
208
+
209
+ /** A28 (4): the node was written inside a recompute that ran OUTSIDE a flush
210
+ * (a creation-time compute — boundary machinery, a mapArray's first run). Such
211
+ * a write is promoted at that recompute's end: readers in the same block see
212
+ * it. Cleared when the next flush begins; set only on that rare path. */ const CONFIG_PROMOTED = 1 << 22;
213
+
214
+ /** A28 for same-tick adoption: the node was staged outside a flush and then
215
+ * adopted by a transaction (initTransition) before any flush carried the
216
+ * staging — the stamp says "held", but nothing flushed is staged for it, so
217
+ * on no channel is the write visible yet: `latest()` answers the committed
218
+ * value, the verdict sees nothing pending (as the store's leaves already did
219
+ * through their own selection). Cleared when the carrying flush re-stamps the
220
+ * transaction's pending nodes (reassignPendingTransition). */ const CONFIG_ADOPTED_UNFLUSHED = 1 << 24;
221
+
222
+ /** The node's active override is a DERIVED one: a lane pass published its
223
+ * speculative result into the override slot instead of `_value` (lanes
224
+ * stage — an optimistic derivation is an override, #3479). Its truth is not
225
+ * `_value` but a recompute from its inputs' truth, so the body-end
226
+ * supersession (`endOptimism`) and the authoritative-flight blockage
227
+ * (`transitionBlocked`) skip it; the revert drops the override and re-derives
228
+ * it (`resolveOptimisticNodes`). Cleared with the override. */ const CONFIG_DERIVED_OVERRIDE = 1 << 23;
229
+
48
230
  const STATUS_PENDING = 1 << 0;
49
231
 
50
232
  const STATUS_ERROR = 1 << 1;
@@ -57,6 +239,9 @@ const EFFECT_USER = 2;
57
239
 
58
240
  const EFFECT_TRACKED = 3;
59
241
 
242
+ /** OR-ed into the `type` a lane passes to its effect runners: lane runs
243
+ * apply ahead of their transaction and are exempt from ownership parking. */ const LANE_RUN = 4;
244
+
60
245
  const NOT_PENDING = {};
61
246
 
62
247
  const NO_SNAPSHOT = {};
@@ -89,4 +274,4 @@ const defaultContext = {};
89
274
  * @internal
90
275
  */ const $REFRESH = Symbol("refresh");
91
276
 
92
- export { $REFRESH, CONFIG_AUTO_DISPOSE, CONFIG_CHILDREN_FORBIDDEN, CONFIG_IN_SNAPSHOT_SCOPE, CONFIG_NO_SNAPSHOT, CONFIG_OWNED_WRITE, CONFIG_SYNC, CONFIG_TRANSPARENT, EFFECT_RENDER, EFFECT_TRACKED, EFFECT_USER, NOT_PENDING, NO_SNAPSHOT, OVERRIDE_UNDEFINED, REACTIVE_CHECK, REACTIVE_DIRTY, REACTIVE_DISPOSED, REACTIVE_IN_HEAP, REACTIVE_IN_HEAP_HEIGHT, REACTIVE_LAZY, REACTIVE_MANUAL_WRITE, REACTIVE_NONE, REACTIVE_OPTIMISTIC_DIRTY, REACTIVE_REASK, REACTIVE_RECOMPUTING_DEPS, REACTIVE_SNAPSHOT_STALE, REACTIVE_ZOMBIE, STATUS_ERROR, STATUS_PENDING, STATUS_UNINITIALIZED, STORE_SNAPSHOT_PROPS, SUPPORTS_PROXY, defaultContext, unwrapOverride };
277
+ export { $REFRESH, CONFIG_ADOPTED_UNFLUSHED, CONFIG_AUTHORITATIVE_OBSERVED, CONFIG_AUTHORITATIVE_READ, CONFIG_AUTO_DISPOSE, CONFIG_CHILDREN_FORBIDDEN, CONFIG_CHILD_COMPANIONS, CONFIG_DERIVED_OVERRIDE, CONFIG_DIRECT_COMMIT, CONFIG_FRESH_READ, CONFIG_FW_CHILDREN, CONFIG_HAS_COMPANIONS, CONFIG_HAS_LANE, CONFIG_HAS_SNAPSHOT, CONFIG_HELD_CHILDREN, CONFIG_HELD_TRUTH, CONFIG_INPUTS_PUBLISHED, CONFIG_IN_SNAPSHOT_SCOPE, CONFIG_LANE_FRAME, CONFIG_NO_SNAPSHOT, CONFIG_OPTIMISTIC, CONFIG_OVERRIDE_SUPERSEDED, CONFIG_OWNED_WRITE, CONFIG_PROMOTED, CONFIG_SLOT_NODE, CONFIG_SYNC, CONFIG_TRANSPARENT, EFFECT_RENDER, EFFECT_TRACKED, EFFECT_USER, LANE_RUN, NOT_PENDING, NO_SNAPSHOT, OVERRIDE_UNDEFINED, REACTIVE_CHECK, REACTIVE_DIRTY, REACTIVE_DISPOSED, REACTIVE_IN_HEAP, REACTIVE_IN_HEAP_HEIGHT, REACTIVE_LAZY, REACTIVE_MANUAL_WRITE, REACTIVE_MISSED_WAKE, REACTIVE_NONE, REACTIVE_OPTIMISTIC_DIRTY, REACTIVE_REASK, REACTIVE_RECOMPUTING_DEPS, REACTIVE_SNAPSHOT_STALE, REACTIVE_ZOMBIE, STATUS_ERROR, STATUS_PENDING, STATUS_UNINITIALIZED, STORE_SNAPSHOT_PROPS, SUPPORTS_PROXY, defaultContext, unwrapOverride };
@@ -29,11 +29,13 @@ import { getOwner } from "./owner.js";
29
29
  if (!t) {
30
30
  throw new NoOwnerError;
31
31
  }
32
- const n = hasContext(e, t) ? t.we[e.id] : e.defaultValue;
33
- if (isUndefined(n)) {
32
+ // `undefined` alone means unset — a provided `null` is a value (no `??`).
33
+ let r = t.Je[e.id];
34
+ if (r === undefined) r = e.defaultValue;
35
+ if (r === undefined) {
34
36
  throw new ContextNotFoundError;
35
37
  }
36
- return n;
38
+ return r;
37
39
  }
38
40
 
39
41
  /**
@@ -44,24 +46,16 @@ import { getOwner } from "./owner.js";
44
46
  * @throws `NoOwnerError` if there's no owner at the time of call.
45
47
  *
46
48
  * @internal
47
- */ function setContext(e, t, n = getOwner()) {
48
- if (!n) {
49
+ */ function setContext(e, t, r = getOwner()) {
50
+ if (!r) {
49
51
  throw new NoOwnerError;
50
52
  }
51
53
  // We're creating a new object to avoid child context values being exposed to parent owners. If
52
54
  // we don't do this, everything will be a singleton and all hell will break lose.
53
- n.we = {
54
- ...n.we,
55
- [e.id]: isUndefined(t) ? e.defaultValue : t
55
+ r.Je = {
56
+ ...r.Je,
57
+ [e.id]: t === undefined ? e.defaultValue : t
56
58
  };
57
59
  }
58
60
 
59
- function hasContext(e, t) {
60
- return !isUndefined(t?.we[e.id]);
61
- }
62
-
63
- function isUndefined(e) {
64
- return typeof e === "undefined";
65
- }
66
-
67
61
  export { createContext, getContext, setContext };