storion 0.2.3 → 0.3.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 (88) hide show
  1. package/README.md +705 -573
  2. package/dist/async/async.d.ts +87 -0
  3. package/dist/async/async.d.ts.map +1 -0
  4. package/dist/async/index.d.ts +13 -0
  5. package/dist/async/index.d.ts.map +1 -0
  6. package/dist/async/index.js +451 -0
  7. package/dist/async/types.d.ts +275 -0
  8. package/dist/async/types.d.ts.map +1 -0
  9. package/dist/collection.d.ts +42 -0
  10. package/dist/collection.d.ts.map +1 -0
  11. package/dist/core/container.d.ts +33 -2
  12. package/dist/core/container.d.ts.map +1 -1
  13. package/dist/core/createResolver.d.ts +47 -0
  14. package/dist/core/createResolver.d.ts.map +1 -0
  15. package/dist/core/equality.d.ts +23 -3
  16. package/dist/core/equality.d.ts.map +1 -1
  17. package/dist/core/fnWrapper.d.ts +54 -0
  18. package/dist/core/fnWrapper.d.ts.map +1 -0
  19. package/dist/core/pick.d.ts +6 -6
  20. package/dist/core/pick.d.ts.map +1 -1
  21. package/dist/core/store.d.ts +8 -8
  22. package/dist/core/store.d.ts.map +1 -1
  23. package/dist/core/storeContext.d.ts +63 -0
  24. package/dist/core/storeContext.d.ts.map +1 -0
  25. package/dist/devtools/controller.d.ts +4 -0
  26. package/dist/devtools/controller.d.ts.map +1 -0
  27. package/dist/devtools/index.d.ts +16 -0
  28. package/dist/devtools/index.d.ts.map +1 -0
  29. package/dist/devtools/index.js +229 -0
  30. package/dist/devtools/middleware.d.ts +22 -0
  31. package/dist/devtools/middleware.d.ts.map +1 -0
  32. package/dist/devtools/types.d.ts +116 -0
  33. package/dist/devtools/types.d.ts.map +1 -0
  34. package/dist/devtools-panel/DevtoolsPanel.d.ts +17 -0
  35. package/dist/devtools-panel/DevtoolsPanel.d.ts.map +1 -0
  36. package/dist/devtools-panel/components/CompareModal.d.ts +10 -0
  37. package/dist/devtools-panel/components/CompareModal.d.ts.map +1 -0
  38. package/dist/devtools-panel/components/EventEntry.d.ts +14 -0
  39. package/dist/devtools-panel/components/EventEntry.d.ts.map +1 -0
  40. package/dist/devtools-panel/components/EventFilterBar.d.ts +10 -0
  41. package/dist/devtools-panel/components/EventFilterBar.d.ts.map +1 -0
  42. package/dist/devtools-panel/components/EventsTab.d.ts +15 -0
  43. package/dist/devtools-panel/components/EventsTab.d.ts.map +1 -0
  44. package/dist/devtools-panel/components/ResizeHandle.d.ts +8 -0
  45. package/dist/devtools-panel/components/ResizeHandle.d.ts.map +1 -0
  46. package/dist/devtools-panel/components/StoreEntry.d.ts +13 -0
  47. package/dist/devtools-panel/components/StoreEntry.d.ts.map +1 -0
  48. package/dist/devtools-panel/components/StoresTab.d.ts +12 -0
  49. package/dist/devtools-panel/components/StoresTab.d.ts.map +1 -0
  50. package/dist/devtools-panel/components/TabLayout.d.ts +48 -0
  51. package/dist/devtools-panel/components/TabLayout.d.ts.map +1 -0
  52. package/dist/devtools-panel/components/icons.d.ts +27 -0
  53. package/dist/devtools-panel/components/icons.d.ts.map +1 -0
  54. package/dist/devtools-panel/components/index.d.ts +15 -0
  55. package/dist/devtools-panel/components/index.d.ts.map +1 -0
  56. package/dist/devtools-panel/hooks.d.ts +23 -0
  57. package/dist/devtools-panel/hooks.d.ts.map +1 -0
  58. package/dist/devtools-panel/index.d.ts +25 -0
  59. package/dist/devtools-panel/index.d.ts.map +1 -0
  60. package/dist/devtools-panel/index.js +3326 -0
  61. package/dist/devtools-panel/mount.d.ts +41 -0
  62. package/dist/devtools-panel/mount.d.ts.map +1 -0
  63. package/dist/devtools-panel/styles.d.ts +50 -0
  64. package/dist/devtools-panel/styles.d.ts.map +1 -0
  65. package/dist/devtools-panel/types.d.ts +15 -0
  66. package/dist/devtools-panel/types.d.ts.map +1 -0
  67. package/dist/devtools-panel/utils.d.ts +21 -0
  68. package/dist/devtools-panel/utils.d.ts.map +1 -0
  69. package/dist/index.d.ts +6 -1
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/is.d.ts +69 -0
  72. package/dist/is.d.ts.map +1 -0
  73. package/dist/react/create.d.ts +1 -1
  74. package/dist/react/index.d.ts +1 -0
  75. package/dist/react/index.d.ts.map +1 -1
  76. package/dist/react/index.js +209 -33
  77. package/dist/react/useLocalStore.d.ts.map +1 -1
  78. package/dist/react/useStore.d.ts +2 -2
  79. package/dist/react/useStore.d.ts.map +1 -1
  80. package/dist/react/withStore.d.ts +140 -0
  81. package/dist/react/withStore.d.ts.map +1 -0
  82. package/dist/{index-rLf6DusB.js → store-XP2pujaJ.js} +537 -740
  83. package/dist/storion.js +740 -9
  84. package/dist/trigger.d.ts +40 -0
  85. package/dist/trigger.d.ts.map +1 -0
  86. package/dist/types.d.ts +516 -50
  87. package/dist/types.d.ts.map +1 -1
  88. package/package.json +13 -1
