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.
Files changed (53) hide show
  1. package/README.md +867 -160
  2. package/dist/core/atom.d.ts +83 -6
  3. package/dist/core/batch.d.ts +3 -3
  4. package/dist/core/derived.d.ts +55 -21
  5. package/dist/core/effect.d.ts +47 -51
  6. package/dist/core/getAtomState.d.ts +29 -0
  7. package/dist/core/promiseCache.d.ts +23 -32
  8. package/dist/core/select.d.ts +208 -29
  9. package/dist/core/types.d.ts +55 -19
  10. package/dist/core/withReady.d.ts +69 -0
  11. package/dist/index-CqO6BDwj.cjs +1 -0
  12. package/dist/index-D8RDOTB_.js +1319 -0
  13. package/dist/index.cjs +1 -1
  14. package/dist/index.d.ts +9 -7
  15. package/dist/index.js +12 -10
  16. package/dist/react/index.cjs +10 -10
  17. package/dist/react/index.d.ts +2 -1
  18. package/dist/react/index.js +423 -379
  19. package/dist/react/rx.d.ts +114 -25
  20. package/dist/react/useAction.d.ts +5 -4
  21. package/dist/react/{useValue.d.ts → useSelector.d.ts} +56 -25
  22. package/dist/react/useSelector.test.d.ts +1 -0
  23. package/package.json +17 -1
  24. package/src/core/atom.test.ts +307 -43
  25. package/src/core/atom.ts +143 -21
  26. package/src/core/batch.test.ts +10 -10
  27. package/src/core/batch.ts +3 -3
  28. package/src/core/derived.test.ts +727 -72
  29. package/src/core/derived.ts +141 -73
  30. package/src/core/effect.test.ts +259 -39
  31. package/src/core/effect.ts +62 -85
  32. package/src/core/getAtomState.ts +69 -0
  33. package/src/core/promiseCache.test.ts +5 -3
  34. package/src/core/promiseCache.ts +76 -71
  35. package/src/core/select.ts +405 -130
  36. package/src/core/selector.test.ts +574 -32
  37. package/src/core/types.ts +54 -26
  38. package/src/core/withReady.test.ts +360 -0
  39. package/src/core/withReady.ts +127 -0
  40. package/src/core/withUse.ts +1 -1
  41. package/src/index.test.ts +4 -4
  42. package/src/index.ts +11 -6
  43. package/src/react/index.ts +2 -1
  44. package/src/react/rx.test.tsx +173 -18
  45. package/src/react/rx.tsx +274 -43
  46. package/src/react/useAction.test.ts +12 -14
  47. package/src/react/useAction.ts +11 -9
  48. package/src/react/{useValue.test.ts → useSelector.test.ts} +16 -16
  49. package/src/react/{useValue.ts → useSelector.ts} +64 -33
  50. package/v2.md +44 -44
  51. package/dist/index-2ok7ilik.js +0 -1217
  52. package/dist/index-B_5SFzfl.cjs +0 -1
  53. /package/dist/{react/useValue.test.d.ts → core/withReady.test.d.ts} +0 -0
@@ -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
- get<T>(atom: Atom<T>): Awaited<T>;
39
+ read<T>(atom: Atom<T>): Awaited<T>;
35
40
  /**
36
41
  * Wait for all atoms to resolve (like Promise.all).
37
- * Variadic form - pass atoms as arguments.
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 - Atoms to wait for (variadic)
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>[]>(...atoms: A): {
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
- * Variadic form - pass atoms as arguments.
62
+ * Object-based - pass atoms as a record with keys.
58
63
  *
59
- * - If any atom is ready → returns first ready value
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 - Atoms to race (variadic)
66
- * @returns First settled value
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<A extends Atom<unknown>[]>(...atoms: A): AtomValue<A[number]>;
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
- * Variadic form - pass atoms as arguments.
85
+ * Object-based - pass atoms as a record with keys.
72
86
  *
73
- * - If any atom is ready → returns first ready value
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 - Atoms to check (variadic)
80
- * @returns First ready value
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<A extends Atom<unknown>[]>(...atoms: A): AtomValue<A[number]>;
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
- * Variadic form - pass atoms as arguments.
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 - Atoms to check (variadic)
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>[]>(...atoms: A): {
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 ContextSelectorFn<T> = (context: SelectContext) => T;
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 `get`, `all`, `any`, `race`, `settled` utilities
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 `get()` to read async atoms - it handles Suspense-style loading
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 get()
243
+ * // ✅ CORRECT - Create async atom and read with read()
133
244
  * const data$ = atom(fetch('/api/data').then(r => r.json()));
134
- * select(({ get }) => get(data$)); // Suspends until resolved
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(({ get, all }) => {
145
- * const user = get(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: ContextSelectorFn<T>): SelectResult<T>;
330
+ export declare function select<T>(fn: ReactiveSelector<T>): SelectResult<T>;
@@ -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.value * 2 }))
29
- * .use(source => ({ ...source, triple: () => source.value * 3 }));
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.value; // Promise<Post[]>
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 `.value` always returns a Promise,
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(({ get }) => get(count$) * 2);
132
- * await double$.value; // number
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(({ get }) => get(count$) * 2, { fallback: 0 });
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;