@solidjs/signals 2.0.0-beta.24 → 2.0.0-beta.25
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.js +465 -81
- package/dist/node.cjs +990 -652
- package/dist/prod/core/core.js +110 -76
- package/dist/prod/core/effect.js +9 -9
- package/dist/prod/core/graph.js +3 -3
- package/dist/prod/core/heap.js +23 -23
- package/dist/prod/core/optimistic.js +6 -4
- package/dist/prod/core/owner.js +10 -10
- package/dist/prod/core/scheduler.js +12 -12
- package/dist/prod/core/verdict.js +3 -3
- package/dist/prod/store/optimistic.js +12 -5
- package/dist/prod/store/projection.js +25 -18
- package/dist/prod/store/reconcile.js +405 -211
- package/dist/prod/store/store.js +196 -102
- package/dist/prod/store/utils.js +22 -22
- package/dist/types/core/core.d.ts +15 -0
- package/dist/types/store/optimistic.d.ts +1 -1
- package/dist/types/store/store.d.ts +20 -2
- package/dist/types-cjs/core/core.d.cts +15 -0
- package/dist/types-cjs/store/optimistic.d.cts +1 -1
- package/dist/types-cjs/store/store.d.cts +20 -2
- package/package.json +1 -1
package/dist/prod/core/owner.js
CHANGED
|
@@ -54,7 +54,7 @@ function disposeChildren(e, n = false, t) {
|
|
|
54
54
|
if (n.be || n.ge) GlobalQueue.un(n);
|
|
55
55
|
}
|
|
56
56
|
if (n && e.ke) e.Te = null;
|
|
57
|
-
let l = t ? e.
|
|
57
|
+
let l = t ? e.ye : e.me;
|
|
58
58
|
while (l) {
|
|
59
59
|
const e = l.ve;
|
|
60
60
|
if (l.Xe) {
|
|
@@ -71,7 +71,7 @@ function disposeChildren(e, n = false, t) {
|
|
|
71
71
|
l = e;
|
|
72
72
|
}
|
|
73
73
|
if (t) {
|
|
74
|
-
e.
|
|
74
|
+
e.ye = null;
|
|
75
75
|
} else {
|
|
76
76
|
e.me = null;
|
|
77
77
|
e.Qe = 0;
|
|
@@ -90,15 +90,15 @@ function disposeChildren(e, n = false, t) {
|
|
|
90
90
|
runDisposal(e, t);
|
|
91
91
|
// Final effect-returned cleanup fires at true disposal, after `_disposal`
|
|
92
92
|
// to mirror rerun ordering (compute-phase teardown first, cleanup last).
|
|
93
|
-
if (n && e.
|
|
94
|
-
const n = e.
|
|
95
|
-
e.
|
|
93
|
+
if (n && e.ft) {
|
|
94
|
+
const n = e.ft;
|
|
95
|
+
e.ft = undefined;
|
|
96
96
|
n();
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
function runDisposal(e, n) {
|
|
101
|
-
let t = n ? e.
|
|
101
|
+
let t = n ? e.Le : e.xe;
|
|
102
102
|
if (!t) return;
|
|
103
103
|
if (Array.isArray(t)) {
|
|
104
104
|
for (let e = 0; e < t.length; e++) {
|
|
@@ -108,7 +108,7 @@ function runDisposal(e, n) {
|
|
|
108
108
|
} else {
|
|
109
109
|
t.call(t);
|
|
110
110
|
}
|
|
111
|
-
n ? e.
|
|
111
|
+
n ? e.Le = null : e.xe = null;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
function childId(e, n) {
|
|
@@ -235,8 +235,8 @@ function disposeRootSelf(e = true) {
|
|
|
235
235
|
const i = {
|
|
236
236
|
id: inheritId(e, t, n),
|
|
237
237
|
T: t ? CONFIG_TRANSPARENT : 0,
|
|
238
|
-
|
|
239
|
-
Nt: n?.
|
|
238
|
+
Et: true,
|
|
239
|
+
Nt: n?.Et ? n.Nt : n,
|
|
240
240
|
me: null,
|
|
241
241
|
ve: null,
|
|
242
242
|
st: null,
|
|
@@ -244,8 +244,8 @@ function disposeRootSelf(e = true) {
|
|
|
244
244
|
C: n?.C ?? globalQueue,
|
|
245
245
|
we: n?.we || defaultContext,
|
|
246
246
|
Qe: 0,
|
|
247
|
-
ye: null,
|
|
248
247
|
Le: null,
|
|
248
|
+
ye: null,
|
|
249
249
|
Ge: n,
|
|
250
250
|
dispose: disposeRootSelf
|
|
251
251
|
};
|
|
@@ -19,14 +19,14 @@ const transitions = new Set;
|
|
|
19
19
|
const dirtyQueue = {
|
|
20
20
|
eE: new Array(2e3).fill(undefined),
|
|
21
21
|
tE: false,
|
|
22
|
-
|
|
22
|
+
Fe: 0,
|
|
23
23
|
EE: 0
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
const zombieQueue = {
|
|
27
27
|
eE: new Array(2e3).fill(undefined),
|
|
28
28
|
tE: false,
|
|
29
|
-
|
|
29
|
+
Fe: 0,
|
|
30
30
|
EE: 0
|
|
31
31
|
};
|
|
32
32
|
|
|
@@ -281,8 +281,8 @@ class GlobalQueue extends Queue {
|
|
|
281
281
|
static ae=null;
|
|
282
282
|
static he=null;
|
|
283
283
|
static un=null;
|
|
284
|
-
static St=null;
|
|
285
284
|
static dt=null;
|
|
285
|
+
static St=null;
|
|
286
286
|
static Rt=null;
|
|
287
287
|
static ze=null;
|
|
288
288
|
static k=null;
|
|
@@ -296,13 +296,13 @@ class GlobalQueue extends Queue {
|
|
|
296
296
|
// once the gate holds.
|
|
297
297
|
static Pt=null;
|
|
298
298
|
static En=null;
|
|
299
|
-
static Tn=null;
|
|
300
299
|
static dn=null;
|
|
300
|
+
static Tn=null;
|
|
301
301
|
static In=null;
|
|
302
302
|
static Ct=null;
|
|
303
303
|
static At=null;
|
|
304
304
|
static Ot=null;
|
|
305
|
-
static
|
|
305
|
+
static Ye=null;
|
|
306
306
|
static Ke=null;
|
|
307
307
|
static Me=null;
|
|
308
308
|
static Nn=null;
|
|
@@ -334,7 +334,7 @@ class GlobalQueue extends Queue {
|
|
|
334
334
|
// A kept ambient batch may hold pending nodes (#2916): stay
|
|
335
335
|
// scheduled so the outer drain loop commits them via the plain
|
|
336
336
|
// flush path instead of leaving them until the next natural flush.
|
|
337
|
-
scheduled = dirtyQueue.EE >= dirtyQueue.
|
|
337
|
+
scheduled = dirtyQueue.EE >= dirtyQueue.Fe || this.m.Qt.length > 0;
|
|
338
338
|
reassignPendingTransition(e.Qt);
|
|
339
339
|
activeTransition = null;
|
|
340
340
|
finalizePureQueue(null, true);
|
|
@@ -362,7 +362,7 @@ class GlobalQueue extends Queue {
|
|
|
362
362
|
} else {
|
|
363
363
|
if (canUseSimpleSyncFlush(this)) {
|
|
364
364
|
commitPendingNodes();
|
|
365
|
-
if (dirtyQueue.EE >= dirtyQueue.
|
|
365
|
+
if (dirtyQueue.EE >= dirtyQueue.Fe) {
|
|
366
366
|
runHeap(dirtyQueue, GlobalQueue.pe);
|
|
367
367
|
commitPendingNodes();
|
|
368
368
|
}
|
|
@@ -373,7 +373,7 @@ class GlobalQueue extends Queue {
|
|
|
373
373
|
}
|
|
374
374
|
clock++;
|
|
375
375
|
// Check if finalization added items to the heap (from optimistic reversion)
|
|
376
|
-
scheduled = dirtyQueue.EE >= dirtyQueue.
|
|
376
|
+
scheduled = dirtyQueue.EE >= dirtyQueue.Fe;
|
|
377
377
|
// Run lane effects first (for ready lanes), then regular effects
|
|
378
378
|
activeLanes.size && GlobalQueue.In(EFFECT_RENDER);
|
|
379
379
|
this.run(EFFECT_RENDER);
|
|
@@ -509,7 +509,7 @@ function commitPendingNode(e) {
|
|
|
509
509
|
}
|
|
510
510
|
t.se &= ~REACTIVE_MANUAL_WRITE;
|
|
511
511
|
if (!(t.S & STATUS_PENDING)) t.S &= ~STATUS_UNINITIALIZED;
|
|
512
|
-
if (t.
|
|
512
|
+
if (t.ye !== null || t.Le !== null) GlobalQueue.Ce(t, false, true);
|
|
513
513
|
if (e.be || e.ge) GlobalQueue.un(e);
|
|
514
514
|
}
|
|
515
515
|
|
|
@@ -527,7 +527,7 @@ function finalizePureQueue(e = null, t = false) {
|
|
|
527
527
|
const i = !t;
|
|
528
528
|
if (i) commitPendingNodes();
|
|
529
529
|
if (!t && globalQueue.vt.length) checkBoundaryChildren(globalQueue);
|
|
530
|
-
const n = dirtyQueue.EE >= dirtyQueue.
|
|
530
|
+
const n = dirtyQueue.EE >= dirtyQueue.Fe;
|
|
531
531
|
if (n) runHeap(dirtyQueue, GlobalQueue.pe);
|
|
532
532
|
if (i) {
|
|
533
533
|
if (n) commitPendingNodes();
|
|
@@ -562,7 +562,7 @@ function finalizePureQueue(e = null, t = false) {
|
|
|
562
562
|
if (t.cn.size) GlobalQueue.Dt(t.cn, e);
|
|
563
563
|
sweepTransientStoreNodes();
|
|
564
564
|
// Lanes only enter activeLanes through the engine's getOrCreateLane.
|
|
565
|
-
if (activeLanes.size) GlobalQueue.
|
|
565
|
+
if (activeLanes.size) GlobalQueue.Tn(e);
|
|
566
566
|
}
|
|
567
567
|
}
|
|
568
568
|
|
|
@@ -668,7 +668,7 @@ function transitionComplete(e) {
|
|
|
668
668
|
// Override blockage lives with the engine. Absent hook = "no optimistic
|
|
669
669
|
// blockage", which is exact: only _optimisticWrite (engine) pushes to
|
|
670
670
|
// _optimisticNodes, so without the engine the loop was vacuous anyway.
|
|
671
|
-
if (t && e.Ze.length && GlobalQueue.
|
|
671
|
+
if (t && e.Ze.length && GlobalQueue.dn(e)) t = false;
|
|
672
672
|
t && (e.fn = true);
|
|
673
673
|
return t;
|
|
674
674
|
}
|
|
@@ -232,7 +232,7 @@ function getLatestValueComputed(e) {
|
|
|
232
232
|
// until the flush (#2922). Mirror the tracked-read pull here: mark the
|
|
233
233
|
// queued staleness through the graph, then bring the shadow up to date.
|
|
234
234
|
const e = queueFor(t);
|
|
235
|
-
if (t.
|
|
235
|
+
if (t.He >= e.Fe && !(t.se & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE))) {
|
|
236
236
|
markHeap(e);
|
|
237
237
|
prepareComputed(t, true);
|
|
238
238
|
}
|
|
@@ -343,9 +343,9 @@ GlobalQueue.he = updateChildCompanions;
|
|
|
343
343
|
|
|
344
344
|
GlobalQueue.un = snapCompanionsToState;
|
|
345
345
|
|
|
346
|
-
GlobalQueue.
|
|
346
|
+
GlobalQueue.dt = latestRead;
|
|
347
347
|
|
|
348
|
-
GlobalQueue.
|
|
348
|
+
GlobalQueue.St = pendingCheckRead;
|
|
349
349
|
|
|
350
350
|
GlobalQueue.Rt = recordFreshRead;
|
|
351
351
|
|
|
@@ -14,7 +14,7 @@ import { installOptimisticEngine } from "../core/optimistic.js";
|
|
|
14
14
|
|
|
15
15
|
import { runProjectionComputed } from "./projection.js";
|
|
16
16
|
|
|
17
|
-
import { storeSetter, $TARGET, STORE_OPTIMISTIC_OVERRIDE, STORE_NODE, STORE_OPTIMISTIC_OWNERS, getOverlayLayer, STORE_VALUE, $DELETED, isWrappable, wrap, visibleNodeValue, $TRACK, notifySelf, STORE_WRAP, createStoreProxy, storeTraps, STORE_LOOKUP, STORE_OPTIMISTIC, STORE_FIREWALL } from "./store.js";
|
|
17
|
+
import { storeSetter, $TARGET, STORE_OPTIMISTIC_OVERRIDE, STORE_NODE, STORE_OPTIMISTIC_OWNERS, getOverlayLayer, STORE_VALUE, $DELETED, isWrappable, wrap, visibleNodeValue, $TRACK, notifySelf, STORE_WRAP, createStoreProxy, storeTraps, STORE_LOOKUP, STORE_SHALLOW, markRawIngest, STORE_OPTIMISTIC, STORE_FIREWALL } from "./store.js";
|
|
18
18
|
|
|
19
19
|
function createOptimisticStore(e, t, i) {
|
|
20
20
|
// Register clear function with scheduler; store nodes marked
|
|
@@ -23,6 +23,8 @@ function createOptimisticStore(e, t, i) {
|
|
|
23
23
|
installOptimisticEngine();
|
|
24
24
|
GlobalQueue.Dt ||= clearOptimisticStores;
|
|
25
25
|
const r = typeof e === "function";
|
|
26
|
+
// Plain form: the second slot carries options.
|
|
27
|
+
if (!r && i === undefined) i = t;
|
|
26
28
|
const o = r ? t : e;
|
|
27
29
|
const n = r ? e : undefined;
|
|
28
30
|
// Create optimistic projection store
|
|
@@ -126,9 +128,14 @@ function clearOptimisticStores(e, t) {
|
|
|
126
128
|
function createOptimisticProjectionInternal(e, t, i) {
|
|
127
129
|
let r;
|
|
128
130
|
const o = new WeakMap;
|
|
131
|
+
const n = !!i?.shallow;
|
|
129
132
|
const wrapper = e => {
|
|
130
133
|
e[STORE_WRAP] = wrapProjection;
|
|
131
134
|
e[STORE_LOOKUP] = o;
|
|
135
|
+
if (n) {
|
|
136
|
+
e[STORE_SHALLOW] = true;
|
|
137
|
+
markRawIngest(e[STORE_VALUE]);
|
|
138
|
+
}
|
|
132
139
|
e[STORE_OPTIMISTIC] = true;
|
|
133
140
|
// Mark as optimistic store
|
|
134
141
|
Object.defineProperty(e, STORE_FIREWALL, {
|
|
@@ -145,7 +152,7 @@ function createOptimisticProjectionInternal(e, t, i) {
|
|
|
145
152
|
o.set(e, t);
|
|
146
153
|
return t;
|
|
147
154
|
};
|
|
148
|
-
const
|
|
155
|
+
const c = wrapProjection(t);
|
|
149
156
|
// If there's a projection function, create a computed to drive it
|
|
150
157
|
if (e) {
|
|
151
158
|
// All writes inside firewall recompute must go to STORE_OVERRIDE (base), not
|
|
@@ -154,7 +161,7 @@ function createOptimisticProjectionInternal(e, t, i) {
|
|
|
154
161
|
// async yields because they fire outside any enclosing try/finally. It also
|
|
155
162
|
// consumes stale optimistic overlays once fresh projected data lands.
|
|
156
163
|
const clearProjectionOverride = () => {
|
|
157
|
-
const e =
|
|
164
|
+
const e = c[$TARGET];
|
|
158
165
|
if (e?.[STORE_OPTIMISTIC_OVERRIDE]) clearOptimisticOverride(e);
|
|
159
166
|
};
|
|
160
167
|
const wrapCommit = e => {
|
|
@@ -170,7 +177,7 @@ function createOptimisticProjectionInternal(e, t, i) {
|
|
|
170
177
|
r = computed(() => {
|
|
171
178
|
setProjectionWriteActive(true);
|
|
172
179
|
try {
|
|
173
|
-
runProjectionComputed(
|
|
180
|
+
runProjectionComputed(c, e, i?.key || "id", wrapCommit, clearProjectionOverride);
|
|
174
181
|
} finally {
|
|
175
182
|
setProjectionWriteActive(false);
|
|
176
183
|
}
|
|
@@ -178,7 +185,7 @@ function createOptimisticProjectionInternal(e, t, i) {
|
|
|
178
185
|
r.T &= ~CONFIG_AUTO_DISPOSE;
|
|
179
186
|
}
|
|
180
187
|
return {
|
|
181
|
-
store:
|
|
188
|
+
store: c,
|
|
182
189
|
node: r
|
|
183
190
|
};
|
|
184
191
|
}
|
|
@@ -14,14 +14,21 @@ import { CONFIG_AUTO_DISPOSE } from "../core/constants.js";
|
|
|
14
14
|
|
|
15
15
|
import { reconcile } from "./reconcile.js";
|
|
16
16
|
|
|
17
|
-
import { storeSetter, $TARGET, STORE_WRAP, createStoreProxy, storeTraps, setWriteOverride, STORE_LOOKUP, STORE_FIREWALL } from "./store.js";
|
|
17
|
+
import { storeSetter, $TARGET, STORE_WRAP, createStoreProxy, storeTraps, setWriteOverride, STORE_LOOKUP, STORE_SHALLOW, markRawIngest, STORE_VALUE, STORE_FIREWALL } from "./store.js";
|
|
18
18
|
|
|
19
19
|
function createProjectionInternal(e, r, t) {
|
|
20
20
|
let o;
|
|
21
|
-
const
|
|
21
|
+
const n = new WeakMap;
|
|
22
|
+
// A shallow projection's children are raw and never wrapped, so the
|
|
23
|
+
// wrapper only ever runs for the root — flagging unconditionally is safe.
|
|
24
|
+
const i = !!t?.shallow;
|
|
22
25
|
const wrapper = e => {
|
|
23
26
|
e[STORE_WRAP] = wrapProjection;
|
|
24
|
-
e[STORE_LOOKUP] =
|
|
27
|
+
e[STORE_LOOKUP] = n;
|
|
28
|
+
if (i) {
|
|
29
|
+
e[STORE_SHALLOW] = true;
|
|
30
|
+
markRawIngest(e[STORE_VALUE]);
|
|
31
|
+
}
|
|
25
32
|
Object.defineProperty(e, STORE_FIREWALL, {
|
|
26
33
|
get() {
|
|
27
34
|
return o;
|
|
@@ -30,20 +37,20 @@ function createProjectionInternal(e, r, t) {
|
|
|
30
37
|
});
|
|
31
38
|
};
|
|
32
39
|
const wrapProjection = e => {
|
|
33
|
-
if (
|
|
40
|
+
if (n.has(e)) return n.get(e);
|
|
34
41
|
if (e[$TARGET]?.[STORE_WRAP] === wrapProjection) return e;
|
|
35
42
|
const r = createStoreProxy(e, storeTraps, wrapper);
|
|
36
|
-
|
|
43
|
+
n.set(e, r);
|
|
37
44
|
return r;
|
|
38
45
|
};
|
|
39
|
-
const
|
|
46
|
+
const c = wrapProjection(r);
|
|
40
47
|
o = computed(() => {
|
|
41
48
|
if (!o) o = getOwner();
|
|
42
|
-
runProjectionComputed(
|
|
49
|
+
runProjectionComputed(c, e, t?.key || "id");
|
|
43
50
|
}, undefined);
|
|
44
51
|
o.T &= ~CONFIG_AUTO_DISPOSE;
|
|
45
52
|
return {
|
|
46
|
-
store:
|
|
53
|
+
store: c,
|
|
47
54
|
node: o
|
|
48
55
|
};
|
|
49
56
|
}
|
|
@@ -106,22 +113,22 @@ function createProjectionInternal(e, r, t) {
|
|
|
106
113
|
* re-enters `setProjectionWriteActive` so reconciles target `STORE_OVERRIDE`
|
|
107
114
|
* instead of `STORE_OPTIMISTIC_OVERRIDE` even when an async yield fires outside
|
|
108
115
|
* the outer `setProjectionWriteActive` scope.
|
|
109
|
-
*/ function runProjectionComputed(e, r, t, o,
|
|
110
|
-
const
|
|
116
|
+
*/ function runProjectionComputed(e, r, t, o, n) {
|
|
117
|
+
const i = getOwner();
|
|
111
118
|
let c = false;
|
|
112
119
|
let s;
|
|
113
|
-
const u = new Proxy(e, createWriteTraps(() => !c ||
|
|
114
|
-
storeSetter(u,
|
|
115
|
-
s = r(
|
|
120
|
+
const u = new Proxy(e, createWriteTraps(() => !c || i.Te === s, n));
|
|
121
|
+
storeSetter(u, n => {
|
|
122
|
+
s = r(n);
|
|
116
123
|
c = true;
|
|
117
124
|
const commit = r => {
|
|
118
|
-
if (r ===
|
|
125
|
+
if (r === n || r === undefined) return;
|
|
119
126
|
const write = () => storeSetter(e, reconcile(r, t));
|
|
120
127
|
o ? o(write) : write();
|
|
121
128
|
};
|
|
122
|
-
commit(handleAsync(
|
|
129
|
+
commit(handleAsync(i, s, commit));
|
|
123
130
|
});
|
|
124
|
-
return
|
|
131
|
+
return i;
|
|
125
132
|
}
|
|
126
133
|
|
|
127
134
|
function createWriteTraps(e, r) {
|
|
@@ -151,12 +158,12 @@ function createWriteTraps(e, r) {
|
|
|
151
158
|
}
|
|
152
159
|
return t;
|
|
153
160
|
},
|
|
154
|
-
set(t, o,
|
|
161
|
+
set(t, o, n) {
|
|
155
162
|
if (e && !e()) return true;
|
|
156
163
|
setWriteOverride(true);
|
|
157
164
|
setProjectionWriteActive(true);
|
|
158
165
|
try {
|
|
159
|
-
t[o] =
|
|
166
|
+
t[o] = n;
|
|
160
167
|
r?.();
|
|
161
168
|
} finally {
|
|
162
169
|
setWriteOverride(false);
|