@solidjs/signals 2.0.0-beta.23 → 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 +615 -125
- package/dist/node.cjs +1551 -1092
- package/dist/prod/core/core.js +106 -69
- package/dist/prod/core/effect.js +9 -9
- package/dist/prod/core/error.js +9 -0
- package/dist/prod/core/graph.js +3 -3
- package/dist/prod/core/heap.js +12 -12
- package/dist/prod/core/optimistic.js +6 -4
- package/dist/prod/core/owner.js +10 -10
- package/dist/prod/core/scheduler.js +6 -6
- package/dist/prod/core/verdict.js +2 -2
- package/dist/prod/map.js +53 -29
- package/dist/prod/store/optimistic.js +40 -31
- package/dist/prod/store/projection.js +25 -18
- package/dist/prod/store/reconcile.js +433 -208
- package/dist/prod/store/store.js +250 -116
- package/dist/prod/store/utils.js +34 -22
- package/dist/types/core/core.d.ts +15 -0
- package/dist/types/core/error.d.ts +1 -1
- package/dist/types/store/optimistic.d.ts +1 -1
- package/dist/types/store/reconcile.d.ts +17 -8
- package/dist/types/store/store.d.ts +20 -2
- package/dist/types-cjs/core/core.d.cts +15 -0
- package/dist/types-cjs/core/error.d.cts +1 -1
- package/dist/types-cjs/store/optimistic.d.cts +1 -1
- package/dist/types-cjs/store/reconcile.d.cts +17 -8
- package/dist/types-cjs/store/store.d.cts +20 -2
- package/package.json +1 -1
|
@@ -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;
|
|
@@ -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
|
|
|
@@ -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
|
}
|
|
@@ -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
|
|
package/dist/prod/map.js
CHANGED
|
@@ -118,22 +118,29 @@ function updateKeyedMap() {
|
|
|
118
118
|
this.Mt = t.slice(0);
|
|
119
119
|
this.jt = s;
|
|
120
120
|
} else {
|
|
121
|
-
let o, c, a, f, u, p, w, l, d
|
|
122
|
-
r = this.Ut ? new Array(s) : undefined;
|
|
123
|
-
n = this.$t ? new Array(s) : undefined;
|
|
121
|
+
let o, c, a, f, u, p, w, l, d;
|
|
124
122
|
// skip common prefix
|
|
125
123
|
for (o = 0, c = Math.min(this.jt, s); o < c && (this.Mt[o] === t[o] || this.Ut && compare(this.Gt, this.Mt[o], t[o])); o++) {
|
|
126
124
|
if (this.Ut) setSignal(this.Ut[o], t[o]);
|
|
127
125
|
}
|
|
128
|
-
// common suffix
|
|
126
|
+
// skip common suffix — counted only; retained entries land in one pass
|
|
127
|
+
// at commit instead of being staged and copied twice
|
|
129
128
|
for (c = this.jt - 1, a = s - 1; c >= o && a >= o && (this.Mt[c] === t[a] || this.Ut && compare(this.Gt, this.Mt[c], t[a])); c--,
|
|
130
|
-
a--)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
129
|
+
a--) ;
|
|
130
|
+
// no structural change (every position matched in place at equal
|
|
131
|
+
// length — the common post-reconcile shape): keep the same mapped
|
|
132
|
+
// array identity so downstream consumers don't re-run at all
|
|
133
|
+
if (o === s && this.jt === s) {
|
|
134
|
+
this.Mt = t.slice(0);
|
|
135
|
+
return;
|
|
135
136
|
}
|
|
136
|
-
|
|
137
|
+
const O = s - this.jt;
|
|
138
|
+
const m = new Array(s);
|
|
139
|
+
const _ = new Array(s);
|
|
140
|
+
r = this.Ut ? new Array(s) : undefined;
|
|
141
|
+
n = this.$t ? new Array(s) : undefined;
|
|
142
|
+
// 0) prepare a map of all indices in the changed window of newItems,
|
|
143
|
+
// scanning backwards so we encounter them in natural order
|
|
137
144
|
p = new Map;
|
|
138
145
|
w = new Array(a + 1);
|
|
139
146
|
for (e = a; e >= o; e--) {
|
|
@@ -143,14 +150,16 @@ function updateKeyedMap() {
|
|
|
143
150
|
w[e] = i === undefined ? -1 : i;
|
|
144
151
|
p.set(u, e);
|
|
145
152
|
}
|
|
146
|
-
// 1) step through
|
|
153
|
+
// 1) step through the old changed window and see if items can be found
|
|
154
|
+
// in the new set; if so, stage them at their new positions; if not,
|
|
155
|
+
// queue them for disposal at commit
|
|
147
156
|
for (i = o; i <= c; i++) {
|
|
148
157
|
f = this.Mt[i];
|
|
149
158
|
u = this.Gt ? this.Gt(f) : f;
|
|
150
159
|
e = p.get(u);
|
|
151
160
|
if (e !== undefined && e !== -1) {
|
|
152
|
-
|
|
153
|
-
|
|
161
|
+
m[e] = this.xt[i];
|
|
162
|
+
_[e] = this.Ft[i];
|
|
154
163
|
r && (r[e] = this.Ut[i]);
|
|
155
164
|
n && (n[e] = this.$t[i]);
|
|
156
165
|
e = w[e];
|
|
@@ -159,33 +168,48 @@ function updateKeyedMap() {
|
|
|
159
168
|
}
|
|
160
169
|
// 2) create new rows into the temp arrays; an abort disposes only these
|
|
161
170
|
try {
|
|
162
|
-
for (e = o; e
|
|
163
|
-
if (e
|
|
164
|
-
(d ??= []).push(
|
|
165
|
-
|
|
171
|
+
for (e = o; e <= a; e++) {
|
|
172
|
+
if (_[e] !== undefined) continue;
|
|
173
|
+
(d ??= []).push(_[e] = createOwner());
|
|
174
|
+
m[e] = runWithOwner(_[e], h);
|
|
166
175
|
}
|
|
167
176
|
} catch (t) {
|
|
168
177
|
if (d) for (i = 0; i < d.length; i++) d[i].dispose();
|
|
169
178
|
throw t;
|
|
170
179
|
}
|
|
171
|
-
// 3) commit: land
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
180
|
+
// 3) commit: land the retained prefix and suffix plus the staged window
|
|
181
|
+
// into the fresh arrays, swap them in (new identity for downstream
|
|
182
|
+
// change propagation), then dispose exited rows
|
|
183
|
+
for (i = 0; i < o; i++) {
|
|
184
|
+
m[i] = this.xt[i];
|
|
185
|
+
_[i] = this.Ft[i];
|
|
186
|
+
r && (r[i] = this.Ut[i]);
|
|
187
|
+
n && (n[i] = this.$t[i]);
|
|
188
|
+
}
|
|
189
|
+
for (e = o; e <= a; e++) {
|
|
190
|
+
if (r) setSignal(r[e], t[e]);
|
|
191
|
+
if (n) setSignal(n[e], e);
|
|
192
|
+
}
|
|
193
|
+
for (e = a + 1; e < s; e++) {
|
|
194
|
+
m[e] = this.xt[e - O];
|
|
195
|
+
_[e] = this.Ft[e - O];
|
|
175
196
|
if (r) {
|
|
176
|
-
|
|
177
|
-
setSignal(
|
|
197
|
+
r[e] = this.Ut[e - O];
|
|
198
|
+
setSignal(r[e], t[e]);
|
|
178
199
|
}
|
|
179
200
|
if (n) {
|
|
180
|
-
|
|
181
|
-
setSignal(
|
|
201
|
+
n[e] = this.$t[e - O];
|
|
202
|
+
if (O !== 0) setSignal(n[e], e);
|
|
182
203
|
}
|
|
183
204
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
205
|
+
this.xt = m;
|
|
206
|
+
this.Ft = _;
|
|
207
|
+
r && (this.Ut = r);
|
|
208
|
+
n && (this.$t = n);
|
|
209
|
+
this.jt = s;
|
|
210
|
+
// save a copy of the mapped items for the next update
|
|
188
211
|
this.Mt = t.slice(0);
|
|
212
|
+
if (l) for (i = 0; i < l.length; i++) l[i].dispose();
|
|
189
213
|
}
|
|
190
214
|
});
|
|
191
215
|
return this.xt;
|
|
@@ -14,19 +14,21 @@ 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
|
-
function createOptimisticStore(e, t,
|
|
19
|
+
function createOptimisticStore(e, t, i) {
|
|
20
20
|
// Register clear function with scheduler; store nodes marked
|
|
21
21
|
// STORE_OPTIMISTIC take the engine's write path, so install it before any
|
|
22
22
|
// node can be created.
|
|
23
23
|
installOptimisticEngine();
|
|
24
24
|
GlobalQueue.Dt ||= clearOptimisticStores;
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
const r = typeof e === "function";
|
|
26
|
+
// Plain form: the second slot carries options.
|
|
27
|
+
if (!r && i === undefined) i = t;
|
|
28
|
+
const o = r ? t : e;
|
|
29
|
+
const n = r ? e : undefined;
|
|
28
30
|
// Create optimistic projection store
|
|
29
|
-
const {store: c} = createOptimisticProjectionInternal(n, o,
|
|
31
|
+
const {store: c} = createOptimisticProjectionInternal(n, o, i);
|
|
30
32
|
return [ c, e => storeSetter(c, e) ];
|
|
31
33
|
}
|
|
32
34
|
|
|
@@ -35,8 +37,8 @@ function createOptimisticStore(e, t, r) {
|
|
|
35
37
|
// scheduler's flush tail carries only a size-guarded hook call. The
|
|
36
38
|
// completing transition scopes each clear to its own layer keys (#2899).
|
|
37
39
|
function clearOptimisticStores(e, t) {
|
|
38
|
-
for (const
|
|
39
|
-
const e =
|
|
40
|
+
for (const i of e) {
|
|
41
|
+
const e = i[$TARGET];
|
|
40
42
|
if (e?.[STORE_OPTIMISTIC_OVERRIDE]) clearOptimisticOverride(e, t);
|
|
41
43
|
}
|
|
42
44
|
e.clear();
|
|
@@ -54,9 +56,9 @@ function clearOptimisticStores(e, t) {
|
|
|
54
56
|
* fresh authoritative data) consumes everything — the correction supersedes
|
|
55
57
|
* every tentative layer.
|
|
56
58
|
*/ function clearOptimisticOverride(e, t) {
|
|
57
|
-
const
|
|
58
|
-
if (!
|
|
59
|
-
const
|
|
59
|
+
const i = e[STORE_OPTIMISTIC_OVERRIDE];
|
|
60
|
+
if (!i) return;
|
|
61
|
+
const r = e[STORE_NODE];
|
|
60
62
|
const o = e[STORE_OPTIMISTIC_OWNERS];
|
|
61
63
|
const n = t !== undefined;
|
|
62
64
|
let c = false;
|
|
@@ -66,7 +68,7 @@ function clearOptimisticStores(e, t) {
|
|
|
66
68
|
const O = projectionWriteActive;
|
|
67
69
|
setProjectionWriteActive(true);
|
|
68
70
|
try {
|
|
69
|
-
for (const O of Reflect.ownKeys(
|
|
71
|
+
for (const O of Reflect.ownKeys(i)) {
|
|
70
72
|
if (n) {
|
|
71
73
|
let e = o?.[O] ?? null;
|
|
72
74
|
// Resolve merge chains (entangled actions settle as one); path-compress
|
|
@@ -83,19 +85,19 @@ function clearOptimisticStores(e, t) {
|
|
|
83
85
|
}
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
|
-
delete
|
|
88
|
+
delete i[O];
|
|
87
89
|
if (o) delete o[O];
|
|
88
90
|
c = true;
|
|
89
|
-
const T =
|
|
91
|
+
const T = r?.[O];
|
|
90
92
|
if (T) {
|
|
91
93
|
// Clear lane association so effects go to regular queue
|
|
92
94
|
T.je = undefined;
|
|
93
95
|
// Re-read from base — this key left the optimistic layer above, so the
|
|
94
96
|
// overlay resolves to STORE_OVERRIDE or STORE_VALUE.
|
|
95
97
|
const t = getOverlayLayer(e, O);
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
const o = isWrappable(
|
|
98
|
+
const i = t ? t[O] : e[STORE_VALUE][O];
|
|
99
|
+
const r = i === $DELETED ? undefined : i;
|
|
100
|
+
const o = isWrappable(r) ? wrap(r, e) : r;
|
|
99
101
|
const n = visibleNodeValue(T);
|
|
100
102
|
T.Ee = NOT_PENDING;
|
|
101
103
|
T.sn = null;
|
|
@@ -108,12 +110,14 @@ function clearOptimisticStores(e, t) {
|
|
|
108
110
|
}
|
|
109
111
|
}
|
|
110
112
|
if (!s) {
|
|
111
|
-
delete
|
|
112
|
-
delete
|
|
113
|
+
// Assignment, not delete: StoreNode targets share one pre-initialized
|
|
114
|
+
// hidden class (see createStoreProxy) and a delete would demote it.
|
|
115
|
+
e[STORE_OPTIMISTIC_OVERRIDE] = undefined;
|
|
116
|
+
e[STORE_OPTIMISTIC_OWNERS] = undefined;
|
|
113
117
|
}
|
|
114
118
|
// Notify $TRACK
|
|
115
|
-
if (c &&
|
|
116
|
-
|
|
119
|
+
if (c && r?.[$TRACK]) {
|
|
120
|
+
r[$TRACK].je = undefined;
|
|
117
121
|
notifySelf(e);
|
|
118
122
|
}
|
|
119
123
|
} finally {
|
|
@@ -121,17 +125,22 @@ function clearOptimisticStores(e, t) {
|
|
|
121
125
|
}
|
|
122
126
|
}
|
|
123
127
|
|
|
124
|
-
function createOptimisticProjectionInternal(e, t,
|
|
125
|
-
let
|
|
128
|
+
function createOptimisticProjectionInternal(e, t, i) {
|
|
129
|
+
let r;
|
|
126
130
|
const o = new WeakMap;
|
|
131
|
+
const n = !!i?.shallow;
|
|
127
132
|
const wrapper = e => {
|
|
128
133
|
e[STORE_WRAP] = wrapProjection;
|
|
129
134
|
e[STORE_LOOKUP] = o;
|
|
135
|
+
if (n) {
|
|
136
|
+
e[STORE_SHALLOW] = true;
|
|
137
|
+
markRawIngest(e[STORE_VALUE]);
|
|
138
|
+
}
|
|
130
139
|
e[STORE_OPTIMISTIC] = true;
|
|
131
140
|
// Mark as optimistic store
|
|
132
141
|
Object.defineProperty(e, STORE_FIREWALL, {
|
|
133
142
|
get() {
|
|
134
|
-
return
|
|
143
|
+
return r;
|
|
135
144
|
},
|
|
136
145
|
configurable: true
|
|
137
146
|
});
|
|
@@ -143,7 +152,7 @@ function createOptimisticProjectionInternal(e, t, r) {
|
|
|
143
152
|
o.set(e, t);
|
|
144
153
|
return t;
|
|
145
154
|
};
|
|
146
|
-
const
|
|
155
|
+
const c = wrapProjection(t);
|
|
147
156
|
// If there's a projection function, create a computed to drive it
|
|
148
157
|
if (e) {
|
|
149
158
|
// All writes inside firewall recompute must go to STORE_OVERRIDE (base), not
|
|
@@ -152,7 +161,7 @@ function createOptimisticProjectionInternal(e, t, r) {
|
|
|
152
161
|
// async yields because they fire outside any enclosing try/finally. It also
|
|
153
162
|
// consumes stale optimistic overlays once fresh projected data lands.
|
|
154
163
|
const clearProjectionOverride = () => {
|
|
155
|
-
const e =
|
|
164
|
+
const e = c[$TARGET];
|
|
156
165
|
if (e?.[STORE_OPTIMISTIC_OVERRIDE]) clearOptimisticOverride(e);
|
|
157
166
|
};
|
|
158
167
|
const wrapCommit = e => {
|
|
@@ -165,19 +174,19 @@ function createOptimisticProjectionInternal(e, t, r) {
|
|
|
165
174
|
setProjectionWriteActive(t);
|
|
166
175
|
}
|
|
167
176
|
};
|
|
168
|
-
|
|
177
|
+
r = computed(() => {
|
|
169
178
|
setProjectionWriteActive(true);
|
|
170
179
|
try {
|
|
171
|
-
runProjectionComputed(
|
|
180
|
+
runProjectionComputed(c, e, i?.key || "id", wrapCommit, clearProjectionOverride);
|
|
172
181
|
} finally {
|
|
173
182
|
setProjectionWriteActive(false);
|
|
174
183
|
}
|
|
175
184
|
}, undefined);
|
|
176
|
-
|
|
185
|
+
r.T &= ~CONFIG_AUTO_DISPOSE;
|
|
177
186
|
}
|
|
178
187
|
return {
|
|
179
|
-
store:
|
|
180
|
-
node:
|
|
188
|
+
store: c,
|
|
189
|
+
node: r
|
|
181
190
|
};
|
|
182
191
|
}
|
|
183
192
|
|
|
@@ -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);
|