@but212/atom-effect 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +583 -12
- package/package.json +4 -4
- package/dist/constants.d.ts +0 -64
- package/dist/constants.d.ts.map +0 -1
- package/dist/core/atom/atom.d.ts +0 -25
- package/dist/core/atom/atom.d.ts.map +0 -1
- package/dist/core/atom/index.d.ts +0 -6
- package/dist/core/atom/index.d.ts.map +0 -1
- package/dist/core/computed/computed-async-handler.d.ts +0 -237
- package/dist/core/computed/computed-async-handler.d.ts.map +0 -1
- package/dist/core/computed/computed-dependencies.d.ts +0 -173
- package/dist/core/computed/computed-dependencies.d.ts.map +0 -1
- package/dist/core/computed/computed-handlers.d.ts +0 -285
- package/dist/core/computed/computed-handlers.d.ts.map +0 -1
- package/dist/core/computed/computed-state-flags.d.ts +0 -335
- package/dist/core/computed/computed-state-flags.d.ts.map +0 -1
- package/dist/core/computed/index.d.ts +0 -35
- package/dist/core/computed/index.d.ts.map +0 -1
- package/dist/core/effect/effect.d.ts +0 -64
- package/dist/core/effect/effect.d.ts.map +0 -1
- package/dist/core/effect/index.d.ts +0 -2
- package/dist/core/effect/index.d.ts.map +0 -1
- package/dist/core/index.d.ts +0 -4
- package/dist/core/index.d.ts.map +0 -1
- package/dist/errors/errors.d.ts +0 -118
- package/dist/errors/errors.d.ts.map +0 -1
- package/dist/errors/messages.d.ts +0 -101
- package/dist/errors/messages.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/scheduler/batch.d.ts +0 -31
- package/dist/scheduler/batch.d.ts.map +0 -1
- package/dist/scheduler/index.d.ts +0 -3
- package/dist/scheduler/index.d.ts.map +0 -1
- package/dist/scheduler/scheduler.d.ts +0 -153
- package/dist/scheduler/scheduler.d.ts.map +0 -1
- package/dist/tracking/context.d.ts +0 -76
- package/dist/tracking/context.d.ts.map +0 -1
- package/dist/tracking/dependency-manager.d.ts +0 -224
- package/dist/tracking/dependency-manager.d.ts.map +0 -1
- package/dist/tracking/index.d.ts +0 -5
- package/dist/tracking/index.d.ts.map +0 -1
- package/dist/tracking/tracking.types.d.ts +0 -12
- package/dist/tracking/tracking.types.d.ts.map +0 -1
- package/dist/tracking/untracked.d.ts +0 -25
- package/dist/tracking/untracked.d.ts.map +0 -1
- package/dist/types/atom.d.ts +0 -13
- package/dist/types/atom.d.ts.map +0 -1
- package/dist/types/common.d.ts +0 -45
- package/dist/types/common.d.ts.map +0 -1
- package/dist/types/computed.d.ts +0 -18
- package/dist/types/computed.d.ts.map +0 -1
- package/dist/types/effect.d.ts +0 -13
- package/dist/types/effect.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -5
- package/dist/types/index.d.ts.map +0 -1
- package/dist/utils/debug.d.ts +0 -85
- package/dist/utils/debug.d.ts.map +0 -1
- package/dist/utils/object-pool.d.ts +0 -159
- package/dist/utils/object-pool.d.ts.map +0 -1
- package/dist/utils/subscriber-manager.d.ts +0 -127
- package/dist/utils/subscriber-manager.d.ts.map +0 -1
- package/dist/utils/type-guards.d.ts +0 -5
- package/dist/utils/type-guards.d.ts.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,583 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*/
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export
|
|
12
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Async computation states for computed atoms
|
|
3
|
+
*/
|
|
4
|
+
export declare const AsyncState: {
|
|
5
|
+
IDLE: "idle";
|
|
6
|
+
PENDING: "pending";
|
|
7
|
+
RESOLVED: "resolved";
|
|
8
|
+
REJECTED: "rejected";
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export declare type AsyncStateType = 'idle' | 'pending' | 'resolved' | 'rejected';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new atom with the given initial value.
|
|
15
|
+
*
|
|
16
|
+
* @template T - The type of value stored in the atom
|
|
17
|
+
* @param initialValue - The initial value of the atom
|
|
18
|
+
* @param options - Optional configuration options
|
|
19
|
+
* @returns A writable atom instance
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* // Basic usage
|
|
24
|
+
* const count = atom(0);
|
|
25
|
+
*
|
|
26
|
+
* // With sync option for immediate notifications
|
|
27
|
+
* const syncCount = atom(0, { sync: true });
|
|
28
|
+
*
|
|
29
|
+
* // Reading and writing
|
|
30
|
+
* console.log(count.value); // 0
|
|
31
|
+
* count.value = 5;
|
|
32
|
+
* console.log(count.peek()); // 5 (non-tracking read)
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare function atom<T>(initialValue: T, options?: AtomOptions): WritableAtom<T>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @fileoverview Error class hierarchy for atom-effect library
|
|
39
|
+
* @description Structured error classes with cause tracking and recoverability flags
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* Base error class for all atom-effect errors
|
|
43
|
+
*
|
|
44
|
+
* Provides enhanced error information including:
|
|
45
|
+
* - Original cause tracking for error chains
|
|
46
|
+
* - Recoverability flag for error handling strategies
|
|
47
|
+
* - Timestamp for debugging and logging
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* throw new AtomError('Invalid state', originalError, false);
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare class AtomError extends Error {
|
|
55
|
+
/** Original error that caused this error, if any */
|
|
56
|
+
cause: Error | null;
|
|
57
|
+
/** Whether this error can be recovered from */
|
|
58
|
+
recoverable: boolean;
|
|
59
|
+
/** When this error occurred */
|
|
60
|
+
timestamp: Date;
|
|
61
|
+
/**
|
|
62
|
+
* Creates a new AtomError
|
|
63
|
+
* @param message - Error message describing what went wrong
|
|
64
|
+
* @param cause - Original error that caused this error
|
|
65
|
+
* @param recoverable - Whether the operation can be retried
|
|
66
|
+
*/
|
|
67
|
+
constructor(message: string, cause?: Error | null, recoverable?: boolean);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export declare interface AtomOptions {
|
|
71
|
+
sync?: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Executes multiple reactive updates in a single batch.
|
|
76
|
+
*
|
|
77
|
+
* Batching groups multiple state changes together, deferring notifications
|
|
78
|
+
* until all updates are complete. This prevents intermediate states from
|
|
79
|
+
* triggering unnecessary recomputations and improves performance.
|
|
80
|
+
*
|
|
81
|
+
* @template T - The return type of the callback function
|
|
82
|
+
* @param callback - The function containing batched updates
|
|
83
|
+
* @returns The result of the callback function
|
|
84
|
+
* @throws {AtomError} If the callback is not a function
|
|
85
|
+
* @throws {AtomError} If an error occurs during batch execution
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* const firstName = atom('John');
|
|
90
|
+
* const lastName = atom('Doe');
|
|
91
|
+
*
|
|
92
|
+
* // Without batching: triggers 2 separate updates
|
|
93
|
+
* firstName.value = 'Jane';
|
|
94
|
+
* lastName.value = 'Smith';
|
|
95
|
+
*
|
|
96
|
+
* // With batching: triggers 1 combined update
|
|
97
|
+
* batch(() => {
|
|
98
|
+
* firstName.value = 'Jane';
|
|
99
|
+
* lastName.value = 'Smith';
|
|
100
|
+
* });
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export declare function batch<T>(callback: () => T): T;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Creates a computed value that automatically tracks and reacts to dependencies
|
|
107
|
+
*
|
|
108
|
+
* Computed atoms are derived reactive state that:
|
|
109
|
+
* - Automatically track dependencies accessed during computation
|
|
110
|
+
* - Lazily recompute only when dependencies change (dirty checking)
|
|
111
|
+
* - Support both synchronous and asynchronous computations
|
|
112
|
+
* - Cache results until dependencies change (memoization)
|
|
113
|
+
* - Use bit flags for efficient state management
|
|
114
|
+
* - Provide async state tracking (idle/pending/resolved/rejected)
|
|
115
|
+
*
|
|
116
|
+
* @template T - The type of the computed value
|
|
117
|
+
* @param fn - Computation function (can return T or Promise<T>)
|
|
118
|
+
* @param options - Configuration options
|
|
119
|
+
* @returns A readonly computed atom with automatic dependency tracking
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* // Synchronous computed
|
|
124
|
+
* const count = atom(0);
|
|
125
|
+
* const doubled = computed(() => count.value * 2);
|
|
126
|
+
*
|
|
127
|
+
* // Asynchronous computed with default value
|
|
128
|
+
* const userData = computed(
|
|
129
|
+
* async () => fetch(`/api/user/${userId.value}`).then(r => r.json()),
|
|
130
|
+
* { defaultValue: null }
|
|
131
|
+
* );
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
export declare function computed<T>(fn: () => T, options?: ComputedOptions<T>): ComputedAtom<T>;
|
|
135
|
+
|
|
136
|
+
export declare function computed<T>(fn: () => Promise<T>, options: ComputedOptions<T> & {
|
|
137
|
+
defaultValue: T;
|
|
138
|
+
}): ComputedAtom<T>;
|
|
139
|
+
|
|
140
|
+
export declare interface ComputedAtom<T = unknown> extends ReadonlyAtom<T> {
|
|
141
|
+
readonly state: AsyncStateType;
|
|
142
|
+
readonly hasError: boolean;
|
|
143
|
+
readonly lastError: Error | null;
|
|
144
|
+
readonly isPending: boolean;
|
|
145
|
+
readonly isResolved: boolean;
|
|
146
|
+
invalidate(): void;
|
|
147
|
+
dispose(): void;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Error thrown during computed value computation
|
|
152
|
+
*
|
|
153
|
+
* Computed errors are considered recoverable by default since they typically
|
|
154
|
+
* result from transient data issues rather than programming errors.
|
|
155
|
+
*/
|
|
156
|
+
export declare class ComputedError extends AtomError {
|
|
157
|
+
/**
|
|
158
|
+
* Creates a new ComputedError
|
|
159
|
+
* @param message - Error message
|
|
160
|
+
* @param cause - Original error
|
|
161
|
+
*/
|
|
162
|
+
constructor(message: string, cause?: Error | null);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export declare interface ComputedOptions<T = unknown> {
|
|
166
|
+
equal?: (a: T, b: T) => boolean;
|
|
167
|
+
defaultValue?: T;
|
|
168
|
+
lazy?: boolean;
|
|
169
|
+
onError?: (error: Error) => void;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Debug configuration defaults
|
|
174
|
+
*/
|
|
175
|
+
export declare const DEBUG_CONFIG: {
|
|
176
|
+
/** Maximum dependencies before warning about large dependency graphs */
|
|
177
|
+
readonly MAX_DEPENDENCIES: 1000;
|
|
178
|
+
/** Enable infinite loop detection warnings */
|
|
179
|
+
readonly WARN_INFINITE_LOOP: true;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Debug configuration instance with runtime utilities.
|
|
184
|
+
*
|
|
185
|
+
* Provides development-time features including:
|
|
186
|
+
* - Circular dependency detection (direct and indirect)
|
|
187
|
+
* - Large dependency graph warnings
|
|
188
|
+
* - Debug metadata attachment for inspection
|
|
189
|
+
*
|
|
190
|
+
* @remarks
|
|
191
|
+
* Most features are only active when `NODE_ENV === 'development'`
|
|
192
|
+
* to avoid performance overhead in production builds.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* // Check for circular dependencies
|
|
197
|
+
* debug.checkCircular(dependencyAtom, computedAtom);
|
|
198
|
+
*
|
|
199
|
+
* // Warn about potential issues
|
|
200
|
+
* debug.warn(count > 100, 'Large dependency count detected');
|
|
201
|
+
*
|
|
202
|
+
* // Attach debug info to a reactive object
|
|
203
|
+
* debug.attachDebugInfo(atom, 'atom', 42);
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
export declare const DEBUG_RUNTIME: DebugConfig;
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Debug configuration interface
|
|
210
|
+
*/
|
|
211
|
+
export declare interface DebugConfig {
|
|
212
|
+
enabled: boolean;
|
|
213
|
+
maxDependencies: number;
|
|
214
|
+
warnInfiniteLoop: boolean;
|
|
215
|
+
warn(condition: boolean, message: string): void;
|
|
216
|
+
checkCircular(dep: unknown, current: unknown, visited?: Set<unknown>): void;
|
|
217
|
+
attachDebugInfo(obj: object, type: string, id: number): void;
|
|
218
|
+
getDebugName(obj: unknown): string | undefined;
|
|
219
|
+
getDebugType(obj: unknown): string | undefined;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Interface for subscribable dependencies
|
|
224
|
+
*/
|
|
225
|
+
export declare interface Dependency {
|
|
226
|
+
subscribe(listener: (() => void) | Subscriber): () => void;
|
|
227
|
+
peek?(): unknown;
|
|
228
|
+
value?: unknown;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* WeakRef-based dependency entry structure
|
|
233
|
+
*/
|
|
234
|
+
export declare interface DependencyEntry<T extends object = Dependency> {
|
|
235
|
+
ref: WeakRef<T>;
|
|
236
|
+
unsubscribe: () => void;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Creates a reactive effect that automatically re-executes when its dependencies change.
|
|
241
|
+
*
|
|
242
|
+
* @param fn - The effect function to execute. May return a cleanup function
|
|
243
|
+
* or a Promise that resolves to a cleanup function.
|
|
244
|
+
* @param options - Configuration options for the effect
|
|
245
|
+
* @param options.sync - If true, re-executes synchronously on dependency changes.
|
|
246
|
+
* Defaults to false (scheduled/batched execution).
|
|
247
|
+
* @param options.maxExecutionsPerSecond - Maximum executions per second before
|
|
248
|
+
* infinite loop detection triggers.
|
|
249
|
+
* Defaults to `SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_SECOND`.
|
|
250
|
+
* @param options.trackModifications - If true, tracks and warns about dependencies
|
|
251
|
+
* that are both read and modified. Defaults to false.
|
|
252
|
+
*
|
|
253
|
+
* @returns An {@link EffectObject} with `run()`, `dispose()`, and state properties
|
|
254
|
+
*
|
|
255
|
+
* @throws {EffectError} If `fn` is not a function
|
|
256
|
+
*
|
|
257
|
+
* @remarks
|
|
258
|
+
* Effects are the primary way to perform side effects in response to reactive
|
|
259
|
+
* state changes. They automatically track which reactive values (atoms, computed)
|
|
260
|
+
* are accessed during execution and re-run when those values change.
|
|
261
|
+
*
|
|
262
|
+
* The effect function may return a cleanup function that will be called before
|
|
263
|
+
* the next execution or when the effect is disposed. This is useful for
|
|
264
|
+
* cleaning up subscriptions, timers, or other resources.
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* Basic usage:
|
|
268
|
+
* ```typescript
|
|
269
|
+
* const counter = atom(0);
|
|
270
|
+
*
|
|
271
|
+
* const fx = effect(() => {
|
|
272
|
+
* console.log('Counter:', counter.value);
|
|
273
|
+
* });
|
|
274
|
+
* // Logs: "Counter: 0"
|
|
275
|
+
*
|
|
276
|
+
* counter.value = 1;
|
|
277
|
+
* // Logs: "Counter: 1"
|
|
278
|
+
*
|
|
279
|
+
* fx.dispose(); // Stop the effect
|
|
280
|
+
* ```
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* With cleanup function:
|
|
284
|
+
* ```typescript
|
|
285
|
+
* const fx = effect(() => {
|
|
286
|
+
* const timer = setInterval(() => console.log('tick'), 1000);
|
|
287
|
+
* return () => clearInterval(timer); // Cleanup
|
|
288
|
+
* });
|
|
289
|
+
* ```
|
|
290
|
+
*
|
|
291
|
+
* @example
|
|
292
|
+
* Synchronous execution:
|
|
293
|
+
* ```typescript
|
|
294
|
+
* const fx = effect(
|
|
295
|
+
* () => console.log(counter.value),
|
|
296
|
+
* { sync: true }
|
|
297
|
+
* );
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
export declare function effect(fn: EffectFunction, options?: EffectOptions): EffectObject;
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Error thrown during effect execution
|
|
304
|
+
*
|
|
305
|
+
* Effect errors are considered non-recoverable by default since effects
|
|
306
|
+
* typically represent critical side effects that shouldn't fail silently.
|
|
307
|
+
*/
|
|
308
|
+
export declare class EffectError extends AtomError {
|
|
309
|
+
/**
|
|
310
|
+
* Creates a new EffectError
|
|
311
|
+
* @param message - Error message
|
|
312
|
+
* @param cause - Original error
|
|
313
|
+
*/
|
|
314
|
+
constructor(message: string, cause?: Error | null);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export declare type EffectFunction = () => void | (() => void) | Promise<undefined | (() => void)>;
|
|
318
|
+
|
|
319
|
+
export declare interface EffectObject {
|
|
320
|
+
dispose(): void;
|
|
321
|
+
run(): void;
|
|
322
|
+
readonly isDisposed: boolean;
|
|
323
|
+
readonly executionCount: number;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export declare interface EffectOptions {
|
|
327
|
+
sync?: boolean;
|
|
328
|
+
maxExecutionsPerSecond?: number;
|
|
329
|
+
trackModifications?: boolean;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export declare function isAtom(obj: unknown): obj is ReadonlyAtom;
|
|
333
|
+
|
|
334
|
+
export declare function isComputed(obj: unknown): obj is ComputedAtom;
|
|
335
|
+
|
|
336
|
+
export declare function isEffect(obj: unknown): obj is EffectObject;
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Object pool configuration
|
|
340
|
+
* Controls memory management and GC pressure reduction
|
|
341
|
+
*/
|
|
342
|
+
export declare const POOL_CONFIG: {
|
|
343
|
+
/** Maximum number of pooled objects to prevent memory bloat */
|
|
344
|
+
readonly MAX_SIZE: 1000;
|
|
345
|
+
/** Number of objects to pre-allocate for performance-critical paths */
|
|
346
|
+
readonly WARMUP_SIZE: 100;
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Interface for poolable objects
|
|
351
|
+
*/
|
|
352
|
+
export declare interface Poolable {
|
|
353
|
+
reset(): void;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export declare interface ReadonlyAtom<T = unknown> {
|
|
357
|
+
readonly value: T;
|
|
358
|
+
subscribe(listener: (newValue?: T, oldValue?: T) => void): () => void;
|
|
359
|
+
peek(): T;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Scheduler for managing reactive updates and batching operations.
|
|
364
|
+
*
|
|
365
|
+
* The Scheduler is responsible for coordinating when reactive computations
|
|
366
|
+
* are executed. It supports both immediate (microtask) execution and
|
|
367
|
+
* batched synchronous execution for optimal performance.
|
|
368
|
+
*
|
|
369
|
+
* Key features:
|
|
370
|
+
* - Deduplication of callbacks via Set
|
|
371
|
+
* - Nested batch support with depth tracking
|
|
372
|
+
* - Infinite loop protection with configurable iteration limit
|
|
373
|
+
* - Error isolation to prevent one callback from breaking others
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
* ```typescript
|
|
377
|
+
* // Schedule a callback for microtask execution
|
|
378
|
+
* scheduler.schedule(() => console.log('Updated!'));
|
|
379
|
+
*
|
|
380
|
+
* // Batch multiple updates
|
|
381
|
+
* scheduler.startBatch();
|
|
382
|
+
* scheduler.schedule(() => console.log('Update 1'));
|
|
383
|
+
* scheduler.schedule(() => console.log('Update 2'));
|
|
384
|
+
* scheduler.endBatch(); // Both execute synchronously here
|
|
385
|
+
* ```
|
|
386
|
+
*/
|
|
387
|
+
declare class Scheduler {
|
|
388
|
+
/** Queue of callbacks waiting for microtask execution */
|
|
389
|
+
/** Queue buffers for double buffering optimization */
|
|
390
|
+
private queueA;
|
|
391
|
+
private queueB;
|
|
392
|
+
/** Currently active queue receiving new tasks */
|
|
393
|
+
private queue;
|
|
394
|
+
/** Whether the scheduler is currently processing the queue */
|
|
395
|
+
private isProcessing;
|
|
396
|
+
/** Whether batching is currently active */
|
|
397
|
+
isBatching: boolean;
|
|
398
|
+
/** Current nesting depth of batch operations */
|
|
399
|
+
private batchDepth;
|
|
400
|
+
/** Array of callbacks queued during batching */
|
|
401
|
+
private batchQueue;
|
|
402
|
+
/** Current size of the batch queue (for array reuse) */
|
|
403
|
+
private batchQueueSize;
|
|
404
|
+
/** Whether synchronous flush is in progress */
|
|
405
|
+
private isFlushingSync;
|
|
406
|
+
/** Maximum iterations allowed during flush to prevent infinite loops */
|
|
407
|
+
private maxFlushIterations;
|
|
408
|
+
/**
|
|
409
|
+
* Schedules a callback for execution.
|
|
410
|
+
*
|
|
411
|
+
* If batching is active or a sync flush is in progress, the callback
|
|
412
|
+
* is added to the batch queue. Otherwise, it's added to the main queue
|
|
413
|
+
* and a flush is triggered via microtask.
|
|
414
|
+
*
|
|
415
|
+
* @param callback - The function to schedule for execution
|
|
416
|
+
* @throws {SchedulerError} If callback is not a function
|
|
417
|
+
*
|
|
418
|
+
* @example
|
|
419
|
+
* ```typescript
|
|
420
|
+
* scheduler.schedule(() => {
|
|
421
|
+
* // This runs in the next microtask (or sync if batching)
|
|
422
|
+
* updateUI();
|
|
423
|
+
* });
|
|
424
|
+
* ```
|
|
425
|
+
*/
|
|
426
|
+
schedule(callback: () => void): void;
|
|
427
|
+
/**
|
|
428
|
+
* Flushes the queue asynchronously via microtask.
|
|
429
|
+
*
|
|
430
|
+
* Executes all queued callbacks in a microtask, allowing the current
|
|
431
|
+
* synchronous execution to complete first. Errors in individual
|
|
432
|
+
* callbacks are caught and logged without interrupting others.
|
|
433
|
+
*
|
|
434
|
+
* @private
|
|
435
|
+
* @remarks
|
|
436
|
+
* This method is idempotent - calling it multiple times while
|
|
437
|
+
* processing is active has no effect.
|
|
438
|
+
*/
|
|
439
|
+
private flush;
|
|
440
|
+
/**
|
|
441
|
+
* Flushes all queued callbacks synchronously.
|
|
442
|
+
*
|
|
443
|
+
* This method is called when a batch ends. It processes all callbacks
|
|
444
|
+
* in the batch queue and main queue synchronously, allowing callbacks
|
|
445
|
+
* to schedule additional callbacks that are processed in the same flush.
|
|
446
|
+
*
|
|
447
|
+
* @private
|
|
448
|
+
* @remarks
|
|
449
|
+
* - Includes infinite loop protection via maxFlushIterations
|
|
450
|
+
* - Errors in callbacks are caught and logged individually
|
|
451
|
+
* - The isFlushingSync flag prevents re-entrancy issues
|
|
452
|
+
*/
|
|
453
|
+
private flushSync;
|
|
454
|
+
/**
|
|
455
|
+
* Starts a new batch operation.
|
|
456
|
+
*
|
|
457
|
+
* While batching is active, all scheduled callbacks are deferred
|
|
458
|
+
* until endBatch() is called. Batches can be nested - only the
|
|
459
|
+
* outermost endBatch() triggers execution.
|
|
460
|
+
*
|
|
461
|
+
* @example
|
|
462
|
+
* ```typescript
|
|
463
|
+
* scheduler.startBatch();
|
|
464
|
+
* // All updates here are deferred
|
|
465
|
+
* atom1.value = 'a';
|
|
466
|
+
* atom2.value = 'b';
|
|
467
|
+
* scheduler.endBatch(); // Both updates processed together
|
|
468
|
+
* ```
|
|
469
|
+
*/
|
|
470
|
+
startBatch(): void;
|
|
471
|
+
/**
|
|
472
|
+
* Ends a batch operation.
|
|
473
|
+
*
|
|
474
|
+
* Decrements the batch depth counter. When depth reaches zero,
|
|
475
|
+
* all queued callbacks are flushed synchronously and batching
|
|
476
|
+
* is disabled.
|
|
477
|
+
*
|
|
478
|
+
* @remarks
|
|
479
|
+
* Safe to call even if startBatch() wasn't called - depth is
|
|
480
|
+
* clamped to zero minimum.
|
|
481
|
+
*
|
|
482
|
+
* @example
|
|
483
|
+
* ```typescript
|
|
484
|
+
* scheduler.startBatch();
|
|
485
|
+
* try {
|
|
486
|
+
* // ... batched operations
|
|
487
|
+
* } finally {
|
|
488
|
+
* scheduler.endBatch(); // Always end batch, even on error
|
|
489
|
+
* }
|
|
490
|
+
* ```
|
|
491
|
+
*/
|
|
492
|
+
endBatch(): void;
|
|
493
|
+
/**
|
|
494
|
+
* Sets the maximum number of flush iterations allowed.
|
|
495
|
+
*
|
|
496
|
+
* This limit prevents infinite loops when reactive dependencies
|
|
497
|
+
* form cycles. If exceeded, the queue is cleared and an error
|
|
498
|
+
* is logged.
|
|
499
|
+
*
|
|
500
|
+
* @param max - Maximum iterations (must be at least 10)
|
|
501
|
+
* @throws {SchedulerError} If max is less than 10
|
|
502
|
+
*
|
|
503
|
+
* @example
|
|
504
|
+
* ```typescript
|
|
505
|
+
* // Increase limit for complex dependency graphs
|
|
506
|
+
* scheduler.setMaxFlushIterations(5000);
|
|
507
|
+
* ```
|
|
508
|
+
*/
|
|
509
|
+
setMaxFlushIterations(max: number): void;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/** Global scheduler instance for reactive updates */
|
|
513
|
+
export declare const scheduler: Scheduler;
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Scheduler configuration
|
|
517
|
+
* Controls batching behavior and performance limits
|
|
518
|
+
*/
|
|
519
|
+
export declare const SCHEDULER_CONFIG: {
|
|
520
|
+
/** Maximum effect executions per second to detect infinite loops */
|
|
521
|
+
readonly MAX_EXECUTIONS_PER_SECOND: 100;
|
|
522
|
+
/** Threshold for cleaning up old execution timestamps */
|
|
523
|
+
readonly CLEANUP_THRESHOLD: 100;
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Error thrown by the scheduler system
|
|
528
|
+
*
|
|
529
|
+
* Scheduler errors indicate fundamental issues with the batching/scheduling
|
|
530
|
+
* mechanism and are considered non-recoverable.
|
|
531
|
+
*/
|
|
532
|
+
export declare class SchedulerError extends AtomError {
|
|
533
|
+
/**
|
|
534
|
+
* Creates a new SchedulerError
|
|
535
|
+
* @param message - Error message
|
|
536
|
+
* @param cause - Original error
|
|
537
|
+
*/
|
|
538
|
+
constructor(message: string, cause?: Error | null);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Subscriber interface for dependency notifications
|
|
543
|
+
*/
|
|
544
|
+
export declare interface Subscriber {
|
|
545
|
+
execute(): void;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Transform function type
|
|
550
|
+
*/
|
|
551
|
+
export declare type TransformFunction<T, U> = (value: T) => U;
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Executes a function without tracking any reactive dependencies.
|
|
555
|
+
*
|
|
556
|
+
* This utility allows reading atom values without establishing
|
|
557
|
+
* a dependency relationship, useful for accessing values that
|
|
558
|
+
* shouldn't trigger recomputation when they change.
|
|
559
|
+
*
|
|
560
|
+
* @template T - The return type of the function
|
|
561
|
+
* @param fn - The function to execute without tracking
|
|
562
|
+
* @returns The result of the executed function
|
|
563
|
+
* @throws {AtomError} If the callback is not a function
|
|
564
|
+
* @throws {AtomError} If an error occurs during execution
|
|
565
|
+
*
|
|
566
|
+
* @example
|
|
567
|
+
* ```typescript
|
|
568
|
+
* const count = atom(0);
|
|
569
|
+
* const doubled = computed(() => {
|
|
570
|
+
* // This read will NOT be tracked as a dependency
|
|
571
|
+
* const untrackedValue = untracked(() => count.value);
|
|
572
|
+
* return untrackedValue * 2;
|
|
573
|
+
* });
|
|
574
|
+
* ```
|
|
575
|
+
*/
|
|
576
|
+
export declare function untracked<T>(fn: () => T): T;
|
|
577
|
+
|
|
578
|
+
export declare interface WritableAtom<T = unknown> extends ReadonlyAtom<T> {
|
|
579
|
+
value: T;
|
|
580
|
+
dispose(): void;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
export { }
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@but212/atom-effect",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A reactive state management library that combines the power of `atom`, `computed`, and `effect` for seamless management of reactive state.",
|
|
6
|
-
"main": "dist/index.cjs",
|
|
7
|
-
"module": "dist/index.mjs",
|
|
8
|
-
"types": "dist/index.d.ts",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
9
|
"files": [
|
|
10
10
|
"dist"
|
|
11
11
|
],
|
package/dist/constants.d.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Constants and configuration for atom-effect library
|
|
3
|
-
* @description Centralized constants for async states, bit flags, and performance tuning
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Async computation states for computed atoms
|
|
7
|
-
*/
|
|
8
|
-
export declare const AsyncState: {
|
|
9
|
-
IDLE: "idle";
|
|
10
|
-
PENDING: "pending";
|
|
11
|
-
RESOLVED: "resolved";
|
|
12
|
-
REJECTED: "rejected";
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* Bit flags for effect state management
|
|
16
|
-
* Using bit flags for efficient state checks (O(1) operations)
|
|
17
|
-
*/
|
|
18
|
-
export declare const EFFECT_STATE_FLAGS: {
|
|
19
|
-
readonly DISPOSED: number;
|
|
20
|
-
readonly EXECUTING: number;
|
|
21
|
-
};
|
|
22
|
-
/**
|
|
23
|
-
* Bit flags for computed atom state management
|
|
24
|
-
* Enables fast state transitions and checks without multiple boolean fields
|
|
25
|
-
*/
|
|
26
|
-
export declare const COMPUTED_STATE_FLAGS: {
|
|
27
|
-
readonly DIRTY: number;
|
|
28
|
-
readonly IDLE: number;
|
|
29
|
-
readonly PENDING: number;
|
|
30
|
-
readonly RESOLVED: number;
|
|
31
|
-
readonly REJECTED: number;
|
|
32
|
-
readonly RECOMPUTING: number;
|
|
33
|
-
readonly HAS_ERROR: number;
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* Object pool configuration
|
|
37
|
-
* Controls memory management and GC pressure reduction
|
|
38
|
-
*/
|
|
39
|
-
export declare const POOL_CONFIG: {
|
|
40
|
-
/** Maximum number of pooled objects to prevent memory bloat */
|
|
41
|
-
readonly MAX_SIZE: 1000;
|
|
42
|
-
/** Number of objects to pre-allocate for performance-critical paths */
|
|
43
|
-
readonly WARMUP_SIZE: 100;
|
|
44
|
-
};
|
|
45
|
-
/**
|
|
46
|
-
* Scheduler configuration
|
|
47
|
-
* Controls batching behavior and performance limits
|
|
48
|
-
*/
|
|
49
|
-
export declare const SCHEDULER_CONFIG: {
|
|
50
|
-
/** Maximum effect executions per second to detect infinite loops */
|
|
51
|
-
readonly MAX_EXECUTIONS_PER_SECOND: 100;
|
|
52
|
-
/** Threshold for cleaning up old execution timestamps */
|
|
53
|
-
readonly CLEANUP_THRESHOLD: 100;
|
|
54
|
-
};
|
|
55
|
-
/**
|
|
56
|
-
* Debug configuration defaults
|
|
57
|
-
*/
|
|
58
|
-
export declare const DEBUG_CONFIG: {
|
|
59
|
-
/** Maximum dependencies before warning about large dependency graphs */
|
|
60
|
-
readonly MAX_DEPENDENCIES: 1000;
|
|
61
|
-
/** Enable infinite loop detection warnings */
|
|
62
|
-
readonly WARN_INFINITE_LOOP: true;
|
|
63
|
-
};
|
|
64
|
-
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;CAKtB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;CAGrB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;CAQvB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,WAAW;IACtB,+DAA+D;;IAE/D,uEAAuE;;CAE/D,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,gBAAgB;IAC3B,oEAAoE;;IAEpE,yDAAyD;;CAEjD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,YAAY;IACvB,wEAAwE;;IAExE,8CAA8C;;CAEtC,CAAC"}
|
package/dist/core/atom/atom.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { AtomOptions, WritableAtom } from '../../types';
|
|
2
|
-
/**
|
|
3
|
-
* Creates a new atom with the given initial value.
|
|
4
|
-
*
|
|
5
|
-
* @template T - The type of value stored in the atom
|
|
6
|
-
* @param initialValue - The initial value of the atom
|
|
7
|
-
* @param options - Optional configuration options
|
|
8
|
-
* @returns A writable atom instance
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```ts
|
|
12
|
-
* // Basic usage
|
|
13
|
-
* const count = atom(0);
|
|
14
|
-
*
|
|
15
|
-
* // With sync option for immediate notifications
|
|
16
|
-
* const syncCount = atom(0, { sync: true });
|
|
17
|
-
*
|
|
18
|
-
* // Reading and writing
|
|
19
|
-
* console.log(count.value); // 0
|
|
20
|
-
* count.value = 5;
|
|
21
|
-
* console.log(count.peek()); // 5 (non-tracking read)
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
export declare function atom<T>(initialValue: T, options?: AtomOptions): WritableAtom<T>;
|
|
25
|
-
//# sourceMappingURL=atom.d.ts.map
|