storion 0.9.0 → 0.10.0

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.
Files changed (77) hide show
  1. package/CHANGELOG.md +62 -4
  2. package/README.md +42 -2021
  3. package/dist/async/abortable.d.ts +295 -0
  4. package/dist/async/abortable.d.ts.map +1 -0
  5. package/dist/async/async.d.ts +86 -5
  6. package/dist/async/async.d.ts.map +1 -1
  7. package/dist/async/context.d.ts +15 -0
  8. package/dist/async/context.d.ts.map +1 -0
  9. package/dist/async/index.d.ts +16 -3
  10. package/dist/async/index.d.ts.map +1 -1
  11. package/dist/async/index.js +407 -137
  12. package/dist/async/safe.d.ts +221 -0
  13. package/dist/async/safe.d.ts.map +1 -0
  14. package/dist/async/types.d.ts +77 -29
  15. package/dist/async/types.d.ts.map +1 -1
  16. package/dist/async/wrappers.d.ts +217 -0
  17. package/dist/async/wrappers.d.ts.map +1 -0
  18. package/dist/core/effect.d.ts +34 -26
  19. package/dist/core/effect.d.ts.map +1 -1
  20. package/dist/core/equality.d.ts +25 -0
  21. package/dist/core/equality.d.ts.map +1 -1
  22. package/dist/core/focus.d.ts +20 -0
  23. package/dist/core/focus.d.ts.map +1 -0
  24. package/dist/core/focusHelpers.d.ts +258 -0
  25. package/dist/core/focusHelpers.d.ts.map +1 -0
  26. package/dist/core/middleware.d.ts +4 -4
  27. package/dist/core/store.d.ts.map +1 -1
  28. package/dist/core/storeContext.d.ts +2 -9
  29. package/dist/core/storeContext.d.ts.map +1 -1
  30. package/dist/dev.d.ts +0 -10
  31. package/dist/dev.d.ts.map +1 -1
  32. package/dist/{index-C8B6Mo8r.js → effect-BDQU8Voz.js} +1241 -583
  33. package/dist/errors.d.ts +6 -0
  34. package/dist/errors.d.ts.map +1 -1
  35. package/dist/index.d.ts +5 -4
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/network/index.d.ts +69 -0
  38. package/dist/network/index.d.ts.map +1 -0
  39. package/dist/network/retry.d.ts +53 -0
  40. package/dist/network/retry.d.ts.map +1 -0
  41. package/dist/network/services.d.ts +58 -0
  42. package/dist/network/services.d.ts.map +1 -0
  43. package/dist/network/store.d.ts +36 -0
  44. package/dist/network/store.d.ts.map +1 -0
  45. package/dist/network/utils.d.ts +9 -0
  46. package/dist/network/utils.d.ts.map +1 -0
  47. package/dist/persist/index.d.ts +1 -1
  48. package/dist/persist/index.d.ts.map +1 -1
  49. package/dist/persist/index.js +11 -9
  50. package/dist/persist/persist.d.ts +14 -14
  51. package/dist/persist/persist.d.ts.map +1 -1
  52. package/dist/pool.d.ts +77 -0
  53. package/dist/pool.d.ts.map +1 -0
  54. package/dist/react/index.d.ts +2 -2
  55. package/dist/react/index.d.ts.map +1 -1
  56. package/dist/react/index.js +245 -244
  57. package/dist/react/stable.d.ts +27 -0
  58. package/dist/react/stable.d.ts.map +1 -0
  59. package/dist/react/useStore.d.ts +38 -13
  60. package/dist/react/useStore.d.ts.map +1 -1
  61. package/dist/react/withStore.d.ts.map +1 -1
  62. package/dist/storion.js +911 -37
  63. package/dist/trigger.d.ts +12 -7
  64. package/dist/trigger.d.ts.map +1 -1
  65. package/dist/types.d.ts +133 -22
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/utils/storeTuple.d.ts +7 -0
  68. package/dist/utils/storeTuple.d.ts.map +1 -0
  69. package/package.json +5 -1
  70. package/dist/collection.d.ts +0 -34
  71. package/dist/collection.d.ts.map +0 -1
  72. package/dist/core/proxy.d.ts +0 -47
  73. package/dist/core/proxy.d.ts.map +0 -1
  74. package/dist/effect-C6h0PDDI.js +0 -446
  75. package/dist/isPromiseLike-bFkfHAbm.js +0 -6
  76. package/dist/react/useLocalStore.d.ts +0 -48
  77. package/dist/react/useLocalStore.d.ts.map +0 -1
@@ -1,37 +1,14 @@
1
- import { a as SetupPhaseError, c as LifetimeMismatchError, w as withHooks, I as InvalidActionError, h as hasReadHook, t as trackRead, f as hasWriteHook, g as trackWrite, d as StoreDisposedError, s as scheduleNotification, b as batch, u as untrack, i as getHooks, H as HooksContextError } from "./effect-C6h0PDDI.js";
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
2
4
  import { e as emitter } from "./emitter-j4rC71vY.js";
3
- import "./meta-40r-AZfe.js";
4
5
  const STORION_TYPE = Symbol("STORION");
5
6
  function is$1(value, kind) {
6
7
  return value !== null && (typeof value === "object" || typeof value === "function") && STORION_TYPE in value && value[STORION_TYPE] === kind;
7
8
  }
8
- function isStorion(value) {
9
- return value !== null && (typeof value === "object" || typeof value === "function") && STORION_TYPE in value && typeof value[STORION_TYPE] === "string";
10
- }
11
- function getKind(value) {
12
- return value[STORION_TYPE];
13
- }
14
9
  function isSpec(value) {
15
10
  return is$1(value, "store.spec");
16
11
  }
17
- function isContainer(value) {
18
- return is$1(value, "container");
19
- }
20
- function isStore(value) {
21
- return is$1(value, "store");
22
- }
23
- function isFocus(value) {
24
- return is$1(value, "focus");
25
- }
26
- function isStoreContext(value) {
27
- return is$1(value, "store.context");
28
- }
29
- function isSelectorContext(value) {
30
- return is$1(value, "selector.context");
31
- }
32
- function isAction(value) {
33
- return is$1(value, "store.action");
34
- }
35
12
  var NOTHING = Symbol.for("immer-nothing");
36
13
  var DRAFTABLE = Symbol.for("immer-draftable");
37
14
  var DRAFT_STATE = Symbol.for("immer-state");
@@ -831,6 +808,106 @@ function currentImpl(value) {
831
808
  }
832
809
  var immer = new Immer2();
833
810
  var produce = immer.produce;
