@solidjs/signals 2.0.0-beta.8 → 2.0.0-beta.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 +172 -79
- package/dist/node.cjs +1091 -1043
- package/dist/prod.js +802 -752
- package/dist/types/boundaries.d.ts +35 -0
- package/dist/types/core/action.d.ts +34 -0
- package/dist/types/core/constants.d.ts +17 -0
- package/dist/types/core/core.d.ts +106 -7
- package/dist/types/core/dev.d.ts +1 -1
- package/dist/types/core/owner.d.ts +54 -3
- package/dist/types/core/scheduler.d.ts +18 -2
- package/dist/types/core/types.d.ts +2 -5
- package/dist/types/index.d.ts +1 -1
- package/dist/types/map.d.ts +32 -3
- package/dist/types/signals.d.ts +264 -11
- package/dist/types/store/optimistic.d.ts +38 -12
- package/dist/types/store/projection.d.ts +40 -14
- package/dist/types/store/reconcile.d.ts +22 -0
- package/dist/types/store/store.d.ts +64 -14
- package/dist/types/store/storePath.d.ts +28 -0
- package/dist/types/store/utils.d.ts +78 -7
- package/dist/types-cjs/boundaries.d.cts +35 -0
- package/dist/types-cjs/core/action.d.cts +34 -0
- package/dist/types-cjs/core/constants.d.cts +17 -0
- package/dist/types-cjs/core/core.d.cts +106 -7
- package/dist/types-cjs/core/dev.d.cts +1 -1
- package/dist/types-cjs/core/owner.d.cts +54 -3
- package/dist/types-cjs/core/scheduler.d.cts +18 -2
- package/dist/types-cjs/core/types.d.cts +2 -5
- package/dist/types-cjs/index.d.cts +1 -1
- package/dist/types-cjs/map.d.cts +32 -3
- package/dist/types-cjs/signals.d.cts +264 -11
- package/dist/types-cjs/store/optimistic.d.cts +38 -12
- package/dist/types-cjs/store/projection.d.cts +40 -14
- package/dist/types-cjs/store/reconcile.d.cts +22 -0
- package/dist/types-cjs/store/store.d.cts +64 -14
- package/dist/types-cjs/store/storePath.d.cts +28 -0
- package/dist/types-cjs/store/utils.d.cts +78 -7
- package/package.json +4 -3
package/dist/dev.js
CHANGED
|
@@ -35,6 +35,12 @@ const REACTIVE_DISPOSED = 1 << 6;
|
|
|
35
35
|
const REACTIVE_OPTIMISTIC_DIRTY = 1 << 7;
|
|
36
36
|
const REACTIVE_SNAPSHOT_STALE = 1 << 8;
|
|
37
37
|
const REACTIVE_LAZY = 1 << 9;
|
|
38
|
+
const CONFIG_OWNED_WRITE = 1 << 0;
|
|
39
|
+
const CONFIG_NO_SNAPSHOT = 1 << 1;
|
|
40
|
+
const CONFIG_TRANSPARENT = 1 << 2;
|
|
41
|
+
const CONFIG_IN_SNAPSHOT_SCOPE = 1 << 3;
|
|
42
|
+
const CONFIG_CHILDREN_FORBIDDEN = 1 << 4;
|
|
43
|
+
const CONFIG_AUTO_DISPOSE = 1 << 5;
|
|
38
44
|
const STATUS_PENDING = 1 << 0;
|
|
39
45
|
const STATUS_ERROR = 1 << 1;
|
|
40
46
|
const STATUS_UNINITIALIZED = 1 << 2;
|
|
@@ -309,6 +315,7 @@ function mergeTransitionState(target, outgoing) {
|
|
|
309
315
|
if (!targetReporters) target._asyncReporters.set(source, (targetReporters = new Set()));
|
|
310
316
|
for (const reporter of reporters) targetReporters.add(reporter);
|
|
311
317
|
}
|
|
318
|
+
for (const sub of outgoing._gatedSubs) target._gatedSubs.add(sub);
|
|
312
319
|
}
|
|
313
320
|
function resolveOptimisticNodes(nodes) {
|
|
314
321
|
for (let i = 0; i < nodes.length; i++) {
|
|
@@ -439,11 +446,15 @@ class GlobalQueue extends Queue {
|
|
|
439
446
|
scheduled = dirtyQueue._max >= dirtyQueue._min;
|
|
440
447
|
reassignPendingTransition(stashedTransition._pendingNodes);
|
|
441
448
|
activeTransition = null;
|
|
442
|
-
if (
|
|
449
|
+
if (
|
|
450
|
+
!stashedTransition._actions.length &&
|
|
451
|
+
!stashedTransition._asyncReporters.size &&
|
|
452
|
+
stashedTransition._optimisticNodes.length
|
|
453
|
+
) {
|
|
443
454
|
stashedOptimisticReads = new Set();
|
|
444
455
|
for (let i = 0; i < stashedTransition._optimisticNodes.length; i++) {
|
|
445
456
|
const node = stashedTransition._optimisticNodes[i];
|
|
446
|
-
if (node._fn || node.
|
|
457
|
+
if (node._fn || node._config & CONFIG_OWNED_WRITE) continue;
|
|
447
458
|
stashedOptimisticReads.add(node);
|
|
448
459
|
queueStashedOptimisticEffects(node);
|
|
449
460
|
}
|
|
@@ -509,7 +520,8 @@ class GlobalQueue extends Queue {
|
|
|
509
520
|
_optimisticStores: new Set(),
|
|
510
521
|
_actions: [],
|
|
511
522
|
_queueStash: { _queues: [[], []], _children: [] },
|
|
512
|
-
_done: false
|
|
523
|
+
_done: false,
|
|
524
|
+
_gatedSubs: new Set()
|
|
513
525
|
};
|
|
514
526
|
} else if (transition) {
|
|
515
527
|
const outgoing = activeTransition;
|
|
@@ -548,7 +560,7 @@ function insertSubs(node, optimistic = false) {
|
|
|
548
560
|
const sourceLane = node._optimisticLane || currentOptimisticLane;
|
|
549
561
|
const hasSnapshot = node._snapshotValue !== undefined;
|
|
550
562
|
for (let s = node._subs; s !== null; s = s._nextSub) {
|
|
551
|
-
if (hasSnapshot && s._sub.
|
|
563
|
+
if (hasSnapshot && s._sub._config & CONFIG_IN_SNAPSHOT_SCOPE) {
|
|
552
564
|
s._sub._flags |= REACTIVE_SNAPSHOT_STALE;
|
|
553
565
|
continue;
|
|
554
566
|
}
|
|
@@ -596,6 +608,22 @@ function finalizePureQueue(completingTransition = null, incomplete = false) {
|
|
|
596
608
|
resolveOptimisticNodes(
|
|
597
609
|
completingTransition ? completingTransition._optimisticNodes : globalQueue._optimisticNodes
|
|
598
610
|
);
|
|
611
|
+
if (completingTransition && completingTransition._gatedSubs.size) {
|
|
612
|
+
for (const sub of completingTransition._gatedSubs) {
|
|
613
|
+
if (sub._flags & REACTIVE_DISPOSED) continue;
|
|
614
|
+
if (sub._type === EFFECT_TRACKED) {
|
|
615
|
+
if (!sub._modified) {
|
|
616
|
+
sub._modified = true;
|
|
617
|
+
sub._queue.enqueue(EFFECT_USER, sub._run);
|
|
618
|
+
}
|
|
619
|
+
continue;
|
|
620
|
+
}
|
|
621
|
+
const queue = sub._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue;
|
|
622
|
+
if (queue._min > sub._height) queue._min = sub._height;
|
|
623
|
+
insertIntoHeap(sub, queue);
|
|
624
|
+
}
|
|
625
|
+
completingTransition._gatedSubs.clear();
|
|
626
|
+
}
|
|
599
627
|
const optimisticStores = completingTransition
|
|
600
628
|
? completingTransition._optimisticStores
|
|
601
629
|
: globalQueue._optimisticStores;
|
|
@@ -796,7 +824,8 @@ function unlinkSubs(link) {
|
|
|
796
824
|
dep._subs = nextSub;
|
|
797
825
|
if (nextSub === null) {
|
|
798
826
|
dep._unobserved?.();
|
|
799
|
-
|
|
827
|
+
const c = dep;
|
|
828
|
+
c._fn && c._config & CONFIG_AUTO_DISPOSE && !(c._flags & REACTIVE_ZOMBIE) && unobserved(c);
|
|
800
829
|
}
|
|
801
830
|
}
|
|
802
831
|
return nextDep;
|
|
@@ -913,7 +942,7 @@ function runDisposal(node, zombie) {
|
|
|
913
942
|
}
|
|
914
943
|
function childId(owner, consume) {
|
|
915
944
|
let counter = owner;
|
|
916
|
-
while (counter.
|
|
945
|
+
while (counter._config & CONFIG_TRANSPARENT && counter._parent) counter = counter._parent;
|
|
917
946
|
if (counter.id != null)
|
|
918
947
|
return formatId(counter.id, consume ? counter._childCount++ : counter._childCount);
|
|
919
948
|
throw new Error("Cannot get child id from owner without an id");
|
|
@@ -953,7 +982,7 @@ function createOwner(options) {
|
|
|
953
982
|
id:
|
|
954
983
|
options?.id ??
|
|
955
984
|
(transparent ? parent?.id : parent?.id != null ? getNextChildId(parent) : undefined),
|
|
956
|
-
|
|
985
|
+
_config: transparent ? CONFIG_TRANSPARENT : 0,
|
|
957
986
|
_root: true,
|
|
958
987
|
_parentComputed: parent?._root ? parent._parentComputed : parent,
|
|
959
988
|
_firstChild: null,
|
|
@@ -969,10 +998,16 @@ function createOwner(options) {
|
|
|
969
998
|
disposeChildren(owner, self);
|
|
970
999
|
}
|
|
971
1000
|
};
|
|
972
|
-
if (parent
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
1001
|
+
if (parent && parent._config & CONFIG_CHILDREN_FORBIDDEN) {
|
|
1002
|
+
emitDiagnostic({
|
|
1003
|
+
code: "PRIMITIVE_IN_FORBIDDEN_SCOPE",
|
|
1004
|
+
kind: "lifecycle",
|
|
1005
|
+
severity: "error",
|
|
1006
|
+
message: PRIMITIVE_IN_FORBIDDEN_SCOPE_MESSAGE,
|
|
1007
|
+
ownerId: parent.id,
|
|
1008
|
+
ownerName: parent._name
|
|
1009
|
+
});
|
|
1010
|
+
throw new Error(PRIMITIVE_IN_FORBIDDEN_SCOPE_MESSAGE);
|
|
976
1011
|
}
|
|
977
1012
|
if (parent) {
|
|
978
1013
|
const lastChild = parent._firstChild;
|
|
@@ -1299,6 +1334,8 @@ function enableExternalSource(config) {
|
|
|
1299
1334
|
}
|
|
1300
1335
|
GlobalQueue._update = recompute;
|
|
1301
1336
|
GlobalQueue._dispose = disposeChildren;
|
|
1337
|
+
const PRIMITIVE_IN_FORBIDDEN_SCOPE_MESSAGE =
|
|
1338
|
+
"[PRIMITIVE_IN_FORBIDDEN_SCOPE] Cannot create reactive primitives inside createTrackedEffect or owner-backed onSettled";
|
|
1302
1339
|
let tracking = false;
|
|
1303
1340
|
let stale = false;
|
|
1304
1341
|
let refreshing = false;
|
|
@@ -1337,7 +1374,7 @@ function releaseSubtree(owner) {
|
|
|
1337
1374
|
}
|
|
1338
1375
|
if (child._fn) {
|
|
1339
1376
|
const comp = child;
|
|
1340
|
-
comp.
|
|
1377
|
+
comp._config &= ~CONFIG_IN_SNAPSHOT_SCOPE;
|
|
1341
1378
|
if (comp._flags & REACTIVE_SNAPSHOT_STALE) {
|
|
1342
1379
|
comp._flags &= ~REACTIVE_SNAPSHOT_STALE;
|
|
1343
1380
|
comp._flags |= REACTIVE_DIRTY;
|
|
@@ -1377,7 +1414,7 @@ function recompute(el, create = false) {
|
|
|
1377
1414
|
clearSignals(el);
|
|
1378
1415
|
}
|
|
1379
1416
|
}
|
|
1380
|
-
|
|
1417
|
+
let isOptimisticDirty = !!(el._flags & REACTIVE_OPTIMISTIC_DIRTY);
|
|
1381
1418
|
const hasOverride = el._overrideValue !== undefined && el._overrideValue !== NOT_PENDING;
|
|
1382
1419
|
const wasPending = !!(el._statusFlags & STATUS_PENDING);
|
|
1383
1420
|
const wasUninitialized = !!(el._statusFlags & STATUS_UNINITIALIZED);
|
|
@@ -1399,6 +1436,20 @@ function recompute(el, create = false) {
|
|
|
1399
1436
|
if (isOptimisticDirty) {
|
|
1400
1437
|
const lane = resolveLane(el);
|
|
1401
1438
|
if (lane) currentOptimisticLane = lane;
|
|
1439
|
+
} else if (activeTransition && !create && activeTransition._optimisticNodes.length) {
|
|
1440
|
+
for (let d = el._deps; d; d = d._nextDep) {
|
|
1441
|
+
const dep = d._dep;
|
|
1442
|
+
if (dep._flags & REACTIVE_OPTIMISTIC_DIRTY) {
|
|
1443
|
+
const depLane = resolveLane(dep);
|
|
1444
|
+
if (depLane) {
|
|
1445
|
+
isOptimisticDirty = true;
|
|
1446
|
+
currentOptimisticLane = depLane;
|
|
1447
|
+
el._flags |= REACTIVE_OPTIMISTIC_DIRTY;
|
|
1448
|
+
assignOrMergeLane(el, depLane);
|
|
1449
|
+
break;
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1402
1453
|
}
|
|
1403
1454
|
try {
|
|
1404
1455
|
const prevInFlight = el._inFlight;
|
|
@@ -1508,9 +1559,12 @@ function computed(fn, options) {
|
|
|
1508
1559
|
id:
|
|
1509
1560
|
options?.id ??
|
|
1510
1561
|
(transparent ? context?.id : context?.id != null ? getNextChildId(context) : undefined),
|
|
1511
|
-
|
|
1562
|
+
_config:
|
|
1563
|
+
(transparent ? CONFIG_TRANSPARENT : 0) |
|
|
1564
|
+
(options?.ownedWrite ? CONFIG_OWNED_WRITE : 0) |
|
|
1565
|
+
(!context || options?.lazy ? CONFIG_AUTO_DISPOSE : 0) |
|
|
1566
|
+
(snapshotCaptureActive && ownerInSnapshotScope(context) ? CONFIG_IN_SNAPSHOT_SCOPE : 0),
|
|
1512
1567
|
_equals: options?.equals != null ? options.equals : isEqual,
|
|
1513
|
-
_ownedWrite: !!options?.ownedWrite,
|
|
1514
1568
|
_unobserved: options?.unobserved,
|
|
1515
1569
|
_disposal: null,
|
|
1516
1570
|
_queue: context?._queue ?? globalQueue,
|
|
@@ -1541,10 +1595,16 @@ function computed(fn, options) {
|
|
|
1541
1595
|
self._name = options?.name ?? "computed";
|
|
1542
1596
|
self._prevHeap = self;
|
|
1543
1597
|
const parent = context?._root ? context._parentComputed : context;
|
|
1544
|
-
if (context
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1598
|
+
if (context && context._config & CONFIG_CHILDREN_FORBIDDEN) {
|
|
1599
|
+
emitDiagnostic({
|
|
1600
|
+
code: "PRIMITIVE_IN_FORBIDDEN_SCOPE",
|
|
1601
|
+
kind: "lifecycle",
|
|
1602
|
+
severity: "error",
|
|
1603
|
+
message: PRIMITIVE_IN_FORBIDDEN_SCOPE_MESSAGE,
|
|
1604
|
+
ownerId: context.id,
|
|
1605
|
+
ownerName: context._name
|
|
1606
|
+
});
|
|
1607
|
+
throw new Error(PRIMITIVE_IN_FORBIDDEN_SCOPE_MESSAGE);
|
|
1548
1608
|
}
|
|
1549
1609
|
if (context) {
|
|
1550
1610
|
const lastChild = context._firstChild;
|
|
@@ -1557,7 +1617,6 @@ function computed(fn, options) {
|
|
|
1557
1617
|
}
|
|
1558
1618
|
DEV$1.hooks.onOwner?.(self);
|
|
1559
1619
|
if (parent) self._height = parent._height + 1;
|
|
1560
|
-
if (snapshotCaptureActive && ownerInSnapshotScope(context)) self._inSnapshotScope = true;
|
|
1561
1620
|
if (externalSourceConfig) {
|
|
1562
1621
|
const bridgeSignal = signal(undefined, { equals: false, ownedWrite: true });
|
|
1563
1622
|
const source = externalSourceConfig.factory(self._fn, () => {
|
|
@@ -1581,8 +1640,9 @@ function computed(fn, options) {
|
|
|
1581
1640
|
function signal(v, options, firewall = null) {
|
|
1582
1641
|
const s = {
|
|
1583
1642
|
_equals: options?.equals != null ? options.equals : isEqual,
|
|
1584
|
-
|
|
1585
|
-
|
|
1643
|
+
_config:
|
|
1644
|
+
(options?.ownedWrite ? CONFIG_OWNED_WRITE : 0) |
|
|
1645
|
+
(options?._noSnapshot ? CONFIG_NO_SNAPSHOT : 0),
|
|
1586
1646
|
_unobserved: options?.unobserved,
|
|
1587
1647
|
_value: v,
|
|
1588
1648
|
_subs: null,
|
|
@@ -1599,7 +1659,7 @@ function signal(v, options, firewall = null) {
|
|
|
1599
1659
|
firewall && (firewall._child = s);
|
|
1600
1660
|
if (
|
|
1601
1661
|
snapshotCaptureActive &&
|
|
1602
|
-
!s.
|
|
1662
|
+
!(s._config & CONFIG_NO_SNAPSHOT) &&
|
|
1603
1663
|
!((firewall?._statusFlags ?? 0) & STATUS_PENDING)
|
|
1604
1664
|
) {
|
|
1605
1665
|
s._snapshotValue = v === undefined ? NO_SNAPSHOT : v;
|
|
@@ -1707,7 +1767,7 @@ function read(el) {
|
|
|
1707
1767
|
const owner = el._firewall || el;
|
|
1708
1768
|
if (strictRead && owner._statusFlags & STATUS_PENDING) {
|
|
1709
1769
|
const message =
|
|
1710
|
-
`Reading a pending async value directly in ${strictRead}. ` +
|
|
1770
|
+
`[PENDING_ASYNC_UNTRACKED_READ] Reading a pending async value directly in ${strictRead}. ` +
|
|
1711
1771
|
`Async values must be read within a tracking scope (JSX, a memo, or an effect's compute function).`;
|
|
1712
1772
|
emitDiagnostic({
|
|
1713
1773
|
code: "PENDING_ASYNC_UNTRACKED_READ",
|
|
@@ -1738,9 +1798,9 @@ function read(el) {
|
|
|
1738
1798
|
}
|
|
1739
1799
|
if (owner._statusFlags & STATUS_PENDING) {
|
|
1740
1800
|
if (c && !(stale && owner._transition && activeTransition !== owner._transition)) {
|
|
1741
|
-
if (c
|
|
1801
|
+
if (c && c._config & CONFIG_CHILDREN_FORBIDDEN) {
|
|
1742
1802
|
const message =
|
|
1743
|
-
"Reading a pending async value inside createTrackedEffect or onSettled will throw. " +
|
|
1803
|
+
"[PENDING_ASYNC_FORBIDDEN_SCOPE] Reading a pending async value inside createTrackedEffect or onSettled will throw. " +
|
|
1744
1804
|
"Use createEffect instead which supports async-aware reactivity.";
|
|
1745
1805
|
emitDiagnostic({
|
|
1746
1806
|
code: "PENDING_ASYNC_FORBIDDEN_SCOPE",
|
|
@@ -1777,7 +1837,7 @@ function read(el) {
|
|
|
1777
1837
|
return read(el);
|
|
1778
1838
|
} else throw el._error;
|
|
1779
1839
|
}
|
|
1780
|
-
if (snapshotCaptureActive && c && c.
|
|
1840
|
+
if (snapshotCaptureActive && c && c._config & CONFIG_IN_SNAPSHOT_SCOPE) {
|
|
1781
1841
|
const sv = el._snapshotValue;
|
|
1782
1842
|
if (sv !== undefined) {
|
|
1783
1843
|
const snapshot = sv === NO_SNAPSHOT ? undefined : sv;
|
|
@@ -1788,7 +1848,7 @@ function read(el) {
|
|
|
1788
1848
|
}
|
|
1789
1849
|
if (strictRead) {
|
|
1790
1850
|
const message =
|
|
1791
|
-
`Reactive value read directly in ${strictRead} will not update. ` +
|
|
1851
|
+
`[STRICT_READ_UNTRACKED] Reactive value read directly in ${strictRead} will not update. ` +
|
|
1792
1852
|
`Move it into a tracking scope (JSX, a memo, or an effect's compute function).`;
|
|
1793
1853
|
emitDiagnostic({
|
|
1794
1854
|
code: "STRICT_READ_UNTRACKED",
|
|
@@ -1806,6 +1866,18 @@ function read(el) {
|
|
|
1806
1866
|
if (c && stale && shouldReadStashedOptimisticValue(el)) return el._value;
|
|
1807
1867
|
return el._overrideValue;
|
|
1808
1868
|
}
|
|
1869
|
+
if (
|
|
1870
|
+
activeTransition !== null &&
|
|
1871
|
+
currentOptimisticLane !== null &&
|
|
1872
|
+
!latestReadActive &&
|
|
1873
|
+
el._pendingValue !== NOT_PENDING &&
|
|
1874
|
+
owner === el &&
|
|
1875
|
+
!el._fn &&
|
|
1876
|
+
c
|
|
1877
|
+
) {
|
|
1878
|
+
activeTransition._gatedSubs.add(c);
|
|
1879
|
+
return el._value;
|
|
1880
|
+
}
|
|
1809
1881
|
const value =
|
|
1810
1882
|
!c ||
|
|
1811
1883
|
(currentOptimisticLane !== null &&
|
|
@@ -1821,9 +1893,8 @@ function read(el) {
|
|
|
1821
1893
|
!c &&
|
|
1822
1894
|
owner === el &&
|
|
1823
1895
|
typeof computed._fn === "function" &&
|
|
1824
|
-
|
|
1896
|
+
el._config & CONFIG_AUTO_DISPOSE &&
|
|
1825
1897
|
!(owner._statusFlags & STATUS_PENDING) &&
|
|
1826
|
-
!computed._parent &&
|
|
1827
1898
|
!el._subs
|
|
1828
1899
|
) {
|
|
1829
1900
|
unobserved(el);
|
|
@@ -1831,9 +1902,14 @@ function read(el) {
|
|
|
1831
1902
|
return value;
|
|
1832
1903
|
}
|
|
1833
1904
|
function setSignal(el, v) {
|
|
1834
|
-
if (
|
|
1905
|
+
if (
|
|
1906
|
+
!(el._config & CONFIG_OWNED_WRITE) &&
|
|
1907
|
+
!(context && context._config & CONFIG_CHILDREN_FORBIDDEN) &&
|
|
1908
|
+
context &&
|
|
1909
|
+
el._firewall !== context
|
|
1910
|
+
) {
|
|
1835
1911
|
const message =
|
|
1836
|
-
"Writing to a Signal inside an owned scope (component, computation) is not allowed. " +
|
|
1912
|
+
"[SIGNAL_WRITE_IN_OWNED_SCOPE] Writing to a Signal inside an owned scope (component, computation) is not allowed. " +
|
|
1837
1913
|
"Move the write outside or set the `ownedWrite` option if this is intentional.";
|
|
1838
1914
|
emitDiagnostic({
|
|
1839
1915
|
code: "SIGNAL_WRITE_IN_OWNED_SCOPE",
|
|
@@ -1894,7 +1970,7 @@ function setSignal(el, v) {
|
|
|
1894
1970
|
function runWithOwner(owner, fn) {
|
|
1895
1971
|
if (owner && owner._flags & REACTIVE_DISPOSED) {
|
|
1896
1972
|
const message =
|
|
1897
|
-
"runWithOwner called with a disposed owner. Children created inside will never be disposed.";
|
|
1973
|
+
"[RUN_WITH_DISPOSED_OWNER] runWithOwner called with a disposed owner. Children created inside will never be disposed.";
|
|
1898
1974
|
emitDiagnostic({
|
|
1899
1975
|
code: "RUN_WITH_DISPOSED_OWNER",
|
|
1900
1976
|
kind: "owner",
|
|
@@ -2073,6 +2149,7 @@ function effect(compute, effect, error, options) {
|
|
|
2073
2149
|
},
|
|
2074
2150
|
lazy: true
|
|
2075
2151
|
});
|
|
2152
|
+
node._config &= ~CONFIG_AUTO_DISPOSE;
|
|
2076
2153
|
node._prevValue = undefined;
|
|
2077
2154
|
node._effectFn = effect;
|
|
2078
2155
|
node._errorFn = error;
|
|
@@ -2103,7 +2180,7 @@ function effect(compute, effect, error, options) {
|
|
|
2103
2180
|
resetUnhandledAsync();
|
|
2104
2181
|
if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) {
|
|
2105
2182
|
const message =
|
|
2106
|
-
"An async value was read outside a Loading boundary. The root mount will be deferred until all pending async settles.";
|
|
2183
|
+
"[ASYNC_OUTSIDE_LOADING_BOUNDARY] An async value was read outside a Loading boundary. The root mount will be deferred until all pending async settles.";
|
|
2107
2184
|
emitDiagnostic({
|
|
2108
2185
|
code: "ASYNC_OUTSIDE_LOADING_BOUNDARY",
|
|
2109
2186
|
kind: "async",
|
|
@@ -2125,7 +2202,8 @@ function effect(compute, effect, error, options) {
|
|
|
2125
2202
|
initialized = true;
|
|
2126
2203
|
cleanup(() => node._cleanup?.());
|
|
2127
2204
|
if (!node._parent) {
|
|
2128
|
-
const message =
|
|
2205
|
+
const message =
|
|
2206
|
+
"[NO_OWNER_EFFECT] Effects created outside a reactive context will never be disposed";
|
|
2129
2207
|
emitDiagnostic({
|
|
2130
2208
|
code: "NO_OWNER_EFFECT",
|
|
2131
2209
|
kind: "lifecycle",
|
|
@@ -2190,7 +2268,7 @@ function trackedEffect(fn, options) {
|
|
|
2190
2268
|
{ ...options, lazy: true }
|
|
2191
2269
|
);
|
|
2192
2270
|
node._cleanup = undefined;
|
|
2193
|
-
node.
|
|
2271
|
+
node._config = (node._config & ~CONFIG_AUTO_DISPOSE) | CONFIG_CHILDREN_FORBIDDEN;
|
|
2194
2272
|
node._modified = true;
|
|
2195
2273
|
node._type = EFFECT_TRACKED;
|
|
2196
2274
|
node._notifyStatus = (status, error) => {
|
|
@@ -2205,7 +2283,8 @@ function trackedEffect(fn, options) {
|
|
|
2205
2283
|
node._queue.enqueue(EFFECT_USER, run);
|
|
2206
2284
|
cleanup(() => node._cleanup?.());
|
|
2207
2285
|
if (!node._parent) {
|
|
2208
|
-
const message =
|
|
2286
|
+
const message =
|
|
2287
|
+
"[NO_OWNER_EFFECT] Effects created outside a reactive context will never be disposed";
|
|
2209
2288
|
emitDiagnostic({
|
|
2210
2289
|
code: "NO_OWNER_EFFECT",
|
|
2211
2290
|
kind: "lifecycle",
|
|
@@ -2266,7 +2345,8 @@ function onCleanup(fn) {
|
|
|
2266
2345
|
{
|
|
2267
2346
|
const owner = getOwner();
|
|
2268
2347
|
if (!owner) {
|
|
2269
|
-
const message =
|
|
2348
|
+
const message =
|
|
2349
|
+
"[NO_OWNER_CLEANUP] onCleanup called outside a reactive context will never be run";
|
|
2270
2350
|
emitDiagnostic({
|
|
2271
2351
|
code: "NO_OWNER_CLEANUP",
|
|
2272
2352
|
kind: "lifecycle",
|
|
@@ -2274,9 +2354,9 @@ function onCleanup(fn) {
|
|
|
2274
2354
|
message: message
|
|
2275
2355
|
});
|
|
2276
2356
|
console.warn(message);
|
|
2277
|
-
} else if (owner.
|
|
2357
|
+
} else if (owner._config & CONFIG_CHILDREN_FORBIDDEN) {
|
|
2278
2358
|
const message =
|
|
2279
|
-
"Cannot use onCleanup inside createTrackedEffect or onSettled; return a cleanup function instead";
|
|
2359
|
+
"[CLEANUP_IN_FORBIDDEN_SCOPE] Cannot use onCleanup inside createTrackedEffect or onSettled; return a cleanup function instead";
|
|
2280
2360
|
emitDiagnostic({
|
|
2281
2361
|
code: "CLEANUP_IN_FORBIDDEN_SCOPE",
|
|
2282
2362
|
kind: "lifecycle",
|
|
@@ -2291,14 +2371,12 @@ function onCleanup(fn) {
|
|
|
2291
2371
|
return cleanup(fn);
|
|
2292
2372
|
}
|
|
2293
2373
|
function accessor(node) {
|
|
2294
|
-
|
|
2295
|
-
fn.$r = true;
|
|
2296
|
-
return fn;
|
|
2374
|
+
return read.bind(null, node);
|
|
2297
2375
|
}
|
|
2298
2376
|
function createSignal(first, second) {
|
|
2299
2377
|
if (typeof first === "function") {
|
|
2300
2378
|
const node = computed(first, second);
|
|
2301
|
-
node.
|
|
2379
|
+
node._config &= ~CONFIG_AUTO_DISPOSE;
|
|
2302
2380
|
return [accessor(node), setSignal.bind(null, node)];
|
|
2303
2381
|
}
|
|
2304
2382
|
const node = signal(first, second);
|
|
@@ -2306,10 +2384,23 @@ function createSignal(first, second) {
|
|
|
2306
2384
|
return [accessor(node), setSignal.bind(null, node)];
|
|
2307
2385
|
}
|
|
2308
2386
|
function createMemo(compute, options) {
|
|
2309
|
-
|
|
2310
|
-
return accessor(node);
|
|
2387
|
+
return accessor(computed(compute, options));
|
|
2311
2388
|
}
|
|
2312
2389
|
function createEffect(compute, effectFn, options) {
|
|
2390
|
+
if (effectFn === undefined) {
|
|
2391
|
+
const message =
|
|
2392
|
+
"[MISSING_EFFECT_FN] createEffect requires both a compute function and an effect function. " +
|
|
2393
|
+
"Use `createEffect(() => signal(), value => doWork(value))`. " +
|
|
2394
|
+
"If you want a derived value, use `createMemo`. " +
|
|
2395
|
+
"If you want a one-shot side effect, just call the function directly.";
|
|
2396
|
+
emitDiagnostic({
|
|
2397
|
+
code: "MISSING_EFFECT_FN",
|
|
2398
|
+
kind: "lifecycle",
|
|
2399
|
+
severity: "error",
|
|
2400
|
+
message: message
|
|
2401
|
+
});
|
|
2402
|
+
throw new Error(message);
|
|
2403
|
+
}
|
|
2313
2404
|
effect(compute, effectFn.effect || effectFn, effectFn.error, {
|
|
2314
2405
|
user: true,
|
|
2315
2406
|
...{ ...options, name: options?.name ?? "effect" }
|
|
@@ -2373,7 +2464,7 @@ function resolve(fn) {
|
|
|
2373
2464
|
function createOptimistic(first, second) {
|
|
2374
2465
|
if (typeof first === "function") {
|
|
2375
2466
|
const node = optimisticComputed(first, second);
|
|
2376
|
-
node.
|
|
2467
|
+
node._config &= ~CONFIG_AUTO_DISPOSE;
|
|
2377
2468
|
return [accessor(node), setSignal.bind(null, node)];
|
|
2378
2469
|
}
|
|
2379
2470
|
const node = optimisticSignal(first, second);
|
|
@@ -2382,7 +2473,7 @@ function createOptimistic(first, second) {
|
|
|
2382
2473
|
}
|
|
2383
2474
|
function onSettled(callback) {
|
|
2384
2475
|
const owner = getOwner();
|
|
2385
|
-
owner && !owner.
|
|
2476
|
+
owner && !(owner._config & CONFIG_CHILDREN_FORBIDDEN)
|
|
2386
2477
|
? createTrackedEffect(() => untrack(callback), { name: "onSettled" })
|
|
2387
2478
|
: globalQueue.enqueue(EFFECT_USER, () => {
|
|
2388
2479
|
const cleanup = callback();
|
|
@@ -2567,7 +2658,7 @@ function createProjectionInternal(fn, seed, options) {
|
|
|
2567
2658
|
},
|
|
2568
2659
|
options?.name ? { name: options.name } : undefined
|
|
2569
2660
|
);
|
|
2570
|
-
node.
|
|
2661
|
+
node._config &= ~CONFIG_AUTO_DISPOSE;
|
|
2571
2662
|
return { store: wrappedStore, node: node };
|
|
2572
2663
|
}
|
|
2573
2664
|
function createProjection(fn, seed, options) {
|
|
@@ -2895,7 +2986,7 @@ const storeTraps = {
|
|
|
2895
2986
|
}
|
|
2896
2987
|
if (strictRead && typeof property === "string") {
|
|
2897
2988
|
const message =
|
|
2898
|
-
`Reactive value read directly in ${strictRead} will not update. ` +
|
|
2989
|
+
`[STRICT_READ_UNTRACKED] Reactive value read directly in ${strictRead} will not update. ` +
|
|
2899
2990
|
`Move it into a tracking scope (JSX, a memo, or an effect's compute function).`;
|
|
2900
2991
|
emitDiagnostic({
|
|
2901
2992
|
code: "STRICT_READ_UNTRACKED",
|
|
@@ -3188,7 +3279,7 @@ function createOptimisticProjectionInternal(fn, initialValue, options) {
|
|
|
3188
3279
|
},
|
|
3189
3280
|
options?.name ? { name: options.name } : undefined
|
|
3190
3281
|
);
|
|
3191
|
-
node.
|
|
3282
|
+
node._config &= ~CONFIG_AUTO_DISPOSE;
|
|
3192
3283
|
}
|
|
3193
3284
|
return { store: wrappedStore, node: node };
|
|
3194
3285
|
}
|
|
@@ -3465,22 +3556,22 @@ function mapArray(list, map, options) {
|
|
|
3465
3556
|
}
|
|
3466
3557
|
}
|
|
3467
3558
|
: map;
|
|
3468
|
-
const
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
node.
|
|
3559
|
+
const data = {
|
|
3560
|
+
_owner: createOwner(),
|
|
3561
|
+
_len: 0,
|
|
3562
|
+
_list: list,
|
|
3563
|
+
_items: [],
|
|
3564
|
+
_map: wrappedMap,
|
|
3565
|
+
_mappings: [],
|
|
3566
|
+
_nodes: [],
|
|
3567
|
+
_key: keyFn,
|
|
3568
|
+
_rows: keyFn || options?.keyed === false ? [] : undefined,
|
|
3569
|
+
_indexes: indexes ? [] : undefined,
|
|
3570
|
+
_fallback: options?.fallback
|
|
3571
|
+
};
|
|
3572
|
+
const node = computed(updateKeyedMap.bind(data));
|
|
3573
|
+
data._owner._parentComputed = node;
|
|
3574
|
+
node._config &= ~CONFIG_AUTO_DISPOSE;
|
|
3484
3575
|
return accessor(node);
|
|
3485
3576
|
}
|
|
3486
3577
|
const pureOptions = { ownedWrite: true };
|
|
@@ -3633,7 +3724,7 @@ function repeat(count, map, options) {
|
|
|
3633
3724
|
_fallback: options?.fallback
|
|
3634
3725
|
})
|
|
3635
3726
|
);
|
|
3636
|
-
node.
|
|
3727
|
+
node._config &= ~CONFIG_AUTO_DISPOSE;
|
|
3637
3728
|
return accessor(node);
|
|
3638
3729
|
}
|
|
3639
3730
|
function updateRepeat() {
|
|
@@ -3699,7 +3790,7 @@ function boundaryComputed(fn, propagationMask) {
|
|
|
3699
3790
|
node._queue.notify(node, node._propagationMask, flags, actualError);
|
|
3700
3791
|
};
|
|
3701
3792
|
node._propagationMask = propagationMask;
|
|
3702
|
-
node.
|
|
3793
|
+
node._config &= ~CONFIG_AUTO_DISPOSE;
|
|
3703
3794
|
recompute(node, true);
|
|
3704
3795
|
return node;
|
|
3705
3796
|
}
|
|
@@ -3938,7 +4029,8 @@ class CollectionQueue extends Queue {
|
|
|
3938
4029
|
}
|
|
3939
4030
|
function createCollectionBoundary(type, fn, fallback, onFn) {
|
|
3940
4031
|
if (!getOwner()) {
|
|
3941
|
-
const message =
|
|
4032
|
+
const message =
|
|
4033
|
+
"[NO_OWNER_BOUNDARY] Boundaries created outside a reactive context will never be disposed.";
|
|
3942
4034
|
emitDiagnostic({
|
|
3943
4035
|
code: "NO_OWNER_BOUNDARY",
|
|
3944
4036
|
kind: "lifecycle",
|
|
@@ -3971,15 +4063,16 @@ function createCollectionBoundary(type, fn, fallback, onFn) {
|
|
|
3971
4063
|
controller.register(queue);
|
|
3972
4064
|
cleanup(() => controller.unregister(queue));
|
|
3973
4065
|
}
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
4066
|
+
return accessor(
|
|
4067
|
+
computed(() => {
|
|
4068
|
+
if (!read(queue._disabled)) {
|
|
4069
|
+
const resolved = read(tree);
|
|
4070
|
+
if (!untrack(() => read(queue._disabled))) return ((queue._initialized = true), resolved);
|
|
4071
|
+
}
|
|
4072
|
+
if (_revealUsed && read(queue._collapsed)) return undefined;
|
|
4073
|
+
return fallback(queue);
|
|
4074
|
+
})
|
|
4075
|
+
);
|
|
3983
4076
|
}
|
|
3984
4077
|
function createLoadingBoundary(fn, fallback, options) {
|
|
3985
4078
|
return createCollectionBoundary(STATUS_PENDING, fn, () => fallback(), options?.on);
|