@solidjs/signals 2.0.0-rc.17 → 2.0.0-rc.19
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 +426 -241
- package/dist/dev.attribution.js +19 -16
- package/dist/dev.js +768 -409
- package/dist/observe/boundaries.js +88 -67
- package/dist/observe/core/action.js +8 -0
- package/dist/observe/core/async.js +183 -138
- package/dist/observe/core/attribution.js +30 -28
- package/dist/observe/core/constants.js +23 -1
- package/dist/observe/core/core.js +185 -157
- package/dist/observe/core/effect.js +34 -37
- package/dist/observe/core/graph.js +8 -8
- package/dist/observe/core/heap.js +5 -5
- package/dist/observe/core/lanes.js +104 -84
- package/dist/observe/core/owner.js +17 -16
- package/dist/observe/core/scheduler.js +61 -47
- package/dist/observe/core/truth.js +6 -6
- package/dist/observe/core/verdict.js +15 -15
- package/dist/observe/deferred.js +40 -38
- package/dist/observe/from.js +248 -0
- package/dist/observe/index.js +4 -2
- package/dist/observe/map.js +22 -22
- package/dist/observe/reveal.js +5 -5
- package/dist/observe/signals.js +57 -15
- package/dist/observe/store/affects.js +1 -1
- package/dist/observe/store/hooks.js +3 -0
- package/dist/observe/store/optimistic.js +11 -11
- package/dist/observe/store/projection.js +34 -21
- package/dist/observe/store/reconcile.js +138 -122
- package/dist/observe/store/store.js +628 -641
- package/dist/observe/store/target.js +1 -5
- package/dist/observe/store/utils.js +7 -2
- package/dist/prod/boundaries.js +153 -132
- package/dist/prod/core/action.js +8 -0
- package/dist/prod/core/async.js +242 -197
- package/dist/prod/core/constants.js +16 -1
- package/dist/prod/core/core.js +166 -138
- package/dist/prod/core/effect.js +31 -34
- package/dist/prod/core/graph.js +5 -5
- package/dist/prod/core/heap.js +12 -12
- package/dist/prod/core/lanes.js +98 -78
- package/dist/prod/core/owner.js +15 -14
- package/dist/prod/core/scheduler.js +64 -50
- package/dist/prod/core/truth.js +6 -6
- package/dist/prod/core/verdict.js +17 -17
- package/dist/prod/deferred.js +40 -38
- package/dist/prod/from.js +248 -0
- package/dist/prod/index.js +4 -2
- package/dist/prod/map.js +14 -14
- package/dist/prod/reveal.js +8 -8
- package/dist/prod/signals.js +46 -4
- package/dist/prod/store/affects.js +1 -1
- package/dist/prod/store/hooks.js +3 -0
- package/dist/prod/store/optimistic.js +16 -16
- package/dist/prod/store/projection.js +22 -9
- package/dist/prod/store/reconcile.js +138 -122
- package/dist/prod/store/store.js +308 -331
- package/dist/prod/store/target.js +13 -17
- package/dist/prod/store/utils.js +2 -0
- package/dist/types/core/action.d.ts +8 -0
- package/dist/types/core/async.d.ts +12 -2
- package/dist/types/core/constants.d.ts +25 -0
- package/dist/types/core/core.d.ts +33 -4
- package/dist/types/core/dev.d.ts +1 -1
- package/dist/types/core/index.d.ts +1 -1
- package/dist/types/core/lanes.d.ts +5 -1
- package/dist/types/core/scheduler.d.ts +17 -3
- package/dist/types/from.d.ts +47 -0
- package/dist/types/index.d.ts +4 -1
- package/dist/types/signals.d.ts +37 -0
- package/dist/types/store/target.d.ts +2 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { STATUS_PENDING, STATUS_ERROR, CONFIG_REDERIVE,
|
|
1
|
+
import { STATUS_PENDING, STATUS_ERROR, CONFIG_REDERIVE, CONFIG_HELD, CONFIG_FRAME, STATUS_UNINITIALIZED, EFFECT_RENDER, CONFIG_VERDICT, REACTIVE_DISPOSED, REACTIVE_LANE_READ, CONFIG_OVERRIDE, EFFECT_USER, EFFECT_TRACKED, REACTIVE_ZOMBIE, CAUGHT_REARMED } from "./core/constants.js";
|
|
2
2
|
|
|
3
3
|
import { signal, runWithOwner, computed, read, setSignal, recompute } from "./core/core.js";
|
|
4
4
|
|
|
@@ -14,7 +14,7 @@ import { enqueueSub } from "./core/heap.js";
|
|
|
14
14
|
|
|
15
15
|
import { createOwner, getOwner, cleanup, dispose } from "./core/owner.js";
|
|
16
16
|
|
|
17
|
-
import { globalQueue, haltReactivityAt, haltReactivity, passLane, joinFuture, GlobalQueue, flushTransaction, heldUnder, setPassLane, passTx, resolveTx,
|
|
17
|
+
import { globalQueue, haltReactivityAt, haltReactivity, schedule, passLane, joinFuture, GlobalQueue, flushTransaction, heldUnder, setPassLane, passTx, resolveTx, txOf, unhold, laneStageHook, installBoundaryHooks } from "./core/scheduler.js";
|
|
18
18
|
|
|
19
19
|
import { attrHooks } from "./core/attribution-hooks.js";
|
|
20
20
|
|
|
@@ -69,6 +69,9 @@ import { accessor } from "./signals.js";
|
|
|
69
69
|
* slot of (reveal.ts); a boundary clears it for its content — only direct
|
|
70
70
|
* children are slots. */ const REVEAL = Symbol("");
|
|
71
71
|
|
|
72
|
+
// Every call site checks the hooks themselves first (not only the slot or
|
|
73
|
+
// controller, which are never set without them): a build that does not
|
|
74
|
+
// import `createRevealOrder` folds the reveal-order arms away.
|
|
72
75
|
let revealHooks = null;
|
|
73
76
|
|
|
74
77
|
function setRevealHooks(e) {
|
|
@@ -98,9 +101,9 @@ const boundaryOf = e => e.A[BOUNDARY];
|
|
|
98
101
|
// the same node.
|
|
99
102
|
n ??= r.T?.F;
|
|
100
103
|
r = n?.source ?? r;
|
|
101
|
-
const
|
|
102
|
-
setSignal(e.F,
|
|
103
|
-
reportClientError(
|
|
104
|
+
const o = unwrapStatusError(n);
|
|
105
|
+
setSignal(e.F, o);
|
|
106
|
+
reportClientError(o, e.H, r);
|
|
104
107
|
}
|
|
105
108
|
record(e, r);
|
|
106
109
|
if (e.h) flip(e);
|
|
@@ -108,7 +111,7 @@ const boundaryOf = e => e.A[BOUNDARY];
|
|
|
108
111
|
// nothing on screen. The fallback is instantiated once per show — a later
|
|
109
112
|
// error reaches it through the `error` accessor, which is why it is one.
|
|
110
113
|
if (!e.L) redraw(e);
|
|
111
|
-
if (e.v !== null) revealHooks.P(e.v);
|
|
114
|
+
if (revealHooks && e.v !== null) revealHooks.P(e.v);
|
|
112
115
|
}
|
|
113
116
|
|
|
114
117
|
/** A re-armed boundary found something pending: fresh again, and the swap
|
|
@@ -120,7 +123,7 @@ const boundaryOf = e => e.A[BOUNDARY];
|
|
|
120
123
|
e.V = e.B;
|
|
121
124
|
const r = e.j;
|
|
122
125
|
if (!e.V && r.l & CONFIG_HELD && txOf(r) !== flushTransaction) unhold(r);
|
|
123
|
-
if (e.V !== null && e.j !== null) laneStageHook(e.j, e.V, true, false);
|
|
126
|
+
if (laneStageHook && e.V !== null && e.j !== null) laneStageHook(e.j, e.V, true, false);
|
|
124
127
|
}
|
|
125
128
|
|
|
126
129
|
function redraw(e) {
|
|
@@ -143,17 +146,17 @@ function redraw(e) {
|
|
|
143
146
|
// on screen changes, the fallback stays as it is.
|
|
144
147
|
if (collecting.size !== 0) for (let r = boundaryOf(e); r; r = r._parent) if (!(e.m & unsettled(r)) && r.U.delete(e) && r.U.size === 0) {
|
|
145
148
|
if (r.L) redraw(r);
|
|
146
|
-
if (r.v !== null) revealHooks.P(r.v);
|
|
149
|
+
if (revealHooks && r.v !== null) revealHooks.P(r.v);
|
|
147
150
|
}
|
|
148
151
|
return false;
|
|
149
152
|
}
|
|
150
|
-
for (let
|
|
151
|
-
if (!(
|
|
152
|
-
if (isCollecting(
|
|
153
|
-
caught(
|
|
154
|
-
return
|
|
153
|
+
for (let o = boundaryOf(e); o; o = o._parent) {
|
|
154
|
+
if (!(o.i & r)) continue;
|
|
155
|
+
if (isCollecting(o)) {
|
|
156
|
+
caught(o, e, n);
|
|
157
|
+
return o.h ? CAUGHT_REARMED : true;
|
|
155
158
|
}
|
|
156
|
-
record(
|
|
159
|
+
record(o, e);
|
|
157
160
|
}
|
|
158
161
|
return false;
|
|
159
162
|
}
|
|
@@ -182,19 +185,19 @@ function redraw(e) {
|
|
|
182
185
|
* still showing its fallback holds it again then. */ function heldRun(e) {
|
|
183
186
|
const r = hiddenBy(e);
|
|
184
187
|
if (r === undefined) return false;
|
|
185
|
-
(r.
|
|
188
|
+
(r.M ??= new Set).add(e);
|
|
186
189
|
return true;
|
|
187
190
|
}
|
|
188
191
|
|
|
189
192
|
/** The reveal: the runs held behind the fallback are this flush's, each in
|
|
190
193
|
* its own phase — render updates with the frame that attaches the content,
|
|
191
194
|
* user effects after it. */ function release(e) {
|
|
192
|
-
if (e.
|
|
193
|
-
for (const r of e.
|
|
195
|
+
if (e.M === null) return;
|
|
196
|
+
for (const r of e.M) {
|
|
194
197
|
const e = r.i;
|
|
195
|
-
globalQueue.enqueue(e === EFFECT_TRACKED ? EFFECT_USER : e, e === EFFECT_TRACKED ? r.
|
|
198
|
+
globalQueue.enqueue(e === EFFECT_TRACKED ? EFFECT_USER : e, e === EFFECT_TRACKED ? r.Z : r.W ??= GlobalQueue.K.bind(null, r));
|
|
196
199
|
}
|
|
197
|
-
e.
|
|
200
|
+
e.M = null;
|
|
198
201
|
}
|
|
199
202
|
|
|
200
203
|
/** Drop the readers that settled or died. Settled: a loading reader no
|
|
@@ -206,9 +209,9 @@ function redraw(e) {
|
|
|
206
209
|
|
|
207
210
|
function prune(e, r) {
|
|
208
211
|
const n = unsettled(e);
|
|
209
|
-
for (const
|
|
210
|
-
if (
|
|
211
|
-
if ((
|
|
212
|
+
for (const o of e.U) {
|
|
213
|
+
if (o.R & REACTIVE_DISPOSED) e.U.delete(o); else if (!(o.m & n)) {
|
|
214
|
+
if ((o !== e.Y || e.h) && (o.l & (CONFIG_HELD | CONFIG_OVERRIDE)) === CONFIG_HELD) {
|
|
212
215
|
// Landed, held: the content is that transaction's — the output's
|
|
213
216
|
// pass enters it and the reveal lands with the reader's run. The
|
|
214
217
|
// seam, past its park decision, waits for the commit instead. (A
|
|
@@ -217,9 +220,9 @@ function prune(e, r) {
|
|
|
217
220
|
// the reader is committed (#3540: what a fresh boundary catches holds
|
|
218
221
|
// nothing outside it).
|
|
219
222
|
if (!r || !e.D) continue;
|
|
220
|
-
joinFuture(txOf(
|
|
223
|
+
joinFuture(txOf(o));
|
|
221
224
|
}
|
|
222
|
-
e.U.delete(
|
|
225
|
+
e.U.delete(o);
|
|
223
226
|
}
|
|
224
227
|
}
|
|
225
228
|
return e.U.size;
|
|
@@ -252,7 +255,7 @@ function prune(e, r) {
|
|
|
252
255
|
if (e.U.size === 0) {
|
|
253
256
|
collecting.delete(e);
|
|
254
257
|
if (e.L) redraw(e);
|
|
255
|
-
if (e.v !== null) revealHooks.P(e.v);
|
|
258
|
+
if (revealHooks && e.v !== null) revealHooks.P(e.v);
|
|
256
259
|
}
|
|
257
260
|
}
|
|
258
261
|
}
|
|
@@ -278,6 +281,8 @@ function prune(e, r) {
|
|
|
278
281
|
return;
|
|
279
282
|
}
|
|
280
283
|
e.h = true;
|
|
284
|
+
// The swap is the change's work: the output joins it (D-13, #3540).
|
|
285
|
+
e.j.l &= ~CONFIG_FRAME;
|
|
281
286
|
// A verdict read in `on` (`isPending`, or a memo of one — #3528's
|
|
282
287
|
// `createMemo(() => isPending(m2))`: the mark carries, core.ts `read`)
|
|
283
288
|
// whose frame has no transaction yet: the swap is still display-ahead — the frame gets one now (it lands
|
|
@@ -313,12 +318,12 @@ function prune(e, r) {
|
|
|
313
318
|
schedule();
|
|
314
319
|
}
|
|
315
320
|
|
|
316
|
-
function createBoundary(e, r, n,
|
|
317
|
-
const
|
|
321
|
+
function createBoundary(e, r, n, o) {
|
|
322
|
+
const t = createOwner();
|
|
318
323
|
const l = {
|
|
319
324
|
i: e,
|
|
320
|
-
_parent: boundaryOf(
|
|
321
|
-
H:
|
|
325
|
+
_parent: boundaryOf(t) ?? null,
|
|
326
|
+
H: t,
|
|
322
327
|
Y: null,
|
|
323
328
|
j: null,
|
|
324
329
|
U: new Set,
|
|
@@ -327,7 +332,7 @@ function createBoundary(e, r, n, t) {
|
|
|
327
332
|
B: null,
|
|
328
333
|
V: null,
|
|
329
334
|
L: false,
|
|
330
|
-
|
|
335
|
+
M: null,
|
|
331
336
|
v: null,
|
|
332
337
|
$: false,
|
|
333
338
|
ee: false,
|
|
@@ -335,21 +340,21 @@ function createBoundary(e, r, n, t) {
|
|
|
335
340
|
re: n,
|
|
336
341
|
ne: null
|
|
337
342
|
};
|
|
338
|
-
const u = e === STATUS_PENDING ?
|
|
343
|
+
const u = e === STATUS_PENDING ? t.A[REVEAL] : null;
|
|
339
344
|
if (getOwner()) cleanup(() => {
|
|
340
345
|
collecting.delete(l);
|
|
341
|
-
if (u) revealHooks.
|
|
346
|
+
if (revealHooks && u) revealHooks.oe(u, l);
|
|
342
347
|
});
|
|
343
348
|
// The `on` dependencies live OUTSIDE the boundary, as the condition of a
|
|
344
349
|
// `<Show>` wrapping it would: created before the owner's context names it.
|
|
345
350
|
// A source of it going pending re-runs it (CONFIG_REDERIVE) rather than
|
|
346
351
|
// marking it: the pass catches the NotReady — it is a notification, it
|
|
347
352
|
// does not suspend the parent — and re-arms.
|
|
348
|
-
if (
|
|
353
|
+
if (o) {
|
|
349
354
|
let e = false;
|
|
350
|
-
runWithOwner(
|
|
355
|
+
runWithOwner(t, () => computed(() => {
|
|
351
356
|
try {
|
|
352
|
-
|
|
357
|
+
o();
|
|
353
358
|
} catch (e) {
|
|
354
359
|
if (!(e instanceof NotReadyError)) {
|
|
355
360
|
if (!globalQueue.notify(getOwner(), STATUS_ERROR, STATUS_ERROR, e)) {
|
|
@@ -363,12 +368,12 @@ function createBoundary(e, r, n, t) {
|
|
|
363
368
|
})).l |= CONFIG_REDERIVE;
|
|
364
369
|
}
|
|
365
370
|
const a = {
|
|
366
|
-
...
|
|
371
|
+
...t.A,
|
|
367
372
|
[BOUNDARY]: l
|
|
368
373
|
};
|
|
369
374
|
if (revealHooks !== null) a[REVEAL] = null;
|
|
370
|
-
|
|
371
|
-
const
|
|
375
|
+
t.A = a;
|
|
376
|
+
const s = runWithOwner(t, () => {
|
|
372
377
|
const e = true ? computed(r, {
|
|
373
378
|
name: "children"
|
|
374
379
|
}) : computed(r);
|
|
@@ -376,23 +381,30 @@ function createBoundary(e, r, n, t) {
|
|
|
376
381
|
name: "boundary"
|
|
377
382
|
}) : computed(() => flatten(read(e)));
|
|
378
383
|
});
|
|
379
|
-
l.Y =
|
|
384
|
+
l.Y = s;
|
|
380
385
|
// A slot of the reveal order in its context (reveal.ts): gated until the
|
|
381
386
|
// controller releases it — before the output's first pass.
|
|
382
|
-
if (u) revealHooks.
|
|
383
|
-
const
|
|
387
|
+
if (revealHooks && u) revealHooks.te(u, l);
|
|
388
|
+
const i = computed(() => {
|
|
389
|
+
// Structure, not a derivation of its content (CONFIG_FRAME, #4283): it
|
|
390
|
+
// reads a hold it is not part of as the screen, as the render effect
|
|
391
|
+
// flattening the same children without a boundary would. Not while a
|
|
392
|
+
// re-arm's swap is the change's work (`arm`), until that swap commits
|
|
393
|
+
// (D-13, #3540).
|
|
394
|
+
const r = getOwner();
|
|
395
|
+
if (!l.h && !(r.l & CONFIG_HELD)) r.l |= CONFIG_FRAME;
|
|
384
396
|
// Reveal order (reveal.ts): a gated slot shows its fallback — or, in a
|
|
385
397
|
// collapsed tail, nothing — whatever its content's state; the
|
|
386
398
|
// controller is told the pass ran (its readiness may have changed) and
|
|
387
399
|
// releases it in turn.
|
|
388
|
-
|
|
400
|
+
if (l.$) {
|
|
389
401
|
// Linked without being read: the tree settling (or changing)
|
|
390
402
|
// re-derives this pass, which is how the controller hears of it.
|
|
391
403
|
// It may release this very slot (the frontier whose content just
|
|
392
404
|
// settled): the pass goes on to show it — the redraw it asks for is
|
|
393
405
|
// refused mid-pass and not needed.
|
|
394
|
-
link(
|
|
395
|
-
if (l.v !== null) revealHooks.P(l.v);
|
|
406
|
+
link(s, r);
|
|
407
|
+
if (revealHooks && l.v !== null) revealHooks.P(l.v);
|
|
396
408
|
if (l.$) {
|
|
397
409
|
if (l.ee) {
|
|
398
410
|
l.L = true;
|
|
@@ -408,21 +420,21 @@ function createBoundary(e, r, n, t) {
|
|
|
408
420
|
// display-ahead `on` causes is the lane's, and must still be the
|
|
409
421
|
// fallback. Linked, so its recovery re-derives this pass; read again
|
|
410
422
|
// once clean.
|
|
411
|
-
const
|
|
412
|
-
if (
|
|
413
|
-
link(
|
|
414
|
-
if (
|
|
423
|
+
const n = s.m & (STATUS_PENDING | STATUS_ERROR);
|
|
424
|
+
if (n !== 0) {
|
|
425
|
+
link(s, r);
|
|
426
|
+
if (n & e) {
|
|
415
427
|
if (isCollecting(l)) {
|
|
416
|
-
caught(l,
|
|
428
|
+
caught(l, s, undefined);
|
|
417
429
|
return fallback(l);
|
|
418
430
|
}
|
|
419
431
|
// Forwarded: a loading boundary showing content keeps it and
|
|
420
432
|
// holds the frame like any reader (recorded for its `on`).
|
|
421
|
-
record(l,
|
|
433
|
+
record(l, s);
|
|
422
434
|
}
|
|
423
435
|
// A pending passes an error boundary by (A6); an error, a loading
|
|
424
436
|
// one; a loading boundary showing content forwards its pending.
|
|
425
|
-
throw
|
|
437
|
+
throw s.T.F;
|
|
426
438
|
}
|
|
427
439
|
if (isCollecting(l)) {
|
|
428
440
|
// A29's boundary exemption (#3540): a boundary MOUNTED over a held
|
|
@@ -436,24 +448,23 @@ function createBoundary(e, r, n, t) {
|
|
|
436
448
|
// enters: the outside sees its committed value until the landing,
|
|
437
449
|
// which reveals the content — a fallback staged earlier is replaced
|
|
438
450
|
// ahead of the commit and never shown.
|
|
439
|
-
|
|
440
|
-
if (l.U.size !== 0 && e.m & STATUS_UNINITIALIZED && !(e.l & CONFIG_HELD)) return fallback(l);
|
|
451
|
+
if (l.U.size !== 0 && r.m & STATUS_UNINITIALIZED && !(r.l & CONFIG_HELD)) return fallback(l);
|
|
441
452
|
// Readers under it still unready: the fallback, the tree untouched.
|
|
442
453
|
// The seam re-derives this pass when they settle.
|
|
443
454
|
if (prune(l, true) !== 0) return fallback(l);
|
|
444
455
|
}
|
|
445
|
-
let
|
|
456
|
+
let o;
|
|
446
457
|
try {
|
|
447
|
-
|
|
458
|
+
o = read(s);
|
|
448
459
|
} catch (r) {
|
|
449
460
|
if (r instanceof NotReadyError ? e === STATUS_PENDING : e === STATUS_ERROR) {
|
|
450
461
|
if (isCollecting(l)) {
|
|
451
|
-
caught(l,
|
|
462
|
+
caught(l, s, r);
|
|
452
463
|
return fallback(l);
|
|
453
464
|
}
|
|
454
465
|
// Forwarded: a loading boundary showing content keeps it and
|
|
455
466
|
// holds the frame like any reader (recorded for its `on`).
|
|
456
|
-
record(l,
|
|
467
|
+
record(l, s);
|
|
457
468
|
}
|
|
458
469
|
// A pending passes an error boundary by (A6).
|
|
459
470
|
throw r;
|
|
@@ -471,34 +482,44 @@ function createBoundary(e, r, n, t) {
|
|
|
471
482
|
// landing when the frame parks (the run is held with it, as the old
|
|
472
483
|
// children of a held pass are) — not now: a held swap keeps the
|
|
473
484
|
// fallback on screen, live, until it commits. A pass back to the
|
|
474
|
-
// fallback before then finds it still built and keeps it.
|
|
485
|
+
// fallback before then finds it still built and keeps it. A fallback
|
|
486
|
+
// the screen does not show (a swap staged with a held frame, replaced
|
|
487
|
+
// before it commits) dies now: what it reads holds nothing (S-22 row
|
|
488
|
+
// 3′, #4268).
|
|
475
489
|
const t = l.ne;
|
|
476
|
-
|
|
490
|
+
const drop = () => {
|
|
477
491
|
if (!l.L && l.ne === t) {
|
|
492
|
+
// A fallback that threw (a rethrow the boundary does not
|
|
493
|
+
// handle) is what an enclosing boundary waits on: it died, and
|
|
494
|
+
// the seam of another round drops it there (#4270).
|
|
495
|
+
if (t.m & STATUS_ERROR) schedule();
|
|
478
496
|
dispose(t);
|
|
479
497
|
l.ne = null;
|
|
480
498
|
}
|
|
481
|
-
}
|
|
499
|
+
};
|
|
500
|
+
if (t !== null) l.j.le !== t.le ? drop() : globalQueue.enqueue(EFFECT_RENDER, drop);
|
|
482
501
|
release(l);
|
|
483
502
|
// Shown: the slot leaves its reveal order (a later re-arm gates nobody
|
|
484
503
|
// else; the frontier moves on).
|
|
485
|
-
if (l.v !== null) {
|
|
504
|
+
if (revealHooks && l.v !== null) {
|
|
486
505
|
const e = l.v;
|
|
487
506
|
l.v = null;
|
|
488
507
|
revealHooks.P(e);
|
|
489
508
|
}
|
|
490
|
-
return
|
|
509
|
+
return o;
|
|
491
510
|
},
|
|
492
511
|
// Boundary structure, not a user source: its value is fallback-or-content
|
|
493
512
|
// and legitimately swaps mid-hydration (resume), so it must never be
|
|
494
513
|
// frozen by snapshot capture.
|
|
495
514
|
{
|
|
496
515
|
name: "value",
|
|
497
|
-
|
|
516
|
+
ue: true
|
|
498
517
|
});
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
518
|
+
i.l |= CONFIG_REDERIVE;
|
|
519
|
+
// The tree is structure too (the output's pass marks the output).
|
|
520
|
+
s.l |= CONFIG_FRAME;
|
|
521
|
+
l.j = i;
|
|
522
|
+
return accessor(i);
|
|
502
523
|
}
|
|
503
524
|
|
|
504
525
|
function fallback(e) {
|
|
@@ -541,7 +562,7 @@ function fallback(e) {
|
|
|
541
562
|
|
|
542
563
|
const ERROR_SIGNAL = {
|
|
543
564
|
ownedWrite: true,
|
|
544
|
-
|
|
565
|
+
ue: true
|
|
545
566
|
};
|
|
546
567
|
|
|
547
568
|
/**
|
|
@@ -70,6 +70,14 @@ import { attrHooks } from "./attribution-hooks.js";
|
|
|
70
70
|
* yield until(() => todos.some(t => t.id === saved.id));
|
|
71
71
|
* ```
|
|
72
72
|
*
|
|
73
|
+
* The same holds inside an async helper the action yields
|
|
74
|
+
* (`yield (async () => { ... })()`): everything after its first `await` runs
|
|
75
|
+
* outside the transaction. An `await refresh(x)` or `await until(...)` there
|
|
76
|
+
* waits for this action's commit, which waits on the helper, so it hangs
|
|
77
|
+
* whenever `x` re-ran during the action (#4263) and works otherwise. Call
|
|
78
|
+
* `refresh(x)` in the generator once the helper returns; `yield` it only when
|
|
79
|
+
* the action needs the fresh value.
|
|
80
|
+
*
|
|
73
81
|
* (For the same reason, don't call `flush()` inside an action body — it
|
|
74
82
|
* cannot reveal the held writes and is refused.)
|
|
75
83
|
*
|