@solidjs/signals 0.13.5 → 0.13.7
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 +297 -228
- package/dist/node.cjs +497 -457
- package/dist/prod.js +605 -565
- package/dist/types/core/scheduler.d.ts +5 -5
- 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
|
}
|
|
@@ -642,6 +655,209 @@ function assignOrMergeLane(el, sourceLane) {
|
|
|
642
655
|
}
|
|
643
656
|
el._optimisticLane = sourceLane;
|
|
644
657
|
}
|
|
658
|
+
function unlinkSubs(link) {
|
|
659
|
+
const dep = link._dep;
|
|
660
|
+
const nextDep = link._nextDep;
|
|
661
|
+
const nextSub = link._nextSub;
|
|
662
|
+
const prevSub = link._prevSub;
|
|
663
|
+
if (nextSub !== null) nextSub._prevSub = prevSub;
|
|
664
|
+
else dep._subsTail = prevSub;
|
|
665
|
+
if (prevSub !== null) prevSub._nextSub = nextSub;
|
|
666
|
+
else {
|
|
667
|
+
dep._subs = nextSub;
|
|
668
|
+
if (nextSub === null) {
|
|
669
|
+
dep._unobserved?.();
|
|
670
|
+
dep._fn && !dep._preventAutoDisposal && !(dep._flags & REACTIVE_ZOMBIE) && unobserved(dep);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
return nextDep;
|
|
674
|
+
}
|
|
675
|
+
function unobserved(el) {
|
|
676
|
+
deleteFromHeap(el, el._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
677
|
+
let dep = el._deps;
|
|
678
|
+
while (dep !== null) {
|
|
679
|
+
dep = unlinkSubs(dep);
|
|
680
|
+
}
|
|
681
|
+
el._deps = null;
|
|
682
|
+
disposeChildren(el, true);
|
|
683
|
+
}
|
|
684
|
+
function link(dep, sub) {
|
|
685
|
+
const prevDep = sub._depsTail;
|
|
686
|
+
if (prevDep !== null && prevDep._dep === dep) return;
|
|
687
|
+
let nextDep = null;
|
|
688
|
+
const isRecomputing = sub._flags & REACTIVE_RECOMPUTING_DEPS;
|
|
689
|
+
if (isRecomputing) {
|
|
690
|
+
nextDep = prevDep !== null ? prevDep._nextDep : sub._deps;
|
|
691
|
+
if (nextDep !== null && nextDep._dep === dep) {
|
|
692
|
+
sub._depsTail = nextDep;
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
const prevSub = dep._subsTail;
|
|
697
|
+
if (prevSub !== null && prevSub._sub === sub && (!isRecomputing || isValidLink(prevSub, sub)))
|
|
698
|
+
return;
|
|
699
|
+
const newLink =
|
|
700
|
+
(sub._depsTail =
|
|
701
|
+
dep._subsTail =
|
|
702
|
+
{ _dep: dep, _sub: sub, _nextDep: nextDep, _prevSub: prevSub, _nextSub: null });
|
|
703
|
+
if (prevDep !== null) prevDep._nextDep = newLink;
|
|
704
|
+
else sub._deps = newLink;
|
|
705
|
+
if (prevSub !== null) prevSub._nextSub = newLink;
|
|
706
|
+
else dep._subs = newLink;
|
|
707
|
+
}
|
|
708
|
+
function isValidLink(checkLink, sub) {
|
|
709
|
+
const depsTail = sub._depsTail;
|
|
710
|
+
if (depsTail !== null) {
|
|
711
|
+
let link = sub._deps;
|
|
712
|
+
do {
|
|
713
|
+
if (link === checkLink) return true;
|
|
714
|
+
if (link === depsTail) break;
|
|
715
|
+
link = link._nextDep;
|
|
716
|
+
} while (link !== null);
|
|
717
|
+
}
|
|
718
|
+
return false;
|
|
719
|
+
}
|
|
720
|
+
const PENDING_OWNER = {};
|
|
721
|
+
function markDisposal(el) {
|
|
722
|
+
let child = el._firstChild;
|
|
723
|
+
while (child) {
|
|
724
|
+
child._flags |= REACTIVE_ZOMBIE;
|
|
725
|
+
if (child._flags & REACTIVE_IN_HEAP) {
|
|
726
|
+
deleteFromHeap(child, dirtyQueue);
|
|
727
|
+
insertIntoHeap(child, zombieQueue);
|
|
728
|
+
}
|
|
729
|
+
markDisposal(child);
|
|
730
|
+
child = child._nextSibling;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
function dispose(node) {
|
|
734
|
+
let toRemove = node._deps || null;
|
|
735
|
+
do {
|
|
736
|
+
toRemove = unlinkSubs(toRemove);
|
|
737
|
+
} while (toRemove !== null);
|
|
738
|
+
node._deps = null;
|
|
739
|
+
node._depsTail = null;
|
|
740
|
+
disposeChildren(node, true);
|
|
741
|
+
}
|
|
742
|
+
function disposeChildren(node, self = false, zombie) {
|
|
743
|
+
if (node._flags & REACTIVE_DISPOSED) return;
|
|
744
|
+
if (self) node._flags = REACTIVE_DISPOSED;
|
|
745
|
+
if (self && node._fn) node._inFlight = null;
|
|
746
|
+
let child = zombie ? node._pendingFirstChild : node._firstChild;
|
|
747
|
+
while (child) {
|
|
748
|
+
const nextChild = child._nextSibling;
|
|
749
|
+
if (child._deps) {
|
|
750
|
+
const n = child;
|
|
751
|
+
deleteFromHeap(n, n._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
752
|
+
let toRemove = n._deps;
|
|
753
|
+
do {
|
|
754
|
+
toRemove = unlinkSubs(toRemove);
|
|
755
|
+
} while (toRemove !== null);
|
|
756
|
+
n._deps = null;
|
|
757
|
+
n._depsTail = null;
|
|
758
|
+
}
|
|
759
|
+
disposeChildren(child, true);
|
|
760
|
+
child = nextChild;
|
|
761
|
+
}
|
|
762
|
+
if (zombie) {
|
|
763
|
+
node._pendingFirstChild = null;
|
|
764
|
+
} else {
|
|
765
|
+
node._firstChild = null;
|
|
766
|
+
node._childCount = 0;
|
|
767
|
+
}
|
|
768
|
+
runDisposal(node, zombie);
|
|
769
|
+
}
|
|
770
|
+
function runDisposal(node, zombie) {
|
|
771
|
+
let disposal = zombie ? node._pendingDisposal : node._disposal;
|
|
772
|
+
if (!disposal) return;
|
|
773
|
+
if (Array.isArray(disposal)) {
|
|
774
|
+
for (let i = 0; i < disposal.length; i++) {
|
|
775
|
+
const callable = disposal[i];
|
|
776
|
+
callable.call(callable);
|
|
777
|
+
}
|
|
778
|
+
} else {
|
|
779
|
+
disposal.call(disposal);
|
|
780
|
+
}
|
|
781
|
+
zombie ? (node._pendingDisposal = null) : (node._disposal = null);
|
|
782
|
+
}
|
|
783
|
+
function childId(owner, consume) {
|
|
784
|
+
let counter = owner;
|
|
785
|
+
while (counter._transparent && counter._parent) counter = counter._parent;
|
|
786
|
+
if (counter.id != null)
|
|
787
|
+
return formatId(counter.id, consume ? counter._childCount++ : counter._childCount);
|
|
788
|
+
throw new Error("Cannot get child id from owner without an id");
|
|
789
|
+
}
|
|
790
|
+
function getNextChildId(owner) {
|
|
791
|
+
return childId(owner, true);
|
|
792
|
+
}
|
|
793
|
+
function peekNextChildId(owner) {
|
|
794
|
+
return childId(owner, false);
|
|
795
|
+
}
|
|
796
|
+
function formatId(prefix, id) {
|
|
797
|
+
const num = id.toString(36),
|
|
798
|
+
len = num.length - 1;
|
|
799
|
+
return prefix + (len ? String.fromCharCode(64 + len) : "") + num;
|
|
800
|
+
}
|
|
801
|
+
function getObserver() {
|
|
802
|
+
if (pendingCheckActive || latestReadActive) return PENDING_OWNER;
|
|
803
|
+
return tracking ? context : null;
|
|
804
|
+
}
|
|
805
|
+
function getOwner() {
|
|
806
|
+
return context;
|
|
807
|
+
}
|
|
808
|
+
function cleanup(fn) {
|
|
809
|
+
if (!context) return fn;
|
|
810
|
+
if (!context._disposal) context._disposal = fn;
|
|
811
|
+
else if (Array.isArray(context._disposal)) context._disposal.push(fn);
|
|
812
|
+
else context._disposal = [context._disposal, fn];
|
|
813
|
+
return fn;
|
|
814
|
+
}
|
|
815
|
+
function isDisposed(node) {
|
|
816
|
+
return !!(node._flags & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE));
|
|
817
|
+
}
|
|
818
|
+
function createOwner(options) {
|
|
819
|
+
const parent = context;
|
|
820
|
+
const transparent = options?.transparent ?? false;
|
|
821
|
+
const owner = {
|
|
822
|
+
id:
|
|
823
|
+
options?.id ??
|
|
824
|
+
(transparent ? parent?.id : parent?.id != null ? getNextChildId(parent) : undefined),
|
|
825
|
+
_transparent: transparent || undefined,
|
|
826
|
+
_root: true,
|
|
827
|
+
_parentComputed: parent?._root ? parent._parentComputed : parent,
|
|
828
|
+
_firstChild: null,
|
|
829
|
+
_nextSibling: null,
|
|
830
|
+
_disposal: null,
|
|
831
|
+
_queue: parent?._queue ?? globalQueue,
|
|
832
|
+
_context: parent?._context || defaultContext,
|
|
833
|
+
_childCount: 0,
|
|
834
|
+
_pendingDisposal: null,
|
|
835
|
+
_pendingFirstChild: null,
|
|
836
|
+
_parent: parent,
|
|
837
|
+
dispose(self = true) {
|
|
838
|
+
disposeChildren(owner, self);
|
|
839
|
+
}
|
|
840
|
+
};
|
|
841
|
+
if (parent?._childrenForbidden) {
|
|
842
|
+
throw new Error(
|
|
843
|
+
"Cannot create reactive primitives inside createTrackedEffect or owner-backed onSettled"
|
|
844
|
+
);
|
|
845
|
+
}
|
|
846
|
+
if (parent) {
|
|
847
|
+
const lastChild = parent._firstChild;
|
|
848
|
+
if (lastChild === null) {
|
|
849
|
+
parent._firstChild = owner;
|
|
850
|
+
} else {
|
|
851
|
+
owner._nextSibling = lastChild;
|
|
852
|
+
parent._firstChild = owner;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
return owner;
|
|
856
|
+
}
|
|
857
|
+
function createRoot(init, options) {
|
|
858
|
+
const owner = createOwner(options);
|
|
859
|
+
return runWithOwner(owner, () => init(owner.dispose));
|
|
860
|
+
}
|
|
645
861
|
function addPendingSource(el, source) {
|
|
646
862
|
if (el._pendingSource === source || el._pendingSources?.has(source)) return false;
|
|
647
863
|
if (!el._pendingSource) {
|
|
@@ -806,6 +1022,17 @@ function handleAsync(el, result, setter) {
|
|
|
806
1022
|
if (iterator) {
|
|
807
1023
|
const it = result[Symbol.asyncIterator]();
|
|
808
1024
|
let hadSyncValue = false;
|
|
1025
|
+
let completed = false;
|
|
1026
|
+
cleanup(() => {
|
|
1027
|
+
if (completed) return;
|
|
1028
|
+
completed = true;
|
|
1029
|
+
try {
|
|
1030
|
+
const returned = it.return?.();
|
|
1031
|
+
if (returned && typeof returned.then === "function") {
|
|
1032
|
+
returned.then(undefined, () => {});
|
|
1033
|
+
}
|
|
1034
|
+
} catch {}
|
|
1035
|
+
});
|
|
809
1036
|
const iterate = () => {
|
|
810
1037
|
let syncResult,
|
|
811
1038
|
resolved = false,
|
|
@@ -815,14 +1042,21 @@ function handleAsync(el, result, setter) {
|
|
|
815
1042
|
if (isSync) {
|
|
816
1043
|
syncResult = r;
|
|
817
1044
|
resolved = true;
|
|
1045
|
+
if (r.done) completed = true;
|
|
1046
|
+
} else if (el._inFlight !== result) {
|
|
1047
|
+
return;
|
|
818
1048
|
} else if (!r.done) asyncWrite(r.value, iterate);
|
|
819
1049
|
else {
|
|
1050
|
+
completed = true;
|
|
820
1051
|
schedule();
|
|
821
1052
|
flush();
|
|
822
1053
|
}
|
|
823
1054
|
},
|
|
824
1055
|
e => {
|
|
825
|
-
if (!isSync)
|
|
1056
|
+
if (!isSync && el._inFlight === result) {
|
|
1057
|
+
completed = true;
|
|
1058
|
+
handleError(e);
|
|
1059
|
+
}
|
|
826
1060
|
}
|
|
827
1061
|
);
|
|
828
1062
|
isSync = false;
|
|
@@ -843,7 +1077,6 @@ function handleAsync(el, result, setter) {
|
|
|
843
1077
|
}
|
|
844
1078
|
function clearStatus(el, clearUninitialized = false) {
|
|
845
1079
|
clearPendingSources(el);
|
|
846
|
-
removeTransitionBlocker(el);
|
|
847
1080
|
el._blocked = false;
|
|
848
1081
|
el._statusFlags = clearUninitialized ? 0 : el._statusFlags & STATUS_UNINITIALIZED;
|
|
849
1082
|
setPendingError(el);
|
|
@@ -867,11 +1100,9 @@ function notifyStatus(el, status, error, blockStatus, lane) {
|
|
|
867
1100
|
if (status === STATUS_PENDING && pendingSource) {
|
|
868
1101
|
addPendingSource(el, pendingSource);
|
|
869
1102
|
el._statusFlags = STATUS_PENDING | (el._statusFlags & STATUS_UNINITIALIZED);
|
|
870
|
-
setPendingError(el,
|
|
871
|
-
if (pendingSource === el) addTransitionBlocker(el);
|
|
1103
|
+
setPendingError(el, pendingSource, error);
|
|
872
1104
|
} else {
|
|
873
1105
|
clearPendingSources(el);
|
|
874
|
-
removeTransitionBlocker(el);
|
|
875
1106
|
el._statusFlags =
|
|
876
1107
|
status | (status !== STATUS_ERROR ? el._statusFlags & STATUS_UNINITIALIZED : 0);
|
|
877
1108
|
el._error = error;
|
|
@@ -884,6 +1115,9 @@ function notifyStatus(el, status, error, blockStatus, lane) {
|
|
|
884
1115
|
const downstreamBlockStatus = blockStatus || startsBlocking;
|
|
885
1116
|
const downstreamLane = blockStatus || isOptimisticBoundary ? undefined : lane;
|
|
886
1117
|
if (el._notifyStatus) {
|
|
1118
|
+
if (blockStatus && status === STATUS_PENDING) {
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
887
1121
|
if (downstreamBlockStatus) {
|
|
888
1122
|
el._notifyStatus(status, error);
|
|
889
1123
|
} else {
|
|
@@ -901,7 +1135,7 @@ function notifyStatus(el, status, error, blockStatus, lane) {
|
|
|
901
1135
|
(status !== STATUS_PENDING &&
|
|
902
1136
|
(sub._error !== error || sub._pendingSource || sub._pendingSources))
|
|
903
1137
|
) {
|
|
904
|
-
!sub._transition
|
|
1138
|
+
if (!downstreamBlockStatus && !sub._transition) globalQueue._pendingNodes.push(sub);
|
|
905
1139
|
notifyStatus(sub, status, error, downstreamBlockStatus, downstreamLane);
|
|
906
1140
|
}
|
|
907
1141
|
});
|
|
@@ -929,208 +1163,6 @@ function enableExternalSource(config) {
|
|
|
929
1163
|
externalSourceConfig = { factory: factory, untrack: untrackFn };
|
|
930
1164
|
}
|
|
931
1165
|
}
|
|
932
|
-
const PENDING_OWNER = {};
|
|
933
|
-
function markDisposal(el) {
|
|
934
|
-
let child = el._firstChild;
|
|
935
|
-
while (child) {
|
|
936
|
-
child._flags |= REACTIVE_ZOMBIE;
|
|
937
|
-
if (child._flags & REACTIVE_IN_HEAP) {
|
|
938
|
-
deleteFromHeap(child, dirtyQueue);
|
|
939
|
-
insertIntoHeap(child, zombieQueue);
|
|
940
|
-
}
|
|
941
|
-
markDisposal(child);
|
|
942
|
-
child = child._nextSibling;
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
function dispose(node) {
|
|
946
|
-
let toRemove = node._deps || null;
|
|
947
|
-
do {
|
|
948
|
-
toRemove = unlinkSubs(toRemove);
|
|
949
|
-
} while (toRemove !== null);
|
|
950
|
-
node._deps = null;
|
|
951
|
-
node._depsTail = null;
|
|
952
|
-
disposeChildren(node, true);
|
|
953
|
-
}
|
|
954
|
-
function disposeChildren(node, self = false, zombie) {
|
|
955
|
-
if (node._flags & REACTIVE_DISPOSED) return;
|
|
956
|
-
if (self) node._flags = REACTIVE_DISPOSED;
|
|
957
|
-
let child = zombie ? node._pendingFirstChild : node._firstChild;
|
|
958
|
-
while (child) {
|
|
959
|
-
const nextChild = child._nextSibling;
|
|
960
|
-
if (child._deps) {
|
|
961
|
-
const n = child;
|
|
962
|
-
deleteFromHeap(n, n._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
963
|
-
let toRemove = n._deps;
|
|
964
|
-
do {
|
|
965
|
-
toRemove = unlinkSubs(toRemove);
|
|
966
|
-
} while (toRemove !== null);
|
|
967
|
-
n._deps = null;
|
|
968
|
-
n._depsTail = null;
|
|
969
|
-
}
|
|
970
|
-
disposeChildren(child, true);
|
|
971
|
-
child = nextChild;
|
|
972
|
-
}
|
|
973
|
-
if (zombie) {
|
|
974
|
-
node._pendingFirstChild = null;
|
|
975
|
-
} else {
|
|
976
|
-
node._firstChild = null;
|
|
977
|
-
node._childCount = 0;
|
|
978
|
-
}
|
|
979
|
-
runDisposal(node, zombie);
|
|
980
|
-
}
|
|
981
|
-
function runDisposal(node, zombie) {
|
|
982
|
-
let disposal = zombie ? node._pendingDisposal : node._disposal;
|
|
983
|
-
if (!disposal) return;
|
|
984
|
-
if (Array.isArray(disposal)) {
|
|
985
|
-
for (let i = 0; i < disposal.length; i++) {
|
|
986
|
-
const callable = disposal[i];
|
|
987
|
-
callable.call(callable);
|
|
988
|
-
}
|
|
989
|
-
} else {
|
|
990
|
-
disposal.call(disposal);
|
|
991
|
-
}
|
|
992
|
-
zombie ? (node._pendingDisposal = null) : (node._disposal = null);
|
|
993
|
-
}
|
|
994
|
-
function childId(owner, consume) {
|
|
995
|
-
let counter = owner;
|
|
996
|
-
while (counter._transparent && counter._parent) counter = counter._parent;
|
|
997
|
-
if (counter.id != null)
|
|
998
|
-
return formatId(counter.id, consume ? counter._childCount++ : counter._childCount);
|
|
999
|
-
throw new Error("Cannot get child id from owner without an id");
|
|
1000
|
-
}
|
|
1001
|
-
function getNextChildId(owner) {
|
|
1002
|
-
return childId(owner, true);
|
|
1003
|
-
}
|
|
1004
|
-
function peekNextChildId(owner) {
|
|
1005
|
-
return childId(owner, false);
|
|
1006
|
-
}
|
|
1007
|
-
function formatId(prefix, id) {
|
|
1008
|
-
const num = id.toString(36),
|
|
1009
|
-
len = num.length - 1;
|
|
1010
|
-
return prefix + (len ? String.fromCharCode(64 + len) : "") + num;
|
|
1011
|
-
}
|
|
1012
|
-
function getObserver() {
|
|
1013
|
-
if (pendingCheckActive || latestReadActive) return PENDING_OWNER;
|
|
1014
|
-
return tracking ? context : null;
|
|
1015
|
-
}
|
|
1016
|
-
function getOwner() {
|
|
1017
|
-
return context;
|
|
1018
|
-
}
|
|
1019
|
-
function cleanup(fn) {
|
|
1020
|
-
if (!context) return fn;
|
|
1021
|
-
if (!context._disposal) context._disposal = fn;
|
|
1022
|
-
else if (Array.isArray(context._disposal)) context._disposal.push(fn);
|
|
1023
|
-
else context._disposal = [context._disposal, fn];
|
|
1024
|
-
return fn;
|
|
1025
|
-
}
|
|
1026
|
-
function isDisposed(node) {
|
|
1027
|
-
return !!(node._flags & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE));
|
|
1028
|
-
}
|
|
1029
|
-
function createOwner(options) {
|
|
1030
|
-
const parent = context;
|
|
1031
|
-
const transparent = options?.transparent ?? false;
|
|
1032
|
-
const owner = {
|
|
1033
|
-
id:
|
|
1034
|
-
options?.id ??
|
|
1035
|
-
(transparent ? parent?.id : parent?.id != null ? getNextChildId(parent) : undefined),
|
|
1036
|
-
_transparent: transparent || undefined,
|
|
1037
|
-
_root: true,
|
|
1038
|
-
_parentComputed: parent?._root ? parent._parentComputed : parent,
|
|
1039
|
-
_firstChild: null,
|
|
1040
|
-
_nextSibling: null,
|
|
1041
|
-
_disposal: null,
|
|
1042
|
-
_queue: parent?._queue ?? globalQueue,
|
|
1043
|
-
_context: parent?._context || defaultContext,
|
|
1044
|
-
_childCount: 0,
|
|
1045
|
-
_pendingDisposal: null,
|
|
1046
|
-
_pendingFirstChild: null,
|
|
1047
|
-
_parent: parent,
|
|
1048
|
-
dispose(self = true) {
|
|
1049
|
-
disposeChildren(owner, self);
|
|
1050
|
-
}
|
|
1051
|
-
};
|
|
1052
|
-
if (parent?._childrenForbidden) {
|
|
1053
|
-
throw new Error(
|
|
1054
|
-
"Cannot create reactive primitives inside createTrackedEffect or owner-backed onSettled"
|
|
1055
|
-
);
|
|
1056
|
-
}
|
|
1057
|
-
if (parent) {
|
|
1058
|
-
const lastChild = parent._firstChild;
|
|
1059
|
-
if (lastChild === null) {
|
|
1060
|
-
parent._firstChild = owner;
|
|
1061
|
-
} else {
|
|
1062
|
-
owner._nextSibling = lastChild;
|
|
1063
|
-
parent._firstChild = owner;
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
return owner;
|
|
1067
|
-
}
|
|
1068
|
-
function createRoot(init, options) {
|
|
1069
|
-
const owner = createOwner(options);
|
|
1070
|
-
return runWithOwner(owner, () => init(owner.dispose));
|
|
1071
|
-
}
|
|
1072
|
-
function unlinkSubs(link) {
|
|
1073
|
-
const dep = link._dep;
|
|
1074
|
-
const nextDep = link._nextDep;
|
|
1075
|
-
const nextSub = link._nextSub;
|
|
1076
|
-
const prevSub = link._prevSub;
|
|
1077
|
-
if (nextSub !== null) nextSub._prevSub = prevSub;
|
|
1078
|
-
else dep._subsTail = prevSub;
|
|
1079
|
-
if (prevSub !== null) prevSub._nextSub = nextSub;
|
|
1080
|
-
else {
|
|
1081
|
-
dep._subs = nextSub;
|
|
1082
|
-
if (nextSub === null) {
|
|
1083
|
-
dep._unobserved?.();
|
|
1084
|
-
dep._fn && !dep._preventAutoDisposal && !(dep._flags & REACTIVE_ZOMBIE) && unobserved(dep);
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
return nextDep;
|
|
1088
|
-
}
|
|
1089
|
-
function unobserved(el) {
|
|
1090
|
-
deleteFromHeap(el, el._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
1091
|
-
let dep = el._deps;
|
|
1092
|
-
while (dep !== null) {
|
|
1093
|
-
dep = unlinkSubs(dep);
|
|
1094
|
-
}
|
|
1095
|
-
el._deps = null;
|
|
1096
|
-
disposeChildren(el, true);
|
|
1097
|
-
}
|
|
1098
|
-
function link(dep, sub) {
|
|
1099
|
-
const prevDep = sub._depsTail;
|
|
1100
|
-
if (prevDep !== null && prevDep._dep === dep) return;
|
|
1101
|
-
let nextDep = null;
|
|
1102
|
-
const isRecomputing = sub._flags & REACTIVE_RECOMPUTING_DEPS;
|
|
1103
|
-
if (isRecomputing) {
|
|
1104
|
-
nextDep = prevDep !== null ? prevDep._nextDep : sub._deps;
|
|
1105
|
-
if (nextDep !== null && nextDep._dep === dep) {
|
|
1106
|
-
sub._depsTail = nextDep;
|
|
1107
|
-
return;
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
const prevSub = dep._subsTail;
|
|
1111
|
-
if (prevSub !== null && prevSub._sub === sub && (!isRecomputing || isValidLink(prevSub, sub)))
|
|
1112
|
-
return;
|
|
1113
|
-
const newLink =
|
|
1114
|
-
(sub._depsTail =
|
|
1115
|
-
dep._subsTail =
|
|
1116
|
-
{ _dep: dep, _sub: sub, _nextDep: nextDep, _prevSub: prevSub, _nextSub: null });
|
|
1117
|
-
if (prevDep !== null) prevDep._nextDep = newLink;
|
|
1118
|
-
else sub._deps = newLink;
|
|
1119
|
-
if (prevSub !== null) prevSub._nextSub = newLink;
|
|
1120
|
-
else dep._subs = newLink;
|
|
1121
|
-
}
|
|
1122
|
-
function isValidLink(checkLink, sub) {
|
|
1123
|
-
const depsTail = sub._depsTail;
|
|
1124
|
-
if (depsTail !== null) {
|
|
1125
|
-
let link = sub._deps;
|
|
1126
|
-
do {
|
|
1127
|
-
if (link === checkLink) return true;
|
|
1128
|
-
if (link === depsTail) break;
|
|
1129
|
-
link = link._nextDep;
|
|
1130
|
-
} while (link !== null);
|
|
1131
|
-
}
|
|
1132
|
-
return false;
|
|
1133
|
-
}
|
|
1134
1166
|
GlobalQueue._update = recompute;
|
|
1135
1167
|
GlobalQueue._dispose = disposeChildren;
|
|
1136
1168
|
let tracking = false;
|
|
@@ -1199,6 +1231,7 @@ function recompute(el, create = false) {
|
|
|
1199
1231
|
if (el._transition && (!isEffect || activeTransition) && activeTransition !== el._transition)
|
|
1200
1232
|
globalQueue.initTransition(el._transition);
|
|
1201
1233
|
deleteFromHeap(el, el._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
1234
|
+
el._inFlight = null;
|
|
1202
1235
|
if (el._transition || isEffect === EFFECT_TRACKED) disposeChildren(el);
|
|
1203
1236
|
else {
|
|
1204
1237
|
markDisposal(el);
|
|
@@ -1503,6 +1536,11 @@ function read(el) {
|
|
|
1503
1536
|
) {
|
|
1504
1537
|
foundPending = true;
|
|
1505
1538
|
}
|
|
1539
|
+
let c = context;
|
|
1540
|
+
if (c?._root) c = c._parentComputed;
|
|
1541
|
+
if (c && tracking) link(el, c);
|
|
1542
|
+
read(getPendingSignal(el));
|
|
1543
|
+
read(getPendingSignal(firewall));
|
|
1506
1544
|
} else {
|
|
1507
1545
|
if (read(getPendingSignal(el))) foundPending = true;
|
|
1508
1546
|
if (firewall && read(getPendingSignal(firewall))) foundPending = true;
|
|
@@ -1559,6 +1597,9 @@ function read(el) {
|
|
|
1559
1597
|
if (!tracking && el !== c) link(el, c);
|
|
1560
1598
|
throw owner._error;
|
|
1561
1599
|
}
|
|
1600
|
+
} else if (c && owner !== el && owner._statusFlags & STATUS_UNINITIALIZED) {
|
|
1601
|
+
if (!tracking && el !== c) link(el, c);
|
|
1602
|
+
throw owner._error;
|
|
1562
1603
|
} else if (!c && owner._statusFlags & STATUS_UNINITIALIZED) {
|
|
1563
1604
|
throw owner._error;
|
|
1564
1605
|
}
|
|
@@ -1874,7 +1915,13 @@ function runEffect() {
|
|
|
1874
1915
|
this._cleanup?.();
|
|
1875
1916
|
this._cleanup = undefined;
|
|
1876
1917
|
try {
|
|
1877
|
-
|
|
1918
|
+
const cleanup = this._effectFn(this._value, this._prevValue);
|
|
1919
|
+
if (true && cleanup !== undefined && typeof cleanup !== "function") {
|
|
1920
|
+
throw new Error(
|
|
1921
|
+
`${this._name || "effect"} callback returned an invalid cleanup value. Return a cleanup function or undefined.`
|
|
1922
|
+
);
|
|
1923
|
+
}
|
|
1924
|
+
this._cleanup = cleanup;
|
|
1878
1925
|
} catch (error) {
|
|
1879
1926
|
this._error = new StatusError(this, error);
|
|
1880
1927
|
this._statusFlags |= STATUS_ERROR;
|
|
@@ -1888,14 +1935,25 @@ function runEffect() {
|
|
|
1888
1935
|
function trackedEffect(fn, options) {
|
|
1889
1936
|
const run = () => {
|
|
1890
1937
|
if (!node._modified || node._flags & REACTIVE_DISPOSED) return;
|
|
1891
|
-
|
|
1892
|
-
|
|
1938
|
+
setTrackedQueueCallback(true);
|
|
1939
|
+
try {
|
|
1940
|
+
node._modified = false;
|
|
1941
|
+
recompute(node);
|
|
1942
|
+
} finally {
|
|
1943
|
+
setTrackedQueueCallback(false);
|
|
1944
|
+
}
|
|
1893
1945
|
};
|
|
1894
1946
|
const node = computed(
|
|
1895
1947
|
() => {
|
|
1896
1948
|
node._cleanup?.();
|
|
1897
1949
|
node._cleanup = undefined;
|
|
1898
|
-
|
|
1950
|
+
const cleanup = staleValues(fn);
|
|
1951
|
+
if (cleanup !== undefined && typeof cleanup !== "function") {
|
|
1952
|
+
throw new Error(
|
|
1953
|
+
`${node._name || "trackedEffect"} callback returned an invalid cleanup value. Return a cleanup function or undefined.`
|
|
1954
|
+
);
|
|
1955
|
+
}
|
|
1956
|
+
node._cleanup = cleanup;
|
|
1899
1957
|
},
|
|
1900
1958
|
undefined,
|
|
1901
1959
|
{ ...options, lazy: true }
|
|
@@ -2015,7 +2073,13 @@ function createReaction(effectFn, options) {
|
|
|
2015
2073
|
() => (tracking(), getOwner()),
|
|
2016
2074
|
node => {
|
|
2017
2075
|
cl?.();
|
|
2018
|
-
|
|
2076
|
+
const cleanup = (effectFn.effect || effectFn)?.();
|
|
2077
|
+
if (true && cleanup !== undefined && typeof cleanup !== "function") {
|
|
2078
|
+
throw new Error(
|
|
2079
|
+
"Reaction callback returned an invalid cleanup value. Return a cleanup function or undefined."
|
|
2080
|
+
);
|
|
2081
|
+
}
|
|
2082
|
+
cl = cleanup;
|
|
2019
2083
|
dispose(node);
|
|
2020
2084
|
},
|
|
2021
2085
|
effectFn.error,
|
|
@@ -2055,9 +2119,14 @@ function createOptimistic(first, second, third) {
|
|
|
2055
2119
|
function onSettled(callback) {
|
|
2056
2120
|
const owner = getOwner();
|
|
2057
2121
|
owner && !owner._childrenForbidden
|
|
2058
|
-
? createTrackedEffect(() => untrack(callback))
|
|
2122
|
+
? createTrackedEffect(() => untrack(callback), { name: "onSettled" })
|
|
2059
2123
|
: globalQueue.enqueue(EFFECT_USER, () => {
|
|
2060
2124
|
const cleanup = callback();
|
|
2125
|
+
if (cleanup !== undefined && typeof cleanup !== "function") {
|
|
2126
|
+
throw new Error(
|
|
2127
|
+
"onSettled callback returned an invalid cleanup value. Return a cleanup function or undefined."
|
|
2128
|
+
);
|
|
2129
|
+
}
|
|
2061
2130
|
cleanup?.();
|
|
2062
2131
|
});
|
|
2063
2132
|
}
|