@solidjs/signals 2.0.0-rc.13 → 2.0.0-rc.15

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 (121) hide show
  1. package/dist/dev-shared.js +2059 -3768
  2. package/dist/dev.attribution.js +237 -101
  3. package/dist/dev.js +7466 -8497
  4. package/dist/observe/affects.js +128 -104
  5. package/dist/observe/boundaries.js +492 -665
  6. package/dist/observe/core/action.js +63 -66
  7. package/dist/observe/core/async.js +243 -379
  8. package/dist/observe/core/attribution-queries.js +1 -1
  9. package/dist/observe/core/attribution.js +394 -253
  10. package/dist/observe/core/constants.js +120 -187
  11. package/dist/observe/core/context.js +3 -3
  12. package/dist/observe/core/core.js +874 -1440
  13. package/dist/observe/core/dev.js +3 -3
  14. package/dist/observe/core/effect.js +73 -84
  15. package/dist/observe/core/external.js +5 -5
  16. package/dist/observe/core/graph.js +62 -71
  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 +750 -181
  20. package/dist/observe/core/owner.js +80 -101
  21. package/dist/observe/core/scheduler.js +719 -1356
  22. package/dist/observe/core/verdict.js +314 -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 +144 -216
  28. package/dist/observe/store/affects.js +142 -0
  29. package/dist/observe/store/hooks.js +13 -0
  30. package/dist/observe/store/index.js +27 -24
  31. package/dist/observe/store/optimistic.js +571 -0
  32. package/dist/observe/store/projection.js +308 -0
  33. package/dist/observe/store/reconcile.js +259 -0
  34. package/dist/observe/store/store.js +1988 -277
  35. package/dist/observe/store/storePath.js +1 -1
  36. package/dist/{prod/store/next → observe/store}/target.js +17 -18
  37. package/dist/observe/store/types.js +73 -0
  38. package/dist/observe/store/utils.js +1 -13
  39. package/dist/prod/affects.js +130 -106
  40. package/dist/prod/boundaries.js +476 -654
  41. package/dist/prod/core/action.js +71 -74
  42. package/dist/prod/core/async.js +306 -444
  43. package/dist/prod/core/constants.js +117 -186
  44. package/dist/prod/core/context.js +3 -3
  45. package/dist/prod/core/core.js +888 -1462
  46. package/dist/prod/core/effect.js +88 -99
  47. package/dist/prod/core/external.js +5 -5
  48. package/dist/prod/core/graph.js +62 -71
  49. package/dist/prod/core/heap.js +75 -98
  50. package/dist/prod/core/invariants.js +1 -32
  51. package/dist/prod/core/lanes.js +712 -181
  52. package/dist/prod/core/owner.js +75 -96
  53. package/dist/prod/core/scheduler.js +686 -1335
  54. package/dist/prod/core/verdict.js +309 -621
  55. package/dist/prod/flatten.js +77 -0
  56. package/dist/prod/index.js +15 -13
  57. package/dist/prod/map.js +142 -145
  58. package/dist/prod/reveal.js +212 -0
  59. package/dist/prod/signals.js +155 -227
  60. package/dist/prod/store/affects.js +142 -0
  61. package/dist/prod/store/hooks.js +13 -0
  62. package/dist/prod/store/index.js +26 -19
  63. package/dist/prod/store/optimistic.js +566 -0
  64. package/dist/prod/store/projection.js +301 -0
  65. package/dist/prod/store/reconcile.js +259 -0
  66. package/dist/prod/store/store.js +1883 -272
  67. package/dist/prod/store/storePath.js +1 -1
  68. package/dist/{observe/store/next → prod/store}/target.js +13 -17
  69. package/dist/prod/store/types.js +73 -0
  70. package/dist/prod/store/utils.js +1 -11
  71. package/dist/types/affects.d.ts +11 -30
  72. package/dist/types/boundaries.d.ts +66 -176
  73. package/dist/types/carved.d.ts +1 -0
  74. package/dist/types/core/action.d.ts +5 -6
  75. package/dist/types/core/async.d.ts +10 -5
  76. package/dist/types/core/attribution-hooks.d.ts +20 -1
  77. package/dist/types/core/attribution.d.ts +26 -11
  78. package/dist/types/core/constants.d.ts +130 -180
  79. package/dist/types/core/core.d.ts +134 -264
  80. package/dist/types/core/dev.d.ts +2 -2
  81. package/dist/types/core/effect.d.ts +0 -7
  82. package/dist/types/core/graph.d.ts +7 -1
  83. package/dist/types/core/heap.d.ts +5 -7
  84. package/dist/types/core/index.d.ts +5 -5
  85. package/dist/types/core/invariants.d.ts +0 -29
  86. package/dist/types/core/lanes.d.ts +74 -86
  87. package/dist/types/core/owner.d.ts +3 -3
  88. package/dist/types/core/scheduler.d.ts +255 -331
  89. package/dist/types/core/types.d.ts +45 -85
  90. package/dist/types/core/verdict.d.ts +3 -0
  91. package/dist/types/flatten.d.ts +8 -0
  92. package/dist/types/index.d.ts +6 -4
  93. package/dist/types/reveal.d.ts +19 -0
  94. package/dist/types/signals.d.ts +35 -91
  95. package/dist/types/store/affects.d.ts +12 -0
  96. package/dist/types/store/hooks.d.ts +48 -0
  97. package/dist/types/store/index.d.ts +34 -15
  98. package/dist/types/store/optimistic.d.ts +23 -0
  99. package/dist/types/store/projection.d.ts +18 -0
  100. package/dist/types/store/reconcile.d.ts +3 -0
  101. package/dist/types/store/store.d.ts +132 -145
  102. package/dist/types/store/storePath.d.ts +1 -1
  103. package/dist/types/store/target.d.ts +151 -0
  104. package/dist/types/store/types.d.ts +84 -0
  105. package/package.json +1 -1
  106. package/dist/observe/core/optimistic.js +0 -669
  107. package/dist/observe/store/next/optimistic.js +0 -717
  108. package/dist/observe/store/next/projection.js +0 -266
  109. package/dist/observe/store/next/reconcile.js +0 -375
  110. package/dist/observe/store/next/store.js +0 -2608
  111. package/dist/prod/core/optimistic.js +0 -658
  112. package/dist/prod/store/next/optimistic.js +0 -710
  113. package/dist/prod/store/next/projection.js +0 -257
  114. package/dist/prod/store/next/reconcile.js +0 -373
  115. package/dist/prod/store/next/store.js +0 -2484
  116. package/dist/types/core/optimistic.d.ts +0 -6
  117. package/dist/types/store/next/optimistic.d.ts +0 -25
  118. package/dist/types/store/next/projection.d.ts +0 -27
  119. package/dist/types/store/next/reconcile.d.ts +0 -10
  120. package/dist/types/store/next/store.d.ts +0 -145
  121. package/dist/types/store/next/target.d.ts +0 -196
