@pumped-fn/lite 2.1.3 → 2.1.5
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/CHANGELOG.md +70 -0
- package/dist/cli.cjs +249 -64
- package/dist/cli.mjs +249 -64
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +176 -157
- package/dist/index.d.cts +15 -15
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +15 -15
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +176 -157
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -5
package/dist/index.mjs
CHANGED
|
@@ -586,9 +586,8 @@ var ControllerImpl = class {
|
|
|
586
586
|
get() {
|
|
587
587
|
const entry = this.scope.getEntry(this.atom);
|
|
588
588
|
if (!entry || entry.state === "idle") throw new Error("Atom not resolved");
|
|
589
|
-
if (entry.state === "failed"
|
|
590
|
-
if (entry.
|
|
591
|
-
if (entry.state === "resolved" && entry.hasValue) return entry.value;
|
|
589
|
+
if (entry.state === "failed") throw entry.error;
|
|
590
|
+
if (entry.hasValue) return entry.value;
|
|
592
591
|
throw new Error("Atom not resolved");
|
|
593
592
|
}
|
|
594
593
|
async resolve() {
|
|
@@ -616,8 +615,7 @@ var ScopeImpl = class {
|
|
|
616
615
|
resolving = /* @__PURE__ */ new Set();
|
|
617
616
|
pending = /* @__PURE__ */ new Map();
|
|
618
617
|
stateListeners = /* @__PURE__ */ new Map();
|
|
619
|
-
invalidationQueue =
|
|
620
|
-
invalidationScheduled = false;
|
|
618
|
+
invalidationQueue = [];
|
|
621
619
|
invalidationChain = null;
|
|
622
620
|
chainPromise = null;
|
|
623
621
|
chainError = null;
|
|
@@ -630,48 +628,33 @@ var ScopeImpl = class {
|
|
|
630
628
|
resolveExts;
|
|
631
629
|
execExts;
|
|
632
630
|
ready;
|
|
633
|
-
scheduleInvalidation(atom$1) {
|
|
634
|
-
|
|
635
|
-
|
|
631
|
+
scheduleInvalidation(atom$1, entry) {
|
|
632
|
+
if (!entry) {
|
|
633
|
+
entry = this.cache.get(atom$1);
|
|
634
|
+
if (!entry || entry.state === "idle") return;
|
|
635
|
+
}
|
|
636
636
|
if (entry.state === "resolving") {
|
|
637
637
|
entry.pendingInvalidate = true;
|
|
638
638
|
return;
|
|
639
639
|
}
|
|
640
|
-
this.invalidationQueue.
|
|
640
|
+
if (!this.invalidationQueue.includes(atom$1)) this.invalidationQueue.push(atom$1);
|
|
641
641
|
if (!this.chainPromise) {
|
|
642
|
-
this.invalidationChain = /* @__PURE__ */ new Set();
|
|
643
|
-
this.invalidationScheduled = true;
|
|
644
642
|
this.chainError = null;
|
|
645
|
-
this.chainPromise = (
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
});
|
|
649
|
-
try {
|
|
650
|
-
await this.processInvalidationChain();
|
|
651
|
-
} catch (error) {
|
|
652
|
-
if (this.chainError === null) this.chainError = error;
|
|
653
|
-
}
|
|
654
|
-
})();
|
|
643
|
+
this.chainPromise = Promise.resolve().then(() => this.processInvalidationChain().catch((error) => {
|
|
644
|
+
if (this.chainError === null) this.chainError = error;
|
|
645
|
+
}));
|
|
655
646
|
}
|
|
656
647
|
}
|
|
657
648
|
async processInvalidationChain() {
|
|
658
649
|
try {
|
|
659
|
-
while (this.invalidationQueue.
|
|
660
|
-
const atom$1 = this.invalidationQueue.
|
|
661
|
-
this.
|
|
662
|
-
if (
|
|
663
|
-
const chainAtoms = Array.from(this.invalidationChain);
|
|
664
|
-
chainAtoms.push(atom$1);
|
|
665
|
-
const path = chainAtoms.map((a) => a.factory?.name || "<anonymous>").join(" → ");
|
|
666
|
-
throw new Error(`Infinite invalidation loop detected: ${path}`);
|
|
667
|
-
}
|
|
668
|
-
this.invalidationChain.add(atom$1);
|
|
669
|
-
await this.doInvalidateSequential(atom$1);
|
|
650
|
+
while (this.invalidationQueue.length > 0 && !this.disposed) {
|
|
651
|
+
const atom$1 = this.invalidationQueue.shift();
|
|
652
|
+
const result = this.doInvalidateSequential(atom$1);
|
|
653
|
+
if (result) await result;
|
|
670
654
|
}
|
|
671
655
|
} finally {
|
|
672
656
|
this.invalidationChain = null;
|
|
673
657
|
this.chainPromise = null;
|
|
674
|
-
this.invalidationScheduled = false;
|
|
675
658
|
}
|
|
676
659
|
}
|
|
677
660
|
constructor(options) {
|
|
@@ -714,79 +697,68 @@ var ScopeImpl = class {
|
|
|
714
697
|
return entry;
|
|
715
698
|
}
|
|
716
699
|
addListener(atom$1, event, listener) {
|
|
717
|
-
this.
|
|
718
|
-
|
|
700
|
+
const entry = this.getOrCreateEntry(atom$1);
|
|
701
|
+
if (entry.gcScheduled) {
|
|
702
|
+
clearTimeout(entry.gcScheduled);
|
|
703
|
+
entry.gcScheduled = null;
|
|
704
|
+
}
|
|
705
|
+
const listeners = entry.listeners.get(event);
|
|
719
706
|
listeners.add(listener);
|
|
720
707
|
return () => {
|
|
721
708
|
listeners.delete(listener);
|
|
722
|
-
this.
|
|
709
|
+
this.maybeScheduleGCEntry(atom$1, entry);
|
|
723
710
|
};
|
|
724
711
|
}
|
|
725
|
-
|
|
726
|
-
const
|
|
727
|
-
|
|
728
|
-
let count = 0;
|
|
729
|
-
for (const listeners of entry.listeners.values()) count += listeners.size;
|
|
730
|
-
return count;
|
|
712
|
+
hasSubscribers(entry) {
|
|
713
|
+
for (const listeners of entry.listeners.values()) if (listeners.size > 0) return true;
|
|
714
|
+
return false;
|
|
731
715
|
}
|
|
732
|
-
|
|
716
|
+
maybeScheduleGCEntry(atom$1, entry) {
|
|
733
717
|
if (!this.gcOptions.enabled) return;
|
|
734
718
|
if (atom$1.keepAlive) return;
|
|
735
|
-
const entry = this.cache.get(atom$1);
|
|
736
|
-
if (!entry) return;
|
|
737
719
|
if (entry.state === "idle") return;
|
|
738
|
-
if (this.
|
|
720
|
+
if (this.hasSubscribers(entry)) return;
|
|
739
721
|
if (entry.dependents.size > 0) return;
|
|
740
722
|
if (entry.gcScheduled) return;
|
|
741
723
|
entry.gcScheduled = setTimeout(() => {
|
|
742
724
|
this.executeGC(atom$1);
|
|
743
725
|
}, this.gcOptions.graceMs);
|
|
744
726
|
}
|
|
745
|
-
cancelScheduledGC(atom$1) {
|
|
746
|
-
const entry = this.cache.get(atom$1);
|
|
747
|
-
if (entry?.gcScheduled) {
|
|
748
|
-
clearTimeout(entry.gcScheduled);
|
|
749
|
-
entry.gcScheduled = null;
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
727
|
async executeGC(atom$1) {
|
|
753
728
|
const entry = this.cache.get(atom$1);
|
|
754
729
|
if (!entry) return;
|
|
755
730
|
entry.gcScheduled = null;
|
|
756
|
-
if (this.
|
|
731
|
+
if (this.hasSubscribers(entry)) return;
|
|
757
732
|
if (entry.dependents.size > 0) return;
|
|
758
733
|
if (atom$1.keepAlive) return;
|
|
759
734
|
await this.release(atom$1);
|
|
760
|
-
if (atom$1.deps) for (const
|
|
735
|
+
if (atom$1.deps) for (const key in atom$1.deps) {
|
|
736
|
+
const dep = atom$1.deps[key];
|
|
761
737
|
const depAtom = isAtom(dep) ? dep : isControllerDep(dep) ? dep.atom : null;
|
|
762
738
|
if (!depAtom) continue;
|
|
763
739
|
const depEntry = this.cache.get(depAtom);
|
|
764
740
|
if (depEntry) {
|
|
765
741
|
depEntry.dependents.delete(atom$1);
|
|
766
|
-
this.
|
|
742
|
+
this.maybeScheduleGCEntry(depAtom, depEntry);
|
|
767
743
|
}
|
|
768
744
|
}
|
|
769
745
|
}
|
|
770
|
-
|
|
771
|
-
const entry = this.cache.get(atom$1);
|
|
772
|
-
if (!entry) return;
|
|
746
|
+
notifyEntry(entry, event) {
|
|
773
747
|
const eventListeners = entry.listeners.get(event);
|
|
774
748
|
if (eventListeners?.size) for (const listener of [...eventListeners]) listener();
|
|
775
749
|
const allListeners = entry.listeners.get("*");
|
|
776
|
-
if (allListeners?.size) for (const listener of
|
|
750
|
+
if (allListeners?.size) for (const listener of allListeners) listener();
|
|
777
751
|
}
|
|
778
|
-
|
|
779
|
-
const entry = this.cache.get(atom$1);
|
|
780
|
-
if (!entry) return;
|
|
752
|
+
notifyEntryAll(entry) {
|
|
781
753
|
const allListeners = entry.listeners.get("*");
|
|
782
|
-
if (allListeners?.size) for (const listener of
|
|
754
|
+
if (allListeners?.size) for (const listener of allListeners) listener();
|
|
783
755
|
}
|
|
784
756
|
emitStateChange(state, atom$1) {
|
|
757
|
+
if (this.stateListeners.size === 0) return;
|
|
785
758
|
const stateMap = this.stateListeners.get(state);
|
|
786
|
-
if (stateMap)
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
}
|
|
759
|
+
if (!stateMap) return;
|
|
760
|
+
const listeners = stateMap.get(atom$1);
|
|
761
|
+
if (listeners?.size) for (const listener of [...listeners]) listener();
|
|
790
762
|
}
|
|
791
763
|
on(event, atom$1, listener) {
|
|
792
764
|
let stateMap = this.stateListeners.get(event);
|
|
@@ -810,14 +782,17 @@ var ScopeImpl = class {
|
|
|
810
782
|
}
|
|
811
783
|
};
|
|
812
784
|
}
|
|
813
|
-
|
|
814
|
-
if (this.disposed)
|
|
815
|
-
if (!this.initialized)
|
|
785
|
+
resolve(atom$1) {
|
|
786
|
+
if (this.disposed) return Promise.reject(/* @__PURE__ */ new Error("Scope is disposed"));
|
|
787
|
+
if (!this.initialized) {
|
|
788
|
+
if (!this.ready) return this.resolveAndTrack(atom$1);
|
|
789
|
+
return this.ready.then(() => this.resolve(atom$1));
|
|
790
|
+
}
|
|
816
791
|
const entry = this.cache.get(atom$1);
|
|
817
|
-
if (entry?.state === "resolved") return entry.value;
|
|
792
|
+
if (entry?.state === "resolved") return entry.resolvedPromise ?? (entry.resolvedPromise = Promise.resolve(entry.value));
|
|
818
793
|
const pendingPromise = this.pending.get(atom$1);
|
|
819
794
|
if (pendingPromise) return pendingPromise;
|
|
820
|
-
if (this.resolving.has(atom$1))
|
|
795
|
+
if (this.resolving.has(atom$1)) return Promise.reject(/* @__PURE__ */ new Error("Circular dependency detected"));
|
|
821
796
|
if (this.presets.has(atom$1)) {
|
|
822
797
|
const presetValue = this.presets.get(atom$1);
|
|
823
798
|
if (isAtom(presetValue)) return this.resolve(presetValue);
|
|
@@ -826,9 +801,12 @@ var ScopeImpl = class {
|
|
|
826
801
|
newEntry.value = presetValue;
|
|
827
802
|
newEntry.hasValue = true;
|
|
828
803
|
this.emitStateChange("resolved", atom$1);
|
|
829
|
-
this.
|
|
830
|
-
return newEntry.value;
|
|
804
|
+
this.notifyEntry(newEntry, "resolved");
|
|
805
|
+
return Promise.resolve(newEntry.value);
|
|
831
806
|
}
|
|
807
|
+
return this.resolveAndTrack(atom$1);
|
|
808
|
+
}
|
|
809
|
+
async resolveAndTrack(atom$1) {
|
|
832
810
|
this.resolving.add(atom$1);
|
|
833
811
|
const promise = this.doResolve(atom$1);
|
|
834
812
|
this.pending.set(atom$1, promise);
|
|
@@ -848,7 +826,7 @@ var ScopeImpl = class {
|
|
|
848
826
|
entry.cleanups = [];
|
|
849
827
|
entry.state = "resolving";
|
|
850
828
|
this.emitStateChange("resolving", atom$1);
|
|
851
|
-
this.
|
|
829
|
+
this.notifyEntry(entry, "resolving");
|
|
852
830
|
}
|
|
853
831
|
const resolvedDeps = await this.resolveDeps(atom$1.deps, void 0, atom$1);
|
|
854
832
|
const ctx = {
|
|
@@ -863,23 +841,25 @@ var ScopeImpl = class {
|
|
|
863
841
|
}
|
|
864
842
|
};
|
|
865
843
|
const factory = atom$1.factory;
|
|
866
|
-
const doResolve = async () => {
|
|
867
|
-
if (atom$1.deps) return factory(ctx, resolvedDeps);
|
|
868
|
-
else return factory(ctx);
|
|
869
|
-
};
|
|
870
844
|
try {
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
845
|
+
let value;
|
|
846
|
+
if (this.resolveExts.length === 0) value = atom$1.deps ? await factory(ctx, resolvedDeps) : await factory(ctx);
|
|
847
|
+
else {
|
|
848
|
+
const doResolve = async () => atom$1.deps ? factory(ctx, resolvedDeps) : factory(ctx);
|
|
849
|
+
const event = {
|
|
850
|
+
kind: "atom",
|
|
851
|
+
target: atom$1,
|
|
852
|
+
scope: this
|
|
853
|
+
};
|
|
854
|
+
value = await this.applyResolveExtensions(event, doResolve);
|
|
855
|
+
}
|
|
877
856
|
entry.state = "resolved";
|
|
878
857
|
entry.value = value;
|
|
879
858
|
entry.hasValue = true;
|
|
880
859
|
entry.error = void 0;
|
|
860
|
+
entry.resolvedPromise = Promise.resolve(value);
|
|
881
861
|
this.emitStateChange("resolved", atom$1);
|
|
882
|
-
this.
|
|
862
|
+
this.notifyEntry(entry, "resolved");
|
|
883
863
|
if (entry.pendingInvalidate) {
|
|
884
864
|
entry.pendingInvalidate = false;
|
|
885
865
|
this.invalidationChain?.delete(atom$1);
|
|
@@ -895,7 +875,7 @@ var ScopeImpl = class {
|
|
|
895
875
|
entry.value = void 0;
|
|
896
876
|
entry.hasValue = false;
|
|
897
877
|
this.emitStateChange("failed", atom$1);
|
|
898
|
-
this.
|
|
878
|
+
this.notifyEntryAll(entry);
|
|
899
879
|
if (entry.pendingInvalidate) {
|
|
900
880
|
entry.pendingInvalidate = false;
|
|
901
881
|
this.invalidationChain?.delete(atom$1);
|
|
@@ -923,39 +903,61 @@ var ScopeImpl = class {
|
|
|
923
903
|
const deferredResources = [];
|
|
924
904
|
for (const key in deps) {
|
|
925
905
|
const dep = deps[key];
|
|
926
|
-
if (isAtom(dep))
|
|
927
|
-
|
|
928
|
-
if (
|
|
929
|
-
|
|
930
|
-
if (
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
|
|
906
|
+
if (isAtom(dep)) {
|
|
907
|
+
const cachedEntry = this.cache.get(dep);
|
|
908
|
+
if (cachedEntry?.state === "resolved") {
|
|
909
|
+
result[key] = cachedEntry.value;
|
|
910
|
+
if (dependentAtom) cachedEntry.dependents.add(dependentAtom);
|
|
911
|
+
} else parallel.push(this.resolve(dep).then((value) => {
|
|
912
|
+
result[key] = value;
|
|
913
|
+
if (dependentAtom) {
|
|
914
|
+
const depEntry = this.getEntry(dep);
|
|
915
|
+
if (depEntry) depEntry.dependents.add(dependentAtom);
|
|
916
|
+
}
|
|
917
|
+
}));
|
|
918
|
+
} else if (isControllerDep(dep)) {
|
|
934
919
|
if (dep.watch) {
|
|
935
920
|
if (!dependentAtom) throw new Error("controller({ watch: true }) is only supported in atom dependencies");
|
|
936
921
|
if (!dep.resolve) throw new Error("controller({ watch: true }) requires resolve: true");
|
|
937
922
|
}
|
|
938
923
|
const ctrl = this.controller(dep.atom);
|
|
939
|
-
if (dep.resolve)
|
|
940
|
-
|
|
941
|
-
if (
|
|
942
|
-
|
|
943
|
-
if (
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
|
|
924
|
+
if (dep.resolve) {
|
|
925
|
+
const cachedCtrlEntry = this.cache.get(dep.atom);
|
|
926
|
+
if (cachedCtrlEntry?.state === "resolved") {
|
|
927
|
+
result[key] = ctrl;
|
|
928
|
+
if (dependentAtom) cachedCtrlEntry.dependents.add(dependentAtom);
|
|
929
|
+
if (dep.watch) {
|
|
930
|
+
const eq = dep.eq ?? shallowEqual;
|
|
931
|
+
let prev = ctrl.get();
|
|
932
|
+
const unsub = this.on("resolved", dep.atom, () => {
|
|
933
|
+
const next = ctrl.get();
|
|
934
|
+
if (!eq(prev, next)) this.scheduleInvalidation(dependentAtom);
|
|
935
|
+
prev = next;
|
|
936
|
+
});
|
|
937
|
+
const depEntry = this.getEntry(dependentAtom);
|
|
938
|
+
if (depEntry) depEntry.cleanups.push(unsub);
|
|
939
|
+
else unsub();
|
|
940
|
+
}
|
|
941
|
+
} else parallel.push(ctrl.resolve().then(() => {
|
|
942
|
+
result[key] = ctrl;
|
|
943
|
+
if (dependentAtom) {
|
|
944
|
+
const depEntry = this.getEntry(dep.atom);
|
|
945
|
+
if (depEntry) depEntry.dependents.add(dependentAtom);
|
|
946
|
+
}
|
|
947
|
+
if (dep.watch) {
|
|
948
|
+
const eq = dep.eq ?? shallowEqual;
|
|
949
|
+
let prev = ctrl.get();
|
|
950
|
+
const unsub = this.on("resolved", dep.atom, () => {
|
|
951
|
+
const next = ctrl.get();
|
|
952
|
+
if (!eq(prev, next)) this.scheduleInvalidation(dependentAtom);
|
|
953
|
+
prev = next;
|
|
954
|
+
});
|
|
955
|
+
const depEntry = this.getEntry(dependentAtom);
|
|
956
|
+
if (depEntry) depEntry.cleanups.push(unsub);
|
|
957
|
+
else unsub();
|
|
958
|
+
}
|
|
959
|
+
}));
|
|
960
|
+
} else {
|
|
959
961
|
result[key] = ctrl;
|
|
960
962
|
if (dependentAtom) {
|
|
961
963
|
const depEntry = this.getEntry(dep.atom);
|
|
@@ -1015,17 +1017,18 @@ var ScopeImpl = class {
|
|
|
1015
1017
|
localResolvingResources.add(resourceKey);
|
|
1016
1018
|
try {
|
|
1017
1019
|
const resourceDeps = await this.resolveDeps(resource$1.deps, ctx);
|
|
1018
|
-
const
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1020
|
+
const factory = resource$1.factory;
|
|
1021
|
+
let value;
|
|
1022
|
+
if (this.resolveExts.length === 0) value = resource$1.deps ? await factory(storeCtx, resourceDeps) : await factory(storeCtx);
|
|
1023
|
+
else {
|
|
1024
|
+
const event = {
|
|
1025
|
+
kind: "resource",
|
|
1026
|
+
target: resource$1,
|
|
1027
|
+
ctx: storeCtx
|
|
1028
|
+
};
|
|
1029
|
+
const doResolve = async () => resource$1.deps ? factory(storeCtx, resourceDeps) : factory(storeCtx);
|
|
1030
|
+
value = await this.applyResolveExtensions(event, doResolve);
|
|
1031
|
+
}
|
|
1029
1032
|
storeCtx.data.set(resourceKey, value);
|
|
1030
1033
|
return value;
|
|
1031
1034
|
} finally {
|
|
@@ -1087,7 +1090,7 @@ var ScopeImpl = class {
|
|
|
1087
1090
|
return;
|
|
1088
1091
|
}
|
|
1089
1092
|
entry.pendingSet = { value };
|
|
1090
|
-
this.scheduleInvalidation(atom$1);
|
|
1093
|
+
this.scheduleInvalidation(atom$1, entry);
|
|
1091
1094
|
}
|
|
1092
1095
|
scheduleUpdate(atom$1, fn) {
|
|
1093
1096
|
const entry = this.cache.get(atom$1);
|
|
@@ -1098,9 +1101,9 @@ var ScopeImpl = class {
|
|
|
1098
1101
|
return;
|
|
1099
1102
|
}
|
|
1100
1103
|
entry.pendingSet = { fn };
|
|
1101
|
-
this.scheduleInvalidation(atom$1);
|
|
1104
|
+
this.scheduleInvalidation(atom$1, entry);
|
|
1102
1105
|
}
|
|
1103
|
-
|
|
1106
|
+
doInvalidateSequential(atom$1) {
|
|
1104
1107
|
const entry = this.cache.get(atom$1);
|
|
1105
1108
|
if (!entry) return;
|
|
1106
1109
|
if (entry.state === "idle") return;
|
|
@@ -1108,23 +1111,27 @@ var ScopeImpl = class {
|
|
|
1108
1111
|
const pendingSet = entry.pendingSet;
|
|
1109
1112
|
entry.pendingSet = void 0;
|
|
1110
1113
|
if (pendingSet) {
|
|
1111
|
-
entry.
|
|
1112
|
-
entry.value = previousValue;
|
|
1113
|
-
entry.error = void 0;
|
|
1114
|
-
entry.pendingInvalidate = false;
|
|
1115
|
-
this.pending.delete(atom$1);
|
|
1116
|
-
this.resolving.delete(atom$1);
|
|
1117
|
-
this.emitStateChange("resolving", atom$1);
|
|
1118
|
-
this.notifyListeners(atom$1, "resolving");
|
|
1119
|
-
if ("value" in pendingSet) entry.value = pendingSet.value;
|
|
1120
|
-
else entry.value = pendingSet.fn(previousValue);
|
|
1114
|
+
entry.value = "value" in pendingSet ? pendingSet.value : pendingSet.fn(previousValue);
|
|
1121
1115
|
entry.state = "resolved";
|
|
1122
1116
|
entry.hasValue = true;
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1117
|
+
entry.error = void 0;
|
|
1118
|
+
entry.pendingInvalidate = false;
|
|
1119
|
+
entry.resolvedPromise = void 0;
|
|
1120
|
+
if (this.stateListeners.size) this.emitStateChange("resolved", atom$1);
|
|
1121
|
+
this.notifyEntry(entry, "resolved");
|
|
1126
1122
|
return;
|
|
1127
1123
|
}
|
|
1124
|
+
if (!this.invalidationChain) this.invalidationChain = /* @__PURE__ */ new Set();
|
|
1125
|
+
if (this.invalidationChain.has(atom$1)) {
|
|
1126
|
+
const chainAtoms = Array.from(this.invalidationChain);
|
|
1127
|
+
chainAtoms.push(atom$1);
|
|
1128
|
+
const path = chainAtoms.map((a) => a.factory?.name || "<anonymous>").join(" → ");
|
|
1129
|
+
throw new Error(`Infinite invalidation loop detected: ${path}`);
|
|
1130
|
+
}
|
|
1131
|
+
this.invalidationChain.add(atom$1);
|
|
1132
|
+
return this.doInvalidateAsync(atom$1, entry, previousValue);
|
|
1133
|
+
}
|
|
1134
|
+
async doInvalidateAsync(atom$1, entry, previousValue) {
|
|
1128
1135
|
for (let i = entry.cleanups.length - 1; i >= 0; i--) try {
|
|
1129
1136
|
await entry.cleanups[i]?.();
|
|
1130
1137
|
} catch {}
|
|
@@ -1136,7 +1143,7 @@ var ScopeImpl = class {
|
|
|
1136
1143
|
this.pending.delete(atom$1);
|
|
1137
1144
|
this.resolving.delete(atom$1);
|
|
1138
1145
|
this.emitStateChange("resolving", atom$1);
|
|
1139
|
-
this.
|
|
1146
|
+
this.notifyEntry(entry, "resolving");
|
|
1140
1147
|
try {
|
|
1141
1148
|
await this.resolve(atom$1);
|
|
1142
1149
|
} catch (e) {
|
|
@@ -1153,15 +1160,17 @@ var ScopeImpl = class {
|
|
|
1153
1160
|
for (let i = entry.cleanups.length - 1; i >= 0; i--) try {
|
|
1154
1161
|
await entry.cleanups[i]?.();
|
|
1155
1162
|
} catch {}
|
|
1156
|
-
if (atom$1.deps) for (const
|
|
1163
|
+
if (atom$1.deps) for (const key in atom$1.deps) {
|
|
1164
|
+
const dep = atom$1.deps[key];
|
|
1157
1165
|
const depAtom = isAtom(dep) ? dep : isControllerDep(dep) ? dep.atom : null;
|
|
1158
1166
|
if (!depAtom) continue;
|
|
1159
1167
|
const depEntry = this.cache.get(depAtom);
|
|
1160
1168
|
if (depEntry) {
|
|
1161
1169
|
depEntry.dependents.delete(atom$1);
|
|
1162
|
-
this.
|
|
1170
|
+
this.maybeScheduleGCEntry(depAtom, depEntry);
|
|
1163
1171
|
}
|
|
1164
1172
|
}
|
|
1173
|
+
this.notifyEntryAll(entry);
|
|
1165
1174
|
this.cache.delete(atom$1);
|
|
1166
1175
|
this.controllers.delete(atom$1);
|
|
1167
1176
|
for (const [state, stateMap] of this.stateListeners) {
|
|
@@ -1174,7 +1183,7 @@ var ScopeImpl = class {
|
|
|
1174
1183
|
await this.chainPromise;
|
|
1175
1184
|
} catch {}
|
|
1176
1185
|
this.disposed = true;
|
|
1177
|
-
this.invalidationQueue.
|
|
1186
|
+
this.invalidationQueue.length = 0;
|
|
1178
1187
|
this.invalidationChain = null;
|
|
1179
1188
|
this.chainPromise = null;
|
|
1180
1189
|
for (const ext of this.extensions) if (ext.dispose) await ext.dispose(this);
|
|
@@ -1196,8 +1205,11 @@ var ScopeImpl = class {
|
|
|
1196
1205
|
createContext(options) {
|
|
1197
1206
|
if (this.disposed) throw new Error("Scope is disposed");
|
|
1198
1207
|
const ctx = new ExecutionContextImpl(this, options);
|
|
1199
|
-
|
|
1200
|
-
|
|
1208
|
+
const ctxTags = options?.tags;
|
|
1209
|
+
if (ctxTags && ctxTags.length > 0) for (let i = 0; i < ctxTags.length; i++) ctx.data.set(ctxTags[i].key, ctxTags[i].value);
|
|
1210
|
+
if (this.tags.length > 0) {
|
|
1211
|
+
for (let i = 0; i < this.tags.length; i++) if (!ctx.data.has(this.tags[i].key)) ctx.data.set(this.tags[i].key, this.tags[i].value);
|
|
1212
|
+
}
|
|
1201
1213
|
return ctx;
|
|
1202
1214
|
}
|
|
1203
1215
|
};
|
|
@@ -1251,8 +1263,11 @@ var ExecutionContextImpl = class ExecutionContextImpl {
|
|
|
1251
1263
|
execName,
|
|
1252
1264
|
flowName: flow$1.name
|
|
1253
1265
|
});
|
|
1254
|
-
for (
|
|
1255
|
-
|
|
1266
|
+
if (execTags && execTags.length > 0) for (let i = 0; i < execTags.length; i++) childCtx.data.set(execTags[i].key, execTags[i].value);
|
|
1267
|
+
const flowTags = flow$1.tags;
|
|
1268
|
+
if (flowTags && flowTags.length > 0) {
|
|
1269
|
+
for (let i = 0; i < flowTags.length; i++) if (!childCtx.data.has(flowTags[i].key)) childCtx.data.set(flowTags[i].key, flowTags[i].value);
|
|
1270
|
+
}
|
|
1256
1271
|
try {
|
|
1257
1272
|
const result = presetValue !== void 0 && typeof presetValue === "function" ? await childCtx.execPresetFn(flow$1, presetValue) : await childCtx.execFlowInternal(flow$1);
|
|
1258
1273
|
await childCtx.close({ ok: true });
|
|
@@ -1287,18 +1302,18 @@ var ExecutionContextImpl = class ExecutionContextImpl {
|
|
|
1287
1302
|
async execFlowInternal(flow$1) {
|
|
1288
1303
|
const resolvedDeps = await this.scope.resolveDeps(flow$1.deps, this);
|
|
1289
1304
|
const factory = flow$1.factory;
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
else return factory(this);
|
|
1293
|
-
};
|
|
1305
|
+
if (this.scope.execExts.length === 0) return flow$1.deps ? factory(this, resolvedDeps) : factory(this);
|
|
1306
|
+
const doExec = async () => flow$1.deps ? factory(this, resolvedDeps) : factory(this);
|
|
1294
1307
|
return this.applyExecExtensions(flow$1, doExec);
|
|
1295
1308
|
}
|
|
1296
1309
|
async execFnInternal(options) {
|
|
1297
1310
|
const { fn, params } = options;
|
|
1311
|
+
if (this.scope.execExts.length === 0) return fn(this, ...params);
|
|
1298
1312
|
const doExec = () => Promise.resolve(fn(this, ...params));
|
|
1299
1313
|
return this.applyExecExtensions(fn, doExec);
|
|
1300
1314
|
}
|
|
1301
1315
|
async execPresetFn(flow$1, fn) {
|
|
1316
|
+
if (this.scope.execExts.length === 0) return fn(this);
|
|
1302
1317
|
const doExec = () => Promise.resolve(fn(this));
|
|
1303
1318
|
return this.applyExecExtensions(flow$1, doExec);
|
|
1304
1319
|
}
|
|
@@ -1314,9 +1329,13 @@ var ExecutionContextImpl = class ExecutionContextImpl {
|
|
|
1314
1329
|
onClose(fn) {
|
|
1315
1330
|
this.cleanups.push(fn);
|
|
1316
1331
|
}
|
|
1317
|
-
|
|
1318
|
-
if (this.closed) return;
|
|
1332
|
+
close(result = { ok: true }) {
|
|
1333
|
+
if (this.closed) return Promise.resolve();
|
|
1319
1334
|
this.closed = true;
|
|
1335
|
+
if (this.cleanups.length === 0) return Promise.resolve();
|
|
1336
|
+
return this.runCleanups(result);
|
|
1337
|
+
}
|
|
1338
|
+
async runCleanups(result) {
|
|
1320
1339
|
for (let i = this.cleanups.length - 1; i >= 0; i--) try {
|
|
1321
1340
|
await this.cleanups[i]?.(result);
|
|
1322
1341
|
} catch {}
|