@solidjs/signals 0.9.7 → 0.9.9
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 +403 -179
- package/dist/node.cjs +1160 -954
- package/dist/prod.js +957 -757
- package/dist/types/boundaries.d.ts +3 -2
- package/dist/types/core/core.d.ts +3 -2
- package/dist/types/core/error.d.ts +6 -2
- package/dist/types/core/scheduler.d.ts +66 -16
- package/package.json +1 -1
package/dist/dev.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
class NotReadyError extends Error {
|
|
2
|
-
|
|
3
|
-
constructor(
|
|
2
|
+
_source;
|
|
3
|
+
constructor(_source) {
|
|
4
4
|
super();
|
|
5
|
-
this.
|
|
5
|
+
this._source = _source;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
class StatusError extends Error {
|
|
9
|
+
_source;
|
|
10
|
+
constructor(_source, original) {
|
|
11
|
+
super(original instanceof Error ? original.message : String(original), { cause: original });
|
|
12
|
+
this._source = _source;
|
|
6
13
|
}
|
|
7
14
|
}
|
|
8
15
|
class NoOwnerError extends Error {
|
|
@@ -26,7 +33,6 @@ const REACTIVE_IN_HEAP_HEIGHT = 1 << 4;
|
|
|
26
33
|
const REACTIVE_ZOMBIE = 1 << 5;
|
|
27
34
|
const REACTIVE_DISPOSED = 1 << 6;
|
|
28
35
|
const REACTIVE_OPTIMISTIC_DIRTY = 1 << 7;
|
|
29
|
-
const STATUS_NONE = 0;
|
|
30
36
|
const STATUS_PENDING = 1 << 0;
|
|
31
37
|
const STATUS_ERROR = 1 << 1;
|
|
32
38
|
const STATUS_UNINITIALIZED = 1 << 2;
|
|
@@ -140,10 +146,85 @@ const zombieQueue = { _heap: new Array(2e3).fill(undefined), _marked: false, _mi
|
|
|
140
146
|
let clock = 0;
|
|
141
147
|
let activeTransition = null;
|
|
142
148
|
let scheduled = false;
|
|
143
|
-
let optimisticReadActive = false;
|
|
144
149
|
let projectionWriteActive = false;
|
|
145
|
-
|
|
146
|
-
|
|
150
|
+
const signalLanes = new WeakMap();
|
|
151
|
+
const activeLanes = new Set();
|
|
152
|
+
let currentOptimisticLane = null;
|
|
153
|
+
function setCurrentOptimisticLane(lane) {
|
|
154
|
+
currentOptimisticLane = lane;
|
|
155
|
+
}
|
|
156
|
+
function getOrCreateLane(signal) {
|
|
157
|
+
let lane = signalLanes.get(signal);
|
|
158
|
+
if (lane) {
|
|
159
|
+
return findLane(lane);
|
|
160
|
+
}
|
|
161
|
+
lane = {
|
|
162
|
+
_source: signal,
|
|
163
|
+
_pendingAsync: new Set(),
|
|
164
|
+
_effectQueues: [[], []],
|
|
165
|
+
_mergedInto: null,
|
|
166
|
+
_transition: activeTransition
|
|
167
|
+
};
|
|
168
|
+
signalLanes.set(signal, lane);
|
|
169
|
+
activeLanes.add(lane);
|
|
170
|
+
signal._laneVersion = signal._overrideVersion || 0;
|
|
171
|
+
return lane;
|
|
172
|
+
}
|
|
173
|
+
function findLane(lane) {
|
|
174
|
+
while (lane._mergedInto) lane = lane._mergedInto;
|
|
175
|
+
return lane;
|
|
176
|
+
}
|
|
177
|
+
function mergeLanes(lane1, lane2) {
|
|
178
|
+
lane1 = findLane(lane1);
|
|
179
|
+
lane2 = findLane(lane2);
|
|
180
|
+
if (lane1 === lane2) return lane1;
|
|
181
|
+
lane2._mergedInto = lane1;
|
|
182
|
+
for (const node of lane2._pendingAsync) lane1._pendingAsync.add(node);
|
|
183
|
+
lane1._effectQueues[0].push(...lane2._effectQueues[0]);
|
|
184
|
+
lane1._effectQueues[1].push(...lane2._effectQueues[1]);
|
|
185
|
+
return lane1;
|
|
186
|
+
}
|
|
187
|
+
function clearLaneEntry(signal) {
|
|
188
|
+
signalLanes.delete(signal);
|
|
189
|
+
}
|
|
190
|
+
function resolveLane(el) {
|
|
191
|
+
const lane = el._optimisticLane;
|
|
192
|
+
if (!lane) return undefined;
|
|
193
|
+
const root = findLane(lane);
|
|
194
|
+
if (activeLanes.has(root)) return root;
|
|
195
|
+
el._optimisticLane = undefined;
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
function hasActiveOverride(el) {
|
|
199
|
+
return !!(el._optimistic && el._pendingValue !== NOT_PENDING);
|
|
200
|
+
}
|
|
201
|
+
function assignOrMergeLane(el, sourceLane) {
|
|
202
|
+
const sourceRoot = findLane(sourceLane);
|
|
203
|
+
const existing = el._optimisticLane;
|
|
204
|
+
if (existing) {
|
|
205
|
+
if (existing._mergedInto) {
|
|
206
|
+
el._optimisticLane = sourceLane;
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const existingRoot = findLane(existing);
|
|
210
|
+
if (activeLanes.has(existingRoot)) {
|
|
211
|
+
if (existingRoot !== sourceRoot && !hasActiveOverride(el)) {
|
|
212
|
+
mergeLanes(sourceRoot, existingRoot);
|
|
213
|
+
}
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
el._optimisticLane = sourceLane;
|
|
218
|
+
}
|
|
219
|
+
function runLaneEffects(type) {
|
|
220
|
+
for (const lane of activeLanes) {
|
|
221
|
+
if (lane._mergedInto || lane._pendingAsync.size > 0) continue;
|
|
222
|
+
const effects = lane._effectQueues[type - 1];
|
|
223
|
+
if (effects.length) {
|
|
224
|
+
lane._effectQueues[type - 1] = [];
|
|
225
|
+
runQueue(effects, type);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
147
228
|
}
|
|
148
229
|
function setProjectionWriteActive(value) {
|
|
149
230
|
projectionWriteActive = value;
|
|
@@ -156,7 +237,6 @@ function schedule() {
|
|
|
156
237
|
class Queue {
|
|
157
238
|
_parent = null;
|
|
158
239
|
_queues = [[], []];
|
|
159
|
-
_optimisticQueues = [[], []];
|
|
160
240
|
_children = [];
|
|
161
241
|
created = clock;
|
|
162
242
|
addChild(child) {
|
|
@@ -170,30 +250,26 @@ class Queue {
|
|
|
170
250
|
child._parent = null;
|
|
171
251
|
}
|
|
172
252
|
}
|
|
173
|
-
notify(node, mask, flags) {
|
|
174
|
-
if (this._parent) return this._parent.notify(node, mask, flags);
|
|
253
|
+
notify(node, mask, flags, error) {
|
|
254
|
+
if (this._parent) return this._parent.notify(node, mask, flags, error);
|
|
175
255
|
return false;
|
|
176
256
|
}
|
|
177
|
-
|
|
178
|
-
if (
|
|
179
|
-
const effects =
|
|
180
|
-
|
|
257
|
+
run(type) {
|
|
258
|
+
if (this._queues[type - 1].length) {
|
|
259
|
+
const effects = this._queues[type - 1];
|
|
260
|
+
this._queues[type - 1] = [];
|
|
181
261
|
runQueue(effects, type);
|
|
182
262
|
}
|
|
183
|
-
for (let i = 0; i < this._children.length; i++)
|
|
184
|
-
this._children[i][method]?.(type);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
run(type) {
|
|
188
|
-
this._runQueue(type, this._queues, "run");
|
|
189
|
-
}
|
|
190
|
-
runOptimistic(type) {
|
|
191
|
-
this._runQueue(type, this._optimisticQueues, "runOptimistic");
|
|
263
|
+
for (let i = 0; i < this._children.length; i++) this._children[i].run?.(type);
|
|
192
264
|
}
|
|
193
265
|
enqueue(type, fn) {
|
|
194
266
|
if (type) {
|
|
195
|
-
|
|
196
|
-
|
|
267
|
+
if (currentOptimisticLane) {
|
|
268
|
+
const lane = findLane(currentOptimisticLane);
|
|
269
|
+
lane._effectQueues[type - 1].push(fn);
|
|
270
|
+
} else {
|
|
271
|
+
this._queues[type - 1].push(fn);
|
|
272
|
+
}
|
|
197
273
|
}
|
|
198
274
|
schedule();
|
|
199
275
|
}
|
|
@@ -242,23 +318,23 @@ class GlobalQueue extends Queue {
|
|
|
242
318
|
this._pendingNodes = [];
|
|
243
319
|
this._optimisticNodes = [];
|
|
244
320
|
this._optimisticStores = new Set();
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
this.stashQueues(activeTransition.
|
|
321
|
+
runLaneEffects(EFFECT_RENDER);
|
|
322
|
+
runLaneEffects(EFFECT_USER);
|
|
323
|
+
this.stashQueues(activeTransition._queueStash);
|
|
248
324
|
clock++;
|
|
249
|
-
scheduled =
|
|
250
|
-
|
|
325
|
+
scheduled = dirtyQueue._max >= dirtyQueue._min;
|
|
326
|
+
reassignPendingTransition(activeTransition._pendingNodes);
|
|
251
327
|
activeTransition = null;
|
|
252
328
|
finalizePureQueue(null, true);
|
|
253
329
|
return;
|
|
254
330
|
}
|
|
255
|
-
this._pendingNodes !== activeTransition.
|
|
256
|
-
this._pendingNodes.push(...activeTransition.
|
|
257
|
-
this.restoreQueues(activeTransition.
|
|
331
|
+
this._pendingNodes !== activeTransition._pendingNodes &&
|
|
332
|
+
this._pendingNodes.push(...activeTransition._pendingNodes);
|
|
333
|
+
this.restoreQueues(activeTransition._queueStash);
|
|
258
334
|
transitions.delete(activeTransition);
|
|
259
335
|
const completingTransition = activeTransition;
|
|
260
336
|
activeTransition = null;
|
|
261
|
-
|
|
337
|
+
reassignPendingTransition(this._pendingNodes);
|
|
262
338
|
finalizePureQueue(completingTransition);
|
|
263
339
|
} else {
|
|
264
340
|
if (transitions.size) runHeap(zombieQueue, GlobalQueue._update);
|
|
@@ -266,23 +342,24 @@ class GlobalQueue extends Queue {
|
|
|
266
342
|
}
|
|
267
343
|
clock++;
|
|
268
344
|
scheduled = dirtyQueue._max >= dirtyQueue._min;
|
|
269
|
-
|
|
345
|
+
runLaneEffects(EFFECT_RENDER);
|
|
270
346
|
this.run(EFFECT_RENDER);
|
|
271
|
-
|
|
347
|
+
runLaneEffects(EFFECT_USER);
|
|
272
348
|
this.run(EFFECT_USER);
|
|
273
349
|
} finally {
|
|
274
350
|
this._running = false;
|
|
275
351
|
}
|
|
276
352
|
}
|
|
277
|
-
notify(node, mask, flags) {
|
|
353
|
+
notify(node, mask, flags, error) {
|
|
278
354
|
if (mask & STATUS_PENDING) {
|
|
279
355
|
if (flags & STATUS_PENDING) {
|
|
356
|
+
const actualError = error !== undefined ? error : node._error;
|
|
280
357
|
if (
|
|
281
358
|
activeTransition &&
|
|
282
|
-
|
|
283
|
-
!activeTransition.
|
|
359
|
+
actualError &&
|
|
360
|
+
!activeTransition._asyncNodes.includes(actualError._source)
|
|
284
361
|
) {
|
|
285
|
-
activeTransition.
|
|
362
|
+
activeTransition._asyncNodes.push(actualError._source);
|
|
286
363
|
schedule();
|
|
287
364
|
}
|
|
288
365
|
}
|
|
@@ -293,47 +370,63 @@ class GlobalQueue extends Queue {
|
|
|
293
370
|
initTransition(transition) {
|
|
294
371
|
if (transition) transition = currentTransition(transition);
|
|
295
372
|
if (transition && transition === activeTransition) return;
|
|
296
|
-
if (!transition && activeTransition && activeTransition.
|
|
373
|
+
if (!transition && activeTransition && activeTransition._time === clock) return;
|
|
297
374
|
if (!activeTransition) {
|
|
298
375
|
activeTransition = transition ?? {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
376
|
+
_time: clock,
|
|
377
|
+
_pendingNodes: [],
|
|
378
|
+
_asyncNodes: [],
|
|
379
|
+
_optimisticNodes: [],
|
|
380
|
+
_optimisticStores: new Set(),
|
|
381
|
+
_actions: [],
|
|
382
|
+
_queueStash: { _queues: [[], []], _children: [] },
|
|
383
|
+
_done: false
|
|
307
384
|
};
|
|
308
385
|
} else if (transition) {
|
|
309
|
-
|
|
310
|
-
transition
|
|
311
|
-
|
|
386
|
+
const outgoing = activeTransition;
|
|
387
|
+
outgoing._done = transition;
|
|
388
|
+
transition._actions.push(...outgoing._actions);
|
|
389
|
+
for (const lane of activeLanes) {
|
|
390
|
+
if (lane._transition === outgoing) lane._transition = transition;
|
|
391
|
+
}
|
|
392
|
+
transition._optimisticNodes.push(...outgoing._optimisticNodes);
|
|
393
|
+
for (const store of outgoing._optimisticStores) {
|
|
394
|
+
transition._optimisticStores.add(store);
|
|
395
|
+
}
|
|
396
|
+
transitions.delete(outgoing);
|
|
312
397
|
activeTransition = transition;
|
|
313
398
|
}
|
|
314
399
|
transitions.add(activeTransition);
|
|
315
|
-
activeTransition.
|
|
400
|
+
activeTransition._time = clock;
|
|
316
401
|
for (let i = 0; i < this._pendingNodes.length; i++) {
|
|
317
402
|
const n = this._pendingNodes[i];
|
|
318
403
|
n._transition = activeTransition;
|
|
319
|
-
activeTransition.
|
|
404
|
+
activeTransition._pendingNodes.push(n);
|
|
320
405
|
}
|
|
321
|
-
this._pendingNodes = activeTransition.
|
|
406
|
+
this._pendingNodes = activeTransition._pendingNodes;
|
|
322
407
|
for (let i = 0; i < this._optimisticNodes.length; i++) {
|
|
323
408
|
const node = this._optimisticNodes[i];
|
|
324
409
|
node._transition = activeTransition;
|
|
325
|
-
activeTransition.
|
|
410
|
+
activeTransition._optimisticNodes.push(node);
|
|
326
411
|
}
|
|
327
|
-
this._optimisticNodes = activeTransition.
|
|
328
|
-
for (const
|
|
329
|
-
|
|
412
|
+
this._optimisticNodes = activeTransition._optimisticNodes;
|
|
413
|
+
for (const lane of activeLanes) {
|
|
414
|
+
if (!lane._transition) lane._transition = activeTransition;
|
|
330
415
|
}
|
|
331
|
-
this._optimisticStores
|
|
416
|
+
for (const store of this._optimisticStores) activeTransition._optimisticStores.add(store);
|
|
417
|
+
this._optimisticStores = activeTransition._optimisticStores;
|
|
332
418
|
}
|
|
333
419
|
}
|
|
334
420
|
function insertSubs(node, optimistic = false) {
|
|
421
|
+
const sourceLane = node._optimisticLane || currentOptimisticLane;
|
|
335
422
|
for (let s = node._subs; s !== null; s = s._nextSub) {
|
|
336
|
-
if (optimistic
|
|
423
|
+
if (optimistic && sourceLane) {
|
|
424
|
+
s._sub._flags |= REACTIVE_OPTIMISTIC_DIRTY;
|
|
425
|
+
assignOrMergeLane(s._sub, sourceLane);
|
|
426
|
+
} else if (optimistic) {
|
|
427
|
+
s._sub._flags |= REACTIVE_OPTIMISTIC_DIRTY;
|
|
428
|
+
s._sub._optimisticLane = undefined;
|
|
429
|
+
}
|
|
337
430
|
const sub = s._sub;
|
|
338
431
|
if (sub._type === EFFECT_TRACKED) {
|
|
339
432
|
if (!sub._modified) {
|
|
@@ -349,10 +442,8 @@ function insertSubs(node, optimistic = false) {
|
|
|
349
442
|
}
|
|
350
443
|
function finalizePureQueue(completingTransition = null, incomplete = false) {
|
|
351
444
|
let resolvePending = !incomplete;
|
|
352
|
-
if (
|
|
353
|
-
|
|
354
|
-
runHeap(dirtyQueue, GlobalQueue._update);
|
|
355
|
-
}
|
|
445
|
+
if (!incomplete) checkBoundaryChildren(globalQueue);
|
|
446
|
+
if (dirtyQueue._max >= dirtyQueue._min) runHeap(dirtyQueue, GlobalQueue._update);
|
|
356
447
|
if (resolvePending) {
|
|
357
448
|
const pendingNodes = globalQueue._pendingNodes;
|
|
358
449
|
for (let i = 0; i < pendingNodes.length; i++) {
|
|
@@ -362,15 +453,17 @@ function finalizePureQueue(completingTransition = null, incomplete = false) {
|
|
|
362
453
|
n._pendingValue = NOT_PENDING;
|
|
363
454
|
if (n._type && n._type !== EFFECT_TRACKED) n._modified = true;
|
|
364
455
|
}
|
|
456
|
+
n._statusFlags &= ~STATUS_UNINITIALIZED;
|
|
365
457
|
if (n._fn) GlobalQueue._dispose(n, false, true);
|
|
366
458
|
}
|
|
367
459
|
pendingNodes.length = 0;
|
|
368
460
|
const optimisticNodes = completingTransition
|
|
369
|
-
? completingTransition.
|
|
461
|
+
? completingTransition._optimisticNodes
|
|
370
462
|
: globalQueue._optimisticNodes;
|
|
371
463
|
for (let i = 0; i < optimisticNodes.length; i++) {
|
|
372
464
|
const n = optimisticNodes[i];
|
|
373
465
|
const original = n._pendingValue;
|
|
466
|
+
n._optimisticLane = undefined;
|
|
374
467
|
if (original !== NOT_PENDING && n._value !== original) {
|
|
375
468
|
n._value = original;
|
|
376
469
|
insertSubs(n, true);
|
|
@@ -380,7 +473,7 @@ function finalizePureQueue(completingTransition = null, incomplete = false) {
|
|
|
380
473
|
}
|
|
381
474
|
optimisticNodes.length = 0;
|
|
382
475
|
const optimisticStores = completingTransition
|
|
383
|
-
? completingTransition.
|
|
476
|
+
? completingTransition._optimisticStores
|
|
384
477
|
: globalQueue._optimisticStores;
|
|
385
478
|
if (GlobalQueue._clearOptimisticStore && optimisticStores.size) {
|
|
386
479
|
for (const store of optimisticStores) {
|
|
@@ -389,13 +482,35 @@ function finalizePureQueue(completingTransition = null, incomplete = false) {
|
|
|
389
482
|
optimisticStores.clear();
|
|
390
483
|
schedule();
|
|
391
484
|
}
|
|
485
|
+
for (const lane of activeLanes) {
|
|
486
|
+
const owned = completingTransition
|
|
487
|
+
? lane._transition === completingTransition
|
|
488
|
+
: !lane._transition;
|
|
489
|
+
if (!owned) continue;
|
|
490
|
+
if (!lane._mergedInto) {
|
|
491
|
+
if (lane._effectQueues[0].length) runQueue(lane._effectQueues[0], EFFECT_RENDER);
|
|
492
|
+
if (lane._effectQueues[1].length) runQueue(lane._effectQueues[1], EFFECT_USER);
|
|
493
|
+
}
|
|
494
|
+
if (lane._source._optimisticLane === lane) lane._source._optimisticLane = undefined;
|
|
495
|
+
lane._pendingAsync.clear();
|
|
496
|
+
lane._effectQueues[0].length = 0;
|
|
497
|
+
lane._effectQueues[1].length = 0;
|
|
498
|
+
activeLanes.delete(lane);
|
|
499
|
+
signalLanes.delete(lane._source);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
function checkBoundaryChildren(queue) {
|
|
504
|
+
for (const child of queue._children) {
|
|
505
|
+
child.checkSources?.();
|
|
506
|
+
checkBoundaryChildren(child);
|
|
392
507
|
}
|
|
393
508
|
}
|
|
394
509
|
function trackOptimisticStore(store) {
|
|
395
510
|
globalQueue._optimisticStores.add(store);
|
|
396
511
|
schedule();
|
|
397
512
|
}
|
|
398
|
-
function
|
|
513
|
+
function reassignPendingTransition(pendingNodes) {
|
|
399
514
|
for (let i = 0; i < pendingNodes.length; i++) {
|
|
400
515
|
pendingNodes[i]._transition = activeTransition;
|
|
401
516
|
}
|
|
@@ -412,20 +527,20 @@ function runQueue(queue, type) {
|
|
|
412
527
|
for (let i = 0; i < queue.length; i++) queue[i](type);
|
|
413
528
|
}
|
|
414
529
|
function transitionComplete(transition) {
|
|
415
|
-
if (transition.
|
|
416
|
-
if (transition.
|
|
530
|
+
if (transition._done) return true;
|
|
531
|
+
if (transition._actions.length) return false;
|
|
417
532
|
let done = true;
|
|
418
|
-
for (let i = 0; i < transition.
|
|
419
|
-
if (transition.
|
|
533
|
+
for (let i = 0; i < transition._asyncNodes.length; i++) {
|
|
534
|
+
if (transition._asyncNodes[i]._statusFlags & STATUS_PENDING) {
|
|
420
535
|
done = false;
|
|
421
536
|
break;
|
|
422
537
|
}
|
|
423
538
|
}
|
|
424
|
-
done && (transition.
|
|
539
|
+
done && (transition._done = true);
|
|
425
540
|
return done;
|
|
426
541
|
}
|
|
427
542
|
function currentTransition(transition) {
|
|
428
|
-
while (transition.
|
|
543
|
+
while (transition._done && typeof transition._done === "object") transition = transition._done;
|
|
429
544
|
return transition;
|
|
430
545
|
}
|
|
431
546
|
function runInTransition(transition, fn) {
|
|
@@ -449,11 +564,11 @@ function action(genFn) {
|
|
|
449
564
|
const it = genFn(...args);
|
|
450
565
|
globalQueue.initTransition();
|
|
451
566
|
let ctx = activeTransition;
|
|
452
|
-
ctx.
|
|
567
|
+
ctx._actions.push(it);
|
|
453
568
|
const done = (v, e) => {
|
|
454
569
|
ctx = currentTransition(ctx);
|
|
455
|
-
const i = ctx.
|
|
456
|
-
if (i >= 0) ctx.
|
|
570
|
+
const i = ctx._actions.indexOf(it);
|
|
571
|
+
if (i >= 0) ctx._actions.splice(i, 1);
|
|
457
572
|
activeTransition = ctx;
|
|
458
573
|
schedule();
|
|
459
574
|
e ? reject(e) : resolve(v);
|
|
@@ -500,7 +615,7 @@ function recompute(el, create = false) {
|
|
|
500
615
|
if (el._transition && (!isEffect || activeTransition) && activeTransition !== el._transition)
|
|
501
616
|
globalQueue.initTransition(el._transition);
|
|
502
617
|
deleteFromHeap(el, el._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
503
|
-
if (el._transition) disposeChildren(el);
|
|
618
|
+
if (el._transition || isEffect === EFFECT_TRACKED) disposeChildren(el);
|
|
504
619
|
else {
|
|
505
620
|
markDisposal(el);
|
|
506
621
|
el._pendingDisposal = el._disposal;
|
|
@@ -510,7 +625,8 @@ function recompute(el, create = false) {
|
|
|
510
625
|
}
|
|
511
626
|
}
|
|
512
627
|
const isOptimisticDirty = !!(el._flags & REACTIVE_OPTIMISTIC_DIRTY);
|
|
513
|
-
const
|
|
628
|
+
const hasOverride = hasActiveOverride(el);
|
|
629
|
+
const wasPending = !!(el._statusFlags & STATUS_PENDING);
|
|
514
630
|
const oldcontext = context;
|
|
515
631
|
context = el;
|
|
516
632
|
el._depsTail = null;
|
|
@@ -519,17 +635,32 @@ function recompute(el, create = false) {
|
|
|
519
635
|
let value = el._pendingValue === NOT_PENDING ? el._value : el._pendingValue;
|
|
520
636
|
let oldHeight = el._height;
|
|
521
637
|
let prevTracking = tracking;
|
|
522
|
-
let
|
|
638
|
+
let prevLane = currentOptimisticLane;
|
|
523
639
|
tracking = true;
|
|
524
|
-
if (isOptimisticDirty)
|
|
640
|
+
if (isOptimisticDirty) {
|
|
641
|
+
const lane = resolveLane(el);
|
|
642
|
+
if (lane) setCurrentOptimisticLane(lane);
|
|
643
|
+
}
|
|
525
644
|
try {
|
|
526
645
|
value = handleAsync(el, el._fn(value));
|
|
527
646
|
clearStatus(el);
|
|
647
|
+
const resolvedLane = resolveLane(el);
|
|
648
|
+
if (resolvedLane) resolvedLane._pendingAsync.delete(el);
|
|
528
649
|
} catch (e) {
|
|
529
|
-
if (e instanceof NotReadyError) {
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
650
|
+
if (e instanceof NotReadyError && currentOptimisticLane) {
|
|
651
|
+
const lane = findLane(currentOptimisticLane);
|
|
652
|
+
if (lane._source !== el) {
|
|
653
|
+
lane._pendingAsync.add(el);
|
|
654
|
+
el._optimisticLane = lane;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
notifyStatus(
|
|
658
|
+
el,
|
|
659
|
+
e instanceof NotReadyError ? STATUS_PENDING : STATUS_ERROR,
|
|
660
|
+
e,
|
|
661
|
+
undefined,
|
|
662
|
+
e instanceof NotReadyError ? el._optimisticLane : undefined
|
|
663
|
+
);
|
|
533
664
|
} finally {
|
|
534
665
|
tracking = prevTracking;
|
|
535
666
|
el._flags = REACTIVE_NONE;
|
|
@@ -545,23 +676,37 @@ function recompute(el, create = false) {
|
|
|
545
676
|
if (depsTail !== null) depsTail._nextDep = null;
|
|
546
677
|
else el._deps = null;
|
|
547
678
|
}
|
|
548
|
-
const
|
|
549
|
-
|
|
550
|
-
|
|
679
|
+
const compareValue = hasOverride
|
|
680
|
+
? el._value
|
|
681
|
+
: el._pendingValue === NOT_PENDING
|
|
682
|
+
? el._value
|
|
683
|
+
: el._pendingValue;
|
|
684
|
+
const valueChanged = !el._equals || !el._equals(compareValue, value);
|
|
551
685
|
if (valueChanged) {
|
|
686
|
+
const prevVisible = hasOverride ? el._value : undefined;
|
|
552
687
|
if (create || (isEffect && activeTransition !== el._transition) || isOptimisticDirty)
|
|
553
688
|
el._value = value;
|
|
554
689
|
else el._pendingValue = value;
|
|
555
|
-
|
|
690
|
+
if (hasOverride && !isOptimisticDirty && wasPending) {
|
|
691
|
+
const ov = el._overrideVersion || 0;
|
|
692
|
+
const lv = el._laneVersion || 0;
|
|
693
|
+
if (ov <= lv) el._value = value;
|
|
694
|
+
}
|
|
695
|
+
if (!hasOverride || isOptimisticDirty || el._value !== prevVisible) {
|
|
696
|
+
insertSubs(el, isOptimisticDirty || hasOverride);
|
|
697
|
+
}
|
|
698
|
+
} else if (hasOverride) {
|
|
699
|
+
el._pendingValue = value;
|
|
556
700
|
} else if (el._height != oldHeight) {
|
|
557
701
|
for (let s = el._subs; s !== null; s = s._nextSub) {
|
|
558
702
|
insertIntoHeapHeight(s._sub, s._sub._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
559
703
|
}
|
|
560
704
|
}
|
|
561
705
|
}
|
|
562
|
-
|
|
706
|
+
setCurrentOptimisticLane(prevLane);
|
|
563
707
|
(!create || el._statusFlags & STATUS_PENDING) &&
|
|
564
708
|
!el._transition &&
|
|
709
|
+
!(activeTransition && el._optimistic) &&
|
|
565
710
|
globalQueue._pendingNodes.push(el);
|
|
566
711
|
el._transition &&
|
|
567
712
|
isEffect &&
|
|
@@ -581,27 +726,40 @@ function handleAsync(el, result, setter) {
|
|
|
581
726
|
const handleError = error => {
|
|
582
727
|
if (el._inFlight !== result) return;
|
|
583
728
|
globalQueue.initTransition(el._transition);
|
|
584
|
-
|
|
585
|
-
if (error.cause !== el) link(error.cause, el);
|
|
586
|
-
notifyStatus(el, STATUS_PENDING, error);
|
|
587
|
-
} else notifyStatus(el, STATUS_ERROR, error);
|
|
729
|
+
notifyStatus(el, error instanceof NotReadyError ? STATUS_PENDING : STATUS_ERROR, error);
|
|
588
730
|
el._time = clock;
|
|
589
731
|
};
|
|
590
732
|
const asyncWrite = (value, then) => {
|
|
591
733
|
if (el._inFlight !== result) return;
|
|
734
|
+
if (el._flags & (REACTIVE_DIRTY | REACTIVE_OPTIMISTIC_DIRTY)) return;
|
|
592
735
|
globalQueue.initTransition(el._transition);
|
|
593
736
|
clearStatus(el);
|
|
737
|
+
const lane = resolveLane(el);
|
|
738
|
+
if (lane) lane._pendingAsync.delete(el);
|
|
594
739
|
if (setter) setter(value);
|
|
595
740
|
else if (el._optimistic) {
|
|
596
|
-
const
|
|
741
|
+
const hadOverride = el._pendingValue !== NOT_PENDING;
|
|
597
742
|
if (el._fn) el._pendingValue = value;
|
|
598
|
-
if (!
|
|
743
|
+
if (!hadOverride) {
|
|
599
744
|
el._value = value;
|
|
600
745
|
insertSubs(el);
|
|
601
746
|
}
|
|
602
747
|
el._time = clock;
|
|
603
|
-
|
|
604
|
-
|
|
748
|
+
} else if (lane) {
|
|
749
|
+
const prevValue = el._value;
|
|
750
|
+
const equals = el._equals;
|
|
751
|
+
if (!equals || !equals(value, prevValue)) {
|
|
752
|
+
el._value = value;
|
|
753
|
+
el._time = clock;
|
|
754
|
+
if (el._pendingValueComputed) {
|
|
755
|
+
setSignal(el._pendingValueComputed, value);
|
|
756
|
+
}
|
|
757
|
+
insertSubs(el, true);
|
|
758
|
+
}
|
|
759
|
+
} else {
|
|
760
|
+
setSignal(el, () => value);
|
|
761
|
+
}
|
|
762
|
+
schedule();
|
|
605
763
|
flush();
|
|
606
764
|
then?.();
|
|
607
765
|
};
|
|
@@ -660,32 +818,51 @@ function handleAsync(el, result, setter) {
|
|
|
660
818
|
return syncValue;
|
|
661
819
|
}
|
|
662
820
|
function clearStatus(el) {
|
|
663
|
-
el._statusFlags =
|
|
821
|
+
el._statusFlags = el._statusFlags & STATUS_UNINITIALIZED;
|
|
664
822
|
el._error = null;
|
|
665
823
|
updatePendingSignal(el);
|
|
824
|
+
el._notifyStatus?.();
|
|
825
|
+
}
|
|
826
|
+
function notifyStatus(el, status, error, blockStatus, lane) {
|
|
827
|
+
if (
|
|
828
|
+
status === STATUS_ERROR &&
|
|
829
|
+
!(error instanceof StatusError) &&
|
|
830
|
+
!(error instanceof NotReadyError)
|
|
831
|
+
)
|
|
832
|
+
error = new StatusError(el, error);
|
|
833
|
+
const isSource = error instanceof NotReadyError && error._source === el;
|
|
834
|
+
const isOptimisticBoundary = status === STATUS_PENDING && el._optimistic && !isSource;
|
|
835
|
+
const startsBlocking = isOptimisticBoundary && hasActiveOverride(el);
|
|
836
|
+
if (!blockStatus) {
|
|
837
|
+
el._statusFlags =
|
|
838
|
+
status | (status !== STATUS_ERROR ? el._statusFlags & STATUS_UNINITIALIZED : 0);
|
|
839
|
+
el._error = error;
|
|
840
|
+
updatePendingSignal(el);
|
|
841
|
+
}
|
|
842
|
+
if (lane && !blockStatus) {
|
|
843
|
+
assignOrMergeLane(el, lane);
|
|
844
|
+
}
|
|
845
|
+
if (startsBlocking && activeTransition && error instanceof NotReadyError) {
|
|
846
|
+
const source = error._source;
|
|
847
|
+
if (!activeTransition._asyncNodes.includes(source)) {
|
|
848
|
+
activeTransition._asyncNodes.push(source);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
const downstreamBlockStatus = blockStatus || startsBlocking;
|
|
852
|
+
const downstreamLane = blockStatus || isOptimisticBoundary ? undefined : lane;
|
|
666
853
|
if (el._notifyStatus) {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
if (s._sub._statusFlags & STATUS_PENDING) {
|
|
672
|
-
insertIntoHeap(s._sub, s._sub._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
673
|
-
}
|
|
674
|
-
}
|
|
854
|
+
if (downstreamBlockStatus) {
|
|
855
|
+
el._notifyStatus(status, error);
|
|
856
|
+
} else {
|
|
857
|
+
el._notifyStatus();
|
|
675
858
|
}
|
|
676
|
-
|
|
859
|
+
return;
|
|
677
860
|
}
|
|
678
|
-
}
|
|
679
|
-
function notifyStatus(el, status, error) {
|
|
680
|
-
el._statusFlags = status | (status !== STATUS_ERROR ? el._statusFlags & STATUS_UNINITIALIZED : 0);
|
|
681
|
-
el._error = error;
|
|
682
|
-
updatePendingSignal(el);
|
|
683
|
-
if (el._notifyStatus) return el._notifyStatus();
|
|
684
861
|
for (let s = el._subs; s !== null; s = s._nextSub) {
|
|
685
862
|
s._sub._time = clock;
|
|
686
863
|
if (s._sub._error !== error) {
|
|
687
864
|
!s._sub._transition && globalQueue._pendingNodes.push(s._sub);
|
|
688
|
-
notifyStatus(s._sub, status, error);
|
|
865
|
+
notifyStatus(s._sub, status, error, downstreamBlockStatus, downstreamLane);
|
|
689
866
|
}
|
|
690
867
|
}
|
|
691
868
|
for (let child = el._child; child !== null; child = child._nextChild) {
|
|
@@ -693,7 +870,7 @@ function notifyStatus(el, status, error) {
|
|
|
693
870
|
s._sub._time = clock;
|
|
694
871
|
if (s._sub._error !== error) {
|
|
695
872
|
!s._sub._transition && globalQueue._pendingNodes.push(s._sub);
|
|
696
|
-
notifyStatus(s._sub, status, error);
|
|
873
|
+
notifyStatus(s._sub, status, error, downstreamBlockStatus, downstreamLane);
|
|
697
874
|
}
|
|
698
875
|
}
|
|
699
876
|
}
|
|
@@ -711,7 +888,7 @@ function updateIfNecessary(el) {
|
|
|
711
888
|
}
|
|
712
889
|
}
|
|
713
890
|
}
|
|
714
|
-
if (el._flags & REACTIVE_DIRTY) {
|
|
891
|
+
if (el._flags & (REACTIVE_DIRTY | REACTIVE_OPTIMISTIC_DIRTY) || (el._error && el._time < clock)) {
|
|
715
892
|
recompute(el);
|
|
716
893
|
}
|
|
717
894
|
el._flags = REACTIVE_NONE;
|
|
@@ -934,8 +1111,8 @@ function getPendingSignal(el) {
|
|
|
934
1111
|
return el._pendingSignal;
|
|
935
1112
|
}
|
|
936
1113
|
function computePendingState(el) {
|
|
937
|
-
if (el._pendingValue !== NOT_PENDING) return true;
|
|
938
1114
|
const comp = el;
|
|
1115
|
+
if (el._pendingValue !== NOT_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED)) return true;
|
|
939
1116
|
return !!(comp._statusFlags & STATUS_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED));
|
|
940
1117
|
}
|
|
941
1118
|
function getPendingValueComputed(el) {
|
|
@@ -951,7 +1128,22 @@ function getPendingValueComputed(el) {
|
|
|
951
1128
|
return el._pendingValueComputed;
|
|
952
1129
|
}
|
|
953
1130
|
function updatePendingSignal(el) {
|
|
954
|
-
if (el._pendingSignal)
|
|
1131
|
+
if (el._pendingSignal) {
|
|
1132
|
+
const pending = computePendingState(el);
|
|
1133
|
+
const sig = el._pendingSignal;
|
|
1134
|
+
setSignal(sig, pending);
|
|
1135
|
+
if (!pending && sig._optimisticLane) {
|
|
1136
|
+
const sourceLane = resolveLane(el);
|
|
1137
|
+
if (sourceLane && sourceLane._pendingAsync.size > 0) {
|
|
1138
|
+
const sigLane = findLane(sig._optimisticLane);
|
|
1139
|
+
if (sigLane !== sourceLane) {
|
|
1140
|
+
mergeLanes(sourceLane, sigLane);
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
clearLaneEntry(sig);
|
|
1144
|
+
sig._optimisticLane = undefined;
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
955
1147
|
}
|
|
956
1148
|
function isEqual(a, b) {
|
|
957
1149
|
return a === b;
|
|
@@ -1009,11 +1201,21 @@ function read(el) {
|
|
|
1009
1201
|
const asyncCompute = el._firewall || el;
|
|
1010
1202
|
if (
|
|
1011
1203
|
c &&
|
|
1012
|
-
!optimisticReadActive &&
|
|
1013
1204
|
asyncCompute._statusFlags & STATUS_PENDING &&
|
|
1014
1205
|
!(stale && asyncCompute._transition && activeTransition !== asyncCompute._transition)
|
|
1015
|
-
)
|
|
1016
|
-
|
|
1206
|
+
) {
|
|
1207
|
+
if (currentOptimisticLane) {
|
|
1208
|
+
const pendingLane = asyncCompute._optimisticLane;
|
|
1209
|
+
const lane = findLane(currentOptimisticLane);
|
|
1210
|
+
if (pendingLane && findLane(pendingLane) === lane && !hasActiveOverride(asyncCompute)) {
|
|
1211
|
+
if (!tracking) link(el, c);
|
|
1212
|
+
throw asyncCompute._error;
|
|
1213
|
+
}
|
|
1214
|
+
} else {
|
|
1215
|
+
if (!tracking) link(el, c);
|
|
1216
|
+
throw asyncCompute._error;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1017
1219
|
if (el._fn && el._statusFlags & STATUS_ERROR) {
|
|
1018
1220
|
if (el._time < clock) {
|
|
1019
1221
|
recompute(el, true);
|
|
@@ -1021,7 +1223,7 @@ function read(el) {
|
|
|
1021
1223
|
} else throw el._error;
|
|
1022
1224
|
}
|
|
1023
1225
|
return !c ||
|
|
1024
|
-
|
|
1226
|
+
currentOptimisticLane !== null ||
|
|
1025
1227
|
el._pendingValue === NOT_PENDING ||
|
|
1026
1228
|
(stale && el._transition && activeTransition !== el._transition)
|
|
1027
1229
|
? el._value
|
|
@@ -1040,16 +1242,27 @@ function setSignal(el, v) {
|
|
|
1040
1242
|
: el._pendingValue;
|
|
1041
1243
|
if (typeof v === "function") v = v(currentValue);
|
|
1042
1244
|
const valueChanged = !el._equals || !el._equals(currentValue, v);
|
|
1043
|
-
if (!valueChanged)
|
|
1245
|
+
if (!valueChanged) {
|
|
1246
|
+
if (isOptimistic && el._pendingValue !== NOT_PENDING && el._fn) {
|
|
1247
|
+
insertSubs(el, true);
|
|
1248
|
+
schedule();
|
|
1249
|
+
}
|
|
1250
|
+
return v;
|
|
1251
|
+
}
|
|
1044
1252
|
if (isOptimistic) {
|
|
1045
|
-
const
|
|
1046
|
-
if (el._transition &&
|
|
1253
|
+
const alreadyTracked = globalQueue._optimisticNodes.includes(el);
|
|
1254
|
+
if (el._transition && alreadyTracked) {
|
|
1047
1255
|
globalQueue.initTransition(el._transition);
|
|
1048
1256
|
}
|
|
1049
|
-
if (
|
|
1257
|
+
if (el._pendingValue === NOT_PENDING) {
|
|
1050
1258
|
el._pendingValue = el._value;
|
|
1259
|
+
}
|
|
1260
|
+
if (!alreadyTracked) {
|
|
1051
1261
|
globalQueue._optimisticNodes.push(el);
|
|
1052
1262
|
}
|
|
1263
|
+
el._overrideVersion = (el._overrideVersion || 0) + 1;
|
|
1264
|
+
const lane = getOrCreateLane(el);
|
|
1265
|
+
el._optimisticLane = lane;
|
|
1053
1266
|
el._value = v;
|
|
1054
1267
|
} else {
|
|
1055
1268
|
if (el._pendingValue === NOT_PENDING) globalQueue._pendingNodes.push(el);
|
|
@@ -1154,6 +1367,8 @@ function isPending(fn) {
|
|
|
1154
1367
|
try {
|
|
1155
1368
|
fn();
|
|
1156
1369
|
return foundPending;
|
|
1370
|
+
} catch {
|
|
1371
|
+
return foundPending;
|
|
1157
1372
|
} finally {
|
|
1158
1373
|
pendingCheckActive = prevPendingCheck;
|
|
1159
1374
|
foundPending = prevFoundPending;
|
|
@@ -1226,25 +1441,27 @@ function effect(compute, effect, error, initialValue, options) {
|
|
|
1226
1441
|
node._errorFn = error;
|
|
1227
1442
|
node._cleanup = undefined;
|
|
1228
1443
|
node._type = options?.render ? EFFECT_RENDER : EFFECT_USER;
|
|
1229
|
-
node._notifyStatus = () => {
|
|
1230
|
-
|
|
1231
|
-
|
|
1444
|
+
node._notifyStatus = (status, error) => {
|
|
1445
|
+
const actualStatus = status !== undefined ? status : node._statusFlags;
|
|
1446
|
+
const actualError = error !== undefined ? error : node._error;
|
|
1447
|
+
if (actualStatus & STATUS_ERROR) {
|
|
1448
|
+
let err = actualError;
|
|
1232
1449
|
node._queue.notify(node, STATUS_PENDING, 0);
|
|
1233
1450
|
if (node._type === EFFECT_USER) {
|
|
1234
1451
|
try {
|
|
1235
1452
|
return node._errorFn
|
|
1236
|
-
? node._errorFn(
|
|
1453
|
+
? node._errorFn(err, () => {
|
|
1237
1454
|
node._cleanup?.();
|
|
1238
1455
|
node._cleanup = undefined;
|
|
1239
1456
|
})
|
|
1240
|
-
: console.error(
|
|
1457
|
+
: console.error(err);
|
|
1241
1458
|
} catch (e) {
|
|
1242
|
-
|
|
1459
|
+
err = e;
|
|
1243
1460
|
}
|
|
1244
1461
|
}
|
|
1245
|
-
if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) throw
|
|
1462
|
+
if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) throw err;
|
|
1246
1463
|
} else if (node._type === EFFECT_RENDER)
|
|
1247
|
-
node._queue.notify(node, STATUS_PENDING | STATUS_ERROR,
|
|
1464
|
+
node._queue.notify(node, STATUS_PENDING | STATUS_ERROR, actualStatus, actualError);
|
|
1248
1465
|
};
|
|
1249
1466
|
recompute(node, true);
|
|
1250
1467
|
!options?.defer &&
|
|
@@ -1992,18 +2209,27 @@ function clearOptimisticStore(store) {
|
|
|
1992
2209
|
if (!target || !target[STORE_OPTIMISTIC_OVERRIDE]) return;
|
|
1993
2210
|
const override = target[STORE_OPTIMISTIC_OVERRIDE];
|
|
1994
2211
|
const nodes = target[STORE_NODE];
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2212
|
+
setProjectionWriteActive(true);
|
|
2213
|
+
try {
|
|
2214
|
+
if (nodes) {
|
|
2215
|
+
for (const key of Reflect.ownKeys(override)) {
|
|
2216
|
+
if (nodes[key]) {
|
|
2217
|
+
nodes[key]._optimisticLane = undefined;
|
|
2218
|
+
const baseValue =
|
|
2219
|
+
target[STORE_OVERRIDE] && key in target[STORE_OVERRIDE]
|
|
2220
|
+
? target[STORE_OVERRIDE][key]
|
|
2221
|
+
: target[STORE_VALUE][key];
|
|
2222
|
+
const value = baseValue === $DELETED ? undefined : baseValue;
|
|
2223
|
+
setSignal(nodes[key], isWrappable(value) ? wrap(value, target) : value);
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
if (nodes[$TRACK]) {
|
|
2227
|
+
nodes[$TRACK]._optimisticLane = undefined;
|
|
2228
|
+
setSignal(nodes[$TRACK], undefined);
|
|
2004
2229
|
}
|
|
2005
2230
|
}
|
|
2006
|
-
|
|
2231
|
+
} finally {
|
|
2232
|
+
setProjectionWriteActive(false);
|
|
2007
2233
|
}
|
|
2008
2234
|
delete target[STORE_OPTIMISTIC_OVERRIDE];
|
|
2009
2235
|
}
|
|
@@ -2451,10 +2677,11 @@ function compare(key, a, b) {
|
|
|
2451
2677
|
}
|
|
2452
2678
|
function boundaryComputed(fn, propagationMask) {
|
|
2453
2679
|
const node = computed(fn, undefined, { lazy: true });
|
|
2454
|
-
node._notifyStatus = () => {
|
|
2455
|
-
const flags = node._statusFlags;
|
|
2680
|
+
node._notifyStatus = (status, error) => {
|
|
2681
|
+
const flags = status !== undefined ? status : node._statusFlags;
|
|
2682
|
+
const actualError = error !== undefined ? error : node._error;
|
|
2456
2683
|
node._statusFlags &= ~node._propagationMask;
|
|
2457
|
-
node._queue.notify(node, node._propagationMask, flags);
|
|
2684
|
+
node._queue.notify(node, node._propagationMask, flags, actualError);
|
|
2458
2685
|
};
|
|
2459
2686
|
node._propagationMask = propagationMask;
|
|
2460
2687
|
node._preventAutoDisposal = true;
|
|
@@ -2482,7 +2709,7 @@ class ConditionalQueue extends Queue {
|
|
|
2482
2709
|
if (!type || read(this._disabled)) return;
|
|
2483
2710
|
return super.run(type);
|
|
2484
2711
|
}
|
|
2485
|
-
notify(node, type, flags) {
|
|
2712
|
+
notify(node, type, flags, error) {
|
|
2486
2713
|
if (read(this._disabled)) {
|
|
2487
2714
|
if (type & STATUS_PENDING) {
|
|
2488
2715
|
if (flags & STATUS_PENDING) {
|
|
@@ -2497,12 +2724,12 @@ class ConditionalQueue extends Queue {
|
|
|
2497
2724
|
} else if (this._errorNodes.delete(node)) type &= ~STATUS_ERROR;
|
|
2498
2725
|
}
|
|
2499
2726
|
}
|
|
2500
|
-
return type ? super.notify(node, type, flags) : true;
|
|
2727
|
+
return type ? super.notify(node, type, flags, error ?? node._error) : true;
|
|
2501
2728
|
}
|
|
2502
2729
|
}
|
|
2503
2730
|
class CollectionQueue extends Queue {
|
|
2504
2731
|
_collectionType;
|
|
2505
|
-
|
|
2732
|
+
_sources = new Set();
|
|
2506
2733
|
_disabled = signal(false, { pureWrite: true });
|
|
2507
2734
|
_initialized = false;
|
|
2508
2735
|
constructor(type) {
|
|
@@ -2513,21 +2740,28 @@ class CollectionQueue extends Queue {
|
|
|
2513
2740
|
if (!type || read(this._disabled)) return;
|
|
2514
2741
|
return super.run(type);
|
|
2515
2742
|
}
|
|
2516
|
-
notify(node, type, flags) {
|
|
2743
|
+
notify(node, type, flags, error) {
|
|
2517
2744
|
if (
|
|
2518
2745
|
!(type & this._collectionType) ||
|
|
2519
2746
|
(this._collectionType & STATUS_PENDING && this._initialized)
|
|
2520
2747
|
)
|
|
2521
|
-
return super.notify(node, type, flags);
|
|
2748
|
+
return super.notify(node, type, flags, error);
|
|
2522
2749
|
if (flags & this._collectionType) {
|
|
2523
|
-
|
|
2524
|
-
if (
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2750
|
+
const source = error?._source || node._error?._source;
|
|
2751
|
+
if (source) {
|
|
2752
|
+
const wasEmpty = this._sources.size === 0;
|
|
2753
|
+
this._sources.add(source);
|
|
2754
|
+
if (wasEmpty) setSignal(this._disabled, true);
|
|
2755
|
+
}
|
|
2528
2756
|
}
|
|
2529
2757
|
type &= ~this._collectionType;
|
|
2530
|
-
return type ? super.notify(node, type, flags) : true;
|
|
2758
|
+
return type ? super.notify(node, type, flags, error) : true;
|
|
2759
|
+
}
|
|
2760
|
+
checkSources() {
|
|
2761
|
+
for (const source of this._sources) {
|
|
2762
|
+
if (!(source._statusFlags & this._collectionType)) this._sources.delete(source);
|
|
2763
|
+
}
|
|
2764
|
+
if (!this._sources.size) setSignal(this._disabled, false);
|
|
2531
2765
|
}
|
|
2532
2766
|
}
|
|
2533
2767
|
var BoundaryMode;
|
|
@@ -2543,8 +2777,12 @@ function createBoundary(fn, condition) {
|
|
|
2543
2777
|
const disabled = read(queue._disabled);
|
|
2544
2778
|
tree._propagationMask = disabled ? STATUS_ERROR | STATUS_PENDING : 0;
|
|
2545
2779
|
if (!disabled) {
|
|
2546
|
-
queue._pendingNodes.forEach(node =>
|
|
2547
|
-
|
|
2780
|
+
queue._pendingNodes.forEach(node =>
|
|
2781
|
+
queue.notify(node, STATUS_PENDING, STATUS_PENDING, node._error)
|
|
2782
|
+
);
|
|
2783
|
+
queue._errorNodes.forEach(node =>
|
|
2784
|
+
queue.notify(node, STATUS_ERROR, STATUS_ERROR, node._error)
|
|
2785
|
+
);
|
|
2548
2786
|
queue._pendingNodes.clear();
|
|
2549
2787
|
queue._errorNodes.clear();
|
|
2550
2788
|
}
|
|
@@ -2570,26 +2808,12 @@ function createCollectionBoundary(type, fn, fallback) {
|
|
|
2570
2808
|
function createLoadBoundary(fn, fallback) {
|
|
2571
2809
|
return createCollectionBoundary(STATUS_PENDING, fn, () => fallback());
|
|
2572
2810
|
}
|
|
2573
|
-
function collectErrorSources(node, sources) {
|
|
2574
|
-
let root = true;
|
|
2575
|
-
let dep = node._deps;
|
|
2576
|
-
while (dep !== null) {
|
|
2577
|
-
const source = dep._dep;
|
|
2578
|
-
if (source._deps && source._statusFlags & STATUS_ERROR) {
|
|
2579
|
-
root = false;
|
|
2580
|
-
collectErrorSources(source, sources);
|
|
2581
|
-
}
|
|
2582
|
-
dep = dep._nextDep;
|
|
2583
|
-
}
|
|
2584
|
-
root && sources.push(node);
|
|
2585
|
-
}
|
|
2586
2811
|
function createErrorBoundary(fn, fallback) {
|
|
2587
2812
|
return createCollectionBoundary(STATUS_ERROR, fn, queue => {
|
|
2588
|
-
let
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
for (const
|
|
2592
|
-
for (const source of sources) recompute(source);
|
|
2813
|
+
let source = queue._sources.values().next().value;
|
|
2814
|
+
const error = source._error?.cause ?? source._error;
|
|
2815
|
+
return fallback(error, () => {
|
|
2816
|
+
for (const source of queue._sources) recompute(source);
|
|
2593
2817
|
schedule();
|
|
2594
2818
|
});
|
|
2595
2819
|
});
|