@@ -0,0 +1,308 @@
1
+ import { CONFIG_AUTO_DISPOSE, STATUS_PENDING, STATUS_UNINITIALIZED } from "../core/constants.js";
2
+
3
+ import { computed } from "../core/core.js";
4
+
5
+ import { NotReadyError } from "../core/error.js";
6
+
7
+ import { handleAsync, addPendingSource, propagateStatus, forEachDependent, settlePendingSource } from "../core/async.js";
8
+
9
+ import { enqueueSub } from "../core/heap.js";
10
+
11
+ import { getOwner, isDisposed } from "../core/owner.js";
12
+
13
+ import { question, setQuestion, schedule } from "../core/scheduler.js";
14
+
15
+ import { reconcileState } from "./reconcile.js";
16
+
17
+ import { wrap, nameStore, storeSetter, runDirect } from "./store.js";
18
+
19
+ import { setLookup } from "./target.js";
20
+
21
+ import { $TARGET, markRawIngest, setWriteOverride, isWrappable } from "./types.js";
22
+
23
+ /**
24
+ * Store — projections (plan sec. 31, S3; INTERNALS §7/§7b).
25
+ *
26
+ * A projection is a computed store: the derive runs inside a computed — the
27
+ * **firewall** — whose pass writes the store through a draft; its output is
28
+ * adopted through the reconcile channel (replace-mode root: entity changes
29
+ * merge in place, the root proxy is stable for life). Children wrap into
30
+ * the projection's own FAMILY (writes land here, never in a source family).
31
+ *
32
+ * The firewall exists so writes from inside a computation are safe (the
33
+ * derive owns its leaves); the price is the ordering obligation: before any
34
+ * value is served through the projection, the derive is brought up to date
35
+ * — **without** the reader subscribing to it (that is the propagation
36
+ * barrier). The store's traps do that pull (`pullFamily`, store.ts): core's
37
+ * `read()` of the firewall with no link — freshness, the status gate
38
+ * (uninitialized / pending / errored) and the reader's height, by the
39
+ * rules a memo's read follows. No per-leaf back-pointer, nothing in core.
40
+ */
41
+ /**
42
+ * Wrap a store proxy as a projection DRAFT: every operation carries the write
43
+ * override (the derive is the author — its ops must not hit the status gate,
44
+ * even in a continuation after an `await`/`yield` where the sync write scope
45
+ * has closed).
46
+ *
47
+ * FAKE TARGET, not the store proxy itself (#3060): after a proxy trap
48
+ * returns, the engine runs spec invariant validation against the proxy's
49
+ * TARGET — [[OwnPropertyKeys]] after ownKeys, [[GetOwnProperty]] after
50
+ * set/getOwnPropertyDescriptor/defineProperty. With the store proxy as
51
+ * target those checks re-enter the store's traps OUTSIDE the override
52
+ * bracket, so `Object.keys(state)` in a derive continuation fired the gate.
53
+ */ function wrapDraft(e, t, r, n, o, i) {
54
+ const mutate = e => {
55
+ if (!t()) return true;
56
+ setWriteOverride(true);
57
+ // A continuation's write is the flight's answer: it asks the flight's
58
+ // question (A18 provenance — a landing beneath a newer guess is held,
59
+ // not a correction; lanes.ts `laneWrite`).
60
+ const n = question;
61
+ if (i !== undefined) setQuestion(i());
62
+ try {
63
+ r ? r(e) : e();
64
+ } finally {
65
+ setWriteOverride(false);
66
+ setQuestion(n);
67
+ }
68
+ if (o) o();
69
+ return true;
70
+ };
71
+ const read = e => {
72
+ setWriteOverride(true);
73
+ try {
74
+ return e();
75
+ } finally {
76
+ setWriteOverride(false);
77
+ }
78
+ };
79
+ const s = {
80
+ get(s, c) {
81
+ const u = read(() => e[c]);
82
+ return !n && typeof u === "object" && u !== null && c !== $TARGET ? wrapDraft(u, t, r, false, o, i) : u;
83
+ },
84
+ has: (t, r) => read(() => r in e),
85
+ set: (t, r, n) => mutate(() => {
86
+ e[r] = n;
87
+ }),
88
+ deleteProperty: (t, r) => mutate(() => {
89
+ delete e[r];
90
+ }),
91
+ ownKeys: () => read(() => Reflect.ownKeys(e)),
92
+ getOwnPropertyDescriptor(t, r) {
93
+ const n = read(() => Reflect.getOwnPropertyDescriptor(e, r));
94
+ if (n) n.configurable = true;
95
+ return n;
96
+ },
97
+ defineProperty: (t, r, n) => mutate(() => {
98
+ Reflect.defineProperty(e, r, n);
99
+ })
100
+ };
101
+ const c = new Proxy(Array.isArray(e) ? [] : {}, s);
102
+ // The wrapper stands for its store proxy wherever the derive's result
103
+ // carries it (`wrap`, `unwrapValue`, reconcile's slot matching).
104
+ const u = e[$TARGET];
105
+ if (u !== undefined) setLookup(c, u);
106
+ return c;
107
+ }
108
+
109
+ function cloneState(e, t) {
110
+ return t ? Array.isArray(e) ? e.slice() : {
111
+ ...e
112
+ } : JSON.parse(JSON.stringify(e));
113
+ }
114
+
115
+ /** The derive's pass went pending (a new question in flight): every reader
116
+ * of a leaf learns it as a reader of the derive would (A9: any leaf reports
117
+ * the firewall's refetch) — core's own rule for a dependency going pending
118
+ * (`notifyStatus`): a verdict or re-derive reader re-runs, any other is
119
+ * pending derivatively on the derive (its readers hold; it re-runs at the
120
+ * landing). The leaves do not subscribe to the derive, so the family does
121
+ * the walk. */ function wakeFamily(e, t) {
122
+ const r = e.node;
123
+ e.woke = true;
124
+ forEachFamilyNode(e, e => {
125
+ if (e.t === null) return;
126
+ // The leaf carries the derive's pending as a propagated copy, as a memo
127
+ // between them would: a dependent recovering one branch stays pending
128
+ // through a leaf it still reads (core `retryReaches`), and the landing's
129
+ // walk retires the copy first (`settleFamily` → `settlePendingSource`).
130
+ addPendingSource(e, r);
131
+ // Its readers: core's propagation from the leaf — a verdict or re-derive
132
+ // reader re-runs, any other is pending derivatively on the derive and
133
+ // queued for the frame (held with it: the frame waits on the flight
134
+ // through them, `blocked`).
135
+ propagateStatus(e, STATUS_PENDING, t);
136
+ });
137
+ }
138
+
139
+ /** The derive's flight rejected: every live reader of the family
140
+ * re-derives (its pull throws the derive's error). */ function errorFamily(e) {
141
+ forEachFamilyNode(e, e => {
142
+ if (e.t === null) return;
143
+ forEachDependent(e, e => {
144
+ enqueueSub(e);
145
+ });
146
+ });
147
+ schedule();
148
+ }
149
+
150
+ /** The flight landed: the readers the wake left pending on the derive
151
+ * settle — core's walk, from each leaf (the leaves are not the derive's
152
+ * dependents, so its own settle walk does not reach them). */ function settleFamily(e) {
153
+ if (!e.woke) return;
154
+ e.woke = false;
155
+ const t = e.node;
156
+ forEachFamilyNode(e, e => {
157
+ if (e.t !== null) settlePendingSource(e, t);
158
+ });
159
+ }
160
+
161
+ function forEachFamilyNode(e, t) {
162
+ for (const r of e.live) {
163
+ const e = r.n;
164
+ if (e !== null) for (const r of Reflect.ownKeys(e)) t(e[r]);
165
+ const n = r.h;
166
+ if (n !== null) for (const e of Reflect.ownKeys(n)) t(n[e]);
167
+ if (r.k !== null) t(r.k);
168
+ if (r.dk !== null) t(r.dk);
169
+ }
170
+ }
171
+
172
+ /** The derive's pass: run `fn` against a draft of the store; commit its
173
+ * result (sync, or each async landing) through the reconcile channel.
174
+ * Draft validity is per run (R37): live from here until the NEXT run starts
175
+ * — a sync derive that subscribes to an external source and pushes into
176
+ * the draft from the callback (#3585) is the model use. */ function runProjectionComputed(e, t, r, n, o) {
177
+ const i = getOwner();
178
+ const s = e[$TARGET];
179
+ const c = s.fam;
180
+ const u = c.run = (c.run || 0) + 1;
181
+ let l;
182
+ // Open loading window (seedLoadingValue): the observable store IS commit #0
183
+ // for the whole first flight — the derive works a detached shadow of the
184
+ // seed so draft writes cannot tear through to readers (#2988). Every
185
+ // commit point reconciles the shadow through the normal commit path.
186
+ const a = i.De ? cloneState(s.v, s.s) : null;
187
+ // The question a write of this run answers: inside a slice, the slice's
188
+ // (the sync pass); in a continuation — the flight still registered — the
189
+ // flight's (`handleAsync` stamped it with the action that asked).
190
+ const asking = () => question || (i.m !== null && i.m.Te !== null ? i.m._e : 0);
191
+ const f = wrapDraft(e, () => c.run === u && !isDisposed(i), o, s.s,
192
+ // A write after the run returned (a continuation, a callback) arms the
193
+ // drain itself when no landing will.
194
+ () => {
195
+ if (!(i.S & STATUS_PENDING) && !i.De) schedule();
196
+ }, asking);
197
+ // The creation run commits directly (a memo's first value is its
198
+ // `_value`); every later run — a re-derive in a flush, an async landing
199
+ // — stages and commits with the flush like a memo's recompute.
200
+ const d = u === 1;
201
+ const pass = () => storeSetter(f, o => {
202
+ l = t(a ?? o);
203
+ const commit = t => {
204
+ // Shadow run: commit a detached snapshot, never the shadow itself
205
+ // (adoption takes the value by identity — handing it the live
206
+ // shadow would fuse the draft to the observable store).
207
+ if (a && (t === undefined || t === a)) t = cloneState(a, s.s);
208
+ if (t !== o && t !== undefined) {
209
+ const write = () => {
210
+ const n = question;
211
+ setQuestion(asking());
212
+ try {
213
+ storeSetter(e, e => reconcileState(t, e, r, true), false);
214
+ } finally {
215
+ setQuestion(n);
216
+ }
217
+ };
218
+ n ? n(write, t) : write();
219
+ }
220
+ // A landing (not the sync pass's own commit): the readers held
221
+ // pending on the derive settle.
222
+ if (!d || !(i.S & STATUS_UNINITIALIZED)) settleFamily(c);
223
+ };
224
+ const u = handleAsync(i, l, commit, (e, t) => {
225
+ // The flight rejected: the leaves' readers learn it from here —
226
+ // they do not subscribe to the derive. Pending again (a NotReady
227
+ // rejection): the wake, as for the pass. Errored: every live
228
+ // reader re-derives and meets the error at its pull (memo parity,
229
+ // #2897) — and the flush that runs them advances the clock, so a
230
+ // later tracked re-read may retry (core `read`).
231
+ if (d && i.S & STATUS_UNINITIALIZED) return;
232
+ if (t) wakeFamily(c, e); else errorFamily(c);
233
+ });
234
+ if (!i.De) commit(u);
235
+ }, false);
236
+ try {
237
+ d ? runDirect(pass) : pass();
238
+ } catch (e) {
239
+ // A flight went up (NotReady out of the pass — the derive's own, with
240
+ // the derive as its source): the leaves' readers learn it from here —
241
+ // they do not subscribe to the derive.
242
+ // A synchronous error the same way (#3956: a rerun that finds the
243
+ // entry failed throws): every live reader re-derives and meets it.
244
+ if (!d) e instanceof NotReadyError ? wakeFamily(c, e) : errorFamily(c);
245
+ throw e;
246
+ }
247
+ // A pass that returned with a flight up (an iterator's sync first yield):
248
+ // the wake, as for the throw. Not a sync pass that superseded one — the
249
+ // status it reads is the dead flight's, cleared when this pass settles
250
+ // (#3181: a reader the settle walk had just released, re-parked for good).
251
+ if (i.S & STATUS_PENDING && i.m.Te !== null && !i.De && !d) wakeFamily(c, i.m?.F);
252
+ return i;
253
+ }
254
+
255
+ function createProjectionInternal(e, t, r) {
256
+ const n = r?.key === undefined ? "id" : r.key;
257
+ const o = {
258
+ map: new WeakMap,
259
+ node: null,
260
+ live: new Set,
261
+ shallow: !!r?.shallow,
262
+ // The row key, for a child paired after the adoption (store.ts
263
+ // `adoptChild`, #3712) as the adoption pairs them.
264
+ key: typeof n === "function" ? n : n === null ? null : e => isWrappable(e) ? e[n] : undefined
265
+ };
266
+ const i = wrap(t, null, null, o);
267
+ if (o.shallow) {
268
+ i[$TARGET].s = true;
269
+ markRawIngest(t);
270
+ }
271
+ let s;
272
+ if (r?.seedLoadingValue) s = {
273
+ loadingValue: undefined
274
+ };
275
+ if (r?.name) {
276
+ s = {
277
+ ...s,
278
+ name: r.name
279
+ };
280
+ nameStore(i, r.name);
281
+ }
282
+ const c = computed(() => {
283
+ if (!o.node) o.node = getOwner();
284
+ runProjectionComputed(i, e, n);
285
+ }, s);
286
+ c.i &= ~CONFIG_AUTO_DISPOSE;
287
+ o.node = c;
288
+ return {
289
+ store: i,
290
+ node: c
291
+ };
292
+ }
293
+
294
+ /**
295
+ * A derived store: `fn` runs in a computed and writes its draft; readers of
296
+ * the store's keys re-run only when the keys they read change (the
297
+ * firewall). `fn` may be async or an async iterator; the seed is a draft,
298
+ * never an observable value, until the first landing (A25).
299
+ */ function createProjection(e, t, r) {
300
+ return createProjectionInternal(e, t, r).store;
301
+ }
302
+
303
+ /** `createStore(fn, seed, options)`: a projection with a user setter. */ function createStoreDerived(e, t, r) {
304
+ const {store: n} = createProjectionInternal(e, t, r);
305
+ return [ n, e => storeSetter(n, e) ];
306
+ }
307
+
308
+ export { createProjection, createStoreDerived, runProjectionComputed };
@@ -0,0 +1,259 @@
1
+ import { isEqual } from "../core/core.js";
2
+
3
+ import { isOwned, $OWNER, storeLookup, lookupTarget } from "./target.js";
4
+
5
+ import { userWriting, unwrapValue, adoptPB, sameKey, materializePB, notifyFold, sameRow, targetsEqual, bumpDeep, notifyKeyValue, notifyKeyDiff, notifyFoldTail, hasAccessorFlag } from "./store.js";
6
+
7
+ import { optHooks } from "./hooks.js";
8
+
9
+ import { $TARGET, markRawIngest, isWrappable, rawValuesUsed, isRawValue } from "./types.js";
10
+
11
+ /**
12
+ * Store — reconcile: the immutable-diff adoption channel (INTERNALS §3).
13
+ *
14
+ * Reconcile never merge-writes into backing objects: it adopts `incoming`
15
+ * as the backing at every proxied level (an internal pointer swap at the
16
+ * fold — no clones, no user-object mutation), value-notifies only where
17
+ * nodes exist, and descends into a changed child pair only where a target
18
+ * with nodes or the sticky descendants flag exists below (§6d: diff the
19
+ * listened path, not every cell). Reference-equal unowned pairs skip
20
+ * outright (an owned backing is setter-diverged and must diff).
21
+ *
22
+ * Keyed arrays: the aligned prefix is walked positionally; from the first
23
+ * misalignment rows match by key (surviving rows keep their proxy
24
+ * identity), unkeyed items fall back to position.
25
+ */ function reconcileState(e, n, t, o = false) {
26
+ if (n == null) throw new Error("");
27
+ const f = n?.[$TARGET];
28
+ if (f === undefined || f.px !== n) throw new Error("");
29
+ const l = t === null ? null : typeof t === "string" ? e => e?.[t] : t;
30
+ // A user's reconcile on an optimistic family (S4): not an adoption of
31
+ // truth but an optimistic edit — the keyed diff is written into the draft
32
+ // (a matched row keeps its proxy, its changed leaves become its guesses),
33
+ // and the setter's exit turns the draft into guesses like any.
34
+ if (userWriting() && f.fam?.opt === true) {
35
+ optHooks.reconcile(n, unwrapValue(e), l);
36
+ return;
37
+ }
38
+ // Replace-mode root handed another store's proxy: chain to it (§7b).
39
+ if (o && e !== n && e?.[$TARGET] !== undefined) {
40
+ const n = f.pb ?? f.v;
41
+ if (n === e) return;
42
+ // already chained to this store
43
+ adoptPB(f, e);
44
+ return;
45
+ }
46
+ const i = unwrapValue(e);
47
+ if (l) {
48
+ const e = f.pb ?? f.v;
49
+ const n = l(e);
50
+ if (n !== undefined && !sameKey(l(i), n)) {
51
+ if (!o) throw new Error("");
52
+ // A different entity at the root: the old backing is disowned (wraps
53
+ // fresh if re-handed) and the new one adopted whole.
54
+ const e = f.pb ?? f.v;
55
+ if (isOwned(e)) delete e[$OWNER]; else (f.fam?.map ?? storeLookup).delete(e);
56
+ adoptPB(f, i);
57
+ return;
58
+ }
59
+ }
60
+ applyAdopt(f, i, l, o);
61
+ }
62
+
63
+ /** Adopt `incoming` at `t` and notify its nodes — one leaf write per
64
+ * changed observed key, the structural nodes once — descending into
65
+ * changed child pairs that are proxied below. */ function applyAdopt(e, n, t, o = false) {
66
+ // The diff base is the view the nodes were last told (#3296). A nested
67
+ // overlay draft (`Object.create(v)`, #3044) reads a key the draft deleted
68
+ // as present through its prototype; materialized first — `adoptPB` does
69
+ // so anyway, after the base was taken — so a deletion the draft made is
70
+ // a deletion here (#3743: the presence and value diffs both read `old`).
71
+ const f = e.ovl ? materializePB(e) : e.pb ?? e.v;
72
+ if (n === f && !isOwned(f)) return;
73
+ const l = e.fam;
74
+ // Q-D: a landing on an optimistic family is reconciled against the VIEW
75
+ // — key matching from the arrangement the guesses made (R28), so a row
76
+ // the guess added keeps its proxy when the server returns it.
77
+ const i = l?.opt === true ? optHooks.view(e, f) : f;
78
+ const s = Array.isArray(n);
79
+ const u = e.s === true;
80
+ const r = f;
81
+ adoptPB(e, n, false);
82
+ if (u) markRawIngest(n);
83
+ if (Array.isArray(i) !== s) {
84
+ notifyFold(e, r, n);
85
+ return;
86
+ }
87
+ if (s) {
88
+ const f = i;
89
+ const s = n;
90
+ const a = e.n;
91
+ let c = 0;
92
+ if (t && !u) {
93
+ const i = f.length;
94
+ const u = s.length;
95
+ let d = false;
96
+ let p = 0;
97
+ // Aligned prefix: same row (by reference or key) at the same index.
98
+ for (const y = Math.min(i, u); p < y; p++) {
99
+ const i = s[p];
100
+ const u = f[p];
101
+ if (u !== i && !sameRow(u, i, t)) break;
102
+ // misaligned: fall to the keyed remainder below
103
+ if ((u !== i || i !== null && typeof i === "object" && isOwned(i)) && i !== null && typeof i === "object") descend(unwrapValue(u), i, t, l, o);
104
+ if (e.dk !== null && !d && !(i !== null && typeof i === "object" ? targetsEqual(u, i) : isEqual(u, i))) {
105
+ bumpDeep(e);
106
+ d = true;
107
+ }
108
+ if (a !== null) {
109
+ const e = a[p];
110
+ if (e !== undefined) {
111
+ c++;
112
+ notifyKeyValue(e, p, r[p], i, r, n);
113
+ }
114
+ }
115
+ }
116
+ if (e.dk !== null && !d && p < s.length) bumpDeep(e);
117
+ const y = p;
118
+ // misalignment point (== nlen on aligned ticks)
119
+ let w = null;
120
+ for (;p < s.length; p++) {
121
+ const e = s[p];
122
+ if (e !== null && typeof e === "object") {
123
+ const n = t(e);
124
+ let i;
125
+ if (n !== undefined) {
126
+ if (w === null) {
127
+ w = new Map;
128
+ for (let e = y; e < f.length; e++) {
129
+ const n = unwrapValue(f[e]);
130
+ if (n !== null && typeof n === "object") {
131
+ const o = t(n);
132
+ if (o === undefined) continue;
133
+ const f = w.get(o);
134
+ if (f === undefined) w.set(o, e); else if (Array.isArray(f)) f.push(e); else w.set(o, [ f, e ]);
135
+ }
136
+ }
137
+ }
138
+ const e = w.get(n);
139
+ if (e === undefined) i = undefined; else if (Array.isArray(e)) {
140
+ i = unwrapValue(f[e.shift()]);
141
+ if (e.length === 1) w.set(n, e[0]);
142
+ } else {
143
+ i = unwrapValue(f[e]);
144
+ w.delete(n);
145
+ }
146
+ } else {
147
+ i = unwrapValue(f[p]);
148
+ // keyless item: positional fallback
149
+ }
150
+ descend(i, e, t, l, o);
151
+ }
152
+ if (a !== null) {
153
+ const e = a[p];
154
+ if (e !== undefined) {
155
+ c++;
156
+ notifyKeyDiff(e, p, r, n, false);
157
+ }
158
+ }
159
+ }
160
+ } else {
161
+ const i = Math.min(f.length, s.length);
162
+ const d = s.length;
163
+ let p = false;
164
+ for (let y = 0; y < d; y++) {
165
+ const d = s[y];
166
+ if (!u && y < i && d !== null && typeof d === "object") descend(unwrapValue(f[y]), d, t, l, o);
167
+ if (e.dk !== null && !p && !(d !== null && typeof d === "object" ? targetsEqual(f[y], d) : isEqual(f[y], d))) {
168
+ bumpDeep(e);
169
+ p = true;
170
+ }
171
+ if (a !== null) {
172
+ const e = a[y];
173
+ if (e !== undefined) {
174
+ c++;
175
+ notifyKeyDiff(e, y, r, n, false);
176
+ }
177
+ }
178
+ }
179
+ }
180
+ // Indices past the new length (and `length` itself) still have nodes.
181
+ if (a !== null && c < e.nc) {
182
+ for (const e of Reflect.ownKeys(a)) {
183
+ const t = typeof e === "string" ? +e : NaN;
184
+ if (!(t >= 0 && t < s.length)) notifyKeyDiff(a[e], e, r, n, false);
185
+ }
186
+ }
187
+ notifyFoldTail(e, r, n);
188
+ return;
189
+ }
190
+ const a = e.n;
191
+ let c = 0;
192
+ let d = false;
193
+ for (const f in n) {
194
+ const s = n[f];
195
+ const p = r[f];
196
+ const y = s !== null && typeof s === "object";
197
+ if (p === s && (!y || !isOwned(s)) && (a === null || a[f] === undefined || !hasAccessorFlag(a[f]))) {
198
+ if (a !== null && a[f] !== undefined) c++;
199
+ continue;
200
+ }
201
+ if (y && !u) descend(unwrapValue(i[f]), s, t, l, o);
202
+ if (e.dk !== null && !d && !(y ? targetsEqual(p, s) : isEqual(p, s))) {
203
+ bumpDeep(e);
204
+ d = true;
205
+ }
206
+ if (a !== null) {
207
+ const e = a[f];
208
+ if (e !== undefined) {
209
+ c++;
210
+ notifyKeyValue(e, f, p, s, r, n);
211
+ }
212
+ }
213
+ }
214
+ const p = Object.getOwnPropertySymbols(n);
215
+ for (let e = 0; e < p.length; e++) {
216
+ const f = p[e];
217
+ if (f === $OWNER) continue;
218
+ const i = n[f];
219
+ if (!u && i !== null && typeof i === "object") descend(unwrapValue(r[f]), i, t, l, o);
220
+ if (a !== null) {
221
+ const e = a[f];
222
+ if (e !== undefined) {
223
+ c++;
224
+ notifyKeyValue(e, f, r[f], i, r, n);
225
+ }
226
+ }
227
+ }
228
+ // Keys the incoming object no longer has still have nodes.
229
+ if (a !== null && c < e.nc) {
230
+ for (const e of Reflect.ownKeys(a)) {
231
+ if (!hasOwnP.call(n, e)) notifyKeyDiff(a[e], e, r, n, false);
232
+ }
233
+ }
234
+ notifyFoldTail(e, r, n);
235
+ }
236
+
237
+ const hasOwnP = Object.prototype.hasOwnProperty;
238
+
239
+ /** Descend into a changed child pair — only where something is proxied
240
+ * below (§6d), never into a raw-marked leaf, never across array/object or a
241
+ * key mismatch (that is a replacement, handled by the parent's slot). */ function descend(e, n, t, o, f = false) {
242
+ if (e === null || typeof e !== "object" || n === null || typeof n !== "object") return;
243
+ const l = lookupTarget(e, o);
244
+ if (l === undefined) return;
245
+ // nothing proxied below this pair
246
+ if (!isWrappable(n)) return;
247
+ if (rawValuesUsed && isRawValue(n)) return;
248
+ n = unwrapValue(n);
249
+ if (Array.isArray(e) !== Array.isArray(n)) return;
250
+ if (t) {
251
+ const o = t(e);
252
+ const f = t(n);
253
+ if (o !== undefined && f !== undefined && !sameKey(o, f)) return;
254
+ }
255
+ if (!f && t !== null && !l.d) return;
256
+ applyAdopt(l, n, t, f);
257
+ }
258
+
259
+ export { reconcileState };