811
+ function tryDispose(value) {
812
+ if (isDisposable(value)) {
813
+ const dispose = value.dispose;
814
+ if (Array.isArray(dispose)) {
815
+ for (const item of dispose) {
816
+ if (typeof item === "function") {
817
+ item();
818
+ } else {
819
+ tryDispose(item);
820
+ }
821
+ }
822
+ } else if (typeof dispose === "function") {
823
+ dispose();
824
+ }
825
+ }
826
+ }
827
+ function isDisposable(value) {
828
+ return (typeof value === "object" || typeof value === "function") && !!value && "dispose" in value;
829
+ }
830
+ function willDispose(value) {
831
+ return () => tryDispose(value);
832
+ }
833
+ class StorionError extends Error {
834
+ constructor(message) {
835
+ super(message);
836
+ this.name = "StorionError";
837
+ }
838
+ }
839
+ class SetupPhaseError extends StorionError {
840
+ constructor(method, hint) {
841
+ super(
842
+ `${method}() can only be called during setup phase. Do not call ${method}() inside actions or async callbacks.` + (hint ? ` ${hint}` : "")
843
+ );
844
+ this.name = "SetupPhaseError";
845
+ }
846
+ }
847
+ class LifetimeMismatchError extends StorionError {
848
+ constructor(parentName, childName, operation) {
849
+ super(
850
+ `Lifetime mismatch: Store "${parentName}" (keepAlive) cannot ${operation} store "${childName}" (autoDispose). A long-lived store cannot ${operation} a store that may be disposed. Either change "${parentName}" to autoDispose, or change "${childName}" to keepAlive.`
851
+ );
852
+ this.name = "LifetimeMismatchError";
853
+ }
854
+ }
855
+ class AsyncFunctionError extends StorionError {
856
+ constructor(context, hint) {
857
+ super(`${context} must be synchronous. ${hint}`);
858
+ this.name = "AsyncFunctionError";
859
+ }
860
+ }
861
+ class StoreDisposedError extends StorionError {
862
+ constructor(storeId) {
863
+ super(`Cannot call action on disposed store: ${storeId}`);
864
+ this.name = "StoreDisposedError";
865
+ }
866
+ }
867
+ class InvalidActionError extends StorionError {
868
+ constructor(actionName, actualType) {
869
+ super(
870
+ `Action "${actionName}" must be a function, got ${actualType}. If using focus(), destructure it and return the getter/setter separately: const [get, set] = focus("path"); return { get, set };`
871
+ );
872
+ this.name = "InvalidActionError";
873
+ }
874
+ }
875
+ class HooksContextError extends StorionError {
876
+ constructor(method, requiredContext) {
877
+ super(
878
+ `${method}() must be called inside ${requiredContext}. It requires an active tracking context.`
879
+ );
880
+ this.name = "HooksContextError";
881
+ }
882
+ }
883
+ class ProviderMissingError extends StorionError {
884
+ constructor(hook, provider) {
885
+ super(`${hook} must be used within a ${provider}`);
886
+ this.name = "ProviderMissingError";
887
+ }
888
+ }
889
+ class LocalStoreDependencyError extends StorionError {
890
+ constructor(storeName, dependencyCount) {
891
+ super(
892
+ `Local store must not have dependencies, but "${storeName}" has ${dependencyCount} dependencies. Use useStore() with a global container for stores with dependencies.`
893
+ );
894
+ this.name = "LocalStoreDependencyError";
895
+ }
896
+ }
897
+ class EffectRefreshError extends StorionError {
898
+ constructor() {
899
+ super("Effect is already running, cannot refresh");
900
+ this.name = "EffectRefreshError";
901
+ }
902
+ }
903
+ class ScopedOutsideSelectorError extends StorionError {
904
+ constructor() {
905
+ super(
906
+ "scoped() can only be called during selector execution. Do not call scoped() in callbacks, event handlers, or async functions."
907
+ );
908
+ this.name = "ScopedOutsideSelectorError";
909
+ }
910
+ }
834
911
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
835
912
  function getDefaultExportFromCjs(x) {
836
913
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
@@ -1233,8 +1310,8 @@ function arraySome$1(array, predicate) {
1233
1310
  return false;
1234
1311
  }
1235
1312
  var _arraySome = arraySome$1;
1236
- function cacheHas$1(cache2, key) {
1237
- return cache2.has(key);
1313
+ function cacheHas$1(cache, key) {
1314
+ return cache.has(key);
1238
1315
  }
1239
1316
  var _cacheHas = cacheHas$1;
1240
1317
  var SetCache = _SetCache, arraySome = _arraySome, cacheHas = _cacheHas;
@@ -1302,7 +1379,7 @@ function setToArray$1(set2) {
1302
1379
  return result;
1303
1380
  }
1304
1381
  var _setToArray = setToArray$1;
1305
- var Symbol$1 = _Symbol, Uint8Array = _Uint8Array, eq = eq_1, equalArrays$1 = _equalArrays, mapToArray = _mapToArray, setToArray = _setToArray;
1382
+ var Symbol$1 = _Symbol, Uint8Array2 = _Uint8Array, eq = eq_1, equalArrays$1 = _equalArrays, mapToArray = _mapToArray, setToArray = _setToArray;
1306
1383
  var COMPARE_PARTIAL_FLAG$2 = 1, COMPARE_UNORDERED_FLAG = 2;
1307
1384
  var boolTag$1 = "[object Boolean]", dateTag$1 = "[object Date]", errorTag$1 = "[object Error]", mapTag$2 = "[object Map]", numberTag$1 = "[object Number]", regexpTag$1 = "[object RegExp]", setTag$2 = "[object Set]", stringTag$1 = "[object String]", symbolTag = "[object Symbol]";
1308
1385
  var arrayBufferTag$1 = "[object ArrayBuffer]", dataViewTag$2 = "[object DataView]";
@@ -1316,7 +1393,7 @@ function equalByTag$1(object, other, tag, bitmask, customizer, equalFunc, stack)
1316
1393
  object = object.buffer;
1317
1394
  other = other.buffer;
1318
1395
  case arrayBufferTag$1:
1319
- if (object.byteLength != other.byteLength || !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
1396
+ if (object.byteLength != other.byteLength || !equalFunc(new Uint8Array2(object), new Uint8Array2(other))) {
1320
1397
  return false;
1321
1398
  }
1322
1399
  return true;
@@ -1437,8 +1514,8 @@ var stubFalse_1 = stubFalse;
1437
1514
  var freeExports = exports$1 && !exports$1.nodeType && exports$1;
1438
1515
  var freeModule = freeExports && true && module && !module.nodeType && module;
1439
1516
  var moduleExports = freeModule && freeModule.exports === freeExports;
1440
- var Buffer = moduleExports ? root2.Buffer : void 0;
1441
- var nativeIsBuffer = Buffer ? Buffer.isBuffer : void 0;
1517
+ var Buffer2 = moduleExports ? root2.Buffer : void 0;
1518
+ var nativeIsBuffer = Buffer2 ? Buffer2.isBuffer : void 0;
1442
1519
  var isBuffer2 = nativeIsBuffer || stubFalse2;
1443
1520
  module.exports = isBuffer2;
1444
1521
  })(isBuffer$2, isBuffer$2.exports);
@@ -1732,28 +1809,234 @@ function resolveEquality(e) {
1732
1809
  function equality(shorthand) {
1733
1810
  return resolveEquality(shorthand);
1734
1811
  }
1735
- function tryDispose(value) {
1736
- if (isDisposable(value)) {
1737
- const dispose = value.dispose;
1738
- if (Array.isArray(dispose)) {
1739
- for (const item of dispose) {
1740
- if (typeof item === "function") {
1741
- item();
1742
- } else {
1743
- tryDispose(item);
1744
- }
1812
+ function createStableFn(fn) {
1813
+ const originalFn = fn;
1814
+ let currentFn = fn;
1815
+ return Object.assign(
1816
+ (...args) => {
1817
+ return currentFn(...args);
1818
+ },
1819
+ {
1820
+ getOriginal: () => originalFn,
1821
+ getCurrent: () => currentFn,
1822
+ setCurrent(newFn) {
1823
+ currentFn = newFn;
1824
+ }
1825
+ }
1826
+ );
1827
+ }
1828
+ function isStableFn(value) {
1829
+ return typeof value === "function" && "getOriginal" in value && "getCurrent" in value && "setCurrent" in value;
1830
+ }
1831
+ function tryStabilize(prev, next, equalityFn) {
1832
+ if (!prev) {
1833
+ if (typeof next === "function") {
1834
+ return [createStableFn(next), false];
1835
+ }
1836
+ return [next, false];
1837
+ }
1838
+ if (typeof next === "function") {
1839
+ if (isStableFn(prev.value)) {
1840
+ prev.value.setCurrent(next);
1841
+ return [prev.value, true];
1842
+ }
1843
+ return [createStableFn(next), false];
1844
+ }
1845
+ if (next && next instanceof Date) {
1846
+ if (prev.value && prev.value instanceof Date) {
1847
+ if (next.getTime() === prev.value.getTime()) {
1848
+ return [prev.value, true];
1745
1849
  }
1746
- } else if (typeof dispose === "function") {
1747
- dispose();
1748
1850
  }
1851
+ return [next, false];
1749
1852
  }
1853
+ if (equalityFn(prev.value, next)) {
1854
+ return [prev.value, true];
1855
+ }
1856
+ return [next, false];
1750
1857
  }
1751
- function isDisposable(value) {
1752
- return (typeof value === "object" || typeof value === "function") && !!value && "dispose" in value;
1858
+ let globalHooks = {
1859
+ scheduleNotification(notify) {
1860
+ notify();
1861
+ },
1862
+ scheduleEffect(runEffect) {
1863
+ runEffect();
1864
+ }
1865
+ };
1866
+ function getHooks() {
1867
+ return globalHooks;
1753
1868
  }
1754
- function willDispose(value) {
1755
- return () => tryDispose(value);
1869
+ function hasReadHook() {
1870
+ return globalHooks.onRead !== void 0;
1871
+ }
1872
+ function hasWriteHook() {
1873
+ return globalHooks.onWrite !== void 0;
1874
+ }
1875
+ function withHooks(hooksOrSetup, fn, onFinish) {
1876
+ const prev = globalHooks;
1877
+ if (typeof hooksOrSetup === "function") {
1878
+ globalHooks = {
1879
+ ...globalHooks,
1880
+ ...hooksOrSetup(prev)
1881
+ };
1882
+ } else {
1883
+ globalHooks = { ...prev, ...hooksOrSetup };
1884
+ }
1885
+ try {
1886
+ return fn();
1887
+ } finally {
1888
+ globalHooks = prev;
1889
+ onFinish == null ? void 0 : onFinish();
1890
+ }
1891
+ }
1892
+ function trackRead(storeId, prop, value, subscribe) {
1893
+ var _a;
1894
+ const key = `${storeId}.${prop}`;
1895
+ (_a = globalHooks.onRead) == null ? void 0 : _a.call(globalHooks, { key, value, subscribe });
1896
+ }
1897
+ function trackWrite(storeId, prop, next, prev) {
1898
+ var _a;
1899
+ const key = `${storeId}.${prop}`;
1900
+ (_a = globalHooks.onWrite) == null ? void 0 : _a.call(globalHooks, { key, next, prev });
1901
+ }
1902
+ function untrack(fn) {
1903
+ return withHooks({ onRead: void 0, onWrite: void 0 }, fn);
1904
+ }
1905
+ function scheduleNotification(notify, key) {
1906
+ globalHooks.scheduleNotification(notify, key);
1907
+ }
1908
+ function batch(fn) {
1909
+ const pending = /* @__PURE__ */ new Map();
1910
+ return withHooks(
1911
+ (current2) => ({
1912
+ ...current2,
1913
+ scheduleNotification: (notify, key) => {
1914
+ const actualKey = key ?? notify;
1915
+ pending.set(actualKey, notify);
1916
+ }
1917
+ }),
1918
+ fn,
1919
+ // Flush on finish
1920
+ () => {
1921
+ for (const notify of pending.values()) {
1922
+ notify();
1923
+ }
1924
+ }
1925
+ );
1926
+ }
1927
+ let pickIdCounter = 0;
1928
+ function pick(selector, equality2) {
1929
+ var _a;
1930
+ const parentHooks = getHooks();
1931
+ if (!parentHooks.onRead) {
1932
+ throw new HooksContextError("pick", "an effect or useStore selector");
1933
+ }
1934
+ const equalityFn = resolveEquality(equality2);
1935
+ const currentReads = [];
1936
+ const evaluate = () => {
1937
+ currentReads.length = 0;
1938
+ const value = withHooks(
1939
+ {
1940
+ onRead: (event) => {
1941
+ currentReads.push(event);
1942
+ }
1943
+ },
1944
+ selector
1945
+ );
1946
+ return value;
1947
+ };
1948
+ let currentValue = evaluate();
1949
+ if (!currentReads.length) {
1950
+ return currentValue;
1951
+ }
1952
+ const pickKey = `pick:${++pickIdCounter}`;
1953
+ const subscribe = (listener) => {
1954
+ const onCleanup = emitter();
1955
+ const setupSubscriptions = () => {
1956
+ for (const read of currentReads) {
1957
+ const unsub = read.subscribe(handleChange);
1958
+ onCleanup.on(unsub);
1959
+ }
1960
+ };
1961
+ const clearSubscriptions = () => {
1962
+ onCleanup.emitAndClear();
1963
+ };
1964
+ const handleChange = () => {
1965
+ try {
1966
+ const prevValue = currentValue;
1967
+ clearSubscriptions();
1968
+ currentValue = evaluate();
1969
+ setupSubscriptions();
1970
+ if (!equalityFn(prevValue, currentValue)) {
1971
+ listener();
1972
+ }
1973
+ } catch (error) {
1974
+ clearSubscriptions();
1975
+ listener();
1976
+ }
1977
+ };
1978
+ setupSubscriptions();
1979
+ return clearSubscriptions;
1980
+ };
1981
+ (_a = parentHooks.onRead) == null ? void 0 : _a.call(parentHooks, {
1982
+ key: pickKey,
1983
+ value: currentValue,
1984
+ subscribe
1985
+ });
1986
+ return currentValue;
1987
+ }
1988
+ function checkIsDev() {
1989
+ var _a;
1990
+ if (typeof __DEV__ !== "undefined") {
1991
+ return __DEV__;
1992
+ }
1993
+ try {
1994
+ const p = globalThis.process;
1995
+ if ((_a = p == null ? void 0 : p.env) == null ? void 0 : _a.NODE_ENV) {
1996
+ return p.env.NODE_ENV !== "production";
1997
+ }
1998
+ } catch {
1999
+ }
2000
+ return false;
2001
+ }
2002
+ function dev(fn) {
2003
+ const isDev = checkIsDev();
2004
+ if (fn) {
2005
+ if (isDev) {
2006
+ fn();
2007
+ }
2008
+ return isDev;
2009
+ }
2010
+ return isDev;
1756
2011
  }
2012
+ ((dev2) => {
2013
+ function log(message, ...args) {
2014
+ if (checkIsDev()) {
2015
+ console.log(`[rextive] ${message}`, ...args);
2016
+ }
2017
+ }
2018
+ dev2.log = log;
2019
+ function warn(message, ...args) {
2020
+ if (checkIsDev()) {
2021
+ console.warn(`[rextive] ${message}`, ...args);
2022
+ }
2023
+ }
2024
+ dev2.warn = warn;
2025
+ function error(message, ...args) {
2026
+ if (checkIsDev()) {
2027
+ console.error(`[rextive] ${message}`, ...args);
2028
+ }
2029
+ }
2030
+ dev2.error = error;
2031
+ function assert(condition, message) {
2032
+ if (checkIsDev()) {
2033
+ if (!condition) {
2034
+ throw new Error(`[rextive] Assertion failed: ${message}`);
2035
+ }
2036
+ }
2037
+ }
2038
+ dev2.assert = assert;
2039
+ })(dev || (dev = {}));
1757
2040
  function getAtPath(obj, segments) {
1758
2041
  let current2 = obj;
1759
2042
  for (const key of segments) {
@@ -1762,15 +2045,30 @@ function getAtPath(obj, segments) {
1762
2045
  }
1763
2046
  return current2;
1764
2047
  }
1765
- function createFocus(context, segments, isSetupPhase, options) {
1766
- if (!isSetupPhase()) {
1767
- throw new SetupPhaseError(
1768
- "createFocus",
1769
- "Focus can only be called during setup phase."
1770
- );
2048
+ function getCacheKey(segments) {
2049
+ return segments.join(".");
2050
+ }
2051
+ function optionsMatch(a, b) {
2052
+ if (!a && !b) return true;
2053
+ if (!a || !b) return false;
2054
+ if (a.equality !== b.equality) return false;
2055
+ if (a.fallback !== b.fallback) return false;
2056
+ return true;
2057
+ }
2058
+ function createFocus(storeContext, resolver, context, segments, cache, options) {
2059
+ const cacheKey = getCacheKey(segments);
2060
+ const cached = cache.get(cacheKey);
2061
+ if (cached) {
2062
+ if (!optionsMatch(cached.options, options)) {
2063
+ dev.warn(
2064
+ `focus("${cacheKey}") called with different options. The first options are used. If you need different behavior, use a different path.`
2065
+ );
2066
+ }
2067
+ return cached.focus;
1771
2068
  }
1772
2069
  const { fallback, equality: equalityOption } = options ?? {};
1773
2070
  const equalityFn = resolveEquality(equalityOption);
2071
+ const initialValue = getAtPath(context.get(), segments);
1774
2072
  const getter = () => {
1775
2073
  const state = context.get();
1776
2074
  const value = getAtPath(state, segments);
@@ -1779,6 +2077,10 @@ function createFocus(context, segments, isSetupPhase, options) {
1779
2077
  }
1780
2078
  return value;
1781
2079
  };
2080
+ const getterWithPick = getter;
2081
+ getterWithPick.pick = (equality2) => {
2082
+ return pick(getter, equality2);
2083
+ };
1782
2084
  const setter = (valueOrReducerOrProduce) => {
1783
2085
  context.update((draft) => {
1784
2086
  let current2 = draft;
@@ -1819,22 +2121,48 @@ function createFocus(context, segments, isSetupPhase, options) {
1819
2121
  };
1820
2122
  const to = (relativePath, childOptions) => {
1821
2123
  return createFocus(
2124
+ storeContext,
2125
+ resolver,
1822
2126
  context,
1823
2127
  [...segments, ...relativePath.split(".")],
1824
- isSetupPhase,
2128
+ cache,
1825
2129
  childOptions
1826
2130
  );
1827
2131
  };
1828
- const focus = [getter, setter];
2132
+ const dirty = () => {
2133
+ const currentValue = getter();
2134
+ return !equalityFn(currentValue, initialValue);
2135
+ };
2136
+ const reset = () => {
2137
+ setter(initialValue);
2138
+ };
2139
+ const focusPick = (equality2) => {
2140
+ return pick(getter, equality2);
2141
+ };
2142
+ const focus = [getterWithPick, setter];
2143
+ const as = (helper) => {
2144
+ return helper(focus);
2145
+ };
1829
2146
  Object.assign(focus, {
1830
2147
  [STORION_TYPE]: "focus",
1831
2148
  on,
1832
2149
  to,
2150
+ as,
2151
+ dirty,
2152
+ reset,
2153
+ pick: focusPick,
1833
2154
  context,
2155
+ _storeContext: storeContext,
2156
+ _resolver: resolver,
1834
2157
  segments
1835
2158
  });
2159
+ cache.set(cacheKey, { focus, options });
1836
2160
  return focus;
1837
2161
  }
2162
+ function storeTuple(instance) {
2163
+ const { state, actions } = instance;
2164
+ return Object.assign([state, actions, instance], { state, actions });
2165
+ }
1838
2166
  function createUpdateFn(update) {
1839
2167
  const updateFn = (updaterOrPartial) => {
1840
2168
  if (typeof updaterOrPartial === "function") {
@@ -1869,6 +2197,7 @@ function createStoreContext(options) {
1869
2197
  isSetupPhase
1870
2198
  } = options;
1871
2199
  const currentLifetime = spec.options.lifetime ?? "keepAlive";
2200
+ const focusCache = /* @__PURE__ */ new Map();
1872
2201
  const ctx = {
1873
2202
  [STORION_TYPE]: "store.context",
1874
2203
  get state() {
@@ -1894,32 +2223,16 @@ function createStoreContext(options) {
1894
2223
  }
1895
2224
  const instance = resolver.get(depSpec);
1896
2225
  onDependency == null ? void 0 : onDependency(instance);
1897
- const tuple = [instance.state, instance.actions];
1898
- return Object.assign(tuple, {
1899
- state: instance.state,
1900
- actions: instance.actions
1901
- });
2226
+ return storeTuple(instance);
1902
2227
  },
1903
2228
  // Implementation handles StoreSpec, Factory, and parameterized Factory overloads
1904
2229
  create(specOrFactory, ...args) {
1905
- if (!isSetupPhase()) {
1906
- throw new SetupPhaseError(
1907
- "create",
1908
- "Declare all child stores at the top of your setup function."
1909
- );
1910
- }
1911
2230
  if (!isSpec(specOrFactory)) {
1912
2231
  const instance2 = specOrFactory(resolver, ...args);
1913
2232
  onDispose == null ? void 0 : onDispose(willDispose(instance2));
1914
2233
  return instance2;
1915
2234
  }
1916
2235
  const childSpec = specOrFactory;
1917
- const childLifetime = childSpec.options.lifetime ?? "keepAlive";
1918
- if (currentLifetime === "keepAlive" && childLifetime === "autoDispose") {
1919
- const currentName = spec.options.name ?? "unknown";
1920
- const childName = childSpec.name ?? "unknown";
1921
- throw new LifetimeMismatchError(currentName, childName, "create");
1922
- }
1923
2236
  const instance = resolver.create(childSpec);
1924
2237
  onDispose == null ? void 0 : onDispose(willDispose(instance));
1925
2238
  return instance;
@@ -1934,6 +2247,9 @@ function createStoreContext(options) {
1934
2247
  onDispose(callback) {
1935
2248
  onDispose == null ? void 0 : onDispose(callback);
1936
2249
  },
2250
+ isSetupPhase() {
2251
+ return isSetupPhase();
2252
+ },
1937
2253
  mixin(mixin, ...args) {
1938
2254
  if (!isSetupPhase()) {
1939
2255
  throw new SetupPhaseError("mixin");
@@ -1948,7 +2264,14 @@ function createStoreContext(options) {
1948
2264
  },
1949
2265
  subscribe
1950
2266
  };
1951
- return createFocus(focusCtx, path.split("."), isSetupPhase, options2);
2267
+ return createFocus(
2268
+ ctx,
2269
+ resolver,
2270
+ focusCtx,
2271
+ path.split("."),
2272
+ focusCache,
2273
+ options2
2274
+ );
1952
2275
  }
1953
2276
  };
1954
2277
  return ctx;
@@ -1971,46 +2294,147 @@ function unwrapFn(fn) {
1971
2294
  const original = fn[ORIGINAL_FN];
1972
2295
  return original ?? fn;
1973
2296
  }
1974
- function isWrappedFn(fn) {
1975
- return ORIGINAL_FN in fn;
1976
- }
1977
- function collection(createItem, initialItems) {
1978
- const map = /* @__PURE__ */ new Map([]);
1979
- return {
1980
- with(key, callback) {
1981
- if (map.has(key)) {
1982
- callback(map.get(key));
2297
+ function pool(createItem, optionsOrInitial) {
2298
+ const isOptionsObject = optionsOrInitial && !Array.isArray(optionsOrInitial) && typeof optionsOrInitial === "object";
2299
+ const options = isOptionsObject ? optionsOrInitial : void 0;
2300
+ const initial = isOptionsObject ? options == null ? void 0 : options.initial : optionsOrInitial;
2301
+ const keyOf = options == null ? void 0 : options.keyOf;
2302
+ const keyEquality = (options == null ? void 0 : options.equality) && !keyOf ? resolveEquality(options.equality) : null;
2303
+ const shouldAutoDispose = !!(options == null ? void 0 : options.autoDispose);
2304
+ if (keyOf) {
2305
+ const map2 = /* @__PURE__ */ new Map();
2306
+ for (const [k, v] of initial ?? []) {
2307
+ map2.set(keyOf(k), { key: k, value: v });
2308
+ }
2309
+ const get22 = (key) => {
2310
+ const hash = keyOf(key);
2311
+ const entry = map2.get(hash);
2312
+ if (entry) return entry.value;
2313
+ const value = createItem(key);
2314
+ map2.set(hash, { key, value });
2315
+ return value;
2316
+ };
2317
+ return Object.assign(get22, {
2318
+ tap(key, callback) {
2319
+ const entry = map2.get(keyOf(key));
2320
+ if (entry) callback(entry.value);
2321
+ return this;
2322
+ },
2323
+ has: (key) => map2.has(keyOf(key)),
2324
+ get: get22,
2325
+ set(key, value) {
2326
+ const hash = keyOf(key);
2327
+ if (shouldAutoDispose) {
2328
+ const existing = map2.get(hash);
2329
+ if (existing && existing.value !== value) {
2330
+ tryDispose(existing.value);
2331
+ }
2332
+ }
2333
+ map2.set(hash, { key, value });
2334
+ return this;
2335
+ },
2336
+ size() {
2337
+ return map2.size;
2338
+ },
2339
+ clear() {
2340
+ if (shouldAutoDispose) {
2341
+ for (const entry of map2.values()) {
2342
+ tryDispose(entry.value);
2343
+ }
2344
+ }
2345
+ map2.clear();
2346
+ return this;
2347
+ },
2348
+ delete(key) {
2349
+ const hash = keyOf(key);
2350
+ if (shouldAutoDispose) {
2351
+ const entry = map2.get(hash);
2352
+ if (entry) tryDispose(entry.value);
2353
+ }
2354
+ map2.delete(hash);
2355
+ return this;
2356
+ },
2357
+ *keys() {
2358
+ for (const entry of map2.values()) yield entry.key;
2359
+ },
2360
+ *values() {
2361
+ for (const entry of map2.values()) yield entry.value;
2362
+ },
2363
+ *entries() {
2364
+ for (const entry of map2.values())
2365
+ yield [entry.key, entry.value];
2366
+ }
2367
+ });
2368
+ }
2369
+ const map = new Map(initial ?? []);
2370
+ const findKey = (key) => {
2371
+ if (!keyEquality) return map.has(key) ? key : void 0;
2372
+ for (const k of map.keys()) {
2373
+ if (keyEquality(k, key)) return k;
2374
+ }
2375
+ return void 0;
2376
+ };
2377
+ const get2 = (key) => {
2378
+ const existingKey = findKey(key);
2379
+ if (existingKey !== void 0) {
2380
+ return map.get(existingKey);
2381
+ }
2382
+ const value = createItem(key);
2383
+ map.set(key, value);
2384
+ return value;
2385
+ };
2386
+ return Object.assign(get2, {
2387
+ tap(key, callback) {
2388
+ const existingKey = findKey(key);
2389
+ if (existingKey !== void 0) {
2390
+ callback(map.get(existingKey));
1983
2391
  }
1984
2392
  return this;
1985
2393
  },
1986
2394
  /** Check if key exists (does NOT create item) */
1987
2395
  has(key) {
1988
- return map.has(key);
1989
- },
1990
- /** Get item by key, creating it if it doesn't exist */
1991
- get(key) {
1992
- if (!map.has(key)) {
1993
- map.set(key, createItem(key));
1994
- }
1995
- return map.get(key);
2396
+ return findKey(key) !== void 0;
1996
2397
  },
2398
+ get: get2,
1997
2399
  /** Explicitly set an item */
1998
2400
  set(key, value) {
1999
- map.set(key, value);
2401
+ const existingKey = findKey(key);
2402
+ if (existingKey !== void 0) {
2403
+ if (shouldAutoDispose) {
2404
+ const existing = map.get(existingKey);
2405
+ if (existing !== value) {
2406
+ tryDispose(existing);
2407
+ }
2408
+ }
2409
+ map.set(existingKey, value);
2410
+ } else {
2411
+ map.set(key, value);
2412
+ }
2000
2413
  return this;
2001
2414
  },
2002
- /** Number of items in the collection */
2003
- get size() {
2415
+ /** Number of items in the pool */
2416
+ size() {
2004
2417
  return map.size;
2005
2418
  },
2006
2419
  /** Remove all items */
2007
2420
  clear() {
2421
+ if (shouldAutoDispose) {
2422
+ for (const value of map.values()) {
2423
+ tryDispose(value);
2424
+ }
2425
+ }
2008
2426
  map.clear();
2009
2427
  return this;
2010
2428
  },
2011
2429
  /** Remove a specific item */
2012
2430
  delete(key) {
2013
- map.delete(key);
2431
+ const existingKey = findKey(key);
2432
+ if (existingKey !== void 0) {
2433
+ if (shouldAutoDispose) {
2434
+ tryDispose(map.get(existingKey));
2435
+ }
2436
+ map.delete(existingKey);
2437
+ }
2014
2438
  return this;
2015
2439
  },
2016
2440
  /** Iterate over keys */
@@ -2025,7 +2449,7 @@ function collection(createItem, initialItems) {
2025
2449
  entries() {
2026
2450
  return map.entries();
2027
2451
  }
2028
- };
2452
+ });
2029
2453
  }
2030
2454
  function store(options) {
2031
2455
  const displayName = options.name ?? generateSpecName();
@@ -2087,10 +2511,12 @@ function createStoreInstance(spec, resolver, instanceOptions = {}) {
2087
2511
  };
2088
2512
  const changeEmitter = emitter();
2089
2513
  const disposeEmitter = emitter();
2090
- const propertyEmitters = collection(() => emitter());
2514
+ const propertyEmitters = pool(
2515
+ () => emitter()
2516
+ );
2091
2517
  const actionInvocations = /* @__PURE__ */ new Map();
2092
2518
  const actionNthCounters = /* @__PURE__ */ new Map();
2093
- const actionEmitters = collection(
2519
+ const actionEmitters = pool(
2094
2520
  () => emitter()
2095
2521
  );
2096
2522
  const wildcardActionEmitter = emitter();
@@ -2122,7 +2548,7 @@ function createStoreInstance(spec, resolver, instanceOptions = {}) {
2122
2548
  if (isSetupPhase) {
2123
2549
  return;
2124
2550
  }
2125
- propertyEmitters.with(
2551
+ propertyEmitters.tap(
2126
2552
  key,
2127
2553
  (em) => em.emit({ newValue, oldValue })
2128
2554
  );
@@ -2393,7 +2819,10 @@ function createStoreInstance(spec, resolver, instanceOptions = {}) {
2393
2819
  disposeEffectsEmitter.on(dispose);
2394
2820
  }
2395
2821
  initialState = currentState;
2396
- Object.assign(instance, { deps: Array.from(deps) });
2822
+ Object.assign(instance, {
2823
+ deps: Array.from(deps),
2824
+ toJSON: () => currentState
2825
+ });
2397
2826
  deps.clear();
2398
2827
  const wrappedActions = {};
2399
2828
  for (const [name, action] of Object.entries(actions)) {
@@ -2457,539 +2886,768 @@ function createStoreInstance(spec, resolver, instanceOptions = {}) {
2457
2886
  instanceActions = wrappedActions;
2458
2887
  return instance;
2459
2888
  }
2460
- function createMetaQuery(entries) {
2461
- const entryArray = Array.isArray(entries) ? entries : entries ? [entries] : [];
2462
- const single = (type) => {
2463
- const result = { store: void 0, fields: {} };
2464
- for (const entry of entryArray) {
2465
- if (entry.type !== type) continue;
2466
- if (entry.fields && entry.fields.length > 0) {
2467
- for (const field of entry.fields) {
2468
- const fieldKey = field;
2469
- if (!(fieldKey in result.fields)) {
2470
- result.fields[fieldKey] = entry.value;
2471
- }
2472
- }
2473
- } else {
2474
- if (result.store === void 0) {
2475
- result.store = entry.value;
2476
- }
2477
- }
2889
+ const abortableSymbol = Symbol.for("storion.abortable");
2890
+ function isAbortable(fn) {
2891
+ return typeof fn === "function" && abortableSymbol in fn && fn[abortableSymbol] === true;
2892
+ }
2893
+ class AbortableAbortedError extends Error {
2894
+ constructor(message = "Abortable was aborted") {
2895
+ super(message);
2896
+ __publicField(this, "name", "AbortableAbortedError");
2897
+ }
2898
+ }
2899
+ function createAbortableContext(controller, pauseState, takeState, setStatus) {
2900
+ const signal = controller.signal;
2901
+ const checkPauseAndAbort = async () => {
2902
+ if (signal.aborted) {
2903
+ throw new AbortableAbortedError();
2904
+ }
2905
+ if (pauseState.isPaused) {
2906
+ setStatus("paused");
2907
+ await new Promise((resolve) => {
2908
+ pauseState.resumeResolve = resolve;
2909
+ });
2910
+ pauseState.resumeResolve = null;
2911
+ setStatus("running");
2912
+ }
2913
+ if (signal.aborted) {
2914
+ throw new AbortableAbortedError();
2478
2915
  }
2479
- return result;
2480
2916
  };
2481
- const all = (type) => {
2482
- const result = { store: [], fields: {} };
2483
- for (const entry of entryArray) {
2484
- if (entry.type !== type) continue;
2485
- if (entry.fields && entry.fields.length > 0) {
2486
- for (const field of entry.fields) {
2487
- const fieldKey = field;
2488
- let arr = result.fields[fieldKey];
2489
- if (!arr) {
2490
- arr = [];
2491
- result.fields[fieldKey] = arr;
2492
- }
2493
- arr.push(entry.value);
2494
- }
2495
- } else {
2496
- result.store.push(entry.value);
2917
+ const afterCheck = async (value) => {
2918
+ await checkPauseAndAbort();
2919
+ return value;
2920
+ };
2921
+ const join = (resultOrResults) => {
2922
+ if (signal.aborted) {
2923
+ return Promise.reject(new AbortableAbortedError());
2924
+ }
2925
+ const isArray2 = Array.isArray(resultOrResults);
2926
+ const results = isArray2 ? resultOrResults : [resultOrResults];
2927
+ const abortAll = () => {
2928
+ for (const result of results) {
2929
+ result.abort();
2497
2930
  }
2931
+ };
2932
+ signal.addEventListener("abort", abortAll, { once: true });
2933
+ const promise = Promise.all(results).then(async (values) => {
2934
+ signal.removeEventListener("abort", abortAll);
2935
+ await checkPauseAndAbort();
2936
+ return isArray2 ? values : values[0];
2937
+ }).catch(async (error) => {
2938
+ signal.removeEventListener("abort", abortAll);
2939
+ abortAll();
2940
+ if (signal.aborted) {
2941
+ throw new AbortableAbortedError();
2942
+ }
2943
+ throw error;
2944
+ });
2945
+ return promise;
2946
+ };
2947
+ const baseSafe = createSafe(
2948
+ () => signal,
2949
+ () => signal.aborted
2950
+ );
2951
+ const safeFn = async (fnOrPromise, ...args) => {
2952
+ if (isAbortable(fnOrPromise)) {
2953
+ const abortableResult = fnOrPromise.withSignal(signal, ...args);
2954
+ return join(abortableResult);
2498
2955
  }
2956
+ const result = await baseSafe(fnOrPromise, ...args);
2957
+ await checkPauseAndAbort();
2499
2958
  return result;
2500
2959
  };
2501
- const fields = (type, predicate) => {
2502
- const result = /* @__PURE__ */ new Set();
2503
- for (const entry of entryArray) {
2504
- if (entry.type !== type) continue;
2505
- if (entry.fields && entry.fields.length > 0) {
2506
- if (!predicate || predicate(entry.value)) {
2507
- for (const field of entry.fields) {
2508
- result.add(field);
2509
- }
2510
- }
2511
- }
2512
- }
2513
- return Array.from(result);
2960
+ const safe = Object.assign(safeFn, {
2961
+ all: baseSafe.all,
2962
+ race: baseSafe.race,
2963
+ settled: baseSafe.settled,
2964
+ any: baseSafe.any,
2965
+ callback: baseSafe.callback
2966
+ });
2967
+ const take = (key) => {
2968
+ const takeKey = String(key ?? "__checkpoint__");
2969
+ if (signal.aborted) {
2970
+ return Promise.reject(new AbortableAbortedError());
2971
+ }
2972
+ const existing = takeState.pendingTakes.get(takeKey);
2973
+ if (existing) {
2974
+ return existing.promise.then(afterCheck);
2975
+ }
2976
+ let resolve;
2977
+ let reject;
2978
+ const promise = new Promise((res, rej) => {
2979
+ resolve = res;
2980
+ reject = rej;
2981
+ });
2982
+ takeState.pendingTakes.set(takeKey, {
2983
+ resolve,
2984
+ reject,
2985
+ promise
2986
+ });
2987
+ setStatus("waiting");
2988
+ return promise.then(afterCheck);
2514
2989
  };
2515
- const any = (...types) => {
2516
- return entryArray.some((entry) => types.includes(entry.type));
2990
+ return {
2991
+ signal,
2992
+ safe,
2993
+ take,
2994
+ join,
2995
+ aborted: () => signal.aborted,
2996
+ abort: () => {
2997
+ if (signal.aborted) return false;
2998
+ controller.abort();
2999
+ return true;
3000
+ },
3001
+ checkpoint: checkPauseAndAbort
2517
3002
  };
2518
- const query = Object.assign(
2519
- (type) => single(type),
2520
- { single, all, any, fields }
2521
- );
2522
- return query;
2523
3003
  }
2524
- function extractDisplayName(factory) {
2525
- if (isSpec(factory)) {
2526
- return factory.displayName;
2527
- }
2528
- if (typeof factory.displayName === "string" && factory.displayName) {
2529
- return factory.displayName;
2530
- }
2531
- if (factory.name && factory.name !== "") {
2532
- return factory.name;
2533
- }
2534
- return void 0;
3004
+ function createSend(takeState, setStatus) {
3005
+ return (key, value) => {
3006
+ const takeKey = String(key ?? "__checkpoint__");
3007
+ const pending = takeState.pendingTakes.get(takeKey);
3008
+ if (pending) {
3009
+ pending.resolve(value);
3010
+ takeState.pendingTakes.delete(takeKey);
3011
+ setStatus("running");
3012
+ }
3013
+ };
2535
3014
  }
2536
- function createResolver(options = {}) {
2537
- const {
2538
- middleware = [],
2539
- parent,
2540
- invokeResolver: invokeResolverOption
2541
- } = options;
2542
- const cache2 = /* @__PURE__ */ new Map();
2543
- const overrides = /* @__PURE__ */ new Map();
2544
- const resolve = (factory) => overrides.get(factory) ?? factory;
2545
- const invoke = (factory, resolverForCtx) => {
2546
- const isStoreSpec = isSpec(factory);
2547
- const displayName = extractDisplayName(factory);
2548
- const meta = createMetaQuery(factory.meta);
2549
- const chain = middleware.reduceRight(
2550
- (next, mw) => () => {
2551
- if (isStoreSpec) {
2552
- const ctx = {
2553
- type: "store",
2554
- factory,
2555
- resolver: resolverForCtx,
2556
- next,
2557
- displayName,
2558
- spec: factory,
2559
- meta
2560
- };
2561
- return mw(ctx);
2562
- } else {
2563
- const ctx = {
2564
- type: "factory",
2565
- factory,
2566
- resolver: resolverForCtx,
2567
- next,
2568
- displayName,
2569
- meta
2570
- };
2571
- return mw(ctx);
2572
- }
2573
- },
2574
- () => factory(resolverForCtx)
2575
- );
2576
- return chain();
3015
+ function executeAbortable(fn, args, parentSignal) {
3016
+ const controller = new AbortController();
3017
+ if (parentSignal) {
3018
+ if (parentSignal.aborted) {
3019
+ controller.abort();
3020
+ } else {
3021
+ const onParentAbort = () => controller.abort();
3022
+ parentSignal.addEventListener("abort", onParentAbort, { once: true });
3023
+ controller.signal.addEventListener(
3024
+ "abort",
3025
+ () => parentSignal.removeEventListener("abort", onParentAbort),
3026
+ { once: true }
3027
+ );
3028
+ }
3029
+ }
3030
+ let status = "running";
3031
+ let resultValue;
3032
+ let errorValue;
3033
+ const pauseState = {
3034
+ isPaused: false,
3035
+ resumeResolve: null
3036
+ };
3037
+ const takeState = {
3038
+ pendingTakes: /* @__PURE__ */ new Map()
3039
+ };
3040
+ const setStatus = (newStatus) => {
3041
+ if (!["success", "error", "aborted"].includes(status)) {
3042
+ status = newStatus;
3043
+ }
2577
3044
  };
2578
- const resolver = {
2579
- get(factory) {
2580
- if (cache2.has(factory)) {
2581
- return cache2.get(factory);
3045
+ const ctx = createAbortableContext(
3046
+ controller,
3047
+ pauseState,
3048
+ takeState,
3049
+ setStatus
3050
+ );
3051
+ const wrappedFn = async () => {
3052
+ try {
3053
+ if (controller.signal.aborted) {
3054
+ throw new AbortableAbortedError();
2582
3055
  }
2583
- if (parent && overrides.size === 0 && parent.has(factory)) {
2584
- return parent.get(factory);
3056
+ const result = await fn(ctx, ...args);
3057
+ return result;
3058
+ } catch (e) {
3059
+ if (controller.signal.aborted) {
3060
+ throw new AbortableAbortedError();
2585
3061
  }
2586
- const instance = invoke(
2587
- resolve(factory),
2588
- invokeResolverOption ?? resolver
2589
- );
2590
- cache2.set(factory, instance);
2591
- return instance;
2592
- },
2593
- create(factory, ...args) {
2594
- const resolverForCtx = invokeResolverOption ?? resolver;
2595
- if (args.length > 0) {
2596
- return factory(resolverForCtx, ...args);
3062
+ throw e;
3063
+ }
3064
+ };
3065
+ const promise = wrappedFn().then((result) => {
3066
+ status = "success";
3067
+ resultValue = result;
3068
+ return result;
3069
+ }).catch((error) => {
3070
+ if (error instanceof AbortableAbortedError || controller.signal.aborted) {
3071
+ status = "aborted";
3072
+ errorValue = error instanceof Error ? error : new AbortableAbortedError();
3073
+ } else {
3074
+ status = "error";
3075
+ errorValue = error instanceof Error ? error : new Error(String(error));
3076
+ }
3077
+ throw errorValue;
3078
+ });
3079
+ const send = createSend(takeState, setStatus);
3080
+ return Object.assign(promise, {
3081
+ send,
3082
+ // Status checks
3083
+ failed: () => status === "error",
3084
+ completed: () => ["success", "error", "aborted"].includes(status),
3085
+ running: () => status === "running",
3086
+ succeeded: () => status === "success",
3087
+ paused: () => status === "paused",
3088
+ waiting: () => status === "waiting",
3089
+ aborted: () => status === "aborted",
3090
+ status: () => status,
3091
+ // Result access
3092
+ result: () => resultValue,
3093
+ error: () => errorValue,
3094
+ // Control methods
3095
+ pause: () => {
3096
+ if (pauseState.isPaused || ["success", "error", "aborted"].includes(status)) {
3097
+ return false;
2597
3098
  }
2598
- return invoke(resolve(factory), resolverForCtx);
2599
- },
2600
- set(factory, override) {
2601
- overrides.set(factory, override);
2602
- cache2.delete(factory);
2603
- },
2604
- has(factory) {
2605
- const inParent = parent && overrides.size === 0 && parent.has(factory);
2606
- return cache2.has(factory) || (inParent ?? false);
3099
+ pauseState.isPaused = true;
3100
+ status = "paused";
3101
+ return true;
2607
3102
  },
2608
- tryGet(factory) {
2609
- if (cache2.has(factory)) {
2610
- return cache2.get(factory);
3103
+ resume: () => {
3104
+ if (!pauseState.isPaused) {
3105
+ return false;
2611
3106
  }
2612
- if (parent && overrides.size === 0) {
2613
- return parent.tryGet(factory);
3107
+ pauseState.isPaused = false;
3108
+ status = "running";
3109
+ if (pauseState.resumeResolve) {
3110
+ pauseState.resumeResolve();
2614
3111
  }
2615
- return void 0;
3112
+ return true;
2616
3113
  },
2617
- delete(factory) {
2618
- const instance = cache2.get(factory);
2619
- if (instance) {
2620
- tryDispose(instance);
2621
- cache2.delete(factory);
2622
- return true;
3114
+ abort: () => {
3115
+ if (controller.signal.aborted || ["success", "error"].includes(status)) {
3116
+ return false;
2623
3117
  }
2624
- return false;
2625
- },
2626
- clear() {
2627
- for (const instance of cache2.values()) {
2628
- tryDispose(instance);
3118
+ status = "aborted";
3119
+ controller.abort();
3120
+ const abortError = new AbortableAbortedError();
3121
+ for (const [, pending] of takeState.pendingTakes) {
3122
+ pending.reject(abortError);
2629
3123
  }
2630
- cache2.clear();
2631
- },
2632
- scope(scopeOptions = {}) {
2633
- return createResolver({
2634
- middleware: scopeOptions.middleware ?? middleware,
2635
- parent: resolver,
2636
- ...scopeOptions
2637
- });
3124
+ takeState.pendingTakes.clear();
3125
+ if (pauseState.resumeResolve) {
3126
+ pauseState.resumeResolve();
3127
+ }
3128
+ return true;
2638
3129
  }
3130
+ });
3131
+ }
3132
+ function abortable(fn) {
3133
+ const wrapper = (...args) => {
3134
+ return executeAbortable(fn, args);
2639
3135
  };
2640
- return resolver;
2641
- }
2642
- let defaultMiddlewareConfig = {};
2643
- const container = function(options = {}) {
2644
- const middleware = [
2645
- ...defaultMiddlewareConfig.pre ?? [],
2646
- ...Array.isArray(options.middleware) ? options.middleware : options.middleware ? [options.middleware] : [],
2647
- ...defaultMiddlewareConfig.post ?? []
2648
- ];
2649
- const instancesById = /* @__PURE__ */ new Map();
2650
- const creationOrder = [];
2651
- const createEmitter = emitter();
2652
- const disposeEmitter = emitter();
2653
- const parent = options._parent;
2654
- let containerApi;
2655
- const internalResolver = createResolver({
2656
- middleware,
2657
- parent,
2658
- get invokeResolver() {
2659
- return containerApi;
2660
- }
3136
+ wrapper.withSignal = (signal, ...args) => {
3137
+ return executeAbortable(fn, args, signal);
3138
+ };
3139
+ wrapper.use = (wrapperFn) => {
3140
+ const wrappedHandler = wrapperFn(fn);
3141
+ return abortable(wrappedHandler);
3142
+ };
3143
+ wrapper.as = () => {
3144
+ return wrapper;
3145
+ };
3146
+ Object.defineProperty(wrapper, abortableSymbol, {
3147
+ value: true,
3148
+ writable: false,
3149
+ enumerable: false,
3150
+ configurable: false
2661
3151
  });
2662
- function trackStore(spec, instance) {
2663
- instancesById.set(instance.id, instance);
2664
- creationOrder.push(spec);
2665
- if (typeof instance.onDispose === "function") {
2666
- instance.onDispose(() => {
2667
- disposeEmitter.emit(instance);
2668
- instancesById.delete(instance.id);
2669
- internalResolver.delete(spec);
2670
- const index = creationOrder.indexOf(spec);
2671
- if (index !== -1) {
2672
- creationOrder.splice(index, 1);
3152
+ return wrapper;
3153
+ }
3154
+ function isPromiseLike(value) {
3155
+ return value !== null && typeof value === "object" && "then" in value && typeof value.then === "function";
3156
+ }
3157
+ function toPromise(value) {
3158
+ if (typeof value === "function") {
3159
+ try {
3160
+ const result = value();
3161
+ return toPromise(result);
3162
+ } catch (e) {
3163
+ return Promise.reject(e);
3164
+ }
3165
+ }
3166
+ if (isPromiseLike(value)) {
3167
+ return Promise.resolve(value);
3168
+ }
3169
+ return Promise.resolve(value);
3170
+ }
3171
+ class AggregateErrorImpl extends Error {
3172
+ constructor(errors2, message) {
3173
+ super(message);
3174
+ __publicField(this, "errors");
3175
+ this.name = "AggregateError";
3176
+ this.errors = errors2;
3177
+ }
3178
+ }
3179
+ function promiseAny(promises) {
3180
+ return new Promise((resolve, reject) => {
3181
+ const promiseArray = Array.from(promises);
3182
+ if (promiseArray.length === 0) {
3183
+ reject(new AggregateErrorImpl([], "All promises were rejected"));
3184
+ return;
3185
+ }
3186
+ const errors2 = [];
3187
+ let rejectedCount = 0;
3188
+ promiseArray.forEach((promise, index) => {
3189
+ Promise.resolve(promise).then(resolve, (error) => {
3190
+ errors2[index] = error;
3191
+ rejectedCount++;
3192
+ if (rejectedCount === promiseArray.length) {
3193
+ reject(new AggregateErrorImpl(errors2, "All promises were rejected"));
2673
3194
  }
2674
3195
  });
3196
+ });
3197
+ });
3198
+ }
3199
+ function createSafe(getSignal, isCancelled) {
3200
+ function wrapPromise(promise) {
3201
+ return new Promise((resolve, reject) => {
3202
+ promise.then(
3203
+ (value) => {
3204
+ if (!isCancelled()) {
3205
+ resolve(value);
3206
+ }
3207
+ },
3208
+ (error) => {
3209
+ if (!isCancelled()) {
3210
+ reject(error);
3211
+ }
3212
+ }
3213
+ );
3214
+ });
3215
+ }
3216
+ function wrapResult(result) {
3217
+ if (isPromiseLike(result)) {
3218
+ return wrapPromise(result);
2675
3219
  }
2676
- createEmitter.emit(instance);
3220
+ return result;
2677
3221
  }
2678
- containerApi = {
2679
- [STORION_TYPE]: "container",
2680
- // Get by ID or factory/spec
2681
- get(specOrIdOrFactory) {
2682
- if (typeof specOrIdOrFactory === "string") {
2683
- return instancesById.get(specOrIdOrFactory);
2684
- }
2685
- const wasCached = internalResolver.has(specOrIdOrFactory);
2686
- const instance = untrack(() => internalResolver.get(specOrIdOrFactory));
2687
- if (!wasCached && isSpec(specOrIdOrFactory)) {
2688
- trackStore(specOrIdOrFactory, instance);
2689
- }
2690
- return instance;
2691
- },
2692
- create(specOrFactory, ...args) {
2693
- const instance = untrack(
2694
- () => internalResolver.create(specOrFactory, ...args)
2695
- );
2696
- if (isSpec(specOrFactory)) {
2697
- const storeInstance = instance;
2698
- instancesById.set(storeInstance.id, storeInstance);
2699
- if (typeof storeInstance.onDispose === "function") {
2700
- storeInstance.onDispose(() => {
2701
- disposeEmitter.emit(storeInstance);
2702
- instancesById.delete(storeInstance.id);
2703
- });
2704
- }
2705
- }
2706
- return instance;
2707
- },
2708
- set(spec, override) {
2709
- const existing = internalResolver.tryGet(spec);
2710
- tryDispose(existing);
2711
- internalResolver.set(spec, override);
2712
- },
2713
- has(spec) {
2714
- return internalResolver.has(spec);
2715
- },
2716
- tryGet(spec) {
2717
- return internalResolver.tryGet(spec);
2718
- },
2719
- delete(spec) {
2720
- const instance = internalResolver.tryGet(spec);
2721
- if (instance) {
2722
- tryDispose(instance);
2723
- return true;
3222
+ function wrapInput(input) {
3223
+ return wrapPromise(toPromise(input));
3224
+ }
3225
+ function safe(input, ...args) {
3226
+ if (isCancelled()) {
3227
+ if (isPromiseLike(input)) {
3228
+ return new Promise(() => {
3229
+ });
2724
3230
  }
2725
- return false;
2726
- },
2727
- clear() {
2728
- const specs = [...creationOrder].reverse();
2729
- for (const spec of specs) {
2730
- const instance = internalResolver.tryGet(spec);
2731
- tryDispose(instance);
2732
- }
2733
- internalResolver.clear();
2734
- instancesById.clear();
2735
- creationOrder.length = 0;
2736
- },
2737
- dispose(spec) {
2738
- return containerApi.delete(spec);
2739
- },
2740
- scope(scopeOptions = {}) {
2741
- return container({
2742
- middleware: scopeOptions.middleware ?? middleware,
2743
- _parent: containerApi
3231
+ }
3232
+ if (isPromiseLike(input)) {
3233
+ return wrapPromise(input);
3234
+ }
3235
+ if (isAbortable(input)) {
3236
+ const signal = getSignal();
3237
+ const result = input.withSignal(signal, ...args);
3238
+ return wrapResult(result);
3239
+ }
3240
+ if (typeof input === "function") {
3241
+ const result = input(...args);
3242
+ return wrapResult(result);
3243
+ }
3244
+ return input;
3245
+ }
3246
+ const all = (inputs) => {
3247
+ if (isCancelled()) {
3248
+ return new Promise(() => {
2744
3249
  });
2745
- },
2746
- onCreate: createEmitter.on,
2747
- onDispose: disposeEmitter.on
3250
+ }
3251
+ if (Array.isArray(inputs)) {
3252
+ return Promise.all(inputs.map(wrapInput));
3253
+ }
3254
+ const obj = inputs;
3255
+ const keys2 = Object.keys(obj);
3256
+ return Promise.all(keys2.map((k) => wrapInput(obj[k]))).then(
3257
+ (values) => Object.fromEntries(keys2.map((k, i) => [k, values[i]]))
3258
+ );
2748
3259
  };
2749
- return containerApi;
2750
- };
2751
- const defaultsFn = (config = {}) => {
2752
- defaultMiddlewareConfig = {
2753
- pre: [...defaultMiddlewareConfig.pre ?? [], ...config.pre ?? []],
2754
- post: [...defaultMiddlewareConfig.post ?? [], ...config.post ?? []]
3260
+ const race = (inputs) => {
3261
+ if (isCancelled()) {
3262
+ return new Promise(() => {
3263
+ });
3264
+ }
3265
+ if (Array.isArray(inputs)) {
3266
+ return Promise.race(inputs.map(wrapInput));
3267
+ }
3268
+ const obj = inputs;
3269
+ const keys2 = Object.keys(obj);
3270
+ return Promise.race(
3271
+ keys2.map((k) => wrapInput(obj[k]).then((v) => [k, v]))
3272
+ );
2755
3273
  };
2756
- };
2757
- defaultsFn.clear = () => {
2758
- defaultMiddlewareConfig = {};
2759
- };
2760
- container.defaults = defaultsFn;
2761
- let pickIdCounter = 0;
2762
- function pick(selector, equality2) {
2763
- var _a;
2764
- const parentHooks = getHooks();
2765
- if (!parentHooks.onRead) {
2766
- throw new HooksContextError("pick", "an effect or useStore selector");
2767
- }
2768
- const equalityFn = resolveEquality(equality2);
2769
- const currentReads = [];
2770
- const evaluate = () => {
2771
- currentReads.length = 0;
2772
- const value = withHooks(
2773
- {
2774
- onRead: (event) => {
2775
- currentReads.push(event);
2776
- }
2777
- },
2778
- selector
3274
+ const settled = (inputs) => {
3275
+ if (isCancelled()) {
3276
+ return new Promise(() => {
3277
+ });
3278
+ }
3279
+ if (Array.isArray(inputs)) {
3280
+ return wrapPromise(Promise.allSettled(inputs.map(toPromise)));
3281
+ }
3282
+ const obj = inputs;
3283
+ const keys2 = Object.keys(obj);
3284
+ return wrapPromise(
3285
+ Promise.allSettled(keys2.map((k) => toPromise(obj[k])))
3286
+ ).then(
3287
+ (results) => Object.fromEntries(keys2.map((k, i) => [k, results[i]]))
2779
3288
  );
2780
- return value;
2781
3289
  };
2782
- let currentValue = evaluate();
2783
- if (!currentReads.length) {
2784
- return currentValue;
2785
- }
2786
- const pickKey = `pick:${++pickIdCounter}`;
2787
- const subscribe = (listener) => {
2788
- const onCleanup = emitter();
2789
- const setupSubscriptions = () => {
2790
- for (const read of currentReads) {
2791
- const unsub = read.subscribe(handleChange);
2792
- onCleanup.on(unsub);
2793
- }
2794
- };
2795
- const clearSubscriptions = () => {
2796
- onCleanup.emitAndClear();
2797
- };
2798
- const handleChange = () => {
2799
- try {
2800
- const prevValue = currentValue;
2801
- clearSubscriptions();
2802
- currentValue = evaluate();
2803
- setupSubscriptions();
2804
- if (!equalityFn(prevValue, currentValue)) {
2805
- listener();
2806
- }
2807
- } catch (error) {
2808
- clearSubscriptions();
2809
- listener();
3290
+ const any = (inputs) => {
3291
+ if (isCancelled()) {
3292
+ return new Promise(() => {
3293
+ });
3294
+ }
3295
+ if (Array.isArray(inputs)) {
3296
+ return wrapPromise(promiseAny(inputs.map(toPromise)));
3297
+ }
3298
+ const obj = inputs;
3299
+ const keys2 = Object.keys(obj);
3300
+ return wrapPromise(
3301
+ promiseAny(
3302
+ keys2.map((k) => toPromise(obj[k]).then((v) => [k, v]))
3303
+ )
3304
+ );
3305
+ };
3306
+ const callback = (cb) => {
3307
+ return (...args) => {
3308
+ if (isCancelled()) {
3309
+ return;
2810
3310
  }
3311
+ cb(...args);
2811
3312
  };
2812
- setupSubscriptions();
2813
- return clearSubscriptions;
2814
3313
  };
2815
- (_a = parentHooks.onRead) == null ? void 0 : _a.call(parentHooks, {
2816
- key: pickKey,
2817
- value: currentValue,
2818
- subscribe
3314
+ return Object.assign(safe, {
3315
+ all,
3316
+ race,
3317
+ settled,
3318
+ any,
3319
+ callback
2819
3320
  });
2820
- return currentValue;
2821
3321
  }
2822
- function patternToPredicate(pattern) {
2823
- if (pattern instanceof RegExp) {
2824
- return (name) => pattern.test(name);
2825
- }
2826
- const startsWithWildcard = pattern.startsWith("*");
2827
- const endsWithWildcard = pattern.endsWith("*");
2828
- if (startsWithWildcard && endsWithWildcard) {
2829
- const substr = pattern.slice(1, -1);
2830
- return (name) => name.includes(substr);
2831
- }
2832
- if (startsWithWildcard) {
2833
- const suffix = pattern.slice(1);
2834
- return (name) => name.endsWith(suffix);
2835
- }
2836
- if (endsWithWildcard) {
2837
- const prefix = pattern.slice(0, -1);
2838
- return (name) => name.startsWith(prefix);
2839
- }
2840
- return (name) => name === pattern;
2841
- }
2842
- function patternsToPredicate(patterns) {
2843
- if (Array.isArray(patterns)) {
2844
- const predicates = patterns.map(patternToPredicate);
2845
- return (ctx) => ctx.displayName !== void 0 && predicates.some((p) => p(ctx.displayName));
2846
- }
2847
- const predicate = patternToPredicate(patterns);
2848
- return (ctx) => ctx.displayName !== void 0 && predicate(ctx.displayName);
2849
- }
2850
- function compose(...middlewares) {
2851
- if (middlewares.length === 0) {
2852
- return (ctx) => ctx.next();
2853
- }
2854
- if (middlewares.length === 1) {
2855
- return middlewares[0];
3322
+ const retryStrategy = {
3323
+ /** Exponential backoff: 1s, 2s, 4s, 8s... (max 30s) */
3324
+ backoff: (attempt) => Math.min(1e3 * 2 ** attempt, 3e4),
3325
+ /** Linear: 1s, 2s, 3s, 4s... (max 30s) */
3326
+ linear: (attempt) => Math.min(1e3 * (attempt + 1), 3e4),
3327
+ /** Fixed 1 second delay */
3328
+ fixed: () => 1e3,
3329
+ /** Fibonacci: 1s, 1s, 2s, 3s, 5s, 8s... (max 30s) */
3330
+ fibonacci: (attempt) => {
3331
+ const fib = [1, 1, 2, 3, 5, 8, 13, 21, 30];
3332
+ return Math.min(fib[attempt] ?? 30, 30) * 1e3;
3333
+ },
3334
+ /** Immediate retry (no delay) */
3335
+ immediate: () => 0,
3336
+ /** Add jitter (±30%) to any strategy */
3337
+ withJitter: (strategy) => (attempt) => {
3338
+ const base = strategy(attempt);
3339
+ const jitter = base * 0.3 * (Math.random() * 2 - 1);
3340
+ return Math.max(0, Math.round(base + jitter));
2856
3341
  }
2857
- return (ctx) => {
2858
- let index = 0;
2859
- const executeNext = () => {
2860
- if (index >= middlewares.length) {
2861
- return ctx.next();
3342
+ };
3343
+ class AsyncNotReadyError extends Error {
3344
+ constructor(message, status) {
3345
+ super(message);
3346
+ this.status = status;
3347
+ this.name = "AsyncNotReadyError";
3348
+ }
3349
+ }
3350
+ class AsyncAggregateError extends Error {
3351
+ constructor(message, errors2) {
3352
+ super(message);
3353
+ this.errors = errors2;
3354
+ this.name = "AsyncAggregateError";
3355
+ }
3356
+ }
3357
+ function createEffectContext(nth, onRefresh) {
3358
+ let cleanupEmitter = null;
3359
+ let abortController = null;
3360
+ let isStale = false;
3361
+ const runCleanups = () => {
3362
+ if (isStale) return;
3363
+ isStale = true;
3364
+ if (abortController) {
3365
+ abortController.abort();
3366
+ abortController = null;
3367
+ }
3368
+ if (cleanupEmitter && cleanupEmitter.size > 0) {
3369
+ cleanupEmitter.emitAndClearLifo();
3370
+ }
3371
+ };
3372
+ const safe = createSafe(
3373
+ () => abortController ? abortController.signal : void 0,
3374
+ () => isStale
3375
+ );
3376
+ const context = {
3377
+ nth,
3378
+ get signal() {
3379
+ if (!abortController) {
3380
+ abortController = new AbortController();
2862
3381
  }
2863
- const currentMiddleware = middlewares[index];
2864
- index++;
2865
- const wrappedCtx = ctx.type === "store" ? { ...ctx, next: executeNext } : { ...ctx, next: executeNext };
2866
- return currentMiddleware(wrappedCtx);
2867
- };
2868
- return executeNext();
3382
+ return abortController.signal;
3383
+ },
3384
+ onCleanup(listener) {
3385
+ if (!cleanupEmitter) {
3386
+ cleanupEmitter = emitter();
3387
+ }
3388
+ return cleanupEmitter.on(listener);
3389
+ },
3390
+ safe,
3391
+ refresh() {
3392
+ if (!isStale) {
3393
+ onRefresh();
3394
+ }
3395
+ }
2869
3396
  };
2870
- }
2871
- function applyFor(predicateOrPatternsOrMap, middleware) {
2872
- if (typeof predicateOrPatternsOrMap === "object" && !Array.isArray(predicateOrPatternsOrMap) && !(predicateOrPatternsOrMap instanceof RegExp)) {
2873
- const entries = Object.entries(predicateOrPatternsOrMap);
2874
- const pairs = entries.map(([pattern, mw]) => ({
2875
- predicate: patternsToPredicate(pattern),
2876
- middleware: Array.isArray(mw) ? compose(...mw) : mw
2877
- }));
2878
- return (ctx) => {
2879
- for (const { predicate: predicate2, middleware: middleware2 } of pairs) {
2880
- if (predicate2(ctx)) {
2881
- return middleware2(ctx);
3397
+ return Object.assign(context, { _runCleanups: runCleanups });
3398
+ }
3399
+ function resolveErrorStrategy(effectOptions) {
3400
+ return (effectOptions == null ? void 0 : effectOptions.onError) ?? "keepAlive";
3401
+ }
3402
+ function getRetryDelay(config, attempt) {
3403
+ const { delay = "backoff" } = config;
3404
+ if (typeof delay === "string") {
3405
+ return retryStrategy[delay](attempt);
3406
+ }
3407
+ if (typeof delay === "function") {
3408
+ return delay(attempt);
3409
+ }
3410
+ return delay;
3411
+ }
3412
+ function effect(fn, options) {
3413
+ let currentContext = null;
3414
+ let subscriptionEmitter = null;
3415
+ let isStarted = false;
3416
+ let isRunning = false;
3417
+ let isDisposed = false;
3418
+ let runGeneration = 0;
3419
+ let retryCount = 0;
3420
+ let retryTimeout = null;
3421
+ let errorStrategy = "keepAlive";
3422
+ let onErrorCallback = null;
3423
+ let prevTrackedDeps = /* @__PURE__ */ new Map();
3424
+ let prevSubscriptionEmitter = null;
3425
+ let trackedDeps = /* @__PURE__ */ new Map();
3426
+ const writtenProps = /* @__PURE__ */ new Set();
3427
+ let newTrackedDeps = null;
3428
+ const getSubscriptionEmitter = () => {
3429
+ if (!subscriptionEmitter) {
3430
+ subscriptionEmitter = emitter();
3431
+ }
3432
+ return subscriptionEmitter;
3433
+ };
3434
+ const clearSubscriptions = () => {
3435
+ if (subscriptionEmitter && subscriptionEmitter.size > 0) {
3436
+ subscriptionEmitter.emitAndClear();
3437
+ }
3438
+ };
3439
+ const areDepsChanged = (prev, next) => {
3440
+ if (prev.size !== next.size) return true;
3441
+ for (const key of next.keys()) {
3442
+ if (!prev.has(key)) return true;
3443
+ }
3444
+ return false;
3445
+ };
3446
+ const subscribeToTrackedDeps = () => {
3447
+ for (const [key, dep] of trackedDeps) {
3448
+ if (writtenProps.has(key)) continue;
3449
+ const unsub = dep.subscribe(() => {
3450
+ scheduleNotification(execute, fn);
3451
+ });
3452
+ getSubscriptionEmitter().on(unsub);
3453
+ }
3454
+ };
3455
+ const handleError = (error) => {
3456
+ onErrorCallback == null ? void 0 : onErrorCallback(error);
3457
+ if (errorStrategy === "failFast") {
3458
+ throw error;
3459
+ }
3460
+ if (errorStrategy === "keepAlive") {
3461
+ console.error("Effect error (keepAlive):", error);
3462
+ if (prevSubscriptionEmitter && prevSubscriptionEmitter.size > 0) {
3463
+ trackedDeps = new Map(prevTrackedDeps);
3464
+ subscriptionEmitter = prevSubscriptionEmitter;
3465
+ prevSubscriptionEmitter = null;
3466
+ return;
3467
+ }
3468
+ if (newTrackedDeps && newTrackedDeps.size > 0) {
3469
+ trackedDeps = newTrackedDeps;
3470
+ }
3471
+ subscribeToTrackedDeps();
3472
+ return;
3473
+ }
3474
+ if (typeof errorStrategy === "function") {
3475
+ const retry = () => {
3476
+ retryCount++;
3477
+ execute();
3478
+ };
3479
+ errorStrategy({ error, retry, retryCount });
3480
+ return;
3481
+ }
3482
+ const retryConfig = errorStrategy;
3483
+ if (retryCount < retryConfig.retries) {
3484
+ const delay = getRetryDelay(retryConfig, retryCount);
3485
+ retryCount++;
3486
+ retryTimeout = setTimeout(() => {
3487
+ retryTimeout = null;
3488
+ execute();
3489
+ }, delay);
3490
+ } else {
3491
+ console.error(
3492
+ `Effect failed after ${retryConfig.retries} retries:`,
3493
+ error
3494
+ );
3495
+ }
3496
+ };
3497
+ let cachedHooks = null;
3498
+ const getTrackingHooks = (current2) => {
3499
+ if (!cachedHooks) {
3500
+ cachedHooks = {
3501
+ ...current2,
3502
+ onRead: (event) => {
3503
+ var _a;
3504
+ (_a = current2.onRead) == null ? void 0 : _a.call(current2, event);
3505
+ if (!newTrackedDeps.has(event.key)) {
3506
+ newTrackedDeps.set(event.key, {
3507
+ key: event.key,
3508
+ value: event.value,
3509
+ subscribe: event.subscribe
3510
+ });
3511
+ }
3512
+ },
3513
+ onWrite: (event) => {
3514
+ var _a;
3515
+ (_a = current2.onWrite) == null ? void 0 : _a.call(current2, event);
3516
+ writtenProps.add(event.key);
3517
+ },
3518
+ scheduleNotification: current2.scheduleNotification,
3519
+ scheduleEffect: current2.scheduleEffect
3520
+ };
3521
+ }
3522
+ return cachedHooks;
3523
+ };
3524
+ const execute = () => {
3525
+ if (isDisposed || isRunning) return;
3526
+ isRunning = true;
3527
+ let shouldRefresh = false;
3528
+ const currentGeneration = ++runGeneration;
3529
+ try {
3530
+ currentContext == null ? void 0 : currentContext._runCleanups();
3531
+ currentContext = null;
3532
+ if (subscriptionEmitter && subscriptionEmitter.size > 0) {
3533
+ prevTrackedDeps = new Map(trackedDeps);
3534
+ prevSubscriptionEmitter = subscriptionEmitter;
3535
+ subscriptionEmitter = null;
3536
+ }
3537
+ newTrackedDeps = /* @__PURE__ */ new Map();
3538
+ writtenProps.clear();
3539
+ let lazyContext = null;
3540
+ if (fn.length) {
3541
+ lazyContext = createEffectContext(currentGeneration, () => {
3542
+ if (isRunning) {
3543
+ throw new EffectRefreshError();
3544
+ }
3545
+ execute();
3546
+ });
3547
+ }
3548
+ withHooks(getTrackingHooks, () => {
3549
+ const result = fn(lazyContext);
3550
+ if (result !== null && result !== void 0 && typeof result.then === "function") {
3551
+ throw new AsyncFunctionError(
3552
+ "Effect function",
3553
+ "Use ctx.safe(promise) for async operations instead of returning a Promise."
3554
+ );
3555
+ }
3556
+ if (lazyContext && lazyContext.refresh === result) {
3557
+ shouldRefresh = true;
3558
+ }
3559
+ });
3560
+ currentContext = lazyContext;
3561
+ retryCount = 0;
3562
+ const depsChanged = areDepsChanged(trackedDeps, newTrackedDeps);
3563
+ if (depsChanged) {
3564
+ if (prevSubscriptionEmitter && prevSubscriptionEmitter.size > 0) {
3565
+ prevSubscriptionEmitter.emitAndClear();
3566
+ }
3567
+ trackedDeps = newTrackedDeps;
3568
+ subscribeToTrackedDeps();
3569
+ } else {
3570
+ if (prevSubscriptionEmitter) {
3571
+ subscriptionEmitter = prevSubscriptionEmitter;
2882
3572
  }
2883
3573
  }
2884
- return ctx.next();
2885
- };
2886
- }
2887
- const predicate = typeof predicateOrPatternsOrMap === "function" ? predicateOrPatternsOrMap : patternsToPredicate(predicateOrPatternsOrMap);
2888
- const composedMiddleware = Array.isArray(middleware) ? compose(...middleware) : middleware;
2889
- return (ctx) => {
2890
- if (predicate(ctx)) {
2891
- return composedMiddleware(ctx);
3574
+ prevTrackedDeps.clear();
3575
+ prevSubscriptionEmitter = null;
3576
+ } catch (error) {
3577
+ if (error instanceof EffectRefreshError) {
3578
+ throw error;
3579
+ }
3580
+ handleError(error);
3581
+ } finally {
3582
+ isRunning = false;
3583
+ }
3584
+ if (shouldRefresh) {
3585
+ execute();
2892
3586
  }
2893
- return ctx.next();
2894
3587
  };
2895
- }
2896
- function applyExcept(predicateOrPatterns, middleware) {
2897
- const matchPredicate = typeof predicateOrPatterns === "function" ? predicateOrPatterns : patternsToPredicate(predicateOrPatterns);
2898
- const invertedPredicate = (ctx) => !matchPredicate(ctx);
2899
- return applyFor(invertedPredicate, middleware);
2900
- }
2901
- function forStores(storeMiddleware) {
2902
- const composedMiddleware = Array.isArray(storeMiddleware) ? compose(...storeMiddleware) : storeMiddleware;
2903
- return (ctx) => {
2904
- if (ctx.type === "store") {
2905
- return composedMiddleware(ctx);
3588
+ const dispose = () => {
3589
+ if (isDisposed) return;
3590
+ isDisposed = true;
3591
+ runGeneration++;
3592
+ if (retryTimeout) {
3593
+ clearTimeout(retryTimeout);
3594
+ retryTimeout = null;
3595
+ }
3596
+ currentContext == null ? void 0 : currentContext._runCleanups();
3597
+ currentContext = null;
3598
+ clearSubscriptions();
3599
+ if (prevSubscriptionEmitter && prevSubscriptionEmitter.size > 0) {
3600
+ prevSubscriptionEmitter.emitAndClear();
2906
3601
  }
2907
- return ctx.next();
2908
3602
  };
2909
- }
2910
- const DEFAULT_KEY = {};
2911
- const cache = /* @__PURE__ */ new Map();
2912
- function getKeyCache(key) {
2913
- let keyCache = cache.get(key);
2914
- if (!keyCache) {
2915
- keyCache = /* @__PURE__ */ new WeakMap();
2916
- cache.set(key, keyCache);
2917
- }
2918
- return keyCache;
2919
- }
2920
- function trigger(keyOrFn, fnOrDepsOrOptions, depsOrFirstArg, ...restArgs) {
2921
- let key;
2922
- let fn;
2923
- let deps;
2924
- let equality2;
2925
- let args;
2926
- if (typeof fnOrDepsOrOptions === "function") {
2927
- key = keyOrFn;
2928
- fn = fnOrDepsOrOptions;
2929
- deps = depsOrFirstArg ?? [];
2930
- args = restArgs;
2931
- } else if (Array.isArray(fnOrDepsOrOptions)) {
2932
- key = DEFAULT_KEY;
2933
- fn = keyOrFn;
2934
- deps = fnOrDepsOrOptions;
2935
- args = depsOrFirstArg !== void 0 ? [depsOrFirstArg, ...restArgs] : [];
2936
- } else {
2937
- const options = fnOrDepsOrOptions ?? {};
2938
- key = options.key ?? DEFAULT_KEY;
2939
- fn = keyOrFn;
2940
- deps = options.deps ?? [];
2941
- equality2 = options.equality ? resolveEquality(options.equality) : void 0;
2942
- args = depsOrFirstArg !== void 0 ? [depsOrFirstArg, ...restArgs] : [];
2943
- }
2944
- const cacheKey = unwrapFn(fn);
2945
- const keyCache = getKeyCache(key);
2946
- const cached = keyCache.get(cacheKey);
2947
- const eq2 = equality2 ?? (cached == null ? void 0 : cached.equality) ?? shallowEqual;
2948
- if (cached && eq2(cached.deps, deps)) {
2949
- return cached.result;
2950
- }
2951
- const result = fn(...args);
2952
- keyCache.set(cacheKey, { deps, result, equality: equality2 });
2953
- return result;
2954
- }
2955
- trigger.clear = (key) => {
2956
- cache.delete(key);
2957
- };
2958
- trigger.clearAll = () => {
2959
- cache.clear();
2960
- };
2961
- function withMeta(factory, meta) {
2962
- return Object.assign(factory, {
2963
- meta: Array.isArray(meta) ? meta : [meta]
3603
+ const start = (runOptions) => {
3604
+ if (isStarted) return;
3605
+ isStarted = true;
3606
+ errorStrategy = resolveErrorStrategy(options);
3607
+ onErrorCallback = (runOptions == null ? void 0 : runOptions.onError) ?? null;
3608
+ execute();
3609
+ };
3610
+ getHooks().scheduleEffect((runOptions) => {
3611
+ start(runOptions);
3612
+ return dispose;
2964
3613
  });
3614
+ return dispose;
2965
3615
  }
2966
3616
  export {
2967
- withMeta as A,
2968
- STORION_TYPE as S,
2969
- is$1 as a,
2970
- isStorion as b,
2971
- container as c,
2972
- isContainer as d,
2973
- isStore as e,
2974
- isFocus as f,
2975
- getKind as g,
2976
- isAction as h,
3617
+ AsyncNotReadyError as A,
3618
+ pool as B,
3619
+ tryDispose as C,
3620
+ unwrapFn as D,
3621
+ EffectRefreshError as E,
3622
+ HooksContextError as H,
3623
+ InvalidActionError as I,
3624
+ LifetimeMismatchError as L,
3625
+ ProviderMissingError as P,
3626
+ SetupPhaseError as S,
3627
+ store as a,
3628
+ AsyncAggregateError as b,
3629
+ createSafe as c,
3630
+ AsyncFunctionError as d,
3631
+ effect as e,
3632
+ isAbortable as f,
3633
+ abortable as g,
3634
+ strictEqual as h,
2977
3635
  isSpec as i,
2978
- isStoreContext as j,
2979
- isSelectorContext as k,
2980
- createResolver as l,
2981
- applyFor as m,
2982
- applyExcept as n,
2983
- forStores as o,
3636
+ ScopedOutsideSelectorError as j,
3637
+ STORION_TYPE as k,
3638
+ resolveEquality as l,
3639
+ is$1 as m,
3640
+ batch as n,
3641
+ equality as o,
2984
3642
  pick as p,
2985
- equality as q,
2986
- resolveEquality as r,
2987
- store as s,
2988
- shallowEqual as t,
2989
- deepEqual as u,
2990
- strictEqual as v,
2991
- trigger as w,
2992
- wrapFn as x,
2993
- unwrapFn as y,
2994
- isWrappedFn as z
3643
+ shallowEqual as q,
3644
+ retryStrategy as r,
3645
+ storeTuple as s,
3646
+ tryStabilize as t,
3647
+ untrack as u,
3648
+ deepEqual as v,
3649
+ withHooks as w,
3650
+ StorionError as x,
3651
+ StoreDisposedError as y,
3652
+ LocalStoreDependencyError as z
2995
3653
  };