atomirx 0.0.1 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +867 -160
- package/dist/core/atom.d.ts +83 -6
- package/dist/core/batch.d.ts +3 -3
- package/dist/core/derived.d.ts +55 -21
- package/dist/core/effect.d.ts +47 -51
- package/dist/core/getAtomState.d.ts +29 -0
- package/dist/core/promiseCache.d.ts +23 -32
- package/dist/core/select.d.ts +208 -29
- package/dist/core/types.d.ts +55 -19
- package/dist/core/withReady.d.ts +69 -0
- package/dist/index-CqO6BDwj.cjs +1 -0
- package/dist/index-D8RDOTB_.js +1319 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +9 -7
- package/dist/index.js +12 -10
- package/dist/react/index.cjs +10 -10
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.js +423 -379
- package/dist/react/rx.d.ts +114 -25
- package/dist/react/useAction.d.ts +5 -4
- package/dist/react/{useValue.d.ts → useSelector.d.ts} +56 -25
- package/dist/react/useSelector.test.d.ts +1 -0
- package/package.json +17 -1
- package/src/core/atom.test.ts +307 -43
- package/src/core/atom.ts +143 -21
- package/src/core/batch.test.ts +10 -10
- package/src/core/batch.ts +3 -3
- package/src/core/derived.test.ts +727 -72
- package/src/core/derived.ts +141 -73
- package/src/core/effect.test.ts +259 -39
- package/src/core/effect.ts +62 -85
- package/src/core/getAtomState.ts +69 -0
- package/src/core/promiseCache.test.ts +5 -3
- package/src/core/promiseCache.ts +76 -71
- package/src/core/select.ts +405 -130
- package/src/core/selector.test.ts +574 -32
- package/src/core/types.ts +54 -26
- package/src/core/withReady.test.ts +360 -0
- package/src/core/withReady.ts +127 -0
- package/src/core/withUse.ts +1 -1
- package/src/index.test.ts +4 -4
- package/src/index.ts +11 -6
- package/src/react/index.ts +2 -1
- package/src/react/rx.test.tsx +173 -18
- package/src/react/rx.tsx +274 -43
- package/src/react/useAction.test.ts +12 -14
- package/src/react/useAction.ts +11 -9
- package/src/react/{useValue.test.ts → useSelector.test.ts} +16 -16
- package/src/react/{useValue.ts → useSelector.ts} +64 -33
- package/v2.md +44 -44
- package/dist/index-2ok7ilik.js +0 -1217
- package/dist/index-B_5SFzfl.cjs +0 -1
- /package/dist/{react/useValue.test.d.ts → core/withReady.test.d.ts} +0 -0
package/dist/core/select.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Atom, AtomValue, SettledResult } from './types';
|
|
1
|
+
import { Atom, AtomValue, KeyedResult, Pipeable, SelectStateResult, SettledResult } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* Result of a select computation.
|
|
4
4
|
*
|
|
@@ -14,11 +14,16 @@ export interface SelectResult<T> {
|
|
|
14
14
|
/** Set of atoms that were accessed during computation */
|
|
15
15
|
dependencies: Set<Atom<unknown>>;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Result type for safe() - error-first tuple.
|
|
19
|
+
* Either [undefined, T] for success or [unknown, undefined] for error.
|
|
20
|
+
*/
|
|
21
|
+
export type SafeResult<T> = [error: undefined, result: T] | [error: unknown, result: undefined];
|
|
17
22
|
/**
|
|
18
23
|
* Context object passed to selector functions.
|
|
19
24
|
* Provides utilities for reading atoms and handling async operations.
|
|
20
25
|
*/
|
|
21
|
-
export interface SelectContext {
|
|
26
|
+
export interface SelectContext extends Pipeable {
|
|
22
27
|
/**
|
|
23
28
|
* Read the current value of an atom.
|
|
24
29
|
* Tracks the atom as a dependency.
|
|
@@ -31,74 +36,180 @@ export interface SelectContext {
|
|
|
31
36
|
* @param atom - The atom to read
|
|
32
37
|
* @returns The atom's current value (Awaited<T>)
|
|
33
38
|
*/
|
|
34
|
-
|
|
39
|
+
read<T>(atom: Atom<T>): Awaited<T>;
|
|
35
40
|
/**
|
|
36
41
|
* Wait for all atoms to resolve (like Promise.all).
|
|
37
|
-
*
|
|
42
|
+
* Array-based - pass atoms as an array.
|
|
38
43
|
*
|
|
39
44
|
* - If all atoms are ready → returns array of values
|
|
40
45
|
* - If any atom has error → throws that error
|
|
41
46
|
* - If any atom is loading (no fallback) → throws Promise
|
|
42
47
|
* - If loading with fallback → uses staleValue
|
|
43
48
|
*
|
|
44
|
-
* @param atoms -
|
|
49
|
+
* @param atoms - Array of atoms to wait for
|
|
45
50
|
* @returns Array of resolved values (same order as input)
|
|
46
51
|
*
|
|
47
52
|
* @example
|
|
48
53
|
* ```ts
|
|
49
|
-
* const [user, posts] = all(user$, posts$);
|
|
54
|
+
* const [user, posts] = all([user$, posts$]);
|
|
50
55
|
* ```
|
|
51
56
|
*/
|
|
52
|
-
all<A extends Atom<unknown>[]>(
|
|
57
|
+
all<A extends Atom<unknown>[]>(atoms: A): {
|
|
53
58
|
[K in keyof A]: AtomValue<A[K]>;
|
|
54
59
|
};
|
|
55
60
|
/**
|
|
56
61
|
* Return the first settled value (like Promise.race).
|
|
57
|
-
*
|
|
62
|
+
* Object-based - pass atoms as a record with keys.
|
|
58
63
|
*
|
|
59
|
-
* - If any atom is ready → returns first ready
|
|
64
|
+
* - If any atom is ready → returns `{ key, value }` for first ready
|
|
60
65
|
* - If any atom has error → throws first error
|
|
61
66
|
* - If all atoms are loading → throws first Promise
|
|
62
67
|
*
|
|
68
|
+
* The `key` in the result identifies which atom won the race.
|
|
69
|
+
*
|
|
63
70
|
* Note: race() does NOT use fallback - it's meant for first "real" settled value.
|
|
64
71
|
*
|
|
65
|
-
* @param atoms -
|
|
66
|
-
* @returns
|
|
72
|
+
* @param atoms - Record of atoms to race
|
|
73
|
+
* @returns KeyedResult with winning key and value
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* const result = race({ cache: cache$, api: api$ });
|
|
78
|
+
* console.log(result.key); // "cache" or "api"
|
|
79
|
+
* console.log(result.value); // The winning value
|
|
80
|
+
* ```
|
|
67
81
|
*/
|
|
68
|
-
race<
|
|
82
|
+
race<T extends Record<string, Atom<unknown>>>(atoms: T): KeyedResult<keyof T & string, AtomValue<T[keyof T]>>;
|
|
69
83
|
/**
|
|
70
84
|
* Return the first ready value (like Promise.any).
|
|
71
|
-
*
|
|
85
|
+
* Object-based - pass atoms as a record with keys.
|
|
72
86
|
*
|
|
73
|
-
* - If any atom is ready → returns first ready
|
|
87
|
+
* - If any atom is ready → returns `{ key, value }` for first ready
|
|
74
88
|
* - If all atoms have errors → throws AggregateError
|
|
75
89
|
* - If any loading (not all errored) → throws Promise
|
|
76
90
|
*
|
|
91
|
+
* The `key` in the result identifies which atom resolved first.
|
|
92
|
+
*
|
|
77
93
|
* Note: any() does NOT use fallback - it waits for a real ready value.
|
|
78
94
|
*
|
|
79
|
-
* @param atoms -
|
|
80
|
-
* @returns
|
|
95
|
+
* @param atoms - Record of atoms to check
|
|
96
|
+
* @returns KeyedResult with winning key and value
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* const result = any({ primary: primaryApi$, fallback: fallbackApi$ });
|
|
101
|
+
* console.log(result.key); // "primary" or "fallback"
|
|
102
|
+
* console.log(result.value); // The winning value
|
|
103
|
+
* ```
|
|
81
104
|
*/
|
|
82
|
-
any<
|
|
105
|
+
any<T extends Record<string, Atom<unknown>>>(atoms: T): KeyedResult<keyof T & string, AtomValue<T[keyof T]>>;
|
|
83
106
|
/**
|
|
84
107
|
* Get all atom statuses when all are settled (like Promise.allSettled).
|
|
85
|
-
*
|
|
108
|
+
* Array-based - pass atoms as an array.
|
|
86
109
|
*
|
|
87
110
|
* - If all atoms are settled → returns array of statuses
|
|
88
111
|
* - If any atom is loading (no fallback) → throws Promise
|
|
89
112
|
* - If loading with fallback → { status: "ready", value: staleValue }
|
|
90
113
|
*
|
|
91
|
-
* @param atoms -
|
|
114
|
+
* @param atoms - Array of atoms to check
|
|
92
115
|
* @returns Array of settled results
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* const [userResult, postsResult] = settled([user$, posts$]);
|
|
120
|
+
* ```
|
|
93
121
|
*/
|
|
94
|
-
settled<A extends Atom<unknown>[]>(
|
|
122
|
+
settled<A extends Atom<unknown>[]>(atoms: A): {
|
|
95
123
|
[K in keyof A]: SettledResult<AtomValue<A[K]>>;
|
|
96
124
|
};
|
|
125
|
+
/**
|
|
126
|
+
* Safely execute a function, catching errors but preserving Suspense.
|
|
127
|
+
*
|
|
128
|
+
* - If function succeeds → returns [undefined, result]
|
|
129
|
+
* - If function throws Error → returns [error, undefined]
|
|
130
|
+
* - If function throws Promise → re-throws (preserves Suspense)
|
|
131
|
+
*
|
|
132
|
+
* Use this when you need error handling inside selectors without
|
|
133
|
+
* accidentally catching Suspense promises.
|
|
134
|
+
*
|
|
135
|
+
* @param fn - Function to execute safely
|
|
136
|
+
* @returns Error-first tuple: [error, result]
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```ts
|
|
140
|
+
* const data$ = derived(({ get, safe }) => {
|
|
141
|
+
* const [err, data] = safe(() => {
|
|
142
|
+
* const raw = get(raw$);
|
|
143
|
+
* return JSON.parse(raw); // Can throw SyntaxError
|
|
144
|
+
* });
|
|
145
|
+
*
|
|
146
|
+
* if (err) {
|
|
147
|
+
* return { error: err.message };
|
|
148
|
+
* }
|
|
149
|
+
* return { data };
|
|
150
|
+
* });
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
safe<T>(fn: () => T): SafeResult<T>;
|
|
154
|
+
/**
|
|
155
|
+
* Get the async state of an atom or selector without throwing.
|
|
156
|
+
*
|
|
157
|
+
* Unlike `read()` which throws promises/errors (Suspense pattern),
|
|
158
|
+
* `state()` always returns a `SelectStateResult<T>` object that you can
|
|
159
|
+
* inspect and handle inline.
|
|
160
|
+
*
|
|
161
|
+
* All properties (`status`, `value`, `error`) are always present,
|
|
162
|
+
* enabling easy destructuring:
|
|
163
|
+
* ```ts
|
|
164
|
+
* const { status, value, error } = state(atom$);
|
|
165
|
+
* ```
|
|
166
|
+
*
|
|
167
|
+
* @param atom - The atom to get state from
|
|
168
|
+
* @returns SelectStateResult with status, value, error (no promise - for equality)
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* // Get state of single atom
|
|
173
|
+
* const dashboard$ = derived(({ state }) => {
|
|
174
|
+
* const userState = state(user$);
|
|
175
|
+
* const postsState = state(posts$);
|
|
176
|
+
*
|
|
177
|
+
* return {
|
|
178
|
+
* user: userState.value, // undefined if not ready
|
|
179
|
+
* isLoading: userState.status === 'loading' || postsState.status === 'loading',
|
|
180
|
+
* };
|
|
181
|
+
* });
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
state<T>(atom: Atom<T>): SelectStateResult<Awaited<T>>;
|
|
185
|
+
/**
|
|
186
|
+
* Get the async state of a selector function without throwing.
|
|
187
|
+
*
|
|
188
|
+
* Wraps the selector in try/catch and returns the result as a
|
|
189
|
+
* `SelectStateResult<T>` object. Useful for getting state of combined
|
|
190
|
+
* operations like `all()`, `race()`, etc.
|
|
191
|
+
*
|
|
192
|
+
* @param selector - Function that may throw promises or errors
|
|
193
|
+
* @returns SelectStateResult with status, value, error (no promise - for equality)
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* ```ts
|
|
197
|
+
* // Get state of combined operation
|
|
198
|
+
* const allData$ = derived(({ state, all }) => {
|
|
199
|
+
* const result = state(() => all(a$, b$, c$));
|
|
200
|
+
*
|
|
201
|
+
* if (result.status === 'loading') return { loading: true };
|
|
202
|
+
* if (result.status === 'error') return { error: result.error };
|
|
203
|
+
* return { data: result.value };
|
|
204
|
+
* });
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
state<T>(selector: () => T): SelectStateResult<T>;
|
|
97
208
|
}
|
|
98
209
|
/**
|
|
99
210
|
* Selector function type for context-based API.
|
|
100
211
|
*/
|
|
101
|
-
export type
|
|
212
|
+
export type ReactiveSelector<T, C extends SelectContext = SelectContext> = (context: C) => T;
|
|
102
213
|
/**
|
|
103
214
|
* Custom error for when all atoms in `any()` are rejected.
|
|
104
215
|
*/
|
|
@@ -110,7 +221,7 @@ export declare class AllAtomsRejectedError extends Error {
|
|
|
110
221
|
* Selects/computes a value from atom(s) with dependency tracking.
|
|
111
222
|
*
|
|
112
223
|
* This is the core computation logic used by `derived()`. It:
|
|
113
|
-
* 1. Creates a context with `
|
|
224
|
+
* 1. Creates a context with `read`, `all`, `any`, `race`, `settled`, `safe` utilities
|
|
114
225
|
* 2. Tracks which atoms are accessed during computation
|
|
115
226
|
* 3. Returns a result with value/error/promise and dependencies
|
|
116
227
|
*
|
|
@@ -123,29 +234,97 @@ export declare class AllAtomsRejectedError extends Error {
|
|
|
123
234
|
* If your selector returns a Promise, it will throw an error. This is because:
|
|
124
235
|
* - `select()` is designed for synchronous derivation from atoms
|
|
125
236
|
* - Async atoms should be created using `atom(Promise)` directly
|
|
126
|
-
* - Use `
|
|
237
|
+
* - Use `read()` to read async atoms - it handles Suspense-style loading
|
|
127
238
|
*
|
|
128
239
|
* ```ts
|
|
129
240
|
* // ❌ WRONG - Don't return a Promise from selector
|
|
130
241
|
* select(({ get }) => fetch('/api/data'));
|
|
131
242
|
*
|
|
132
|
-
* // ✅ CORRECT - Create async atom and read with
|
|
243
|
+
* // ✅ CORRECT - Create async atom and read with read()
|
|
133
244
|
* const data$ = atom(fetch('/api/data').then(r => r.json()));
|
|
134
|
-
* select(({
|
|
245
|
+
* select(({ read }) => read(data$)); // Suspends until resolved
|
|
246
|
+
* ```
|
|
247
|
+
*
|
|
248
|
+
* ## IMPORTANT: Do NOT Use try/catch - Use safe() Instead
|
|
249
|
+
*
|
|
250
|
+
* **Never wrap `read()` calls in try/catch blocks.** The `read()` function throws
|
|
251
|
+
* Promises when atoms are loading (Suspense pattern). A try/catch will catch
|
|
252
|
+
* these Promises and break the Suspense mechanism.
|
|
253
|
+
*
|
|
254
|
+
* ```ts
|
|
255
|
+
* // ❌ WRONG - Catches Suspense Promise, breaks loading state
|
|
256
|
+
* select(({ read }) => {
|
|
257
|
+
* try {
|
|
258
|
+
* return read(asyncAtom$);
|
|
259
|
+
* } catch (e) {
|
|
260
|
+
* return 'fallback'; // This catches BOTH errors AND loading promises!
|
|
261
|
+
* }
|
|
262
|
+
* });
|
|
263
|
+
*
|
|
264
|
+
* // ✅ CORRECT - Use safe() to catch errors but preserve Suspense
|
|
265
|
+
* select(({ read, safe }) => {
|
|
266
|
+
* const [err, data] = safe(() => {
|
|
267
|
+
* const raw = read(asyncAtom$); // Can throw Promise (Suspense)
|
|
268
|
+
* return JSON.parse(raw); // Can throw Error
|
|
269
|
+
* });
|
|
270
|
+
*
|
|
271
|
+
* if (err) return { error: err.message };
|
|
272
|
+
* return { data };
|
|
273
|
+
* });
|
|
274
|
+
* ```
|
|
275
|
+
*
|
|
276
|
+
* The `safe()` utility:
|
|
277
|
+
* - **Catches errors** and returns `[error, undefined]`
|
|
278
|
+
* - **Re-throws Promises** to preserve Suspense behavior
|
|
279
|
+
* - Returns `[undefined, result]` on success
|
|
280
|
+
*
|
|
281
|
+
* ## IMPORTANT: SelectContext Methods Are Synchronous Only
|
|
282
|
+
*
|
|
283
|
+
* **All context methods (`read`, `all`, `race`, `any`, `settled`, `safe`) must be
|
|
284
|
+
* called synchronously during selector execution.** They cannot be used in async
|
|
285
|
+
* callbacks like `setTimeout`, `Promise.then`, or event handlers.
|
|
286
|
+
*
|
|
287
|
+
* ```ts
|
|
288
|
+
* // ❌ WRONG - Calling read() in async callback
|
|
289
|
+
* select(({ read }) => {
|
|
290
|
+
* setTimeout(() => {
|
|
291
|
+
* read(atom$); // Error: called outside selection context
|
|
292
|
+
* }, 100);
|
|
293
|
+
* return 'value';
|
|
294
|
+
* });
|
|
295
|
+
*
|
|
296
|
+
* // ❌ WRONG - Storing read() for later use
|
|
297
|
+
* let savedRead;
|
|
298
|
+
* select(({ read }) => {
|
|
299
|
+
* savedRead = read; // Don't do this!
|
|
300
|
+
* return read(atom$);
|
|
301
|
+
* });
|
|
302
|
+
* savedRead(atom$); // Error: called outside selection context
|
|
303
|
+
*
|
|
304
|
+
* // ✅ CORRECT - For async access, use atom.get() directly
|
|
305
|
+
* effect(({ read }) => {
|
|
306
|
+
* const config = read(config$);
|
|
307
|
+
* setTimeout(async () => {
|
|
308
|
+
* // Use atom.get() for async access
|
|
309
|
+
* const data = await asyncAtom$.get();
|
|
310
|
+
* console.log(data);
|
|
311
|
+
* }, 100);
|
|
312
|
+
* });
|
|
135
313
|
* ```
|
|
136
314
|
*
|
|
137
315
|
* @template T - The type of the computed value
|
|
138
316
|
* @param fn - Context-based selector function (must return sync value)
|
|
139
317
|
* @returns SelectResult with value, error, promise, and dependencies
|
|
140
318
|
* @throws Error if selector returns a Promise or PromiseLike
|
|
319
|
+
* @throws Error if context methods are called outside selection context
|
|
141
320
|
*
|
|
142
321
|
* @example
|
|
143
322
|
* ```ts
|
|
144
|
-
* select(({
|
|
145
|
-
* const user =
|
|
146
|
-
* const [posts, comments] = all(posts$, comments$);
|
|
323
|
+
* select(({ read, all }) => {
|
|
324
|
+
* const user = read(user$);
|
|
325
|
+
* const [posts, comments] = all([posts$, comments$]);
|
|
147
326
|
* return { user, posts, comments };
|
|
148
327
|
* });
|
|
149
328
|
* ```
|
|
150
329
|
*/
|
|
151
|
-
export declare function select<T>(fn:
|
|
330
|
+
export declare function select<T>(fn: ReactiveSelector<T>): SelectResult<T>;
|
package/dist/core/types.d.ts
CHANGED
|
@@ -25,8 +25,8 @@ export declare const SYMBOL_DERIVED: unique symbol;
|
|
|
25
25
|
* @example
|
|
26
26
|
* ```ts
|
|
27
27
|
* const enhanced = atom(0)
|
|
28
|
-
* .use(source => ({ ...source, double: () => source.
|
|
29
|
-
* .use(source => ({ ...source, triple: () => source.
|
|
28
|
+
* .use(source => ({ ...source, double: () => source.get() * 2 }))
|
|
29
|
+
* .use(source => ({ ...source, triple: () => source.get() * 3 }));
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
32
|
export interface Pipeable {
|
|
@@ -50,10 +50,10 @@ export interface AtomMeta {
|
|
|
50
50
|
export interface Atom<T> {
|
|
51
51
|
/** Symbol marker to identify atom instances */
|
|
52
52
|
readonly [SYMBOL_ATOM]: true;
|
|
53
|
-
/** The current value */
|
|
54
|
-
readonly value: T;
|
|
55
53
|
/** Optional metadata for the atom */
|
|
56
54
|
readonly meta?: AtomMeta;
|
|
55
|
+
/** Get the current value */
|
|
56
|
+
get(): T;
|
|
57
57
|
/**
|
|
58
58
|
* Subscribe to value changes.
|
|
59
59
|
* @param listener - Callback invoked when value changes
|
|
@@ -79,7 +79,7 @@ export interface Atom<T> {
|
|
|
79
79
|
*
|
|
80
80
|
* // Async value (stores Promise as-is)
|
|
81
81
|
* const posts = atom(fetchPosts());
|
|
82
|
-
* posts.
|
|
82
|
+
* posts.get(); // Promise<Post[]>
|
|
83
83
|
* posts.set(fetchPosts()); // Store new Promise
|
|
84
84
|
* ```
|
|
85
85
|
*/
|
|
@@ -119,7 +119,7 @@ export interface MutableAtom<T> extends Atom<T>, Pipeable {
|
|
|
119
119
|
* A derived (computed) atom that always returns Promise<T> for its value.
|
|
120
120
|
*
|
|
121
121
|
* DerivedAtom computes its value from other atoms. The computation is
|
|
122
|
-
* re-run whenever dependencies change. The `.
|
|
122
|
+
* re-run whenever dependencies change. The `.get()` always returns a Promise,
|
|
123
123
|
* even for synchronous computations.
|
|
124
124
|
*
|
|
125
125
|
* @template T - The resolved type of the computed value
|
|
@@ -128,13 +128,13 @@ export interface MutableAtom<T> extends Atom<T>, Pipeable {
|
|
|
128
128
|
* @example
|
|
129
129
|
* ```ts
|
|
130
130
|
* // Without fallback
|
|
131
|
-
* const double$ = derived(({
|
|
132
|
-
* await double$.
|
|
131
|
+
* const double$ = derived(({ read }) => read(count$) * 2);
|
|
132
|
+
* await double$.get(); // number
|
|
133
133
|
* double$.staleValue; // number | undefined
|
|
134
134
|
* double$.state(); // { status: "ready", value: 10 }
|
|
135
135
|
*
|
|
136
136
|
* // With fallback - during loading
|
|
137
|
-
* const double$ = derived(({
|
|
137
|
+
* const double$ = derived(({ read }) => read(count$) * 2, { fallback: 0 });
|
|
138
138
|
* double$.staleValue; // number (guaranteed)
|
|
139
139
|
* double$.state(); // { status: "loading", promise } during loading
|
|
140
140
|
* ```
|
|
@@ -178,13 +178,59 @@ export type AtomValue<A> = A extends DerivedAtom<infer V, boolean> ? V : A exten
|
|
|
178
178
|
export type AtomState<T> = {
|
|
179
179
|
status: "ready";
|
|
180
180
|
value: T;
|
|
181
|
+
error?: undefined;
|
|
182
|
+
promise?: undefined;
|
|
181
183
|
} | {
|
|
182
184
|
status: "error";
|
|
183
185
|
error: unknown;
|
|
186
|
+
value?: undefined;
|
|
187
|
+
promise?: undefined;
|
|
184
188
|
} | {
|
|
185
189
|
status: "loading";
|
|
186
190
|
promise: Promise<T>;
|
|
191
|
+
value?: undefined;
|
|
192
|
+
error?: undefined;
|
|
187
193
|
};
|
|
194
|
+
/**
|
|
195
|
+
* Result type for SelectContext.state() - simplified AtomState without promise.
|
|
196
|
+
*
|
|
197
|
+
* All properties (`status`, `value`, `error`) are always present:
|
|
198
|
+
* - `value` is `T` when ready, `undefined` otherwise
|
|
199
|
+
* - `error` is the error when errored, `undefined` otherwise
|
|
200
|
+
*
|
|
201
|
+
* This enables easy destructuring without type narrowing:
|
|
202
|
+
* ```ts
|
|
203
|
+
* const { status, value, error } = state(atom$);
|
|
204
|
+
* ```
|
|
205
|
+
*
|
|
206
|
+
* Equality comparisons work correctly (no promise reference issues).
|
|
207
|
+
*/
|
|
208
|
+
export type SelectStateResult<T> = {
|
|
209
|
+
status: "ready";
|
|
210
|
+
value: T;
|
|
211
|
+
error: undefined;
|
|
212
|
+
} | {
|
|
213
|
+
status: "error";
|
|
214
|
+
value: undefined;
|
|
215
|
+
error: unknown;
|
|
216
|
+
} | {
|
|
217
|
+
status: "loading";
|
|
218
|
+
value: undefined;
|
|
219
|
+
error: undefined;
|
|
220
|
+
};
|
|
221
|
+
/**
|
|
222
|
+
* Result type for race() and any() - includes winning key.
|
|
223
|
+
*
|
|
224
|
+
* @template K - The key type (string literal union)
|
|
225
|
+
* @template V - The value type
|
|
226
|
+
*/
|
|
227
|
+
export type KeyedResult<K extends string, V> = {
|
|
228
|
+
/** The key that won the race/any */
|
|
229
|
+
key: K;
|
|
230
|
+
/** The resolved value */
|
|
231
|
+
value: V;
|
|
232
|
+
};
|
|
233
|
+
export type AtomPlugin = <T extends Atom<any>>(atom: T) => T | void;
|
|
188
234
|
/**
|
|
189
235
|
* Result type for settled operations.
|
|
190
236
|
*/
|
|
@@ -227,8 +273,6 @@ export interface DerivedOptions<T> {
|
|
|
227
273
|
export interface EffectOptions {
|
|
228
274
|
/** Optional key for debugging */
|
|
229
275
|
key?: string;
|
|
230
|
-
/** Error handler for uncaught errors in the effect */
|
|
231
|
-
onError?: (error: Error) => void;
|
|
232
276
|
}
|
|
233
277
|
/**
|
|
234
278
|
* A function that returns a value when called.
|
|
@@ -269,11 +313,3 @@ export interface ModuleMeta {
|
|
|
269
313
|
}
|
|
270
314
|
export type Listener<T> = (value: T) => void;
|
|
271
315
|
export type SingleOrMultipleListeners<T> = Listener<T> | Listener<T>[];
|
|
272
|
-
/**
|
|
273
|
-
* Type guard to check if a value is an Atom.
|
|
274
|
-
*/
|
|
275
|
-
export declare function isAtom<T>(value: unknown): value is Atom<T>;
|
|
276
|
-
/**
|
|
277
|
-
* Type guard to check if a value is a DerivedAtom.
|
|
278
|
-
*/
|
|
279
|
-
export declare function isDerived<T>(value: unknown): value is DerivedAtom<T, boolean>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { SelectContext } from './select';
|
|
2
|
+
import { Atom } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Extension interface that adds `ready()` method to SelectContext.
|
|
5
|
+
* Used in derived atoms and effects to wait for non-null values.
|
|
6
|
+
*/
|
|
7
|
+
export interface WithReadySelectContext {
|
|
8
|
+
/**
|
|
9
|
+
* Wait for an atom to have a non-null/non-undefined value.
|
|
10
|
+
*
|
|
11
|
+
* If the value is null/undefined, the computation suspends until the atom
|
|
12
|
+
* changes to a non-null value, then automatically resumes.
|
|
13
|
+
*
|
|
14
|
+
* **IMPORTANT: Only use in `derived()` or `effect()` context**
|
|
15
|
+
*
|
|
16
|
+
* @param atom - The atom to read and wait for
|
|
17
|
+
* @returns The non-null value (type excludes null | undefined)
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* // Wait for currentArticleId to be set before computing
|
|
22
|
+
* const currentArticle$ = derived(({ ready, read }) => {
|
|
23
|
+
* const id = ready(currentArticleId$); // Suspends if null
|
|
24
|
+
* const cache = read(articleCache$);
|
|
25
|
+
* return cache[id];
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
ready<T>(atom: Atom<T>): T extends PromiseLike<any> ? never : Exclude<T, null | undefined>;
|
|
30
|
+
/**
|
|
31
|
+
* Wait for a selected value from an atom to be non-null/non-undefined.
|
|
32
|
+
*
|
|
33
|
+
* If the selected value is null/undefined, the computation suspends until the
|
|
34
|
+
* selected value changes to a non-null value, then automatically resumes.
|
|
35
|
+
*
|
|
36
|
+
* **IMPORTANT: Only use in `derived()` or `effect()` context**
|
|
37
|
+
*
|
|
38
|
+
* @param atom - The atom to read
|
|
39
|
+
* @param selector - Function to extract/transform the value
|
|
40
|
+
* @returns The non-null selected value
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* // Wait for user's email to be set
|
|
45
|
+
* const emailDerived$ = derived(({ ready }) => {
|
|
46
|
+
* const email = ready(user$, u => u.email); // Suspends if email is null
|
|
47
|
+
* return `Contact: ${email}`;
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
ready<T, R>(atom: Atom<T>, selector: (current: Awaited<T>) => R): R extends PromiseLike<any> ? never : Exclude<R, null | undefined>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Plugin that adds `ready()` method to a SelectContext.
|
|
55
|
+
*
|
|
56
|
+
* `ready()` enables a "reactive suspension" pattern where derived atoms
|
|
57
|
+
* wait for required values before computing. This is useful for:
|
|
58
|
+
*
|
|
59
|
+
* - Route-based entity loading (`/article/:id` - wait for ID to be set)
|
|
60
|
+
* - Authentication-gated content (wait for user to be logged in)
|
|
61
|
+
* - Conditional data dependencies (wait for prerequisite data)
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* // Used internally by derived() - you don't need to call this directly
|
|
66
|
+
* const result = select((context) => fn(context.use(withReady())));
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare function withReady(): <TContext extends SelectContext>(context: TContext) => TContext & WithReadySelectContext;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var yt=Object.defineProperty;var _t=(e,t,r)=>t in e?yt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var m=(e,t,r)=>_t(e,typeof t!="symbol"?t+"":t,r);function bt(e){const t=Object.assign(r=>()=>{const a=t.current;return t.current=r(a),()=>{t.current=a}},{current:e,override:r=>{t.current=r(t.current)},reset:()=>{t.current=e}});return t}function $t(e,t){const r=[];for(const a of e)r.push(a());try{return t()}finally{for(const a of r.reverse())a()}}const Y=Object.assign(bt,{use:$t}),j=Y(),mt=()=>{};class At{constructor(t){m(this,"_listeners");m(this,"_settledPayload");m(this,"_isSettled",!1);m(this,"size",()=>this._listeners.size);m(this,"settled",()=>this._isSettled);m(this,"forEach",t=>{this._listeners.forEach(t)});m(this,"on",(t,r)=>{let a;if(r===void 0)a=Array.isArray(t)?t:[t];else{const n=t,u=Array.isArray(r)?r:[r];a=[i=>{const f=n(i);if(f)for(let l=0;l<u.length;l++)u[l](f.value)}]}if(this._isSettled){const n=this._settledPayload;for(let u=0;u<a.length;u++)a[u](n);return mt}const s=this._listeners;for(let n=0;n<a.length;n++)s.add(a[n]);return()=>{for(let n=0;n<a.length;n++)s.delete(a[n])}});m(this,"emit",t=>{this._isSettled||this._doEmit(t,!1,!1)});m(this,"emitLifo",t=>{this._isSettled||this._doEmit(t,!1,!0)});m(this,"clear",()=>{this._listeners.clear()});m(this,"emitAndClear",t=>{this._isSettled||this._doEmit(t,!0,!1)});m(this,"emitAndClearLifo",t=>{this._isSettled||this._doEmit(t,!0,!0)});m(this,"settle",t=>{this._isSettled||(this._settledPayload=t,this._isSettled=!0,this._doEmit(t,!0,!1))});m(this,"_doEmit",(t,r,a)=>{const s=this._listeners,n=s.size;if(n===0)return;const u=Array.from(s);if(r&&s.clear(),a)for(let i=n-1;i>=0;i--)u[i](t);else for(let i=0;i<n;i++)u[i](t)});this._listeners=new Set(t)}}function B(e){return new At(e)}var K=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function wt(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function Tt(){this.__data__=[],this.size=0}var St=Tt;function jt(e,t){return e===t||e!==e&&t!==t}var Xe=jt,Ct=Xe;function Et(e,t){for(var r=e.length;r--;)if(Ct(e[r][0],t))return r;return-1}var re=Et,Ot=re,Pt=Array.prototype,Dt=Pt.splice;function It(e){var t=this.__data__,r=Ot(t,e);if(r<0)return!1;var a=t.length-1;return r==a?t.pop():Dt.call(t,r,1),--this.size,!0}var Lt=It,xt=re;function Mt(e){var t=this.__data__,r=xt(t,e);return r<0?void 0:t[r][1]}var Ft=Mt,Gt=re;function Rt(e){return Gt(this.__data__,e)>-1}var qt=Rt,Ht=re;function Nt(e,t){var r=this.__data__,a=Ht(r,e);return a<0?(++this.size,r.push([e,t])):r[a][1]=t,this}var zt=Nt,Bt=St,Ut=Lt,kt=Ft,Kt=qt,Vt=zt;function F(e){var t=-1,r=e==null?0:e.length;for(this.clear();++t<r;){var a=e[t];this.set(a[0],a[1])}}F.prototype.clear=Bt;F.prototype.delete=Ut;F.prototype.get=kt;F.prototype.has=Kt;F.prototype.set=Vt;var ae=F,Wt=ae;function Jt(){this.__data__=new Wt,this.size=0}var Yt=Jt;function Xt(e){var t=this.__data__,r=t.delete(e);return this.size=t.size,r}var Zt=Xt;function Qt(e){return this.__data__.get(e)}var er=Qt;function tr(e){return this.__data__.has(e)}var rr=tr,ar=typeof K=="object"&&K&&K.Object===Object&&K,Ze=ar,nr=Ze,sr=typeof self=="object"&&self&&self.Object===Object&&self,ir=nr||sr||Function("return this")(),P=ir,or=P,ur=or.Symbol,_e=ur,we=_e,Qe=Object.prototype,cr=Qe.hasOwnProperty,lr=Qe.toString,z=we?we.toStringTag:void 0;function fr(e){var t=cr.call(e,z),r=e[z];try{e[z]=void 0;var a=!0}catch{}var s=lr.call(e);return a&&(t?e[z]=r:delete e[z]),s}var dr=fr,vr=Object.prototype,hr=vr.toString;function gr(e){return hr.call(e)}var pr=gr,Te=_e,yr=dr,_r=pr,br="[object Null]",$r="[object Undefined]",Se=Te?Te.toStringTag:void 0;function mr(e){return e==null?e===void 0?$r:br:Se&&Se in Object(e)?yr(e):_r(e)}var ne=mr;function Ar(e){var t=typeof e;return e!=null&&(t=="object"||t=="function")}var et=Ar,wr=ne,Tr=et,Sr="[object AsyncFunction]",jr="[object Function]",Cr="[object GeneratorFunction]",Er="[object Proxy]";function Or(e){if(!Tr(e))return!1;var t=wr(e);return t==jr||t==Cr||t==Sr||t==Er}var tt=Or,Pr=P,Dr=Pr["__core-js_shared__"],Ir=Dr,ue=Ir,je=function(){var e=/[^.]+$/.exec(ue&&ue.keys&&ue.keys.IE_PROTO||"");return e?"Symbol(src)_1."+e:""}();function Lr(e){return!!je&&je in e}var xr=Lr,Mr=Function.prototype,Fr=Mr.toString;function Gr(e){if(e!=null){try{return Fr.call(e)}catch{}try{return e+""}catch{}}return""}var rt=Gr,Rr=tt,qr=xr,Hr=et,Nr=rt,zr=/[\\^$.*+?()[\]{}|]/g,Br=/^\[object .+?Constructor\]$/,Ur=Function.prototype,kr=Object.prototype,Kr=Ur.toString,Vr=kr.hasOwnProperty,Wr=RegExp("^"+Kr.call(Vr).replace(zr,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function Jr(e){if(!Hr(e)||qr(e))return!1;var t=Rr(e)?Wr:Br;return t.test(Nr(e))}var Yr=Jr;function Xr(e,t){return e==null?void 0:e[t]}var Zr=Xr,Qr=Yr,ea=Zr;function ta(e,t){var r=ea(e,t);return Qr(r)?r:void 0}var G=ta,ra=G,aa=P,na=ra(aa,"Map"),be=na,sa=G,ia=sa(Object,"create"),se=ia,Ce=se;function oa(){this.__data__=Ce?Ce(null):{},this.size=0}var ua=oa;function ca(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}var la=ca,fa=se,da="__lodash_hash_undefined__",va=Object.prototype,ha=va.hasOwnProperty;function ga(e){var t=this.__data__;if(fa){var r=t[e];return r===da?void 0:r}return ha.call(t,e)?t[e]:void 0}var pa=ga,ya=se,_a=Object.prototype,ba=_a.hasOwnProperty;function $a(e){var t=this.__data__;return ya?t[e]!==void 0:ba.call(t,e)}var ma=$a,Aa=se,wa="__lodash_hash_undefined__";function Ta(e,t){var r=this.__data__;return this.size+=this.has(e)?0:1,r[e]=Aa&&t===void 0?wa:t,this}var Sa=Ta,ja=ua,Ca=la,Ea=pa,Oa=ma,Pa=Sa;function R(e){var t=-1,r=e==null?0:e.length;for(this.clear();++t<r;){var a=e[t];this.set(a[0],a[1])}}R.prototype.clear=ja;R.prototype.delete=Ca;R.prototype.get=Ea;R.prototype.has=Oa;R.prototype.set=Pa;var Da=R,Ee=Da,Ia=ae,La=be;function xa(){this.size=0,this.__data__={hash:new Ee,map:new(La||Ia),string:new Ee}}var Ma=xa;function Fa(e){var t=typeof e;return t=="string"||t=="number"||t=="symbol"||t=="boolean"?e!=="__proto__":e===null}var Ga=Fa,Ra=Ga;function qa(e,t){var r=e.__data__;return Ra(t)?r[typeof t=="string"?"string":"hash"]:r.map}var ie=qa,Ha=ie;function Na(e){var t=Ha(this,e).delete(e);return this.size-=t?1:0,t}var za=Na,Ba=ie;function Ua(e){return Ba(this,e).get(e)}var ka=Ua,Ka=ie;function Va(e){return Ka(this,e).has(e)}var Wa=Va,Ja=ie;function Ya(e,t){var r=Ja(this,e),a=r.size;return r.set(e,t),this.size+=r.size==a?0:1,this}var Xa=Ya,Za=Ma,Qa=za,en=ka,tn=Wa,rn=Xa;function q(e){var t=-1,r=e==null?0:e.length;for(this.clear();++t<r;){var a=e[t];this.set(a[0],a[1])}}q.prototype.clear=Za;q.prototype.delete=Qa;q.prototype.get=en;q.prototype.has=tn;q.prototype.set=rn;var at=q,an=ae,nn=be,sn=at,on=200;function un(e,t){var r=this.__data__;if(r instanceof an){var a=r.__data__;if(!nn||a.length<on-1)return a.push([e,t]),this.size=++r.size,this;r=this.__data__=new sn(a)}return r.set(e,t),this.size=r.size,this}var cn=un,ln=ae,fn=Yt,dn=Zt,vn=er,hn=rr,gn=cn;function H(e){var t=this.__data__=new ln(e);this.size=t.size}H.prototype.clear=fn;H.prototype.delete=dn;H.prototype.get=vn;H.prototype.has=hn;H.prototype.set=gn;var pn=H,yn="__lodash_hash_undefined__";function _n(e){return this.__data__.set(e,yn),this}var bn=_n;function $n(e){return this.__data__.has(e)}var mn=$n,An=at,wn=bn,Tn=mn;function X(e){var t=-1,r=e==null?0:e.length;for(this.__data__=new An;++t<r;)this.add(e[t])}X.prototype.add=X.prototype.push=wn;X.prototype.has=Tn;var Sn=X;function jn(e,t){for(var r=-1,a=e==null?0:e.length;++r<a;)if(t(e[r],r,e))return!0;return!1}var Cn=jn;function En(e,t){return e.has(t)}var On=En,Pn=Sn,Dn=Cn,In=On,Ln=1,xn=2;function Mn(e,t,r,a,s,n){var u=r&Ln,i=e.length,f=t.length;if(i!=f&&!(u&&f>i))return!1;var l=n.get(e),v=n.get(t);if(l&&v)return l==t&&v==e;var y=-1,o=!0,c=r&xn?new Pn:void 0;for(n.set(e,t),n.set(t,e);++y<i;){var d=e[y],h=t[y];if(a)var g=u?a(h,d,y,t,e,n):a(d,h,y,e,t,n);if(g!==void 0){if(g)continue;o=!1;break}if(c){if(!Dn(t,function(_,b){if(!In(c,b)&&(d===_||s(d,_,r,a,n)))return c.push(b)})){o=!1;break}}else if(!(d===h||s(d,h,r,a,n))){o=!1;break}}return n.delete(e),n.delete(t),o}var nt=Mn,Fn=P,Gn=Fn.Uint8Array,Rn=Gn;function qn(e){var t=-1,r=Array(e.size);return e.forEach(function(a,s){r[++t]=[s,a]}),r}var Hn=qn;function Nn(e){var t=-1,r=Array(e.size);return e.forEach(function(a){r[++t]=a}),r}var zn=Nn,Oe=_e,Pe=Rn,Bn=Xe,Un=nt,kn=Hn,Kn=zn,Vn=1,Wn=2,Jn="[object Boolean]",Yn="[object Date]",Xn="[object Error]",Zn="[object Map]",Qn="[object Number]",es="[object RegExp]",ts="[object Set]",rs="[object String]",as="[object Symbol]",ns="[object ArrayBuffer]",ss="[object DataView]",De=Oe?Oe.prototype:void 0,ce=De?De.valueOf:void 0;function is(e,t,r,a,s,n,u){switch(r){case ss:if(e.byteLength!=t.byteLength||e.byteOffset!=t.byteOffset)return!1;e=e.buffer,t=t.buffer;case ns:return!(e.byteLength!=t.byteLength||!n(new Pe(e),new Pe(t)));case Jn:case Yn:case Qn:return Bn(+e,+t);case Xn:return e.name==t.name&&e.message==t.message;case es:case rs:return e==t+"";case Zn:var i=kn;case ts:var f=a&Vn;if(i||(i=Kn),e.size!=t.size&&!f)return!1;var l=u.get(e);if(l)return l==t;a|=Wn,u.set(e,t);var v=Un(i(e),i(t),a,s,n,u);return u.delete(e),v;case as:if(ce)return ce.call(e)==ce.call(t)}return!1}var os=is;function us(e,t){for(var r=-1,a=t.length,s=e.length;++r<a;)e[s+r]=t[r];return e}var cs=us,ls=Array.isArray,$e=ls,fs=cs,ds=$e;function vs(e,t,r){var a=t(e);return ds(e)?a:fs(a,r(e))}var hs=vs;function gs(e,t){for(var r=-1,a=e==null?0:e.length,s=0,n=[];++r<a;){var u=e[r];t(u,r,e)&&(n[s++]=u)}return n}var ps=gs;function ys(){return[]}var _s=ys,bs=ps,$s=_s,ms=Object.prototype,As=ms.propertyIsEnumerable,Ie=Object.getOwnPropertySymbols,ws=Ie?function(e){return e==null?[]:(e=Object(e),bs(Ie(e),function(t){return As.call(e,t)}))}:$s,Ts=ws;function Ss(e,t){for(var r=-1,a=Array(e);++r<e;)a[r]=t(r);return a}var js=Ss;function Cs(e){return e!=null&&typeof e=="object"}var oe=Cs,Es=ne,Os=oe,Ps="[object Arguments]";function Ds(e){return Os(e)&&Es(e)==Ps}var Is=Ds,Le=Is,Ls=oe,st=Object.prototype,xs=st.hasOwnProperty,Ms=st.propertyIsEnumerable,Fs=Le(function(){return arguments}())?Le:function(e){return Ls(e)&&xs.call(e,"callee")&&!Ms.call(e,"callee")},Gs=Fs,Z={exports:{}};function Rs(){return!1}var qs=Rs;Z.exports;(function(e,t){var r=P,a=qs,s=t&&!t.nodeType&&t,n=s&&!0&&e&&!e.nodeType&&e,u=n&&n.exports===s,i=u?r.Buffer:void 0,f=i?i.isBuffer:void 0,l=f||a;e.exports=l})(Z,Z.exports);var it=Z.exports,Hs=9007199254740991,Ns=/^(?:0|[1-9]\d*)$/;function zs(e,t){var r=typeof e;return t=t??Hs,!!t&&(r=="number"||r!="symbol"&&Ns.test(e))&&e>-1&&e%1==0&&e<t}var Bs=zs,Us=9007199254740991;function ks(e){return typeof e=="number"&&e>-1&&e%1==0&&e<=Us}var ot=ks,Ks=ne,Vs=ot,Ws=oe,Js="[object Arguments]",Ys="[object Array]",Xs="[object Boolean]",Zs="[object Date]",Qs="[object Error]",ei="[object Function]",ti="[object Map]",ri="[object Number]",ai="[object Object]",ni="[object RegExp]",si="[object Set]",ii="[object String]",oi="[object WeakMap]",ui="[object ArrayBuffer]",ci="[object DataView]",li="[object Float32Array]",fi="[object Float64Array]",di="[object Int8Array]",vi="[object Int16Array]",hi="[object Int32Array]",gi="[object Uint8Array]",pi="[object Uint8ClampedArray]",yi="[object Uint16Array]",_i="[object Uint32Array]",p={};p[li]=p[fi]=p[di]=p[vi]=p[hi]=p[gi]=p[pi]=p[yi]=p[_i]=!0;p[Js]=p[Ys]=p[ui]=p[Xs]=p[ci]=p[Zs]=p[Qs]=p[ei]=p[ti]=p[ri]=p[ai]=p[ni]=p[si]=p[ii]=p[oi]=!1;function bi(e){return Ws(e)&&Vs(e.length)&&!!p[Ks(e)]}var $i=bi;function mi(e){return function(t){return e(t)}}var Ai=mi,Q={exports:{}};Q.exports;(function(e,t){var r=Ze,a=t&&!t.nodeType&&t,s=a&&!0&&e&&!e.nodeType&&e,n=s&&s.exports===a,u=n&&r.process,i=function(){try{var f=s&&s.require&&s.require("util").types;return f||u&&u.binding&&u.binding("util")}catch{}}();e.exports=i})(Q,Q.exports);var wi=Q.exports,Ti=$i,Si=Ai,xe=wi,Me=xe&&xe.isTypedArray,ji=Me?Si(Me):Ti,ut=ji,Ci=js,Ei=Gs,Oi=$e,Pi=it,Di=Bs,Ii=ut,Li=Object.prototype,xi=Li.hasOwnProperty;function Mi(e,t){var r=Oi(e),a=!r&&Ei(e),s=!r&&!a&&Pi(e),n=!r&&!a&&!s&&Ii(e),u=r||a||s||n,i=u?Ci(e.length,String):[],f=i.length;for(var l in e)(t||xi.call(e,l))&&!(u&&(l=="length"||s&&(l=="offset"||l=="parent")||n&&(l=="buffer"||l=="byteLength"||l=="byteOffset")||Di(l,f)))&&i.push(l);return i}var Fi=Mi,Gi=Object.prototype;function Ri(e){var t=e&&e.constructor,r=typeof t=="function"&&t.prototype||Gi;return e===r}var qi=Ri;function Hi(e,t){return function(r){return e(t(r))}}var Ni=Hi,zi=Ni,Bi=zi(Object.keys,Object),Ui=Bi,ki=qi,Ki=Ui,Vi=Object.prototype,Wi=Vi.hasOwnProperty;function Ji(e){if(!ki(e))return Ki(e);var t=[];for(var r in Object(e))Wi.call(e,r)&&r!="constructor"&&t.push(r);return t}var Yi=Ji,Xi=tt,Zi=ot;function Qi(e){return e!=null&&Zi(e.length)&&!Xi(e)}var eo=Qi,to=Fi,ro=Yi,ao=eo;function no(e){return ao(e)?to(e):ro(e)}var so=no,io=hs,oo=Ts,uo=so;function co(e){return io(e,uo,oo)}var lo=co,Fe=lo,fo=1,vo=Object.prototype,ho=vo.hasOwnProperty;function go(e,t,r,a,s,n){var u=r&fo,i=Fe(e),f=i.length,l=Fe(t),v=l.length;if(f!=v&&!u)return!1;for(var y=f;y--;){var o=i[y];if(!(u?o in t:ho.call(t,o)))return!1}var c=n.get(e),d=n.get(t);if(c&&d)return c==t&&d==e;var h=!0;n.set(e,t),n.set(t,e);for(var g=u;++y<f;){o=i[y];var _=e[o],b=t[o];if(a)var $=u?a(b,_,o,t,e,n):a(_,b,o,e,t,n);if(!($===void 0?_===b||s(_,b,r,a,n):$)){h=!1;break}g||(g=o=="constructor")}if(h&&!g){var A=e.constructor,D=t.constructor;A!=D&&"constructor"in e&&"constructor"in t&&!(typeof A=="function"&&A instanceof A&&typeof D=="function"&&D instanceof D)&&(h=!1)}return n.delete(e),n.delete(t),h}var po=go,yo=G,_o=P,bo=yo(_o,"DataView"),$o=bo,mo=G,Ao=P,wo=mo(Ao,"Promise"),To=wo,So=G,jo=P,Co=So(jo,"Set"),Eo=Co,Oo=G,Po=P,Do=Oo(Po,"WeakMap"),Io=Do,fe=$o,de=be,ve=To,he=Eo,ge=Io,ct=ne,N=rt,Ge="[object Map]",Lo="[object Object]",Re="[object Promise]",qe="[object Set]",He="[object WeakMap]",Ne="[object DataView]",xo=N(fe),Mo=N(de),Fo=N(ve),Go=N(he),Ro=N(ge),I=ct;(fe&&I(new fe(new ArrayBuffer(1)))!=Ne||de&&I(new de)!=Ge||ve&&I(ve.resolve())!=Re||he&&I(new he)!=qe||ge&&I(new ge)!=He)&&(I=function(e){var t=ct(e),r=t==Lo?e.constructor:void 0,a=r?N(r):"";if(a)switch(a){case xo:return Ne;case Mo:return Ge;case Fo:return Re;case Go:return qe;case Ro:return He}return t});var qo=I,le=pn,Ho=nt,No=os,zo=po,ze=qo,Be=$e,Ue=it,Bo=ut,Uo=1,ke="[object Arguments]",Ke="[object Array]",V="[object Object]",ko=Object.prototype,Ve=ko.hasOwnProperty;function Ko(e,t,r,a,s,n){var u=Be(e),i=Be(t),f=u?Ke:ze(e),l=i?Ke:ze(t);f=f==ke?V:f,l=l==ke?V:l;var v=f==V,y=l==V,o=f==l;if(o&&Ue(e)){if(!Ue(t))return!1;u=!0,v=!1}if(o&&!v)return n||(n=new le),u||Bo(e)?Ho(e,t,r,a,s,n):No(e,t,f,r,a,s,n);if(!(r&Uo)){var c=v&&Ve.call(e,"__wrapped__"),d=y&&Ve.call(t,"__wrapped__");if(c||d){var h=c?e.value():e,g=d?t.value():t;return n||(n=new le),s(h,g,r,a,n)}}return o?(n||(n=new le),zo(e,t,r,a,s,n)):!1}var Vo=Ko,Wo=Vo,We=oe;function lt(e,t,r,a,s){return e===t?!0:e==null||t==null||!We(e)&&!We(t)?e!==e&&t!==t:Wo(e,t,r,a,lt,s)}var Jo=lt,Yo=Jo;function Xo(e,t){return Yo(e,t)}var Zo=Xo;const Qo=wt(Zo);function eu(e,t){return Object.is(e,t)}function U(e,t,r=Object.is){if(Object.is(e,t))return!0;if(typeof e!="object"||e===null||typeof t!="object"||t===null)return!1;const a=Object.keys(e),s=Object.keys(t);if(a.length!==s.length)return!1;for(const n of a)if(!Object.prototype.hasOwnProperty.call(t,n)||!r(e[n],t[n]))return!1;return!0}function me(e,t){return U(e,t,U)}function tu(e,t){return U(e,t,me)}const ru=Qo;function Ae(e){return!e||e==="strict"?eu:e==="shallow"?U:e==="shallow2"?me:e==="shallow3"?tu:e==="deep"?ru:e}function Je(e){const t=e;let r=e;return Object.assign((...a)=>r(...a),{getOriginal:()=>t,getCurrent:()=>r,setCurrent(a){r=a}})}function au(e){return typeof e=="function"&&"getOriginal"in e&&"getCurrent"in e&&"setCurrent"in e}function nu(e,t,r){return e?typeof t=="function"?au(e.value)?(e.value.setCurrent(t),[e.value,!0]):[Je(t),!1]:t&&t instanceof Date?e.value&&e.value instanceof Date&&t.getTime()===e.value.getTime()?[e.value,!0]:[t,!1]:r(e.value,t)?[e.value,!0]:[t,!1]:typeof t=="function"?[Je(t),!1]:[t,!1]}const ee=Y(e=>e()),te=Symbol.for("atomirx.atom"),pe=Symbol.for("atomirx.derived");function k(e){return Object.assign(e,{use(t){const r=t(e);return r?typeof r=="object"||typeof r=="function"?"use"in r?r:k(r):r:e}})}function w(e){return e!==null&&typeof e=="object"&&"then"in e&&typeof e.then=="function"}const ye=new WeakMap;function Ye(e){return ye.get(e)}function W(e,t){if(t.length===1){if(e==="allSettled"){const a=Promise.allSettled(t).then(()=>{});return ye.set(a,{type:e,promises:t}),a}return t[0]}const r=Promise[e](t);return r.catch(()=>{}),ye.set(r,{type:e,promises:t}),r}function su(e,t){if(e===t)return!0;if(!e||!t)return!1;const r=Ye(e),a=Ye(t);return!!r&&!!a&&me(r,a)}const M=new WeakMap;function C(e){const t=M.get(e);if(t)return t;const r={status:"pending",promise:e};return M.set(e,r),e.then(a=>{const s=M.get(e);(s==null?void 0:s.status)==="pending"&&M.set(e,{status:"fulfilled",value:a})},a=>{const s=M.get(e);(s==null?void 0:s.status)==="pending"&&M.set(e,{status:"rejected",error:a})}),r}function iu(e){if(!w(e))return e;const r=C(e);switch(r.status){case"pending":throw r.promise;case"rejected":throw r.error;case"fulfilled":return r.value}}function ou(e){return w(e)?C(e).status==="pending":!1}function uu(e){return w(e)?C(e).status==="fulfilled":!1}function cu(e){return w(e)?C(e).status==="rejected":!1}function lu(e,t={}){var _,b;const r=B(),a=Ae(t.equals);let s=null;const n=B(),u=$=>{s&&(s.abort($),s=null),n.emitAndClear()},i=()=>(s=new AbortController,k({signal:s.signal,onCleanup:n.on})),f=typeof e=="function";let v=f?e(i()):e,y=!1;w(v)&&C(v);const o=()=>{r.forEach($=>{ee.current($)})},c=$=>{let A;typeof $=="function"?A=$(v):A=$,!a(A,v)&&(u("value changed"),v=A,y=!0,w(v)&&C(v),o())},d=()=>{u("reset");const $=f?e(i()):e;w($)&&C($);const A=!a($,v);v=$,y=!1,A&&o()},h=()=>y,g=k({[te]:!0,meta:t.meta,get(){return v},use:void 0,set:c,reset:d,dirty:h,on:r.on});return(b=j.current)==null||b.call(j,{type:"mutable",key:(_=t.meta)==null?void 0:_.key,meta:t.meta,atom:g}),g}function fu(e){return e}let J=0;function ft(e){if(J++,J===1){let t=new Set;const r=a=>{t.add(a)};try{return Y.use([ee(()=>r)],e)}finally{J--,Y.use([ee(()=>r)],()=>{for(;t.size>0;){const a=t;t=new Set;for(const s of a)s()}})}}try{return e()}finally{J--}}function du(e,t){let r,a;const s=i=>{i&&typeof i=="object"&&"dispose"in i&&typeof i.dispose=="function"&&i.dispose()},n=()=>{s(r),r=void 0};return Object.assign(()=>{var i;return r||(a?r=a(e):r=e(),(i=j.current)==null||i.call(j,{type:"module",key:t==null?void 0:t.key,meta:t==null?void 0:t.meta,module:r})),r},{key:t==null?void 0:t.key,override:i=>{if(r!==void 0)throw new Error("Cannot override after initialization. Call override() before accessing the service.");a=i},reset:()=>{a=void 0,n()},invalidate:()=>{a=void 0,n()},isOverridden:()=>a!==void 0,isInitialized:()=>r!==void 0})}function dt(e){return e!==null&&typeof e=="object"&&te in e&&e[te]===!0}function vt(e){return e!==null&&typeof e=="object"&&pe in e&&e[pe]===!0}function L(e){if(vt(e))return e.state();const t=e.get();if(!w(t))return{status:"ready",value:t};const r=C(t);switch(r.status){case"fulfilled":return{status:"ready",value:r.value};case"rejected":return{status:"error",error:r.error};case"pending":return{status:"loading",promise:r.promise}}}const vu=typeof AggregateError<"u"?AggregateError:class extends Error{constructor(r,a){super(a);m(this,"errors");this.name="AggregateError",this.errors=r}};class hu extends Error{constructor(r,a="All atoms rejected"){super(a);m(this,"errors");this.name="AllAtomsRejectedError",this.errors=r}}function ht(e){const t=new Set;let r=!0;const a=o=>{if(!r)throw new Error(`${o}() was called outside of the selection context. This usually happens when calling context methods in async callbacks (setTimeout, Promise.then, etc.). All atom reads must happen synchronously during selector execution. For async access, use atom.get() directly (e.g., myMutableAtom$.get() or await myDerivedAtom$.get()).`)},s=o=>{a("read"),t.add(o);const c=L(o);switch(c.status){case"ready":return c.value;case"error":throw c.error;case"loading":throw c.promise}},n=o=>{a("all");const c=[],d=[];for(const h of o){t.add(h);const g=L(h);switch(g.status){case"ready":c.push(g.value);break;case"error":throw g.error;case"loading":d.push(g.promise);break}}if(d.length>0)throw W("all",d);return c},u=o=>{a("race");const c=[],d=Object.entries(o);for(const[h,g]of d){t.add(g);const _=L(g);switch(_.status){case"ready":return{key:h,value:_.value};case"error":throw _.error;case"loading":c.push(_.promise);break}}throw c.length>0?W("race",c):new Error("race() called with no atoms")},i=o=>{a("any");const c=[],d=[],h=Object.entries(o);for(const[g,_]of h){t.add(_);const b=L(_);switch(b.status){case"ready":return{key:g,value:b.value};case"error":c.push(b.error);break;case"loading":d.push(b.promise);break}}throw d.length>0?W("race",d):new vu(c,"All atoms rejected")},f=o=>{a("settled");const c=[],d=[];for(const h of o){t.add(h);const g=L(h);switch(g.status){case"ready":c.push({status:"ready",value:g.value});break;case"error":c.push({status:"error",error:g.error});break;case"loading":d.push(g.promise);break}}if(d.length>0)throw W("allSettled",d);return c},l=o=>{a("safe");try{return[void 0,o()]}catch(c){if(w(c))throw c;return[c,void 0]}};function v(o){if(a("state"),dt(o)){t.add(o);const c=L(o);switch(c.status){case"ready":return{status:"ready",value:c.value,error:void 0};case"error":return{status:"error",value:void 0,error:c.error};case"loading":return{status:"loading",value:void 0,error:void 0}}}try{return{status:"ready",value:o(),error:void 0}}catch(c){return w(c)?{status:"loading",value:void 0,error:void 0}:{status:"error",value:void 0,error:c}}}const y=k({read:s,all:n,any:i,race:u,settled:f,safe:l,state:v});try{const o=e(y);if(w(o))throw new Error("select() selector must return a synchronous value, not a Promise. For async data, create an async atom with atom(Promise) and use get() to read it.");return{value:o,error:void 0,promise:void 0,dependencies:t}}catch(o){return w(o)?{value:void 0,error:void 0,promise:o,dependencies:t}:{value:void 0,error:o,promise:void 0,dependencies:t}}finally{r=!1}}function gu(e){if(e==null)throw new Promise(()=>{});return e}function pu(){return e=>({...e,ready:(t,r)=>{const a=e.read(t),s=r?r(a):a;if(w(s)){const n=C(s);if(n.status==="pending")throw n.promise;if(n.status==="fulfilled")return n.value;throw n.error}return gu(s)}})}function gt(e,t={}){var A,D;const r=B(),a=Ae(t.equals),s="fallback"in t,n=t.fallback;let u,i,f=null,l=!1,v=!1,y=0,o=null,c=null;const d=new Map,h=()=>{r.forEach(T=>{ee.current(T)})},g=T=>{for(const[E,x]of d)T.has(E)||(x(),d.delete(E));for(const E of T)if(!d.has(E)){const x=E.on(()=>{_()});d.set(E,x)}},_=(T=!1)=>{const E=++y;v=!0,i=void 0,o||(f=new Promise((O,S)=>{o=O,c=S}));const x=()=>{const O=ht(S=>e(S.use(pu())));if(g(O.dependencies),O.promise)T||h(),O.promise.then(()=>{y===E&&x()},S=>{y===E&&(v=!1,i=S,c==null||c(S),o=null,c=null,h())});else if(O.error!==void 0)v=!1,i=O.error,c==null||c(O.error),o=null,c=null,T||h();else{const S=O.value,pt=!u;v=!1,i=void 0,(!u||!a(S,u.value))&&(u={value:S},(pt||!T)&&h()),o==null||o(S),o=null,c=null}};return x(),f},b=()=>{l||(l=!0,_(!0))},$={[te]:!0,[pe]:!0,meta:t.meta,get(){return b(),f},get staleValue(){if(b(),u)return u.value;if(s)return n},state(){return b(),v?{status:"loading",promise:f}:i!==void 0?{status:"error",error:i}:u?{status:"ready",value:u.value}:{status:"loading",promise:f}},refresh(){l?_():b()},on(T){return b(),r.on(T)}};return(D=j.current)==null||D.call(j,{type:"derived",key:(A=t.meta)==null?void 0:A.key,meta:t.meta,atom:$}),$}function yu(e,t){let r=!1;const a=B();return gt(n=>{if(a.emitAndClear(),r)return;const u={...n,something:!0,onCleanup:a.on};ft(()=>e(u))}).get().catch(()=>{}),()=>{r||(r=!0,a.emitAndClear())}}exports.AllAtomsRejectedError=hu;exports.atom=lu;exports.batch=ft;exports.define=du;exports.derived=gt;exports.effect=yu;exports.emitter=B;exports.getAtomState=L;exports.isAtom=dt;exports.isDerived=vt;exports.isFulfilled=uu;exports.isPending=ou;exports.isPromiseLike=w;exports.isRejected=cu;exports.onCreateHook=j;exports.promisesEqual=su;exports.readonly=fu;exports.resolveEquality=Ae;exports.select=ht;exports.shallowEqual=U;exports.trackPromise=C;exports.tryStabilize=nu;exports.unwrap=iu;exports.withUse=k;
|