@solidjs/signals 0.13.4 → 0.13.6
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 +137 -80
- package/dist/node.cjs +519 -478
- package/dist/prod.js +394 -353
- package/dist/types/core/index.d.ts +1 -1
- package/dist/types/core/owner.d.ts +1 -1
- package/dist/types/core/scheduler.d.ts +5 -5
- package/dist/types/index.d.ts +2 -2
- package/dist/types/signals.d.ts +2 -0
- package/dist/types/store/projection.d.ts +1 -0
- package/package.json +1 -1
package/dist/dev.js
CHANGED
|
@@ -151,6 +151,7 @@ let clock = 0;
|
|
|
151
151
|
let activeTransition = null;
|
|
152
152
|
let scheduled = false;
|
|
153
153
|
let projectionWriteActive = false;
|
|
154
|
+
let inTrackedQueueCallback = false;
|
|
154
155
|
let _enforceLoadingBoundary = false;
|
|
155
156
|
let _hitUnhandledAsync = false;
|
|
156
157
|
let stashedOptimisticReads = null;
|
|
@@ -192,6 +193,9 @@ function queueStashedOptimisticEffects(node) {
|
|
|
192
193
|
function setProjectionWriteActive(value) {
|
|
193
194
|
projectionWriteActive = value;
|
|
194
195
|
}
|
|
196
|
+
function setTrackedQueueCallback(value) {
|
|
197
|
+
inTrackedQueueCallback = value;
|
|
198
|
+
}
|
|
195
199
|
function mergeTransitionState(target, outgoing) {
|
|
196
200
|
outgoing._done = target;
|
|
197
201
|
target._actions.push(...outgoing._actions);
|
|
@@ -242,20 +246,6 @@ function schedule() {
|
|
|
242
246
|
scheduled = true;
|
|
243
247
|
if (!globalQueue._running && !projectionWriteActive) queueMicrotask(flush);
|
|
244
248
|
}
|
|
245
|
-
function addTransitionBlocker(node) {
|
|
246
|
-
if (activeTransition && !activeTransition._asyncNodes.includes(node)) {
|
|
247
|
-
activeTransition._asyncNodes.push(node);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
function removeTransitionBlocker(node) {
|
|
251
|
-
const remove = list => {
|
|
252
|
-
if (!list) return;
|
|
253
|
-
const index = list.indexOf(node);
|
|
254
|
-
if (index >= 0) list.splice(index, 1);
|
|
255
|
-
};
|
|
256
|
-
remove(node._transition?._asyncNodes);
|
|
257
|
-
remove(activeTransition?._asyncNodes);
|
|
258
|
-
}
|
|
259
249
|
class Queue {
|
|
260
250
|
_parent = null;
|
|
261
251
|
_queues = [[], []];
|
|
@@ -532,6 +522,14 @@ function reassignPendingTransition(pendingNodes) {
|
|
|
532
522
|
}
|
|
533
523
|
const globalQueue = new GlobalQueue();
|
|
534
524
|
function flush() {
|
|
525
|
+
if (globalQueue._running) {
|
|
526
|
+
if (inTrackedQueueCallback) {
|
|
527
|
+
throw new Error(
|
|
528
|
+
"Cannot call flush() from inside onSettled or createTrackedEffect. flush() is not reentrant there."
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
535
533
|
let count = 0;
|
|
536
534
|
while (scheduled || activeTransition) {
|
|
537
535
|
if (++count === 1e5) throw new Error("Potential Infinite Loop Detected.");
|
|
@@ -552,6 +550,21 @@ function transitionComplete(transition) {
|
|
|
552
550
|
break;
|
|
553
551
|
}
|
|
554
552
|
}
|
|
553
|
+
if (done) {
|
|
554
|
+
for (let i = 0; i < transition._optimisticNodes.length; i++) {
|
|
555
|
+
const node = transition._optimisticNodes[i];
|
|
556
|
+
if (
|
|
557
|
+
hasActiveOverride(node) &&
|
|
558
|
+
"_statusFlags" in node &&
|
|
559
|
+
node._statusFlags & STATUS_PENDING &&
|
|
560
|
+
node._error instanceof NotReadyError &&
|
|
561
|
+
node._error.source !== node
|
|
562
|
+
) {
|
|
563
|
+
done = false;
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
555
568
|
done && (transition._done = true);
|
|
556
569
|
return done;
|
|
557
570
|
}
|
|
@@ -843,7 +856,6 @@ function handleAsync(el, result, setter) {
|
|
|
843
856
|
}
|
|
844
857
|
function clearStatus(el, clearUninitialized = false) {
|
|
845
858
|
clearPendingSources(el);
|
|
846
|
-
removeTransitionBlocker(el);
|
|
847
859
|
el._blocked = false;
|
|
848
860
|
el._statusFlags = clearUninitialized ? 0 : el._statusFlags & STATUS_UNINITIALIZED;
|
|
849
861
|
setPendingError(el);
|
|
@@ -867,11 +879,9 @@ function notifyStatus(el, status, error, blockStatus, lane) {
|
|
|
867
879
|
if (status === STATUS_PENDING && pendingSource) {
|
|
868
880
|
addPendingSource(el, pendingSource);
|
|
869
881
|
el._statusFlags = STATUS_PENDING | (el._statusFlags & STATUS_UNINITIALIZED);
|
|
870
|
-
setPendingError(el,
|
|
871
|
-
if (pendingSource === el) addTransitionBlocker(el);
|
|
882
|
+
setPendingError(el, pendingSource, error);
|
|
872
883
|
} else {
|
|
873
884
|
clearPendingSources(el);
|
|
874
|
-
removeTransitionBlocker(el);
|
|
875
885
|
el._statusFlags =
|
|
876
886
|
status | (status !== STATUS_ERROR ? el._statusFlags & STATUS_UNINITIALIZED : 0);
|
|
877
887
|
el._error = error;
|
|
@@ -884,6 +894,9 @@ function notifyStatus(el, status, error, blockStatus, lane) {
|
|
|
884
894
|
const downstreamBlockStatus = blockStatus || startsBlocking;
|
|
885
895
|
const downstreamLane = blockStatus || isOptimisticBoundary ? undefined : lane;
|
|
886
896
|
if (el._notifyStatus) {
|
|
897
|
+
if (blockStatus && status === STATUS_PENDING) {
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
887
900
|
if (downstreamBlockStatus) {
|
|
888
901
|
el._notifyStatus(status, error);
|
|
889
902
|
} else {
|
|
@@ -901,7 +914,7 @@ function notifyStatus(el, status, error, blockStatus, lane) {
|
|
|
901
914
|
(status !== STATUS_PENDING &&
|
|
902
915
|
(sub._error !== error || sub._pendingSource || sub._pendingSources))
|
|
903
916
|
) {
|
|
904
|
-
!sub._transition
|
|
917
|
+
if (!downstreamBlockStatus && !sub._transition) globalQueue._pendingNodes.push(sub);
|
|
905
918
|
notifyStatus(sub, status, error, downstreamBlockStatus, downstreamLane);
|
|
906
919
|
}
|
|
907
920
|
});
|
|
@@ -1016,16 +1029,8 @@ function getObserver() {
|
|
|
1016
1029
|
function getOwner() {
|
|
1017
1030
|
return context;
|
|
1018
1031
|
}
|
|
1019
|
-
function
|
|
1020
|
-
if (!context)
|
|
1021
|
-
console.warn("onCleanup called outside a reactive context will never be run");
|
|
1022
|
-
return fn;
|
|
1023
|
-
}
|
|
1024
|
-
if (context._childrenForbidden) {
|
|
1025
|
-
throw new Error(
|
|
1026
|
-
"Cannot use onCleanup inside createTrackedEffect or onSettled; return a cleanup function instead"
|
|
1027
|
-
);
|
|
1028
|
-
}
|
|
1032
|
+
function cleanup(fn) {
|
|
1033
|
+
if (!context) return fn;
|
|
1029
1034
|
if (!context._disposal) context._disposal = fn;
|
|
1030
1035
|
else if (Array.isArray(context._disposal)) context._disposal.push(fn);
|
|
1031
1036
|
else context._disposal = [context._disposal, fn];
|
|
@@ -1398,7 +1403,7 @@ function computed(fn, initialValue, options) {
|
|
|
1398
1403
|
const source = externalSourceConfig.factory(self._fn, () => {
|
|
1399
1404
|
setSignal(bridgeSignal, undefined);
|
|
1400
1405
|
});
|
|
1401
|
-
|
|
1406
|
+
cleanup(() => source.dispose());
|
|
1402
1407
|
self._fn = prev => {
|
|
1403
1408
|
read(bridgeSignal);
|
|
1404
1409
|
return source.track(prev);
|
|
@@ -1504,8 +1509,17 @@ function read(el) {
|
|
|
1504
1509
|
const firewall = el._firewall;
|
|
1505
1510
|
const prevCheck = pendingCheckActive;
|
|
1506
1511
|
pendingCheckActive = false;
|
|
1507
|
-
if (
|
|
1508
|
-
|
|
1512
|
+
if (firewall && el._overrideValue !== undefined) {
|
|
1513
|
+
if (
|
|
1514
|
+
el._overrideValue !== NOT_PENDING &&
|
|
1515
|
+
(firewall._inFlight || !!(firewall._statusFlags & STATUS_PENDING))
|
|
1516
|
+
) {
|
|
1517
|
+
foundPending = true;
|
|
1518
|
+
}
|
|
1519
|
+
} else {
|
|
1520
|
+
if (read(getPendingSignal(el))) foundPending = true;
|
|
1521
|
+
if (firewall && read(getPendingSignal(firewall))) foundPending = true;
|
|
1522
|
+
}
|
|
1509
1523
|
pendingCheckActive = prevCheck;
|
|
1510
1524
|
return el._value;
|
|
1511
1525
|
}
|
|
@@ -1558,6 +1572,9 @@ function read(el) {
|
|
|
1558
1572
|
if (!tracking && el !== c) link(el, c);
|
|
1559
1573
|
throw owner._error;
|
|
1560
1574
|
}
|
|
1575
|
+
} else if (c && owner !== el && owner._statusFlags & STATUS_UNINITIALIZED) {
|
|
1576
|
+
if (!tracking && el !== c) link(el, c);
|
|
1577
|
+
throw owner._error;
|
|
1561
1578
|
} else if (!c && owner._statusFlags & STATUS_UNINITIALIZED) {
|
|
1562
1579
|
throw owner._error;
|
|
1563
1580
|
}
|
|
@@ -1686,6 +1703,9 @@ function computePendingState(el) {
|
|
|
1686
1703
|
}
|
|
1687
1704
|
return true;
|
|
1688
1705
|
}
|
|
1706
|
+
if (el._overrideValue !== undefined && el._overrideValue === NOT_PENDING && !el._parentSource) {
|
|
1707
|
+
return false;
|
|
1708
|
+
}
|
|
1689
1709
|
if (el._pendingValue !== NOT_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED)) return true;
|
|
1690
1710
|
return !!(comp._statusFlags & STATUS_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED));
|
|
1691
1711
|
}
|
|
@@ -1857,7 +1877,7 @@ function effect(compute, effect, error, initialValue, options) {
|
|
|
1857
1877
|
? node._queue.enqueue(node._type, runEffect.bind(node))
|
|
1858
1878
|
: runEffect.call(node));
|
|
1859
1879
|
initialized = true;
|
|
1860
|
-
|
|
1880
|
+
cleanup(() => node._cleanup?.());
|
|
1861
1881
|
if (!node._parent)
|
|
1862
1882
|
console.warn("Effects created outside a reactive context will never be disposed");
|
|
1863
1883
|
}
|
|
@@ -1884,8 +1904,13 @@ function runEffect() {
|
|
|
1884
1904
|
function trackedEffect(fn, options) {
|
|
1885
1905
|
const run = () => {
|
|
1886
1906
|
if (!node._modified || node._flags & REACTIVE_DISPOSED) return;
|
|
1887
|
-
|
|
1888
|
-
|
|
1907
|
+
setTrackedQueueCallback(true);
|
|
1908
|
+
try {
|
|
1909
|
+
node._modified = false;
|
|
1910
|
+
recompute(node);
|
|
1911
|
+
} finally {
|
|
1912
|
+
setTrackedQueueCallback(false);
|
|
1913
|
+
}
|
|
1889
1914
|
};
|
|
1890
1915
|
const node = computed(
|
|
1891
1916
|
() => {
|
|
@@ -1910,7 +1935,7 @@ function trackedEffect(fn, options) {
|
|
|
1910
1935
|
};
|
|
1911
1936
|
node._run = run;
|
|
1912
1937
|
node._queue.enqueue(EFFECT_USER, run);
|
|
1913
|
-
|
|
1938
|
+
cleanup(() => node._cleanup?.());
|
|
1914
1939
|
if (!node._parent)
|
|
1915
1940
|
console.warn("Effects created outside a reactive context will never be disposed");
|
|
1916
1941
|
}
|
|
@@ -1958,6 +1983,17 @@ function action(genFn) {
|
|
|
1958
1983
|
step();
|
|
1959
1984
|
});
|
|
1960
1985
|
}
|
|
1986
|
+
function onCleanup(fn) {
|
|
1987
|
+
{
|
|
1988
|
+
const owner = getOwner();
|
|
1989
|
+
if (!owner) console.warn("onCleanup called outside a reactive context will never be run");
|
|
1990
|
+
else if (owner._childrenForbidden)
|
|
1991
|
+
throw new Error(
|
|
1992
|
+
"Cannot use onCleanup inside createTrackedEffect or onSettled; return a cleanup function instead"
|
|
1993
|
+
);
|
|
1994
|
+
}
|
|
1995
|
+
return cleanup(fn);
|
|
1996
|
+
}
|
|
1961
1997
|
function accessor(node) {
|
|
1962
1998
|
const fn = read.bind(null, node);
|
|
1963
1999
|
fn.$r = true;
|
|
@@ -1991,16 +2027,16 @@ function createTrackedEffect(compute, options) {
|
|
|
1991
2027
|
trackedEffect(compute, { ...options, name: options?.name ?? "trackedEffect" });
|
|
1992
2028
|
}
|
|
1993
2029
|
function createReaction(effectFn, options) {
|
|
1994
|
-
let
|
|
1995
|
-
|
|
2030
|
+
let cl = undefined;
|
|
2031
|
+
cleanup(() => cl?.());
|
|
1996
2032
|
const owner = getOwner();
|
|
1997
2033
|
return tracking => {
|
|
1998
2034
|
runWithOwner(owner, () => {
|
|
1999
2035
|
effect(
|
|
2000
2036
|
() => (tracking(), getOwner()),
|
|
2001
2037
|
node => {
|
|
2002
|
-
|
|
2003
|
-
|
|
2038
|
+
cl?.();
|
|
2039
|
+
cl = (effectFn.effect || effectFn)?.();
|
|
2004
2040
|
dispose(node);
|
|
2005
2041
|
},
|
|
2006
2042
|
effectFn.error,
|
|
@@ -2214,8 +2250,16 @@ function createProjectionInternal(fn, initialValue = {}, options) {
|
|
|
2214
2250
|
const wrappedStore = wrapProjection(initialValue);
|
|
2215
2251
|
node = computed(() => {
|
|
2216
2252
|
const owner = getOwner();
|
|
2217
|
-
|
|
2218
|
-
|
|
2253
|
+
let settled = false;
|
|
2254
|
+
let result;
|
|
2255
|
+
const draft = new Proxy(
|
|
2256
|
+
wrappedStore,
|
|
2257
|
+
createWriteTraps(() => !settled || owner._inFlight === result)
|
|
2258
|
+
);
|
|
2259
|
+
storeSetter(draft, s => {
|
|
2260
|
+
result = fn(s);
|
|
2261
|
+
settled = true;
|
|
2262
|
+
const value = handleAsync(owner, result, value => {
|
|
2219
2263
|
value !== s &&
|
|
2220
2264
|
value !== undefined &&
|
|
2221
2265
|
storeSetter(wrappedStore, reconcile(value, options?.key || "id"));
|
|
@@ -2229,42 +2273,47 @@ function createProjectionInternal(fn, initialValue = {}, options) {
|
|
|
2229
2273
|
function createProjection(fn, initialValue = {}, options) {
|
|
2230
2274
|
return createProjectionInternal(fn, initialValue, options).store;
|
|
2231
2275
|
}
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2276
|
+
function createWriteTraps(isActive) {
|
|
2277
|
+
const traps = {
|
|
2278
|
+
get(_, prop) {
|
|
2279
|
+
let value;
|
|
2280
|
+
setWriteOverride(true);
|
|
2281
|
+
setProjectionWriteActive(true);
|
|
2282
|
+
try {
|
|
2283
|
+
value = _[prop];
|
|
2284
|
+
} finally {
|
|
2285
|
+
setWriteOverride(false);
|
|
2286
|
+
setProjectionWriteActive(false);
|
|
2287
|
+
}
|
|
2288
|
+
return typeof value === "object" && value !== null ? new Proxy(value, traps) : value;
|
|
2289
|
+
},
|
|
2290
|
+
set(_, prop, value) {
|
|
2291
|
+
if (isActive && !isActive()) return true;
|
|
2292
|
+
setWriteOverride(true);
|
|
2293
|
+
setProjectionWriteActive(true);
|
|
2294
|
+
try {
|
|
2295
|
+
_[prop] = value;
|
|
2296
|
+
} finally {
|
|
2297
|
+
setWriteOverride(false);
|
|
2298
|
+
setProjectionWriteActive(false);
|
|
2299
|
+
}
|
|
2300
|
+
return true;
|
|
2301
|
+
},
|
|
2302
|
+
deleteProperty(_, prop) {
|
|
2303
|
+
if (isActive && !isActive()) return true;
|
|
2304
|
+
setWriteOverride(true);
|
|
2305
|
+
setProjectionWriteActive(true);
|
|
2306
|
+
try {
|
|
2307
|
+
delete _[prop];
|
|
2308
|
+
} finally {
|
|
2309
|
+
setWriteOverride(false);
|
|
2310
|
+
setProjectionWriteActive(false);
|
|
2311
|
+
}
|
|
2312
|
+
return true;
|
|
2264
2313
|
}
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
}
|
|
2314
|
+
};
|
|
2315
|
+
return traps;
|
|
2316
|
+
}
|
|
2268
2317
|
const $TRACK = Symbol("STORE_TRACK"),
|
|
2269
2318
|
$TARGET = Symbol("STORE_TARGET"),
|
|
2270
2319
|
$PROXY = Symbol("STORE_PROXY"),
|
|
@@ -2674,10 +2723,18 @@ function createOptimisticProjectionInternal(fn, initialValue = {}, options) {
|
|
|
2674
2723
|
if (fn) {
|
|
2675
2724
|
node = computed(() => {
|
|
2676
2725
|
const owner = getOwner();
|
|
2726
|
+
let settled = false;
|
|
2727
|
+
let result;
|
|
2728
|
+
const draft = new Proxy(
|
|
2729
|
+
wrappedStore,
|
|
2730
|
+
createWriteTraps(() => !settled || owner._inFlight === result)
|
|
2731
|
+
);
|
|
2677
2732
|
setProjectionWriteActive(true);
|
|
2678
2733
|
try {
|
|
2679
|
-
storeSetter(
|
|
2680
|
-
|
|
2734
|
+
storeSetter(draft, s => {
|
|
2735
|
+
result = fn(s);
|
|
2736
|
+
settled = true;
|
|
2737
|
+
const value = handleAsync(owner, result, value => {
|
|
2681
2738
|
setProjectionWriteActive(true);
|
|
2682
2739
|
try {
|
|
2683
2740
|
value !== s &&
|
|
@@ -3202,7 +3259,7 @@ function boundaryComputed(fn, propagationMask) {
|
|
|
3202
3259
|
function createBoundChildren(owner, fn, queue, mask) {
|
|
3203
3260
|
const parentQueue = owner._queue;
|
|
3204
3261
|
parentQueue.addChild((owner._queue = queue));
|
|
3205
|
-
|
|
3262
|
+
cleanup(() => parentQueue.removeChild(owner._queue));
|
|
3206
3263
|
return runWithOwner(owner, () => {
|
|
3207
3264
|
const c = computed(fn);
|
|
3208
3265
|
return boundaryComputed(() => staleValues(() => flatten(read(c))), mask);
|