@solidjs/signals 2.0.0-rc.6 → 2.0.0-rc.8
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.
- package/dist/dev-shared.js +5243 -0
- package/dist/dev.attribution.js +2333 -0
- package/dist/dev.js +1758 -6621
- package/dist/observe/affects.js +127 -0
- package/dist/observe/attribution.js +1 -0
- package/dist/observe/boundaries.js +586 -0
- package/dist/observe/core/action.js +167 -0
- package/dist/observe/core/async.js +736 -0
- package/dist/observe/core/attribution-hooks.js +60 -0
- package/dist/observe/core/attribution.js +2318 -0
- package/dist/{types-cjs/core/constants.d.cts → observe/core/constants.js} +135 -71
- package/dist/{types-cjs/core/context.d.cts → observe/core/context.js} +37 -12
- package/dist/observe/core/core.js +1289 -0
- package/dist/observe/core/dev.js +232 -0
- package/dist/observe/core/effect.js +179 -0
- package/dist/observe/core/error.js +80 -0
- package/dist/observe/core/external.js +98 -0
- package/dist/observe/core/graph.js +155 -0
- package/dist/observe/core/heap.js +147 -0
- package/dist/observe/core/invariants.js +43 -0
- package/dist/observe/core/lanes.js +168 -0
- package/dist/observe/core/optimistic.js +438 -0
- package/dist/observe/core/owner.js +308 -0
- package/dist/observe/core/scheduler.js +1190 -0
- package/dist/observe/core/verdict.js +551 -0
- package/dist/observe/index.js +55 -0
- package/dist/observe/map.js +482 -0
- package/dist/{types-cjs/signals.d.cts → observe/signals.js} +305 -317
- package/dist/observe/store/index.js +38 -0
- package/dist/observe/store/next/optimistic.js +651 -0
- package/dist/observe/store/next/projection.js +242 -0
- package/dist/observe/store/next/reconcile.js +373 -0
- package/dist/observe/store/next/store.js +2213 -0
- package/dist/observe/store/next/target.js +51 -0
- package/dist/observe/store/store.js +323 -0
- package/dist/observe/store/storePath.js +103 -0
- package/dist/observe/store/utils.js +210 -0
- package/dist/prod/attribution.js +32 -0
- package/dist/prod/boundaries.js +3 -1
- package/dist/prod/core/action.js +52 -32
- package/dist/prod/core/async.js +177 -128
- package/dist/prod/core/attribution-hooks.js +3 -0
- package/dist/prod/core/constants.js +32 -1
- package/dist/prod/core/context.js +10 -16
- package/dist/prod/core/core.js +505 -286
- package/dist/prod/core/dev.js +2 -0
- package/dist/prod/core/effect.js +72 -43
- package/dist/prod/core/external.js +2 -2
- package/dist/prod/core/graph.js +40 -36
- package/dist/prod/core/heap.js +50 -51
- package/dist/prod/core/lanes.js +43 -22
- package/dist/prod/core/optimistic.js +224 -80
- package/dist/prod/core/owner.js +43 -39
- package/dist/prod/core/scheduler.js +347 -232
- package/dist/prod/core/verdict.js +71 -74
- package/dist/prod/index.js +9 -5
- package/dist/prod/map.js +311 -150
- package/dist/prod/signals.js +52 -38
- package/dist/prod/store/next/optimistic.js +127 -131
- package/dist/prod/store/next/projection.js +3 -3
- package/dist/prod/store/next/reconcile.js +149 -294
- package/dist/prod/store/next/store.js +694 -380
- package/dist/prod/store/next/target.js +32 -10
- package/dist/prod/store/store.js +12 -14
- package/dist/prod/store/utils.js +36 -27
- package/dist/types/attribution.d.ts +15 -0
- package/dist/types/attribution.prod.d.ts +13 -0
- package/dist/types/core/async.d.ts +1 -1
- package/dist/types/core/attribution-hooks.d.ts +183 -6
- package/dist/types/core/attribution.d.ts +435 -24
- package/dist/types/core/constants.d.ts +31 -0
- package/dist/types/core/core.d.ts +19 -3
- package/dist/types/core/dev.d.ts +165 -26
- package/dist/types/core/effect.d.ts +8 -1
- package/dist/types/core/heap.d.ts +5 -3
- package/dist/types/core/index.d.ts +2 -1
- package/dist/types/core/invariants.d.ts +1 -1
- package/dist/types/core/lanes.d.ts +17 -0
- package/dist/types/core/scheduler.d.ts +69 -4
- package/dist/types/core/types.d.ts +29 -9
- package/dist/types/index.d.ts +9 -2
- package/dist/types/map.d.ts +2 -0
- package/dist/types/signals.d.ts +10 -0
- package/dist/types/store/index.d.ts +4 -6
- package/dist/types/store/next/optimistic.d.ts +4 -2
- package/dist/types/store/next/reconcile.d.ts +5 -12
- package/dist/types/store/next/store.d.ts +8 -9
- package/dist/types/store/next/target.d.ts +56 -55
- package/dist/types/store/store.d.ts +14 -9
- package/dist/types/store/utils.d.ts +7 -0
- package/package.json +21 -16
- package/dist/node.cjs +0 -11121
- package/dist/prod/store/next/patch-hooks.js +0 -13
- package/dist/prod/store/next/patch.js +0 -614
- package/dist/types/store/next/patch-hooks.d.ts +0 -41
- package/dist/types/store/next/patch.d.ts +0 -91
- package/dist/types-cjs/affects.d.cts +0 -47
- package/dist/types-cjs/boundaries.d.cts +0 -175
- package/dist/types-cjs/core/action.d.cts +0 -64
- package/dist/types-cjs/core/async.d.cts +0 -23
- package/dist/types-cjs/core/attribution-hooks.d.cts +0 -63
- package/dist/types-cjs/core/attribution.d.cts +0 -239
- package/dist/types-cjs/core/core.d.cts +0 -176
- package/dist/types-cjs/core/dev.d.cts +0 -95
- package/dist/types-cjs/core/effect.d.cts +0 -30
- package/dist/types-cjs/core/error.d.cts +0 -56
- package/dist/types-cjs/core/external.d.cts +0 -15
- package/dist/types-cjs/core/graph.d.cts +0 -28
- package/dist/types-cjs/core/heap.d.cts +0 -22
- package/dist/types-cjs/core/index.d.cts +0 -13
- package/dist/types-cjs/core/invariants.d.cts +0 -59
- package/dist/types-cjs/core/lanes.d.cts +0 -44
- package/dist/types-cjs/core/optimistic.d.cts +0 -6
- package/dist/types-cjs/core/owner.d.cts +0 -124
- package/dist/types-cjs/core/scheduler.d.cts +0 -231
- package/dist/types-cjs/core/types.d.cts +0 -204
- package/dist/types-cjs/core/verdict.d.cts +0 -2
- package/dist/types-cjs/index.d.cts +0 -10
- package/dist/types-cjs/map.d.cts +0 -69
- package/dist/types-cjs/package.json +0 -3
- package/dist/types-cjs/store/index.d.cts +0 -21
- package/dist/types-cjs/store/next/optimistic.d.cts +0 -23
- package/dist/types-cjs/store/next/patch-hooks.d.cts +0 -41
- package/dist/types-cjs/store/next/patch.d.cts +0 -91
- package/dist/types-cjs/store/next/projection.d.cts +0 -8
- package/dist/types-cjs/store/next/reconcile.d.cts +0 -17
- package/dist/types-cjs/store/next/store.d.cts +0 -127
- package/dist/types-cjs/store/next/target.d.cts +0 -192
- package/dist/types-cjs/store/store.d.cts +0 -138
- package/dist/types-cjs/store/storePath.d.cts +0 -58
- package/dist/types-cjs/store/utils.d.cts +0 -74
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CONFIG_AUTO_DISPOSE, STATUS_PENDING, NOT_PENDING, CONFIG_OPTIMISTIC, CONFIG_HELD_TRUTH, unwrapOverride } from "../../core/constants.js";
|
|
1
|
+
import { CONFIG_AUTO_DISPOSE, STATUS_PENDING, STATUS_UNINITIALIZED, NOT_PENDING, CONFIG_OPTIMISTIC, CONFIG_HELD_TRUTH, unwrapOverride } from "../../core/constants.js";
|
|
2
2
|
|
|
3
3
|
import { computed, setSignal, isEqual } from "../../core/core.js";
|
|
4
4
|
|
|
@@ -18,13 +18,11 @@ import { $TARGET, markRawIngest, setNextOptimisticViewResolver, isWrappable, raw
|
|
|
18
18
|
|
|
19
19
|
import { runProjectionComputedNext } from "./projection.js";
|
|
20
20
|
|
|
21
|
-
import { wrapNext, runAuthoritative, storeSetterNext, hasActiveOverride, unwrapValue, targetsEqual, getNode, getHasNode, getKeySetNode, bumpDeep, stagedTruthPB, authoritativeRead } from "./store.js";
|
|
21
|
+
import { wrapNext, runAuthoritative, storeSetterNext, hasActiveOverride, unwrapValue, targetsEqual, heldMaskView, getNode, getHasNode, getKeySetNode, bumpDeep, stagedTruthPB, authoritativeRead } from "./store.js";
|
|
22
22
|
|
|
23
|
-
import {
|
|
23
|
+
import { sameKey } from "./reconcile.js";
|
|
24
24
|
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
import { setOptHooks } from "./target.js";
|
|
25
|
+
import { setOptHooks, $OWNER, lookupTarget } from "./target.js";
|
|
28
26
|
|
|
29
27
|
/**
|
|
30
28
|
* Store rewrite — optimistic stores (§3/§7, RUL-3): no store-side layer, no
|
|
@@ -57,7 +55,7 @@ import { setOptHooks } from "./target.js";
|
|
|
57
55
|
* staged values to converge (normal speculation). Resolves merges first:
|
|
58
56
|
* merge unions optimistic nodes/stores into the target. */ function transitionHoldsOptimism(e) {
|
|
59
57
|
const t = currentTransition(e);
|
|
60
|
-
return t.
|
|
58
|
+
return t.ft !== true && (t.it.length !== 0 || t.En.size !== 0);
|
|
61
59
|
}
|
|
62
60
|
|
|
63
61
|
let blockedInstalled = false;
|
|
@@ -78,37 +76,28 @@ function installNextBlockedHalf() {
|
|
|
78
76
|
// Scheduler flush tails call _clearOptimisticStores whenever tracked
|
|
79
77
|
// stores exist; next has no layer to clear — reverts are engine-native —
|
|
80
78
|
// so the hook only empties the batch set.
|
|
81
|
-
if (!GlobalQueue.
|
|
82
|
-
GlobalQueue.
|
|
83
|
-
// Patch channel (revert site): engine-native reverts flip node values
|
|
84
|
-
// back to committed; patched records need a forced DOM re-apply from
|
|
85
|
-
// the post-revert view. Emission only — next keeps no layer to clear.
|
|
79
|
+
if (!GlobalQueue.ni) {
|
|
80
|
+
GlobalQueue.ni = e => {
|
|
86
81
|
for (const t of e) {
|
|
87
82
|
const e = t?.[$TARGET];
|
|
88
83
|
const n = e?.fam?.overlaid;
|
|
89
84
|
if (n !== undefined) {
|
|
90
85
|
for (const e of n) {
|
|
91
|
-
if (e.pc !== null && e.pc.p !== null) patchHooks.emitPatchOptimistic(e, null, null);
|
|
92
|
-
// Row-ops resync (family increment 2): reverts flip node values
|
|
93
|
-
// back engine-natively; a driven list must rebuild retention by
|
|
94
|
-
// row identity against the post-revert view (resolved from the
|
|
95
|
-
// target at drain — overrides are gone by then).
|
|
96
|
-
if (e.pc !== null && e.pc.ro !== null) rowHooks.emitRowOpsOptimistic(e, null, null);
|
|
97
86
|
// Keyset resync (classic channel twin): the keyset node's own
|
|
98
87
|
// revert can compare EQUAL (a landing's bump matched the
|
|
99
88
|
// tentative bump) while the arrangement underneath changed —
|
|
100
89
|
// mapArray/ownKeys subscribers must re-read the post-revert
|
|
101
90
|
// view. Authoritative bump: never re-arm the node we are
|
|
102
91
|
// clearing.
|
|
103
|
-
|
|
92
|
+
if (e.k !== null) runAuthoritative(() => setSignal(e.k, e => e + 1));
|
|
104
93
|
}
|
|
105
94
|
}
|
|
106
95
|
}
|
|
107
96
|
e.clear();
|
|
108
97
|
};
|
|
109
98
|
}
|
|
110
|
-
const e = GlobalQueue.
|
|
111
|
-
GlobalQueue.
|
|
99
|
+
const e = GlobalQueue.cn;
|
|
100
|
+
GlobalQueue.cn = t => {
|
|
112
101
|
for (const e of t.En) {
|
|
113
102
|
const n = e?.[$TARGET];
|
|
114
103
|
const i = n?.fam;
|
|
@@ -139,10 +128,10 @@ function familyHasLiveOverrides(e) {
|
|
|
139
128
|
if (t === null) continue;
|
|
140
129
|
for (const e of Reflect.ownKeys(t)) {
|
|
141
130
|
const n = t[e];
|
|
142
|
-
if (n.o?.
|
|
131
|
+
if (n.o?.be !== undefined && n.o?.be !== NOT_PENDING) return true;
|
|
143
132
|
}
|
|
144
133
|
}
|
|
145
|
-
if (e.k !== null && e.k.o?.
|
|
134
|
+
if (e.k !== null && e.k.o?.be !== undefined && e.k.o?.be !== NOT_PENDING) return true;
|
|
146
135
|
}
|
|
147
136
|
t.clear();
|
|
148
137
|
// nothing live — drop the bookkeeping
|
|
@@ -155,23 +144,23 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
155
144
|
installOptimisticEngine();
|
|
156
145
|
installNextBlockedHalf();
|
|
157
146
|
const i = typeof e === "function";
|
|
158
|
-
|
|
159
|
-
const
|
|
160
|
-
const
|
|
147
|
+
const o = i ? n : t;
|
|
148
|
+
const r = i ? t : e;
|
|
149
|
+
const s = {
|
|
161
150
|
map: new WeakMap,
|
|
162
151
|
node: null,
|
|
163
|
-
shallow: !!
|
|
152
|
+
shallow: !!o?.shallow,
|
|
164
153
|
opt: true
|
|
165
154
|
};
|
|
166
|
-
const l = wrapNext(
|
|
167
|
-
|
|
155
|
+
const l = wrapNext(r, null, null, s);
|
|
156
|
+
s.px = l;
|
|
168
157
|
// Same key resolution the projection channels use ("id" default) — replay's
|
|
169
158
|
// satisfaction rule reads it off the family.
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
if (
|
|
159
|
+
const u = o?.key === undefined ? "id" : o.key;
|
|
160
|
+
s.key = typeof u === "function" ? u : u === null ? null : e => isWrappable(e) ? e[u] : undefined;
|
|
161
|
+
if (s.shallow) {
|
|
173
162
|
l[$TARGET].s = true;
|
|
174
|
-
markRawIngest(
|
|
163
|
+
markRawIngest(r);
|
|
175
164
|
}
|
|
176
165
|
if (i) {
|
|
177
166
|
const t = e;
|
|
@@ -185,11 +174,11 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
185
174
|
// flight (loading window) keeps the ambient reveal (#2933: the loading
|
|
186
175
|
// rail is transaction-invisible).
|
|
187
176
|
const enterFlightTransition = () => {
|
|
188
|
-
const e =
|
|
177
|
+
const e = s.ft;
|
|
189
178
|
if (e == null) return;
|
|
190
179
|
let t = liveTransition(e);
|
|
191
|
-
if (t === null)
|
|
192
|
-
|
|
180
|
+
if (t === null) s.ft = t = createTransition();
|
|
181
|
+
s.node.ge = t;
|
|
193
182
|
globalQueue.initTransition(t);
|
|
194
183
|
};
|
|
195
184
|
// Landing router (#3164 fold ruling): while a transaction retains
|
|
@@ -200,9 +189,9 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
200
189
|
// flight-owned transaction (#3146). Sync commits (the derive's body,
|
|
201
190
|
// owner is the firewall itself) reveal with their own recompute's flush.
|
|
202
191
|
const wrapCommit = (e, t) => {
|
|
203
|
-
const n = retainingTransition(
|
|
204
|
-
if (n !== null) return void stageLanding(
|
|
205
|
-
if (getOwner() !==
|
|
192
|
+
const n = retainingTransition(s);
|
|
193
|
+
if (n !== null) return void stageLanding(s, n, t);
|
|
194
|
+
if (getOwner() !== s.node) enterFlightTransition();
|
|
206
195
|
runAuthoritative(e);
|
|
207
196
|
};
|
|
208
197
|
// Draft writes (the derive mutating its draft, sync body and post-await
|
|
@@ -212,7 +201,7 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
212
201
|
// batch; the write-override eager-commit branch in notifyWrites yields
|
|
213
202
|
// to any active transaction).
|
|
214
203
|
const aroundDraftWrite = e => {
|
|
215
|
-
const t = retainingTransition(
|
|
204
|
+
const t = retainingTransition(s);
|
|
216
205
|
if (t === null) e(); else runFolded(t, e);
|
|
217
206
|
};
|
|
218
207
|
// Flight declaration (#3146): a recompute that registered a truth-flight
|
|
@@ -234,33 +223,42 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
234
223
|
// (#2933: the loading rail is transaction-invisible); a sync run clears
|
|
235
224
|
// the declaration.
|
|
236
225
|
const declareFlight = e => {
|
|
237
|
-
if (e.o?.
|
|
238
|
-
if (!e.
|
|
226
|
+
if (e.o?.Pe == null) {
|
|
227
|
+
if (!e.Ae) s.ft = null;
|
|
239
228
|
return;
|
|
240
229
|
}
|
|
241
|
-
|
|
230
|
+
// First flight (#3146 carve-out): nothing has ever committed, so there
|
|
231
|
+
// is no truth to keep on screen and no optimistic state to protect. An
|
|
232
|
+
// uninitialized ask suspends its readers into their Loading boundary
|
|
233
|
+
// exactly like a plain derived store's first flight — declaring a
|
|
234
|
+
// transaction here instead held the ROOT MOUNT (render()'s scheduled
|
|
235
|
+
// insert rides transitions) until the fetch landed, so the boundary's
|
|
236
|
+
// fallback never showed and the whole page stayed blank. The loading
|
|
237
|
+
// window (#2933) already declares nothing for the same reason; once
|
|
238
|
+
// the first truth lands, every refetch flight declares as before.
|
|
239
|
+
if (e.Ae || e.S & STATUS_UNINITIALIZED) return;
|
|
242
240
|
let t = activeTransition;
|
|
243
241
|
if (t === null) globalQueue.initTransition(t = createTransition());
|
|
244
|
-
|
|
245
|
-
e.
|
|
246
|
-
let n = t.
|
|
247
|
-
if (n === undefined) t.
|
|
242
|
+
s.ft = t;
|
|
243
|
+
e.ge = t;
|
|
244
|
+
let n = t.Re.get(e);
|
|
245
|
+
if (n === undefined) t.Re.set(e, n = new Set);
|
|
248
246
|
n.add(e);
|
|
249
247
|
};
|
|
250
|
-
let
|
|
251
|
-
if (
|
|
248
|
+
let n;
|
|
249
|
+
if (o?.seedLoadingValue) n = {
|
|
252
250
|
loadingValue: undefined
|
|
253
251
|
};
|
|
254
|
-
const
|
|
252
|
+
const i = computed(() => {
|
|
255
253
|
const e = getOwner();
|
|
256
254
|
try {
|
|
257
|
-
runAuthoritative(() => runProjectionComputedNext(l, t,
|
|
255
|
+
runAuthoritative(() => runProjectionComputedNext(l, t, o?.key === undefined ? "id" : o.key, wrapCommit, aroundDraftWrite));
|
|
258
256
|
} finally {
|
|
259
257
|
declareFlight(e);
|
|
260
258
|
}
|
|
261
|
-
},
|
|
262
|
-
|
|
263
|
-
|
|
259
|
+
}, n);
|
|
260
|
+
i.T &= ~CONFIG_AUTO_DISPOSE;
|
|
261
|
+
s.node = i;
|
|
264
262
|
}
|
|
265
263
|
return [ l, e => {
|
|
266
264
|
// Retention ledger (#3164): record the owning transaction so landings
|
|
@@ -270,14 +268,14 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
270
268
|
// per #2951 and dies with it).
|
|
271
269
|
const t = activeTransition;
|
|
272
270
|
storeSetterNext(l, e);
|
|
273
|
-
if (t !== null) (
|
|
271
|
+
if (t !== null) (s.rt ??= new Set).add(t);
|
|
274
272
|
} ];
|
|
275
273
|
}
|
|
276
274
|
|
|
277
275
|
/** Resolve a retained transition through its merge chain (`_done` holds the
|
|
278
276
|
* merge target while merged, `true` once settled). Null = dead. */ function liveTransition(e) {
|
|
279
|
-
while (typeof e.
|
|
280
|
-
return e.
|
|
277
|
+
while (typeof e.ft === "object") e = e.ft;
|
|
278
|
+
return e.ft === true ? null : e;
|
|
281
279
|
}
|
|
282
280
|
|
|
283
281
|
/** The transaction truth landings fold into: the first live member of the
|
|
@@ -322,10 +320,10 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
322
320
|
* stay unarmed — the override is their display and its revert their
|
|
323
321
|
* notification, A17). */ function runFolded(e, t) {
|
|
324
322
|
runAsTransitionBatch(e, t);
|
|
325
|
-
const n = e
|
|
323
|
+
const n = e.$t;
|
|
326
324
|
for (let t = 0; t < n.length; t++) {
|
|
327
325
|
const i = n[t];
|
|
328
|
-
i.
|
|
326
|
+
i.ge = e;
|
|
329
327
|
if (i.T & CONFIG_OPTIMISTIC && !hasActiveOverride(i)) i.T |= CONFIG_HELD_TRUTH;
|
|
330
328
|
}
|
|
331
329
|
}
|
|
@@ -349,8 +347,8 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
349
347
|
if (!isWrappable(i)) continue;
|
|
350
348
|
const r = n(i);
|
|
351
349
|
if (r === undefined) continue;
|
|
352
|
-
const
|
|
353
|
-
if (
|
|
350
|
+
const s = (o ??= new Map).get(r);
|
|
351
|
+
if (s === undefined) o.set(r, [ i ]); else s.push(i);
|
|
354
352
|
}
|
|
355
353
|
// Echo adoption: an optimistic structural add whose key the landing
|
|
356
354
|
// confirms must keep its raw (and so its proxy — list drivers keep the
|
|
@@ -360,35 +358,35 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
360
358
|
// keys; overlay rows only extend coverage. Adopted raws enter staged
|
|
361
359
|
// truth; at settle the override reverts and the reveal re-seats the
|
|
362
360
|
// same raw.
|
|
363
|
-
const
|
|
364
|
-
if (
|
|
365
|
-
for (const e of Reflect.ownKeys(
|
|
366
|
-
const t =
|
|
361
|
+
const s = e[$TARGET]?.n;
|
|
362
|
+
if (s != null) {
|
|
363
|
+
for (const e of Reflect.ownKeys(s)) {
|
|
364
|
+
const t = s[e];
|
|
367
365
|
if (!hasActiveOverride(t)) continue;
|
|
368
|
-
const i = unwrapValue(unwrapOverride(t.o.
|
|
366
|
+
const i = unwrapValue(unwrapOverride(t.o.be));
|
|
369
367
|
if (!isWrappable(i)) continue;
|
|
370
368
|
const r = n(i);
|
|
371
369
|
if (r === undefined) continue;
|
|
372
|
-
const
|
|
373
|
-
if (
|
|
370
|
+
const l = (o ??= new Map).get(r);
|
|
371
|
+
if (l === undefined) o.set(r, [ i ]); else l.push(i);
|
|
374
372
|
}
|
|
375
373
|
}
|
|
376
374
|
for (let r = 0; r < i; r++) {
|
|
377
375
|
const i = t[r];
|
|
378
|
-
let
|
|
376
|
+
let s;
|
|
379
377
|
if (isWrappable(i) && o !== null) {
|
|
380
378
|
const e = n(i);
|
|
381
379
|
if (e !== undefined) {
|
|
382
380
|
for (const [t, n] of o) {
|
|
383
381
|
if (!sameKey(t, e)) continue;
|
|
384
|
-
|
|
382
|
+
s = n.shift();
|
|
385
383
|
if (n.length === 0) o.delete(t);
|
|
386
384
|
break;
|
|
387
385
|
}
|
|
388
386
|
}
|
|
389
387
|
}
|
|
390
|
-
if (
|
|
391
|
-
if (unwrapValue(e[r]) !==
|
|
388
|
+
if (s !== undefined) {
|
|
389
|
+
if (unwrapValue(e[r]) !== s) e[r] = s;
|
|
392
390
|
stagedApply(e[r], i, n);
|
|
393
391
|
} else {
|
|
394
392
|
const t = unwrapValue(e[r]);
|
|
@@ -409,15 +407,15 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
409
407
|
// Object merge; also the degenerate root-kind-change shape (arrays accept
|
|
410
408
|
// keyed writes/deletes, so a wholesale restatement still lands staged).
|
|
411
409
|
for (const o of Reflect.ownKeys(t)) {
|
|
412
|
-
if (i && o === "length") continue;
|
|
410
|
+
if (i && o === "length" || o === $OWNER) continue;
|
|
413
411
|
const r = t[o];
|
|
414
|
-
const
|
|
415
|
-
if (
|
|
416
|
-
if (isWrappable(r) && isWrappable(
|
|
412
|
+
const s = unwrapValue(e[o]);
|
|
413
|
+
if (s === r) continue;
|
|
414
|
+
if (isWrappable(r) && isWrappable(s) && Array.isArray(r) === Array.isArray(s)) {
|
|
417
415
|
// Different-keyed entities never merge (tentative-channel parity):
|
|
418
416
|
// the incoming object replaces the slot wholesale.
|
|
419
417
|
if (n !== null) {
|
|
420
|
-
const t = n(
|
|
418
|
+
const t = n(s);
|
|
421
419
|
const i = n(r);
|
|
422
420
|
if (t !== undefined && i !== undefined && !sameKey(t, i)) {
|
|
423
421
|
e[o] = r;
|
|
@@ -425,12 +423,12 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
425
423
|
}
|
|
426
424
|
}
|
|
427
425
|
stagedApply(e[o], r, n);
|
|
428
|
-
} else if (!isEqual(
|
|
426
|
+
} else if (!isEqual(s, r) && !targetsEqual(s, r)) {
|
|
429
427
|
e[o] = r;
|
|
430
428
|
}
|
|
431
429
|
}
|
|
432
430
|
for (const n of Reflect.ownKeys(e)) {
|
|
433
|
-
if (i && n === "length" || n in t) continue;
|
|
431
|
+
if (i && n === "length" || n === $OWNER || n in t) continue;
|
|
434
432
|
delete e[n];
|
|
435
433
|
}
|
|
436
434
|
}
|
|
@@ -453,50 +451,49 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
453
451
|
const e = liveTransition(n);
|
|
454
452
|
if (e !== null) globalQueue.initTransition(e);
|
|
455
453
|
}
|
|
456
|
-
|
|
457
|
-
//
|
|
458
|
-
//
|
|
459
|
-
//
|
|
460
|
-
|
|
461
|
-
//
|
|
462
|
-
//
|
|
463
|
-
//
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
const visible = (t, n) => {
|
|
454
|
+
// The write is judged against what ordinary readers SEE, not against the
|
|
455
|
+
// committed backing slot: under an adoption hold (#3074) `t.v` is already
|
|
456
|
+
// the truth a live transaction is holding, and an optimistic write equal
|
|
457
|
+
// to it compared as a no-op — no override, no lane, and the screen kept
|
|
458
|
+
// the pre-hold value until the transaction committed (#3330's store
|
|
459
|
+
// twin: `s.v = 1` after a `yield` while the derive had already staged
|
|
460
|
+
// `v: 1`). Signal parity: the override reveals on its lane now, with its
|
|
461
|
+
// derivations; the held truth reveals on the transaction's schedule.
|
|
462
|
+
const i = heldMaskView(e) ?? e.v;
|
|
463
|
+
// Compare RAWS on both sides (`nv` below is unwrapped already). A chained
|
|
464
|
+
// target's `old` is the inner store's proxy, whose reads hand back inner
|
|
465
|
+
// child PROXIES; the draft's clone holds the inner raws. Comparing the two
|
|
466
|
+
// as-is marked every untouched row changed, and the overlay then served
|
|
467
|
+
// each from an override as a fresh non-chained target — row identities
|
|
468
|
+
// churned for the life of the action and snapped back at settle (#3323).
|
|
469
|
+
const visible = (t, n) => {
|
|
473
470
|
const i = e.n?.[t];
|
|
474
|
-
return i !== undefined && hasActiveOverride(i) ? unwrapOverride(i.o?.
|
|
471
|
+
return unwrapValue(i !== undefined && hasActiveOverride(i) ? unwrapOverride(i.o?.be) : n);
|
|
475
472
|
};
|
|
476
473
|
const visiblePresent = t => {
|
|
477
474
|
const n = e.h?.[t];
|
|
478
|
-
return n !== undefined && hasActiveOverride(n) ? !!unwrapOverride(n.o?.
|
|
475
|
+
return n !== undefined && hasActiveOverride(n) ? !!unwrapOverride(n.o?.be) : t in i;
|
|
479
476
|
};
|
|
480
477
|
let o = false;
|
|
481
478
|
const r = Array.isArray(t);
|
|
482
479
|
for (const n of Reflect.ownKeys(t)) {
|
|
483
|
-
if (r && n === "length") continue;
|
|
484
|
-
const
|
|
480
|
+
if (r && n === "length" || n === $OWNER) continue;
|
|
481
|
+
const s = unwrapValue(t[n]);
|
|
485
482
|
if (!visiblePresent(n)) {
|
|
486
483
|
// Optimistic add: value node + presence node + membership bump.
|
|
487
|
-
setSignal(getNode(e, n, i[n]), () =>
|
|
484
|
+
setSignal(getNode(e, n, i[n]), () => s);
|
|
488
485
|
setSignal(getHasNode(e, n, n in i), true);
|
|
489
486
|
o = true;
|
|
490
487
|
} else {
|
|
491
488
|
const t = visible(n, i[n]);
|
|
492
|
-
if (!isEqual(t,
|
|
493
|
-
setSignal(getNode(e, n, t), () =>
|
|
489
|
+
if (!isEqual(t, s) && !targetsEqual(t, s)) {
|
|
490
|
+
setSignal(getNode(e, n, t), () => s);
|
|
494
491
|
if (r) o = true;
|
|
495
492
|
}
|
|
496
493
|
}
|
|
497
494
|
}
|
|
498
495
|
for (const n of Reflect.ownKeys(i)) {
|
|
499
|
-
if (r && n === "length") continue;
|
|
496
|
+
if (r && n === "length" || n === $OWNER) continue;
|
|
500
497
|
if (n in t || !visiblePresent(n)) continue;
|
|
501
498
|
// Optimistic delete: node reads undefined, presence flips, membership bumps.
|
|
502
499
|
setSignal(getNode(e, n, i[n]), () => undefined);
|
|
@@ -521,7 +518,7 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
521
518
|
e.pb = stagedTruthPB.get(e) ?? null;
|
|
522
519
|
if (e.pb !== null) stagedTruthPB.delete(e);
|
|
523
520
|
(e.fam.overlaid ??= new Set).add(e);
|
|
524
|
-
GlobalQueue.
|
|
521
|
+
GlobalQueue.Nn?.(e.fam.px ?? e.px);
|
|
525
522
|
}
|
|
526
523
|
|
|
527
524
|
/** Optimistic-view composition for snapshot/deep (O1: snapshot is the CURRENT
|
|
@@ -540,7 +537,7 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
540
537
|
for (const e of Reflect.ownKeys(i)) {
|
|
541
538
|
const n = i[e];
|
|
542
539
|
if (!hasActiveOverride(n)) continue;
|
|
543
|
-
const o = unwrapOverride(n.o?.
|
|
540
|
+
const o = unwrapOverride(n.o?.be);
|
|
544
541
|
if (e === "length" && Array.isArray(t)) {
|
|
545
542
|
if (t.length !== o) ensure().length = o;
|
|
546
543
|
} else if (!isEqual(t[e], o)) ensure()[e] = o;
|
|
@@ -551,7 +548,7 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
551
548
|
for (const e of Reflect.ownKeys(o)) {
|
|
552
549
|
const i = o[e];
|
|
553
550
|
if (!hasActiveOverride(i)) continue;
|
|
554
|
-
const r = !!unwrapOverride(i.o?.
|
|
551
|
+
const r = !!unwrapOverride(i.o?.be);
|
|
555
552
|
if (!r && e in (n ?? t)) delete ensure()[e];
|
|
556
553
|
}
|
|
557
554
|
}
|
|
@@ -561,12 +558,16 @@ function createOptimisticStoreNext(e, t, n) {
|
|
|
561
558
|
function applyTentative(e, t, n) {
|
|
562
559
|
const i = e.pb ?? e.v;
|
|
563
560
|
const o = optimisticView(e, i);
|
|
564
|
-
const r = e.fam
|
|
565
|
-
const
|
|
566
|
-
if (Array.isArray(o) !==
|
|
561
|
+
const r = e.fam;
|
|
562
|
+
const s = Array.isArray(t);
|
|
563
|
+
if (Array.isArray(o) !== s) return;
|
|
567
564
|
// kind change at root: flat overrides below
|
|
568
|
-
const
|
|
569
|
-
|
|
565
|
+
const l = [];
|
|
566
|
+
let u;
|
|
567
|
+
if (s) u = [ ...t ]; else {
|
|
568
|
+
u = {};
|
|
569
|
+
for (const e of Reflect.ownKeys(t)) if (e !== $OWNER) u[e] = t[e];
|
|
570
|
+
}
|
|
570
571
|
const match = (e, t) => {
|
|
571
572
|
if (!isWrappable(e) || !isWrappable(t)) return null;
|
|
572
573
|
if (rawValuesUsed && (isRawValue(e) || isRawValue(t))) return null;
|
|
@@ -578,15 +579,15 @@ function applyTentative(e, t, n) {
|
|
|
578
579
|
// channel — NaN keys are self-equal.
|
|
579
580
|
if (i !== undefined && o !== undefined && !sameKey(i, o)) return null;
|
|
580
581
|
}
|
|
581
|
-
return
|
|
582
|
+
return lookupTarget(unwrapValue(e), r) ?? null;
|
|
582
583
|
};
|
|
583
|
-
if (
|
|
584
|
+
if (s) {
|
|
584
585
|
const e = o;
|
|
585
586
|
let i = null;
|
|
586
587
|
for (let o = 0; o < t.length; o++) {
|
|
587
588
|
const r = t[o];
|
|
588
589
|
if (!isWrappable(r)) continue;
|
|
589
|
-
let
|
|
590
|
+
let s;
|
|
590
591
|
if (n) {
|
|
591
592
|
const t = n(r);
|
|
592
593
|
if (t !== undefined) {
|
|
@@ -606,30 +607,31 @@ function applyTentative(e, t, n) {
|
|
|
606
607
|
}
|
|
607
608
|
}
|
|
608
609
|
const o = i.get(t);
|
|
609
|
-
if (o === undefined)
|
|
610
|
-
|
|
610
|
+
if (o === undefined) s = undefined; else if (Array.isArray(o)) {
|
|
611
|
+
s = unwrapValue(e[o.shift()]);
|
|
611
612
|
if (o.length === 1) i.set(t, o[0]);
|
|
612
613
|
} else {
|
|
613
|
-
|
|
614
|
+
s = unwrapValue(e[o]);
|
|
614
615
|
i.delete(t);
|
|
615
616
|
}
|
|
616
|
-
} else
|
|
617
|
-
} else
|
|
618
|
-
const a = match(
|
|
617
|
+
} else s = unwrapValue(e[o]);
|
|
618
|
+
} else s = unwrapValue(e[o]);
|
|
619
|
+
const a = match(s, r);
|
|
619
620
|
if (a !== null) {
|
|
620
621
|
// Keep the existing row in the slot (identity preserved); recurse.
|
|
621
|
-
u[o] = unwrapValue(
|
|
622
|
-
|
|
622
|
+
u[o] = unwrapValue(s);
|
|
623
|
+
l.push([ a, r ]);
|
|
623
624
|
}
|
|
624
625
|
}
|
|
625
626
|
} else {
|
|
626
627
|
for (const e of Reflect.ownKeys(t)) {
|
|
628
|
+
if (e === $OWNER) continue;
|
|
627
629
|
const n = unwrapValue(o[e]);
|
|
628
630
|
const i = t[e];
|
|
629
631
|
const r = match(n, i);
|
|
630
632
|
if (r !== null) {
|
|
631
633
|
u[e] = n;
|
|
632
|
-
|
|
634
|
+
l.push([ r, i ]);
|
|
633
635
|
}
|
|
634
636
|
}
|
|
635
637
|
}
|
|
@@ -639,13 +641,7 @@ function applyTentative(e, t, n) {
|
|
|
639
641
|
e.pb = null;
|
|
640
642
|
notifyOptimisticWrites(e, u);
|
|
641
643
|
e.pb = a;
|
|
642
|
-
for (let e = 0; e <
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
function shallowWithSymbols(e) {
|
|
646
|
-
const t = {};
|
|
647
|
-
for (const n of Reflect.ownKeys(e)) t[n] = e[n];
|
|
648
|
-
return t;
|
|
644
|
+
for (let e = 0; e < l.length; e++) applyTentative(l[e][0], unwrapValue(l[e][1]), n);
|
|
649
645
|
}
|
|
650
646
|
|
|
651
647
|
export { createOptimisticStoreNext, notifyOptimisticWrites, optimisticView, transitionHoldsOptimism };
|
|
@@ -215,8 +215,8 @@ function runProjectionComputedNext(e, t, r, i, o) {
|
|
|
215
215
|
// for the whole first flight — the derive works a detached shadow of the
|
|
216
216
|
// seed so draft writes cannot tear through to readers (#2988). Every commit
|
|
217
217
|
// point reconciles the shadow through the normal commit path.
|
|
218
|
-
const u = n.
|
|
219
|
-
const l = wrapDraft(e, () => !c || n.o?.
|
|
218
|
+
const u = n.Ae ? JSON.parse(JSON.stringify(e[$TARGET][STORE_VALUE])) : null;
|
|
219
|
+
const l = wrapDraft(e, () => !c || n.o?.Pe === s, o);
|
|
220
220
|
storeSetterNext(l, o => {
|
|
221
221
|
s = t(u ?? o);
|
|
222
222
|
c = true;
|
|
@@ -230,7 +230,7 @@ function runProjectionComputedNext(e, t, r, i, o) {
|
|
|
230
230
|
i ? i(write, t) : write();
|
|
231
231
|
};
|
|
232
232
|
const l = handleAsync(n, s, commit);
|
|
233
|
-
if (!n.
|
|
233
|
+
if (!n.Ae) commit(l);
|
|
234
234
|
}, false);
|
|
235
235
|
return n;
|
|
236
236
|
}
|