@@ -0,0 +1,87 @@
1
+ import { Focus } from '../types';
2
+ import { AsyncState, AsyncMode, AsyncHandler, AsyncOptions, AsyncActions, CancellablePromise, InferAsyncData, MapAsyncData, MapSettledResult, RaceResult } from './types';
3
+
4
+ /**
5
+ * Get the pending promise for an async state (for Suspense).
6
+ * Returns undefined if no pending promise.
7
+ */
8
+ export declare function getPendingPromise<T>(state: AsyncState<T, any>): Promise<T> | undefined;
9
+ /**
10
+ * Wraps a synchronous or async function to always return a Promise.
11
+ * Ensures async execution even for synchronous functions.
12
+ */
13
+ declare function promiseTry<T>(fn: () => T | PromiseLike<T>): Promise<Awaited<T>>;
14
+ export declare function async<T, M extends AsyncMode, TArgs extends any[]>(focus: Focus<AsyncState<T, M>>, handler: AsyncHandler<T, TArgs>, options?: AsyncOptions): AsyncActions<T, M, TArgs>;
15
+ export declare namespace async {
16
+ /**
17
+ * Create a fresh mode async state (data undefined during loading/error).
18
+ */
19
+ function fresh<T = unknown>(): AsyncState<T, "fresh">;
20
+ /**
21
+ * Create a stale mode async state with initial data.
22
+ * Data is preserved during loading and error states.
23
+ */
24
+ function stale<T>(initialData: T): AsyncState<T, "stale">;
25
+ function delay<T = void>(ms: number, resolved?: T): CancellablePromise<T>;
26
+ /**
27
+ * Wraps a synchronous or async function to always return a Promise.
28
+ * Ensures async execution even for synchronous functions.
29
+ *
30
+ * This is the same utility used internally for dispatching handlers.
31
+ *
32
+ * @example
33
+ * const promise = async.invoke(() => {
34
+ * // Sync or async code
35
+ * return someValue;
36
+ * });
37
+ */
38
+ const invoke: typeof promiseTry;
39
+ /**
40
+ * Extract data from AsyncState, throws if not ready.
41
+ * - Success: returns data
42
+ * - Stale mode (idle/pending/error with data): returns stale data
43
+ * - Pending with promise: throws promise (for Suspense)
44
+ * - Otherwise: throws error or AsyncNotReadyError
45
+ */
46
+ function wait<T, M extends AsyncMode>(state: AsyncState<T, M>): M extends "stale" ? T : T;
47
+ /**
48
+ * Returns the first successful result from a record of async states.
49
+ * Also considers stale data as "ready" in stale mode.
50
+ */
51
+ function race<T extends Record<string, AsyncState<any, any>>>(states: T): RaceResult<T>;
52
+ /**
53
+ * Returns all data if all states are ready.
54
+ * In stale mode, stale data counts as ready.
55
+ */
56
+ function all<T extends readonly AsyncState<any, any>[]>(...states: T): MapAsyncData<T>;
57
+ /**
58
+ * Returns the first ready data from multiple states.
59
+ */
60
+ function any<T extends readonly AsyncState<any, any>[]>(...states: T): InferAsyncData<T[number]>;
61
+ /**
62
+ * Returns settled results for all states (never throws).
63
+ * Includes mode-aware data in results.
64
+ */
65
+ function settled<T extends readonly AsyncState<any, any>[]>(...states: T): MapSettledResult<T>;
66
+ /**
67
+ * Check if state has data available (success or stale).
68
+ */
69
+ function hasData<T, M extends AsyncMode>(state: AsyncState<T, M>): state is AsyncState<T, M> & {
70
+ data: T;
71
+ };
72
+ /**
73
+ * Check if state is loading (pending status).
74
+ */
75
+ function isLoading<T, M extends AsyncMode>(state: AsyncState<T, M>): state is AsyncState<T, M> & {
76
+ status: "pending";
77
+ };
78
+ /**
79
+ * Check if state has an error.
80
+ */
81
+ function isError<T, M extends AsyncMode>(state: AsyncState<T, M>): state is AsyncState<T, M> & {
82
+ status: "error";
83
+ error: Error;
84
+ };
85
+ }
86
+ export {};
87
+ //# sourceMappingURL=async.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async.d.ts","sourceRoot":"","sources":["../../src/async/async.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EACV,UAAU,EACV,SAAS,EAET,YAAY,EACZ,YAAY,EACZ,YAAY,EAEZ,kBAAkB,EAElB,cAAc,EAEd,YAAY,EACZ,gBAAgB,EAChB,UAAU,EAIX,MAAM,SAAS,CAAC;AAOjB;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,GACxB,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAKxB;AAID;;;GAGG;AACH,iBAAS,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAIxE;AAuDD,wBAAgB,KAAK,CAAC,CAAC,EAAE,CAAC,SAAS,SAAS,EAAE,KAAK,SAAS,GAAG,EAAE,EAC/D,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAC9B,OAAO,EAAE,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAkU3B;AAID,yBAAiB,KAAK,CAAC;IAGrB;;OAEG;IACH,SAAgB,KAAK,CAAC,CAAC,GAAG,OAAO,KAAK,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CAS3D;IAED;;;OAGG;IACH,SAAgB,KAAK,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CAS/D;IAGD,SAAgB,KAAK,CAAC,CAAC,GAAG,IAAI,EAC5B,EAAE,EAAE,MAAM,EACV,QAAQ,CAAC,EAAE,CAAC,GACX,kBAAkB,CAAC,CAAC,CAAC,CAUvB;IAED;;;;;;;;;;;OAWG;IACI,MAAM,MAAM,mBAAa,CAAC;IAEjC;;;;;;OAMG;IACH,SAAgB,IAAI,CAAC,CAAC,EAAE,CAAC,SAAS,SAAS,EACzC,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GACtB,CAAC,SAAS,OAAO,GAAG,CAAC,GAAG,CAAC,CA0B3B;IAED;;;OAGG;IACH,SAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EACjE,MAAM,EAAE,CAAC,GACR,UAAU,CAAC,CAAC,CAAC,CAoCf;IAED;;;OAGG;IACH,SAAgB,GAAG,CAAC,CAAC,SAAS,SAAS,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAC3D,GAAG,MAAM,EAAE,CAAC,GACX,YAAY,CAAC,CAAC,CAAC,CA4BjB;IAED;;OAEG;IACH,SAAgB,GAAG,CAAC,CAAC,SAAS,SAAS,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAC3D,GAAG,MAAM,EAAE,CAAC,GACX,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CA8B3B;IAED;;;OAGG;IACH,SAAgB,OAAO,CAAC,CAAC,SAAS,SAAS,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAC/D,GAAG,MAAM,EAAE,CAAC,GACX,gBAAgB,CAAC,CAAC,CAAC,CA+BrB;IAED;;OAEG;IACH,SAAgB,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,SAAS,EAC5C,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GACtB,KAAK,IAAI,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAIzC;IAED;;OAEG;IACH,SAAgB,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,SAAS,EAC9C,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GACtB,KAAK,IAAI,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,MAAM,EAAE,SAAS,CAAA;KAAE,CAEnD;IAED;;OAEG;IACH,SAAgB,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,SAAS,EAC5C,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GACtB,KAAK,IAAI,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAE/D;CACF"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Async module for Storion
3
+ *
4
+ * Provides utilities for handling async operations (queries/mutations)
5
+ * with built-in cancellation, retry, and state management.
6
+ *
7
+ * Two modes:
8
+ * - fresh: data is undefined during loading/error (only show fresh data)
9
+ * - stale: data is preserved during loading/error (stale-while-revalidate)
10
+ */
11
+ export { async, getPendingPromise } from './async';
12
+ export { AsyncNotReadyError, AsyncAggregateError, type AsyncMode, type AsyncState, type AsyncIdleState, type AsyncIdleStateFresh, type AsyncIdleStateStale, type AsyncPendingState, type AsyncPendingStateFresh, type AsyncPendingStateStale, type AsyncSuccessState, type AsyncErrorState, type AsyncErrorStateFresh, type AsyncErrorStateStale, type AsyncStatus, type AsyncContext, type AsyncHandler, type AsyncOptions, type AsyncRetryOptions, type AsyncActions, type AsyncLastInvocation, type CancellablePromise, type InferAsyncData, type InferAsyncMode, type SettledResult, type MapAsyncData, type MapSettledResult, type RaceResult, type AsyncKey, type SerializedAsyncState, } from './types';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/async/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,oBAAoB,GAC1B,MAAM,SAAS,CAAC"}
@@ -0,0 +1,451 @@
1
+ class AsyncNotReadyError extends Error {
2
+ constructor(message, status) {
3
+ super(message);
4
+ this.status = status;
5
+ this.name = "AsyncNotReadyError";
6
+ }
7
+ }
8
+ class AsyncAggregateError extends Error {
9
+ constructor(message, errors) {
10
+ super(message);
11
+ this.errors = errors;
12
+ this.name = "AsyncAggregateError";
13
+ }
14
+ }
15
+ const pendingPromises = /* @__PURE__ */ new WeakMap();
16
+ function getPendingPromise(state) {
17
+ if (state.status === "pending" && "__key" in state && state.__key) {
18
+ return pendingPromises.get(state.__key);
19
+ }
20
+ return void 0;
21
+ }
22
+ function promiseTry(fn) {
23
+ return new Promise((resolve) => {
24
+ resolve(fn());
25
+ });
26
+ }
27
+ function createCancellablePromise(promise, cancel) {
28
+ const cancellable = promise;
29
+ cancellable.cancel = cancel;
30
+ return cancellable;
31
+ }
32
+ function stateToJSON() {
33
+ if (this.mode === "stale") {
34
+ return { status: "success", mode: "stale", data: this.data };
35
+ }
36
+ if (this.status === "success") {
37
+ return { status: "success", mode: "fresh", data: this.data };
38
+ }
39
+ return null;
40
+ }
41
+ function getRetryCount(retry) {
42
+ if (typeof retry === "number") return retry;
43
+ if (retry && typeof retry === "object") return retry.count;
44
+ return 0;
45
+ }
46
+ function getRetryDelay(retry, attempt, error) {
47
+ if (typeof retry === "number") return 1e3;
48
+ if (retry && typeof retry === "object") {
49
+ if (typeof retry.delay === "function") return retry.delay(attempt, error);
50
+ return retry.delay ?? 1e3;
51
+ }
52
+ return 1e3;
53
+ }
54
+ function async(focus, handler, options) {
55
+ const [getState, setState] = focus;
56
+ const asyncKey = {};
57
+ let lastCancel = null;
58
+ let lastArgs = null;
59
+ let invocationCount = 0;
60
+ function dispatch(...args) {
61
+ if (lastCancel && (options == null ? void 0 : options.autoCancel) !== false) {
62
+ lastCancel();
63
+ }
64
+ const abortController = new AbortController();
65
+ let isCancelled = false;
66
+ const requestId = {};
67
+ let rejectOnCancel = null;
68
+ const cancelPromise = new Promise((_, reject) => {
69
+ rejectOnCancel = reject;
70
+ });
71
+ const cancel2 = () => {
72
+ if (!isCancelled) {
73
+ isCancelled = true;
74
+ abortController.abort();
75
+ pendingPromises.delete(asyncKey);
76
+ rejectOnCancel == null ? void 0 : rejectOnCancel(new DOMException("Aborted", "AbortError"));
77
+ }
78
+ };
79
+ lastCancel = cancel2;
80
+ lastArgs = args;
81
+ invocationCount++;
82
+ const prevState = getState();
83
+ const mode = prevState.mode;
84
+ const staleData = mode === "stale" ? prevState.data : prevState.status === "success" ? prevState.data : void 0;
85
+ const autoCancel = (options == null ? void 0 : options.autoCancel) !== false;
86
+ const isStateExternallyModified = () => {
87
+ if (!autoCancel) {
88
+ const currentState2 = getState();
89
+ return currentState2.__requestId === void 0;
90
+ }
91
+ const currentState = getState();
92
+ return currentState.__requestId !== requestId;
93
+ };
94
+ const retryCount = getRetryCount(options == null ? void 0 : options.retry);
95
+ const executeWithRetry = async () => {
96
+ let lastError = null;
97
+ for (let attempt = 0; attempt <= retryCount; attempt++) {
98
+ try {
99
+ const isCancelledOrAborted = () => isCancelled || abortController.signal.aborted;
100
+ const asyncContext = {
101
+ signal: abortController.signal,
102
+ safe(promiseOrCallback) {
103
+ if (promiseOrCallback instanceof Promise) {
104
+ return new Promise((resolve, reject) => {
105
+ promiseOrCallback.then(
106
+ (value) => {
107
+ if (!isCancelledOrAborted()) {
108
+ resolve(value);
109
+ }
110
+ },
111
+ (error) => {
112
+ if (!isCancelledOrAborted()) {
113
+ reject(error);
114
+ }
115
+ }
116
+ );
117
+ });
118
+ }
119
+ return (...args2) => {
120
+ if (!isCancelledOrAborted()) {
121
+ return promiseOrCallback(
122
+ ...args2
123
+ );
124
+ }
125
+ return void 0;
126
+ };
127
+ },
128
+ cancel: cancel2
129
+ };
130
+ const result = await promiseTry(() => handler(asyncContext, ...args));
131
+ if (isCancelled) {
132
+ throw new DOMException("Aborted", "AbortError");
133
+ }
134
+ if (isStateExternallyModified()) {
135
+ return result;
136
+ }
137
+ setState({
138
+ status: "success",
139
+ mode,
140
+ data: result,
141
+ error: void 0,
142
+ timestamp: Date.now(),
143
+ __requestId: requestId,
144
+ toJSON: stateToJSON
145
+ });
146
+ if (lastCancel === cancel2) {
147
+ lastCancel = null;
148
+ }
149
+ return result;
150
+ } catch (error) {
151
+ if (isCancelled || abortController.signal.aborted) {
152
+ throw error instanceof Error ? error : new DOMException("Aborted", "AbortError");
153
+ }
154
+ lastError = error instanceof Error ? error : new Error(String(error));
155
+ if (attempt < retryCount) {
156
+ const delay = getRetryDelay(options == null ? void 0 : options.retry, attempt + 1, lastError);
157
+ await new Promise((resolve) => setTimeout(resolve, delay));
158
+ continue;
159
+ }
160
+ }
161
+ }
162
+ if (!abortController.signal.aborted) {
163
+ abortController.abort();
164
+ }
165
+ if (isStateExternallyModified()) {
166
+ throw lastError;
167
+ }
168
+ setState({
169
+ status: "error",
170
+ mode,
171
+ data: mode === "stale" ? staleData : void 0,
172
+ error: lastError,
173
+ timestamp: void 0,
174
+ __requestId: requestId,
175
+ toJSON: stateToJSON
176
+ });
177
+ if (lastCancel === cancel2) {
178
+ lastCancel = null;
179
+ }
180
+ if ((options == null ? void 0 : options.onError) && lastError) {
181
+ options.onError(lastError);
182
+ }
183
+ throw lastError;
184
+ };
185
+ const executionPromise = executeWithRetry();
186
+ const promise = Promise.race([executionPromise, cancelPromise]);
187
+ pendingPromises.set(asyncKey, executionPromise);
188
+ setState({
189
+ status: "pending",
190
+ mode,
191
+ data: mode === "stale" ? staleData : void 0,
192
+ error: void 0,
193
+ timestamp: void 0,
194
+ __key: asyncKey,
195
+ __requestId: requestId,
196
+ toJSON: stateToJSON
197
+ });
198
+ promise.then(
199
+ () => pendingPromises.delete(asyncKey),
200
+ () => pendingPromises.delete(asyncKey)
201
+ );
202
+ return createCancellablePromise(promise, cancel2);
203
+ }
204
+ function refresh() {
205
+ if (lastArgs === null) {
206
+ return void 0;
207
+ }
208
+ return dispatch(...lastArgs);
209
+ }
210
+ function cancel() {
211
+ if (lastCancel) {
212
+ lastCancel();
213
+ lastCancel = null;
214
+ }
215
+ }
216
+ function reset() {
217
+ cancel();
218
+ lastArgs = null;
219
+ const currentState = getState();
220
+ const mode = currentState.mode;
221
+ const resetRequestId = {};
222
+ if (mode === "stale") {
223
+ setState({
224
+ status: "idle",
225
+ mode: "stale",
226
+ data: currentState.data,
227
+ error: void 0,
228
+ timestamp: void 0,
229
+ __requestId: resetRequestId,
230
+ toJSON: stateToJSON
231
+ });
232
+ } else {
233
+ setState({
234
+ status: "idle",
235
+ mode: "fresh",
236
+ data: void 0,
237
+ error: void 0,
238
+ timestamp: void 0,
239
+ __requestId: resetRequestId,
240
+ toJSON: stateToJSON
241
+ });
242
+ }
243
+ }
244
+ function last() {
245
+ const hasDispatched = !!lastArgs;
246
+ if (!hasDispatched) {
247
+ return void 0;
248
+ }
249
+ return {
250
+ args: lastArgs,
251
+ nth: invocationCount,
252
+ // Read state to trigger reactivity (via focus getter) - this is the only tracked read
253
+ state: getState()
254
+ };
255
+ }
256
+ return {
257
+ dispatch,
258
+ refresh,
259
+ cancel,
260
+ reset,
261
+ last
262
+ };
263
+ }
264
+ ((async2) => {
265
+ function fresh() {
266
+ return {
267
+ status: "idle",
268
+ mode: "fresh",
269
+ data: void 0,
270
+ error: void 0,
271
+ timestamp: void 0,
272
+ toJSON: stateToJSON
273
+ };
274
+ }
275
+ async2.fresh = fresh;
276
+ function stale(initialData) {
277
+ return {
278
+ status: "idle",
279
+ mode: "stale",
280
+ data: initialData,
281
+ error: void 0,
282
+ timestamp: void 0,
283
+ toJSON: stateToJSON
284
+ };
285
+ }
286
+ async2.stale = stale;
287
+ function delay(ms, resolved) {
288
+ let timeout;
289
+ return createCancellablePromise(
290
+ new Promise((resolve) => {
291
+ timeout = setTimeout(resolve, ms, resolved);
292
+ }),
293
+ () => {
294
+ clearTimeout(timeout);
295
+ }
296
+ );
297
+ }
298
+ async2.delay = delay;
299
+ async2.invoke = promiseTry;
300
+ function wait(state) {
301
+ if (state.status === "success") {
302
+ return state.data;
303
+ }
304
+ if (state.mode === "stale" && state.data !== void 0) {
305
+ return state.data;
306
+ }
307
+ if (state.status === "error") {
308
+ throw state.error;
309
+ }
310
+ if (state.status === "pending") {
311
+ const promise = getPendingPromise(state);
312
+ if (promise) {
313
+ throw promise;
314
+ }
315
+ }
316
+ throw new AsyncNotReadyError(
317
+ `Cannot wait: state is ${state.status}`,
318
+ state.status
319
+ );
320
+ }
321
+ async2.wait = wait;
322
+ function race(states) {
323
+ for (const key in states) {
324
+ if (Object.prototype.hasOwnProperty.call(states, key)) {
325
+ const state = states[key];
326
+ if (state.status === "success") {
327
+ return [key, state.data];
328
+ }
329
+ }
330
+ }
331
+ for (const key in states) {
332
+ if (Object.prototype.hasOwnProperty.call(states, key)) {
333
+ const state = states[key];
334
+ if (state.mode === "stale" && state.data !== void 0) {
335
+ return [key, state.data];
336
+ }
337
+ }
338
+ }
339
+ for (const key in states) {
340
+ if (Object.prototype.hasOwnProperty.call(states, key)) {
341
+ const state = states[key];
342
+ if (state.status === "error") {
343
+ throw state.error;
344
+ }
345
+ }
346
+ }
347
+ throw new AsyncNotReadyError(
348
+ "No async state has resolved successfully",
349
+ "pending"
350
+ );
351
+ }
352
+ async2.race = race;
353
+ function all(...states) {
354
+ const results = [];
355
+ for (let i = 0; i < states.length; i++) {
356
+ const state = states[i];
357
+ if (state.status === "success") {
358
+ results.push(state.data);
359
+ continue;
360
+ }
361
+ if (state.mode === "stale" && state.data !== void 0) {
362
+ results.push(state.data);
363
+ continue;
364
+ }
365
+ if (state.status === "error") {
366
+ throw state.error;
367
+ }
368
+ throw new AsyncNotReadyError(
369
+ `State at index ${i} is ${state.status}`,
370
+ state.status
371
+ );
372
+ }
373
+ return results;
374
+ }
375
+ async2.all = all;
376
+ function any(...states) {
377
+ const errors = [];
378
+ for (const state of states) {
379
+ if (state.status === "success") {
380
+ return state.data;
381
+ }
382
+ }
383
+ for (const state of states) {
384
+ if (state.mode === "stale" && state.data !== void 0) {
385
+ return state.data;
386
+ }
387
+ if (state.status === "error") {
388
+ errors.push(state.error);
389
+ }
390
+ }
391
+ if (errors.length === states.length) {
392
+ throw new AsyncAggregateError("All async states have errors", errors);
393
+ }
394
+ throw new AsyncNotReadyError(
395
+ "No async state has resolved successfully",
396
+ "pending"
397
+ );
398
+ }
399
+ async2.any = any;
400
+ function settled(...states) {
401
+ const results = [];
402
+ for (const state of states) {
403
+ switch (state.status) {
404
+ case "success":
405
+ results.push({ status: "success", data: state.data });
406
+ break;
407
+ case "error":
408
+ results.push({
409
+ status: "error",
410
+ error: state.error,
411
+ data: state.mode === "stale" ? state.data : void 0
412
+ });
413
+ break;
414
+ case "pending":
415
+ results.push({
416
+ status: "pending",
417
+ data: state.mode === "stale" ? state.data : void 0
418
+ });
419
+ break;
420
+ case "idle":
421
+ results.push({
422
+ status: "idle",
423
+ data: state.mode === "stale" ? state.data : void 0
424
+ });
425
+ break;
426
+ }
427
+ }
428
+ return results;
429
+ }
430
+ async2.settled = settled;
431
+ function hasData(state) {
432
+ if (state.status === "success") return true;
433
+ if (state.mode === "stale" && state.data !== void 0) return true;
434
+ return false;
435
+ }
436
+ async2.hasData = hasData;
437
+ function isLoading(state) {
438
+ return state.status === "pending";
439
+ }
440
+ async2.isLoading = isLoading;
441
+ function isError(state) {
442
+ return state.status === "error";
443
+ }
444
+ async2.isError = isError;
445
+ })(async || (async = {}));
446
+ export {
447
+ AsyncAggregateError,
448
+ AsyncNotReadyError,
449
+ async,
450
+ getPendingPromise
451
+ };