@solidjs/signals 2.0.0-rc.11 → 2.0.0-rc.14

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 (118) hide show
  1. package/dist/dev-shared.js +2056 -3773
  2. package/dist/dev.attribution.js +159 -91
  3. package/dist/dev.js +7263 -8384
  4. package/dist/observe/affects.js +125 -104
  5. package/dist/observe/boundaries.js +458 -665
  6. package/dist/observe/core/action.js +63 -66
  7. package/dist/observe/core/async.js +240 -383
  8. package/dist/observe/core/attribution-queries.js +1 -1
  9. package/dist/observe/core/attribution.js +271 -199
  10. package/dist/observe/core/constants.js +115 -178
  11. package/dist/observe/core/context.js +3 -3
  12. package/dist/observe/core/core.js +840 -1428
  13. package/dist/observe/core/dev.js +41 -18
  14. package/dist/observe/core/effect.js +75 -86
  15. package/dist/observe/core/external.js +5 -5
  16. package/dist/observe/core/graph.js +61 -70
  17. package/dist/observe/core/heap.js +75 -98
  18. package/dist/observe/core/invariants.js +1 -34
  19. package/dist/observe/core/lanes.js +704 -181
  20. package/dist/observe/core/owner.js +80 -101
  21. package/dist/observe/core/scheduler.js +708 -1351
  22. package/dist/observe/core/verdict.js +302 -621
  23. package/dist/observe/flatten.js +79 -0
  24. package/dist/observe/index.js +15 -13
  25. package/dist/observe/map.js +232 -235
  26. package/dist/observe/reveal.js +212 -0
  27. package/dist/observe/signals.js +133 -215
  28. package/dist/observe/store/affects.js +135 -0
  29. package/dist/observe/store/index.js +29 -24
  30. package/dist/observe/store/optimistic.js +538 -0
  31. package/dist/observe/store/projection.js +302 -0
  32. package/dist/observe/store/reconcile.js +257 -0
  33. package/dist/observe/store/store.js +1945 -277
  34. package/dist/observe/store/storePath.js +1 -1
  35. package/dist/{prod/store/next → observe/store}/target.js +17 -18
  36. package/dist/observe/store/types.js +73 -0
  37. package/dist/observe/store/utils.js +1 -13
  38. package/dist/prod/affects.js +127 -106
  39. package/dist/prod/boundaries.js +442 -654
  40. package/dist/prod/core/action.js +71 -74
  41. package/dist/prod/core/async.js +307 -442
  42. package/dist/prod/core/constants.js +112 -177
  43. package/dist/prod/core/context.js +3 -3
  44. package/dist/prod/core/core.js +852 -1448
  45. package/dist/prod/core/effect.js +88 -99
  46. package/dist/prod/core/external.js +5 -5
  47. package/dist/prod/core/graph.js +61 -70
  48. package/dist/prod/core/heap.js +75 -98
  49. package/dist/prod/core/invariants.js +1 -32
  50. package/dist/prod/core/lanes.js +666 -181
  51. package/dist/prod/core/owner.js +75 -96
  52. package/dist/prod/core/scheduler.js +677 -1332
  53. package/dist/prod/core/verdict.js +297 -621
  54. package/dist/prod/flatten.js +77 -0
  55. package/dist/prod/index.js +15 -13
  56. package/dist/prod/map.js +143 -146
  57. package/dist/prod/reveal.js +212 -0
  58. package/dist/prod/signals.js +144 -226
  59. package/dist/prod/store/affects.js +135 -0
  60. package/dist/prod/store/index.js +28 -19
  61. package/dist/prod/store/optimistic.js +533 -0
  62. package/dist/prod/store/projection.js +295 -0
  63. package/dist/prod/store/reconcile.js +257 -0
  64. package/dist/prod/store/store.js +1840 -272
  65. package/dist/prod/store/storePath.js +1 -1
  66. package/dist/{observe/store/next → prod/store}/target.js +13 -17
  67. package/dist/prod/store/types.js +73 -0
  68. package/dist/prod/store/utils.js +1 -11
  69. package/dist/types/affects.d.ts +11 -30
  70. package/dist/types/boundaries.d.ts +62 -176
  71. package/dist/types/carved.d.ts +1 -0
  72. package/dist/types/core/action.d.ts +5 -6
  73. package/dist/types/core/async.d.ts +10 -5
  74. package/dist/types/core/attribution-hooks.d.ts +48 -1
  75. package/dist/types/core/attribution.d.ts +29 -9
  76. package/dist/types/core/constants.d.ts +125 -171
  77. package/dist/types/core/core.d.ts +104 -264
  78. package/dist/types/core/dev.d.ts +60 -7
  79. package/dist/types/core/effect.d.ts +0 -7
  80. package/dist/types/core/graph.d.ts +7 -1
  81. package/dist/types/core/heap.d.ts +5 -7
  82. package/dist/types/core/index.d.ts +6 -6
  83. package/dist/types/core/invariants.d.ts +0 -29
  84. package/dist/types/core/lanes.d.ts +65 -87
  85. package/dist/types/core/owner.d.ts +3 -3
  86. package/dist/types/core/scheduler.d.ts +249 -331
  87. package/dist/types/core/types.d.ts +51 -85
  88. package/dist/types/core/verdict.d.ts +3 -0
  89. package/dist/types/flatten.d.ts +8 -0
  90. package/dist/types/index.d.ts +7 -5
  91. package/dist/types/reveal.d.ts +19 -0
  92. package/dist/types/signals.d.ts +53 -92
  93. package/dist/types/store/affects.d.ts +1 -0
  94. package/dist/types/store/index.d.ts +35 -15
  95. package/dist/types/store/optimistic.d.ts +23 -0
  96. package/dist/types/store/projection.d.ts +18 -0
  97. package/dist/types/store/reconcile.d.ts +3 -0
  98. package/dist/types/store/store.d.ts +165 -143
  99. package/dist/types/store/storePath.d.ts +1 -1
  100. package/dist/types/store/target.d.ts +151 -0
  101. package/dist/types/store/types.d.ts +84 -0
  102. package/package.json +1 -1
  103. package/dist/observe/core/optimistic.js +0 -669
  104. package/dist/observe/store/next/optimistic.js +0 -717
  105. package/dist/observe/store/next/projection.js +0 -266
  106. package/dist/observe/store/next/reconcile.js +0 -375
  107. package/dist/observe/store/next/store.js +0 -2480
  108. package/dist/prod/core/optimistic.js +0 -658
  109. package/dist/prod/store/next/optimistic.js +0 -710
  110. package/dist/prod/store/next/projection.js +0 -257
  111. package/dist/prod/store/next/reconcile.js +0 -373
  112. package/dist/prod/store/next/store.js +0 -2356
  113. package/dist/types/core/optimistic.d.ts +0 -6
  114. package/dist/types/store/next/optimistic.d.ts +0 -25
  115. package/dist/types/store/next/projection.d.ts +0 -27
  116. package/dist/types/store/next/reconcile.d.ts +0 -10
  117. package/dist/types/store/next/store.d.ts +0 -143
  118. package/dist/types/store/next/target.d.ts +0 -196
@@ -1,44 +1,49 @@
1
- import "../core/core.js";
1
+ import { createStore as createStore$1, deep as deep$1, snapshot as snapshot$1 } from "./store.js";
2
2
 
3
- import "../core/dev.js";
3
+ export { storeHasFamily, storeHasOptimisticFamily, storeIsShallow } from "./store.js";
4
4
 
5
- import "../core/scheduler.js";
5
+ import "./affects.js";
6
6
 
7
- import "../core/invariants.js";
7
+ export { createOptimisticStore } from "./optimistic.js";
8
8
 
9
- import "../core/verdict.js";
9
+ import { createStoreDerived } from "./projection.js";
10
10
 
11
- import "../core/effect.js";
11
+ export { createProjection } from "./projection.js";
12
+
13
+ import { reconcileState } from "./reconcile.js";
12
14
 
13
- import { createStoreNext, nameStore, deepNext, snapshotNext } from "./next/store.js";
15
+ import "../core/verdict.js";
16
+
17
+ import "../core/core.js";
14
18
 
15
- export { storeHasFamily, storeHasOptimisticFamily, storeIsShallow } from "./next/store.js";
19
+ import "../core/dev.js";
16
20
 
17
- import { reconcileNextState } from "./next/reconcile.js";
21
+ import "../core/scheduler.js";
18
22
 
19
- import { createStoreDerivedNext } from "./next/projection.js";
23
+ import "../core/effect.js";
20
24
 
21
- export { createProjectionNext as createProjection } from "./next/projection.js";
25
+ import "../core/lanes.js";
22
26
 
23
- function createStore(e, t, r) {
24
- if (typeof e === "function") return createStoreDerivedNext(e, t, r);
25
- {
26
- const r = createStoreNext(e, !!t?.shallow);
27
- if (t?.name) nameStore(r[0], t.name);
28
- return r;
29
- }
27
+ function createStore(e, r, t) {
28
+ if (typeof e === "function") return createStoreDerived(e, r, t);
29
+ return createStore$1(e, r);
30
30
  }
31
31
 
32
- function reconcile(e, t = "id") {
33
- return r => reconcileNextState(e, r, t);
32
+ /**
33
+ * A setter transform that reconciles `value` into the store by key
34
+ * (`"id"` by default; `null` positional), preserving store identity for
35
+ * surviving rows.
36
+ */ function reconcile(e, r = "id") {
37
+ return t => reconcileState(e, t, r);
34
38
  }
35
39
 
36
- function snapshot(e) {
37
- return snapshotNext(e);
40
+ /** Non-tracking snapshot of a store's current value (source identity for
41
+ * unmodified subtrees). */ function snapshot(e) {
42
+ return snapshot$1(e);
38
43
  }
39
44
 
40
- function deep(e) {
41
- return deepNext(e);
45
+ /** Tracking snapshot: subscribes to every reachable record. */ function deep(e) {
46
+ return deep$1(e);
42
47
  }
43
48
 
44
49
  export { createStore, deep, reconcile, snapshot };
@@ -0,0 +1,538 @@
1
+ import { CONFIG_OVERRIDE, CONFIG_AUTO_DISPOSE, NOT_PENDING } from "../core/constants.js";
2
+
3
+ import { computed, ext, untrack, read, isEqual } from "../core/core.js";
4
+
5
+ import { pendingGuessOf, laneValueOf, optimisticWrite } from "../core/lanes.js";
6
+
7
+ import { getOwner } from "../core/owner.js";
8
+
9
+ import { GlobalQueue, txOf, list, insertSubs, laneDirty, notifyEpoch, schedule } from "../core/scheduler.js";
10
+
11
+ import { runProjectionComputed } from "./projection.js";
12
+
13
+ import { wrap, nameStore, storeSetter, LaneView, committed, getNode, unwrapValue, sameKey, installOptHooks, resolveChainedRaw, getHasNode, targetsEqual, getContainerNode, cloneRaw } from "./store.js";
14
+
15
+ import { $OWNER } from "./target.js";
16
+
17
+ import { $TARGET, markRawIngest, $TRACK, isWrappable } from "./types.js";
18
+
19
+ /**
20
+ * Store — optimistic stores on lanes (plan sec. 31, S4; INTERNALS §3/§7, RUL-3).
21
+ *
22
+ * No store-side layer, no backup snapshots, no retaining ledger: a user
23
+ * write to an optimistic store is a GUESS on the written key's node
24
+ * (`optimisticWrite` — the same write `createOptimistic`'s setter makes),
25
+ * a presence guess on its presence node, and, when membership or
26
+ * arrangement changed, an arrangement guess on the container node. Lanes
27
+ * do the rest: the guess shows under the action's hold, a landing beneath
28
+ * it stages as truth and confirms it when equal (A18/A24), the action's
29
+ * settle dissolves it (a revert to the value it covered, or the landed
30
+ * truth). The committed backing is never touched by a guess.
31
+ *
32
+ * Reads compose: a reader of an overlaid target sees the truth it is served
33
+ * with the lanes' values over it (`optimisticView` — per node, by the same
34
+ * rule a leaf read follows: what the lane shows).
35
+ *
36
+ * Landings (Q-D, plan sec. 31.7): the derive's output is reconciled against the
37
+ * optimistic VIEW — a row the guess added and the server returns with the
38
+ * same key in the same position keeps its proxy (the row target adopts the
39
+ * server object), its leaves write truth beneath their guesses, and the
40
+ * container's arrangement guess is confirmed silently (`LaneView`'s
41
+ * comparator) — `For` does not run. Retained-setter replay (the
42
+ * 2026-08-31b continuation half) is not built here; the matrix decides.
43
+ */ const hasOwn = Object.prototype.hasOwnProperty;
44
+
45
+ /** A user setter's writes on an optimistic family, as guesses: one per
46
+ * changed key's leaf, one per presence change, the container's arrangement
47
+ * when membership or order changed. `pb` is the draft (a clone of the view
48
+ * the user saw); `old` the view it composed on. */
49
+ /** An optimistic setter's targets whose staging was set aside (`draft`),
50
+ * restored when the setter's writes become guesses (`writes`). */ const optStaged = new Map;
51
+
52
+ // A chained backing is a proxy: reading it as a handler can expose a
53
+ // derived store's staging. Compose the writer's view on the committed
54
+ // backing of each link, retaining any optimistic guesses on that link.
55
+ function writerBacking(e) {
56
+ const n = committed(e);
57
+ const t = n[$TARGET];
58
+ return t === undefined ? n : optimisticView(t, writerBacking(t), laneValueOf, true);
59
+ }
60
+
61
+ /** The user's draft on an optimistic family: a clone of the view the user
62
+ * saw — the committed frame with the lanes' values and the tick's own
63
+ * unflushed guesses over it (#3665). A staging already on the target (a
64
+ * landing adopted this flush) is set aside for the setter's duration: the
65
+ * guesses go over it, it stays the truth beneath. */ function optimisticDraft(e) {
66
+ if (e.pb !== null) optStaged.set(e, e.pb);
67
+ return cloneRaw(optimisticView(e, writerBacking(e), laneValueOf, true), e);
68
+ }
69
+
70
+ function notifyOptimisticWrites(e, n) {
71
+ // The view the user saw: the committed frame (a staging adopted eagerly
72
+ // is not it) with the lanes' values and the tick's own guesses over it.
73
+ const t = writerBacking(e);
74
+ const i = optimisticView(e, t, laneValueOf, true);
75
+ const r = Array.isArray(n);
76
+ // A chained target's nodes are links (§7b): their committed value is
77
+ // never served and never learns the inner store's commits — yet a guess
78
+ // is judged against it, and reverts to it (#3672). Hand the node the
79
+ // inner store's truth for its key before guessing over it.
80
+ const o = e.ch ? e.v : null;
81
+ const guess = (e, n, i, r) => {
82
+ if (o !== null) e.pe = i ? n in t : unwrapValue(t[n]);
83
+ // By value: a function leaf is a value, not an updater (#3017).
84
+ optimisticWrite(e, () => r);
85
+ };
86
+ let s = false;
87
+ for (const t of Reflect.ownKeys(n)) {
88
+ if (r && t === "length" || t === $OWNER) continue;
89
+ // A chained draft holds the inner store's raws; a raw is the inner slot it
90
+ // resolves to (as a read of it serves) — the row a held write staged is
91
+ // the same row, not a guess over the slot (#3796).
92
+ const a = n[t];
93
+ const f = unwrapValue(o && a ? resolveChainedRaw(e, t, a) : a);
94
+ if (!(t in i)) {
95
+ guess(getNode(e, t), t, false, f);
96
+ guess(getHasNode(e, t), t, true, true);
97
+ s = true;
98
+ } else {
99
+ const n = i[t];
100
+ const a = unwrapValue(o && n ? resolveChainedRaw(e, t, n) : n);
101
+ if (!isEqual(a, f) && !targetsEqual(a, f)) {
102
+ guess(getNode(e, t), t, false, f);
103
+ if (r) s = true;
104
+ }
105
+ }
106
+ }
107
+ for (const t of Reflect.ownKeys(i)) {
108
+ if (r && t === "length" || t === $OWNER) continue;
109
+ if (t in n) continue;
110
+ guess(getNode(e, t), t, false, undefined);
111
+ guess(getHasNode(e, t), t, true, false);
112
+ s = true;
113
+ }
114
+ if (r && i.length !== n.length) {
115
+ guess(getNode(e, "length"), "length", false, n.length);
116
+ s = true;
117
+ }
118
+ if (s) {
119
+ const o = r ? n.map(unwrapValue) : shallowKeys(n);
120
+ // The rows the setter removed from the view it saw, by key: a later
121
+ // re-base over another action's truth must not bring them back.
122
+ let s = null;
123
+ const a = e.fam.key;
124
+ if (r && a !== null && a !== undefined) {
125
+ const e = new Set;
126
+ for (let n = 0; n < o.length; n++) {
127
+ const t = isWrappable(o[n]) ? a(o[n]) : undefined;
128
+ if (t !== undefined) e.add(t);
129
+ }
130
+ for (let n = 0; n < i.length; n++) {
131
+ const t = unwrapValue(i[n]);
132
+ const r = isWrappable(t) ? a(t) : undefined;
133
+ if (r !== undefined && !e.has(r)) (s ??= new Set).add(r);
134
+ }
135
+ }
136
+ optimisticWrite(getContainerNode(e), new LaneView(o, t, s));
137
+ }
138
+ if (e.dk !== null) optimisticWrite(e.dk, {});
139
+ markOverlaid(e);
140
+ const a = optStaged.get(e);
141
+ if (a === undefined) return null;
142
+ optStaged.delete(e);
143
+ return a;
144
+ }
145
+
146
+ /** The container comparator's lane arm (store.ts `containerEquals`): an
147
+ * arrangement guess (`LaneView`) against a landing or another arrangement,
148
+ * by row identity — by key when the family has one. */ function arrangement(e, n, t) {
149
+ const i = n instanceof LaneView;
150
+ const r = t instanceof LaneView;
151
+ if (!i && !r) return false;
152
+ return arrangementEqual(i ? n.rows : n, r ? t.rows : t, e.fam?.key ?? null);
153
+ }
154
+
155
+ function rowSame(e, n, t) {
156
+ if (isEqual(e, n) || targetsEqual(e, n)) return true;
157
+ if (t === null || !isWrappable(e) || !isWrappable(n)) return false;
158
+ const i = t(unwrapValue(e));
159
+ const r = t(unwrapValue(n));
160
+ return i !== undefined && sameKey(i, r);
161
+ }
162
+
163
+ function arrangementEqual(e, n, t) {
164
+ if (Array.isArray(e) !== Array.isArray(n)) return false;
165
+ if (Array.isArray(e)) {
166
+ if (e.length !== n.length) return false;
167
+ for (let i = 0; i < e.length; i++) if (!rowSame(e[i], n[i], t)) return false;
168
+ return true;
169
+ }
170
+ const i = Reflect.ownKeys(e).filter(e => e !== $OWNER);
171
+ const r = Reflect.ownKeys(n).filter(e => e !== $OWNER);
172
+ if (i.length !== r.length) return false;
173
+ for (const e of i) if (!(e in n)) return false;
174
+ return true;
175
+ }
176
+
177
+ /** Write `incoming` into the draft `draft` (a store proxy inside a user's
178
+ * setter): arrays match rows by key (position when unkeyed) and recurse into
179
+ * the matched row's draft; objects recurse into a wrappable pair, assign
180
+ * otherwise; keys `incoming` lacks are deleted. */ function reconcileDraft(e, n, t) {
181
+ if (Array.isArray(n)) {
182
+ const i = e.length;
183
+ const r = new Array(i);
184
+ for (let n = 0; n < i; n++) r[n] = e[n];
185
+ let o = null;
186
+ if (t !== null) {
187
+ o = new Map;
188
+ for (let e = 0; e < i; e++) {
189
+ const n = unwrapValue(r[e]);
190
+ if (!isWrappable(n)) continue;
191
+ const i = t(n);
192
+ if (i !== undefined && !o.has(i)) o.set(i, r[e]);
193
+ }
194
+ }
195
+ for (let s = 0; s < n.length; s++) {
196
+ const a = n[s];
197
+ let f;
198
+ if (isWrappable(a)) {
199
+ if (o !== null) {
200
+ const e = t(a);
201
+ if (e !== undefined) f = o.get(e);
202
+ } else if (s < i && isWrappable(unwrapValue(r[s]))) f = r[s];
203
+ }
204
+ if (f !== undefined) {
205
+ if (unwrapValue(f) !== a) reconcileDraft(f, a, t);
206
+ if (e[s] !== f) e[s] = f;
207
+ } else if (unwrapValue(e[s]) !== a) e[s] = a;
208
+ }
209
+ if (e.length !== n.length) e.length = n.length;
210
+ return;
211
+ }
212
+ for (const i of Object.keys(n)) {
213
+ const r = n[i];
214
+ const o = e[i];
215
+ const s = unwrapValue(o);
216
+ if (isWrappable(r) && isWrappable(s) && Array.isArray(r) === Array.isArray(s) && (t === null || Array.isArray(r) || sameKey(t(r), t(s)))) {
217
+ if (s !== r) reconcileDraft(o, r, t);
218
+ } else if (s !== r) e[i] = r;
219
+ }
220
+ for (const t of Object.keys(e)) if (!(t in n)) delete e[t];
221
+ }
222
+
223
+ /** Q-D (plan sec. 39): an OLDER question's truth landed beneath an arrangement
224
+ * guess (`laneWrite` held it — another action's landing is not this guess's
225
+ * answer). The guess is re-based over it: order from the guess, rows from
226
+ * the truth by key (a guessed row the truth has is the truth's object — the
227
+ * row target adopted it, its proxy survives), guessed rows the truth lacks
228
+ * kept (the guess's own landing judges them), truth rows the guess lacks
229
+ * appended. The composed arrangement becomes the lane's value on every
230
+ * index whose row the committed backing does not already show — compared
231
+ * BY KEY, never by raw identity: the same key's new object is the same row
232
+ * (its target adopted it) and the slot stays the committed backing's — (a
233
+ * node is born for it as the lane's derivation), on `length` only when the
234
+ * committed length differs, and as the `LaneView`'s base for structural
235
+ * reads. Unkeyed families compose
236
+ * positionally — the guess stands as written (the documented residue). */ GlobalQueue.In = (e, n) => {
237
+ const t = e.yt;
238
+ if (t === undefined || e.bt !== $TRACK) return;
239
+ const i = e.m.Z;
240
+ if (!(i instanceof LaneView)) return;
241
+ if (!Array.isArray(n) || !Array.isArray(i.rows)) {
242
+ i.base = n;
243
+ return;
244
+ }
245
+ const r = t.fam?.key ?? null;
246
+ if (r === null) return;
247
+ const o = new Map;
248
+ for (let e = 0; e < n.length; e++) {
249
+ const t = n[e];
250
+ const i = isWrappable(t) ? r(t) : undefined;
251
+ if (i !== undefined && !o.has(i)) o.set(i, t);
252
+ }
253
+ const s = new Set;
254
+ const a = [];
255
+ const f = i.rows;
256
+ for (let e = 0; e < f.length; e++) {
257
+ const n = f[e];
258
+ const t = isWrappable(n) ? r(n) : undefined;
259
+ const i = t !== undefined ? o.get(t) : undefined;
260
+ if (i !== undefined) {
261
+ a.push(i);
262
+ s.add(t);
263
+ } else a.push(n);
264
+ }
265
+ const l = i.removed;
266
+ for (let e = 0; e < n.length; e++) {
267
+ const t = n[e];
268
+ const i = isWrappable(t) ? r(t) : undefined;
269
+ if (i !== undefined && !s.has(i) && (l === null || !l.has(i))) a.push(t);
270
+ }
271
+ i.rows = a;
272
+ i.base = a;
273
+ const u = txOf(e);
274
+ const c = committed(t);
275
+ const d = t.n;
276
+ for (let e = 0; e < a.length; e++) {
277
+ const n = d?.[e];
278
+ // A slot the lane does not own shows the committed row: it becomes the
279
+ // lane's only where the composed row is another row (by key — the same
280
+ // key's new object is the same row, its target adopted it).
281
+ if (n === undefined) {
282
+ if (!sameRow(c[e], a[e], r)) laneSet(getNode(t, e), a[e], u);
283
+ } else if (!sameRow(n.u & CONFIG_OVERRIDE ? n.m.Z : c[e], a[e], r)) laneSet(n, a[e], u);
284
+ }
285
+ if (d !== null) {
286
+ for (let e = a.length; ;e++) {
287
+ const n = d[e];
288
+ if (n === undefined) break;
289
+ laneSet(n, undefined, u);
290
+ }
291
+ const e = d.length;
292
+ if (e !== undefined && (e.u & CONFIG_OVERRIDE || c.length !== a.length)) laneSet(e, a.length, u);
293
+ }
294
+ };
295
+
296
+ function sameRow(e, n, t) {
297
+ if (e === n) return true;
298
+ if (!isWrappable(e) || !isWrappable(n)) return false;
299
+ const i = t(unwrapValue(e));
300
+ return i !== undefined && sameKey(i, t(unwrapValue(n)));
301
+ }
302
+
303
+ /** A composed value becomes the lane's on `node`: a guess re-based, or a
304
+ * node that was not the lane's becomes its derivation (its committed value
305
+ * untouched beneath; the lane's end commits the latest). */ function laneSet(e, n, t) {
306
+ const i = ext(e);
307
+ if (!(e.u & CONFIG_OVERRIDE)) {
308
+ e.u |= CONFIG_OVERRIDE;
309
+ list(e, t);
310
+ } else if (i.Z === n) return;
311
+ i.Z = n;
312
+ if (e.t !== null) {
313
+ insertSubs(e);
314
+ laneDirty(e, t);
315
+ }
316
+ }
317
+
318
+ installOptHooks({
319
+ draft: optimisticDraft,
320
+ writes: notifyOptimisticWrites,
321
+ arrangement: arrangement,
322
+ reconcile: reconcileDraft,
323
+ view: (e, n, t = false) => t ? optimisticView(e, n, laneValueOf, true) : optimisticView(e, n),
324
+ has: optimisticHas,
325
+ descriptor: optimisticOwnDescriptor,
326
+ sweep: sweepOverlaid
327
+ });
328
+
329
+ function shallowKeys(e) {
330
+ const n = {};
331
+ for (const t of Reflect.ownKeys(e)) if (t !== $OWNER) n[t] = unwrapValue(e[t]);
332
+ return n;
333
+ }
334
+
335
+ /** Families with a target carrying a lane value — swept at the flush's
336
+ * commit (`sweepOverlaid`): a target none of whose nodes is a lane's any
337
+ * more leaves its family's `overlaid`. (Not on the read path: a guess is
338
+ * pending between the setter and the seam, and a read in between must not
339
+ * take the target for clean.) */ const overlaidFamilies = new Set;
340
+
341
+ function markOverlaid(e) {
342
+ const n = e.fam;
343
+ (n.overlaid ??= new Set).add(e);
344
+ overlaidFamilies.add(n);
345
+ }
346
+
347
+ function sweepOverlaid() {
348
+ if (overlaidFamilies.size === 0) return;
349
+ for (const e of overlaidFamilies) {
350
+ const n = e.overlaid;
351
+ for (const e of n) if (!carriesLane(e)) {
352
+ n.delete(e);
353
+ if (e.ch) rebaseChained(e);
354
+ // The container shows its backing again (a shown arrangement guess
355
+ // that ended without a landing left its `LaneView` as the value).
356
+ const t = e.k;
357
+ if (t !== null && t.pe instanceof LaneView) t.pe = t.pe.base;
358
+ }
359
+ if (n.size === 0) overlaidFamilies.delete(e);
360
+ }
361
+ }
362
+
363
+ /** A chained view's lanes ended: its nodes are links (§7b) whose committed
364
+ * value is the inner store's at the guess, not now — the inner may have
365
+ * moved underneath the guess (the base committed while the view showed
366
+ * its arrangement, #3672/F1). Re-base each node on the inner's truth and
367
+ * re-derive the readers whose shown value it is not. */ function rebaseChained(e) {
368
+ const n = e.v;
369
+ let t = false;
370
+ const i = e.n;
371
+ if (i !== null) for (const e of Reflect.ownKeys(i)) {
372
+ const r = i[e];
373
+ const o = untrack(() => unwrapValue(n[e]));
374
+ if (r.tn && r.tn(r.pe, o)) continue;
375
+ r.pe = o;
376
+ // (The lane's end notified it this epoch when the shown value and the
377
+ // covered one differed — its readers re-derive already.)
378
+ if (r.t !== null && r.Pt !== notifyEpoch) {
379
+ insertSubs(r);
380
+ t = true;
381
+ }
382
+ }
383
+ const r = e.h;
384
+ if (r !== null) for (const e of Reflect.ownKeys(r)) {
385
+ const i = r[e];
386
+ const o = untrack(() => e in n);
387
+ if (i.pe === o) continue;
388
+ i.pe = o;
389
+ if (i.t !== null && i.Pt !== notifyEpoch) {
390
+ insertSubs(i);
391
+ t = true;
392
+ }
393
+ }
394
+ // The arrangement the readers saw (the shown guess) against the inner's
395
+ // now: a structural reader re-derives when they differ.
396
+ const o = e.k;
397
+ if (o !== null && o.t !== null && o.pe instanceof LaneView && o.Pt !== notifyEpoch) {
398
+ const i = Array.isArray(n) ? untrack(() => n.map(unwrapValue)) : n;
399
+ if (!arrangementEqual(o.pe.rows, i, e.fam?.key ?? null)) {
400
+ insertSubs(o);
401
+ t = true;
402
+ }
403
+ }
404
+ if (t) schedule();
405
+ }
406
+
407
+ function carriesLane(e) {
408
+ if (e.k !== null && e.k.u & CONFIG_OVERRIDE) return true;
409
+ if (e.dk !== null && e.dk.u & CONFIG_OVERRIDE) return true;
410
+ const n = e.n;
411
+ if (n !== null) for (const e of Reflect.ownKeys(n)) if (n[e].u & CONFIG_OVERRIDE) return true;
412
+ const t = e.h;
413
+ if (t !== null) for (const e of Reflect.ownKeys(t)) if (t[e].u & CONFIG_OVERRIDE) return true;
414
+ return false;
415
+ }
416
+
417
+ function overlaid(e) {
418
+ const n = e.fam;
419
+ return n !== null && n.opt === true && n.overlaid !== undefined && n.overlaid.has(e);
420
+ }
421
+
422
+ /** What a lane node shows an untracked reader here: core's rule (`read`
423
+ * without a link — the lane's world inside its own pass, the screen
424
+ * outside, a verdict window's answer under one). */ const shown = e => untrack(() => read(e));
425
+
426
+ /** An untracked `key in store` on an optimistic family: the presence guess
427
+ * (what its lane shows) when the key carries one; `undefined` when not —
428
+ * the backing answers. */ function optimisticHas(e, n) {
429
+ if (!overlaid(e)) return undefined;
430
+ const t = e.h?.[n];
431
+ if (t !== undefined && t.u & CONFIG_OVERRIDE) return !!shown(t);
432
+ const i = e.n?.[n];
433
+ if (i !== undefined && i.u & CONFIG_OVERRIDE) return shown(i) !== undefined;
434
+ return undefined;
435
+ }
436
+
437
+ /** A descriptor read of a guessed key: synthesized from the lane's value
438
+ * (`null`: the guess removed the key; `undefined`: no guess — the backing
439
+ * describes it). */ function optimisticOwnDescriptor(e, n) {
440
+ const t = optimisticHas(e, n);
441
+ if (t === undefined) return undefined;
442
+ if (!t) return null;
443
+ const i = e.n?.[n];
444
+ const r = i !== undefined && i.u & CONFIG_OVERRIDE ? shown(i) : e.v[n];
445
+ // An array's `length` is reported as the array has it (non-configurable).
446
+ if (n === "length" && Array.isArray(e.v)) return {
447
+ value: r,
448
+ writable: true,
449
+ enumerable: false,
450
+ configurable: false
451
+ };
452
+ return {
453
+ value: r,
454
+ writable: true,
455
+ enumerable: true,
456
+ configurable: true
457
+ };
458
+ }
459
+
460
+ /** The truth `src` with the target's lane values over it: each overlaid
461
+ * leaf's value (`pick`: what the lane shows, or — for `latest` — the lane's
462
+ * latest), each presence guess as a key added or removed, the array
463
+ * length. Returns `src` itself when nothing is overlaid. */ function optimisticView(e, n, t = shown,
464
+ // The writer's view: the unflushed guesses too (on nodes that are no
465
+ // lane's yet) — what the next write composes on (#3665).
466
+ i = false) {
467
+ if (!i && !overlaid(e)) return n;
468
+ let r = null;
469
+ const ensure = () => r ??= Array.isArray(n) ? [ ...n ] : {
470
+ ...n
471
+ };
472
+ const o = e.n;
473
+ if (o !== null) {
474
+ for (const e of Reflect.ownKeys(o)) {
475
+ const r = o[e];
476
+ let s;
477
+ if (r.u & CONFIG_OVERRIDE) s = t(r); else if (!i || (s = pendingGuessOf(r)) === NOT_PENDING) continue;
478
+ if (e === "length" && Array.isArray(n)) {
479
+ if (n.length !== s) ensure().length = s;
480
+ } else if (!isEqual(n[e], s) || !hasOwn.call(n, e)) {
481
+ ensure()[e] = s;
482
+ }
483
+ }
484
+ }
485
+ const s = e.h;
486
+ if (s !== null) {
487
+ for (const e of Reflect.ownKeys(s)) {
488
+ const o = s[e];
489
+ let a;
490
+ if (o.u & CONFIG_OVERRIDE) a = t(o); else if (!i || (a = pendingGuessOf(o)) === NOT_PENDING) continue;
491
+ const f = !!a;
492
+ const l = r ?? n;
493
+ if (!f && e in l) delete ensure()[e];
494
+ }
495
+ }
496
+ return r ?? n;
497
+ }
498
+
499
+ function createOptimisticStore(e, n, t) {
500
+ const i = typeof e === "function";
501
+ const r = i ? t : n;
502
+ const o = i ? n : e;
503
+ const s = r?.key === undefined ? "id" : r.key;
504
+ const a = {
505
+ map: new WeakMap,
506
+ node: null,
507
+ live: new Set,
508
+ shallow: !!r?.shallow,
509
+ opt: true,
510
+ key: typeof s === "function" ? s : s === null ? null : e => isWrappable(e) ? e[s] : undefined
511
+ };
512
+ const f = wrap(o, null, null, a);
513
+ nameStore(f, r?.name);
514
+ if (a.shallow) {
515
+ f[$TARGET].s = true;
516
+ markRawIngest(o);
517
+ }
518
+ if (i) {
519
+ const n = e;
520
+ let t;
521
+ if (r?.seedLoadingValue) t = {
522
+ loadingValue: undefined
523
+ };
524
+ if (r?.name) t = {
525
+ ...t,
526
+ name: r.name
527
+ };
528
+ const i = computed(() => {
529
+ if (!a.node) a.node = getOwner();
530
+ runProjectionComputed(f, n, s);
531
+ }, t);
532
+ i.u &= ~CONFIG_AUTO_DISPOSE;
533
+ a.node = i;
534
+ }
535
+ return [ f, e => storeSetter(f, e) ];
536
+ }
537
+
538
+ export { createOptimisticStore, notifyOptimisticWrites, optimisticHas, optimisticOwnDescriptor, optimisticView, sweepOverlaid };