@but212/atom-effect 0.1.0 → 0.1.1

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.
@@ -1,19 +1,149 @@
1
+ /**
2
+ * Scheduler for managing reactive updates and batching operations.
3
+ *
4
+ * The Scheduler is responsible for coordinating when reactive computations
5
+ * are executed. It supports both immediate (microtask) execution and
6
+ * batched synchronous execution for optimal performance.
7
+ *
8
+ * Key features:
9
+ * - Deduplication of callbacks via Set
10
+ * - Nested batch support with depth tracking
11
+ * - Infinite loop protection with configurable iteration limit
12
+ * - Error isolation to prevent one callback from breaking others
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * // Schedule a callback for microtask execution
17
+ * scheduler.schedule(() => console.log('Updated!'));
18
+ *
19
+ * // Batch multiple updates
20
+ * scheduler.startBatch();
21
+ * scheduler.schedule(() => console.log('Update 1'));
22
+ * scheduler.schedule(() => console.log('Update 2'));
23
+ * scheduler.endBatch(); // Both execute synchronously here
24
+ * ```
25
+ */
1
26
  declare class Scheduler {
27
+ /** Queue of callbacks waiting for microtask execution */
2
28
  private queue;
29
+ /** Whether the scheduler is currently processing the queue */
3
30
  private isProcessing;
31
+ /** Whether batching is currently active */
4
32
  isBatching: boolean;
33
+ /** Current nesting depth of batch operations */
5
34
  private batchDepth;
35
+ /** Array of callbacks queued during batching */
6
36
  private batchQueue;
37
+ /** Current size of the batch queue (for array reuse) */
7
38
  private batchQueueSize;
39
+ /** Whether synchronous flush is in progress */
8
40
  private isFlushingSync;
41
+ /** Maximum iterations allowed during flush to prevent infinite loops */
9
42
  private maxFlushIterations;
43
+ /**
44
+ * Schedules a callback for execution.
45
+ *
46
+ * If batching is active or a sync flush is in progress, the callback
47
+ * is added to the batch queue. Otherwise, it's added to the main queue
48
+ * and a flush is triggered via microtask.
49
+ *
50
+ * @param callback - The function to schedule for execution
51
+ * @throws {SchedulerError} If callback is not a function
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * scheduler.schedule(() => {
56
+ * // This runs in the next microtask (or sync if batching)
57
+ * updateUI();
58
+ * });
59
+ * ```
60
+ */
10
61
  schedule(callback: () => void): void;
62
+ /**
63
+ * Flushes the queue asynchronously via microtask.
64
+ *
65
+ * Executes all queued callbacks in a microtask, allowing the current
66
+ * synchronous execution to complete first. Errors in individual
67
+ * callbacks are caught and logged without interrupting others.
68
+ *
69
+ * @private
70
+ * @remarks
71
+ * This method is idempotent - calling it multiple times while
72
+ * processing is active has no effect.
73
+ */
11
74
  private flush;
75
+ /**
76
+ * Flushes all queued callbacks synchronously.
77
+ *
78
+ * This method is called when a batch ends. It processes all callbacks
79
+ * in the batch queue and main queue synchronously, allowing callbacks
80
+ * to schedule additional callbacks that are processed in the same flush.
81
+ *
82
+ * @private
83
+ * @remarks
84
+ * - Includes infinite loop protection via maxFlushIterations
85
+ * - Errors in callbacks are caught and logged individually
86
+ * - The isFlushingSync flag prevents re-entrancy issues
87
+ */
12
88
  private flushSync;
89
+ /**
90
+ * Starts a new batch operation.
91
+ *
92
+ * While batching is active, all scheduled callbacks are deferred
93
+ * until endBatch() is called. Batches can be nested - only the
94
+ * outermost endBatch() triggers execution.
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * scheduler.startBatch();
99
+ * // All updates here are deferred
100
+ * atom1.value = 'a';
101
+ * atom2.value = 'b';
102
+ * scheduler.endBatch(); // Both updates processed together
103
+ * ```
104
+ */
13
105
  startBatch(): void;
106
+ /**
107
+ * Ends a batch operation.
108
+ *
109
+ * Decrements the batch depth counter. When depth reaches zero,
110
+ * all queued callbacks are flushed synchronously and batching
111
+ * is disabled.
112
+ *
113
+ * @remarks
114
+ * Safe to call even if startBatch() wasn't called - depth is
115
+ * clamped to zero minimum.
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * scheduler.startBatch();
120
+ * try {
121
+ * // ... batched operations
122
+ * } finally {
123
+ * scheduler.endBatch(); // Always end batch, even on error
124
+ * }
125
+ * ```
126
+ */
14
127
  endBatch(): void;
128
+ /**
129
+ * Sets the maximum number of flush iterations allowed.
130
+ *
131
+ * This limit prevents infinite loops when reactive dependencies
132
+ * form cycles. If exceeded, the queue is cleared and an error
133
+ * is logged.
134
+ *
135
+ * @param max - Maximum iterations (must be at least 10)
136
+ * @throws {SchedulerError} If max is less than 10
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * // Increase limit for complex dependency graphs
141
+ * scheduler.setMaxFlushIterations(5000);
142
+ * ```
143
+ */
15
144
  setMaxFlushIterations(max: number): void;
16
145
  }
146
+ /** Global scheduler instance for reactive updates */
17
147
  export declare const scheduler: Scheduler;
18
148
  export {};
19
149
  //# sourceMappingURL=scheduler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/scheduler/scheduler.ts"],"names":[],"mappings":"AAEA,cAAM,SAAS;IACb,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,YAAY,CAAkB;IAC/B,UAAU,EAAE,OAAO,CAAS;IACnC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,kBAAkB,CAAgB;IAE1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAepC,OAAO,CAAC,KAAK;IA0Bb,OAAO,CAAC,SAAS;IAoDjB,UAAU,IAAI,IAAI;IAKlB,QAAQ,IAAI,IAAI;IAShB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAMzC;AAED,eAAO,MAAM,SAAS,WAAkB,CAAC"}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/scheduler/scheduler.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,cAAM,SAAS;IACb,yDAAyD;IACzD,OAAO,CAAC,KAAK,CAA8B;IAE3C,8DAA8D;IAC9D,OAAO,CAAC,YAAY,CAAkB;IAEtC,2CAA2C;IACpC,UAAU,EAAE,OAAO,CAAS;IAEnC,gDAAgD;IAChD,OAAO,CAAC,UAAU,CAAa;IAE/B,gDAAgD;IAChD,OAAO,CAAC,UAAU,CAAyB;IAE3C,wDAAwD;IACxD,OAAO,CAAC,cAAc,CAAK;IAE3B,+CAA+C;IAC/C,OAAO,CAAC,cAAc,CAAkB;IAExC,wEAAwE;IACxE,OAAO,CAAC,kBAAkB,CAAgB;IAE1C;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAepC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,KAAK;IA0Bb;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,SAAS;IAoDjB;;;;;;;;;;;;;;;OAeG;IACH,UAAU,IAAI,IAAI;IAKlB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,IAAI,IAAI;IAShB;;;;;;;;;;;;;;;OAeG;IACH,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAMzC;AAED,qDAAqD;AACrD,eAAO,MAAM,SAAS,WAAkB,CAAC"}
@@ -1,8 +1,76 @@
1
1
  import { Listener } from './tracking.types';
2
+ /**
3
+ * Interface for the tracking context that manages dependency tracking.
4
+ *
5
+ * The tracking context is responsible for maintaining the current listener
6
+ * during reactive computations, enabling automatic dependency collection.
7
+ *
8
+ * @interface TrackingContext
9
+ */
2
10
  export interface TrackingContext {
11
+ /**
12
+ * The currently active listener being tracked.
13
+ * `null` when no tracking is in progress.
14
+ */
3
15
  current: Listener | null;
16
+ /**
17
+ * Executes a function within a tracking context.
18
+ *
19
+ * Sets the provided listener as the current tracking target,
20
+ * executes the function, and restores the previous context.
21
+ *
22
+ * @template T - The return type of the function
23
+ * @param listener - The listener to set as current during execution
24
+ * @param fn - The function to execute within the tracking context
25
+ * @returns The result of the executed function
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const result = trackingContext.run(myListener, () => {
30
+ * // Any atom access here will be tracked
31
+ * return someAtom.value + otherAtom.value;
32
+ * });
33
+ * ```
34
+ */
4
35
  run<T>(listener: Listener, fn: () => T): T;
36
+ /**
37
+ * Gets the currently active listener.
38
+ *
39
+ * @returns The current listener or `null` if no tracking is active
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const current = trackingContext.getCurrent();
44
+ * if (current) {
45
+ * // Dependency tracking is active
46
+ * }
47
+ * ```
48
+ */
5
49
  getCurrent(): Listener | null;
6
50
  }
51
+ /**
52
+ * Global tracking context singleton for dependency tracking.
53
+ *
54
+ * This object manages the current listener during reactive computations,
55
+ * enabling atoms and computed values to automatically track their dependencies.
56
+ *
57
+ * @remarks
58
+ * - The context uses a stack-like behavior via the `run` method
59
+ * - Nested `run` calls properly restore the previous context
60
+ * - Thread-safe within a single JavaScript execution context
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * // Setting up tracking for a computed value
65
+ * const value = trackingContext.run(computedListener, () => {
66
+ * return atom1.value + atom2.value; // Both atoms are tracked
67
+ * });
68
+ *
69
+ * // Checking if tracking is active
70
+ * if (trackingContext.getCurrent()) {
71
+ * // Register this atom as a dependency
72
+ * }
73
+ * ```
74
+ */
7
75
  export declare const trackingContext: TrackingContext;
8
76
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/tracking/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;IACzB,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3C,UAAU,IAAI,QAAQ,GAAG,IAAI,CAAC;CAC/B;AAED,eAAO,MAAM,eAAe,EAAE,eAgB7B,CAAC"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/tracking/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;IAEzB;;;;;;;;;;;;;;;;;;OAkBG;IACH,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAE3C;;;;;;;;;;;;OAYG;IACH,UAAU,IAAI,QAAQ,GAAG,IAAI,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,eAAe,EAAE,eAsB7B,CAAC"}
@@ -1,17 +1,220 @@
1
1
  import { Dependency } from '../types';
2
+ /**
3
+ * Manages reactive dependencies with automatic cleanup and memory-efficient tracking.
4
+ *
5
+ * This class provides a centralized way to track dependencies between reactive
6
+ * primitives (atoms, computed values) and their subscribers. It uses WeakRef
7
+ * and WeakMap for memory-efficient storage that allows garbage collection
8
+ * of unused dependencies.
9
+ *
10
+ * @remarks
11
+ * - Uses WeakMap for O(1) lookup and automatic GC of unreferenced dependencies
12
+ * - Uses WeakRef array for iteration while allowing GC
13
+ * - Periodic cleanup removes stale WeakRefs to prevent memory leaks
14
+ * - Thread-safe for single-threaded JavaScript execution
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const manager = new DependencyManager();
19
+ *
20
+ * // Add a dependency with its unsubscribe callback
21
+ * const unsubscribe = atom.subscribe(() => recompute());
22
+ * manager.addDependency(atom, unsubscribe);
23
+ *
24
+ * // Check if dependency exists
25
+ * if (manager.hasDependency(atom)) {
26
+ * console.log('Dependency tracked');
27
+ * }
28
+ *
29
+ * // Remove specific dependency
30
+ * manager.removeDependency(atom);
31
+ *
32
+ * // Clean up all dependencies
33
+ * manager.unsubscribeAll();
34
+ * ```
35
+ */
2
36
  export declare class DependencyManager {
37
+ /**
38
+ * WeakMap storing dependency -> unsubscribe function mappings.
39
+ * Allows O(1) lookup and automatic garbage collection.
40
+ */
3
41
  private depMap;
42
+ /**
43
+ * Array of WeakRefs for iteration over live dependencies.
44
+ * WeakRefs allow the referenced objects to be garbage collected.
45
+ */
4
46
  private depRefs;
47
+ /**
48
+ * Number of additions before triggering automatic cleanup.
49
+ * @defaultValue 100
50
+ */
5
51
  private cleanupThreshold;
52
+ /**
53
+ * Counter tracking additions since last cleanup.
54
+ */
6
55
  private addCount;
56
+ /**
57
+ * Adds a dependency with its associated unsubscribe callback.
58
+ *
59
+ * If the dependency already exists, the new unsubscribe callback is
60
+ * immediately called to prevent duplicate subscriptions.
61
+ *
62
+ * @param dep - The dependency to track (atom, computed, etc.)
63
+ * @param unsubscribe - Callback to invoke when removing the dependency
64
+ *
65
+ * @remarks
66
+ * - Duplicate dependencies are rejected with immediate unsubscribe
67
+ * - Automatic cleanup is triggered every `cleanupThreshold` additions
68
+ * - Time complexity: O(1) for add, O(n) when cleanup triggers
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * const unsubscribe = atom.subscribe(() => markDirty());
73
+ * manager.addDependency(atom, unsubscribe);
74
+ * ```
75
+ */
7
76
  addDependency(dep: Dependency, unsubscribe: () => void): void;
77
+ /**
78
+ * Removes a dependency and calls its unsubscribe callback.
79
+ *
80
+ * @param dep - The dependency to remove
81
+ * @returns `true` if the dependency was found and removed, `false` otherwise
82
+ *
83
+ * @remarks
84
+ * - Unsubscribe errors are caught and logged to prevent cascading failures
85
+ * - The WeakRef entry is not immediately removed (cleaned up lazily)
86
+ * - Time complexity: O(1)
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * const wasRemoved = manager.removeDependency(atom);
91
+ * if (wasRemoved) {
92
+ * console.log('Dependency successfully removed');
93
+ * }
94
+ * ```
95
+ */
8
96
  removeDependency(dep: Dependency): boolean;
97
+ /**
98
+ * Checks if a dependency is currently being tracked.
99
+ *
100
+ * @param dep - The dependency to check
101
+ * @returns `true` if the dependency exists in the manager
102
+ *
103
+ * @remarks
104
+ * Time complexity: O(1)
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * if (manager.hasDependency(atom)) {
109
+ * // Dependency is already tracked
110
+ * }
111
+ * ```
112
+ */
9
113
  hasDependency(dep: Dependency): boolean;
114
+ /**
115
+ * Removes all dependencies and calls their unsubscribe callbacks.
116
+ *
117
+ * This method iterates through all tracked dependencies, calls their
118
+ * unsubscribe callbacks, and clears internal storage.
119
+ *
120
+ * @remarks
121
+ * - Errors during unsubscribe are caught and logged individually
122
+ * - Safe to call multiple times (idempotent after first call)
123
+ * - Time complexity: O(n) where n is the number of dependencies
124
+ *
125
+ * @example
126
+ * ```typescript
127
+ * // Clean up when disposing a computed value
128
+ * manager.unsubscribeAll();
129
+ * ```
130
+ */
10
131
  unsubscribeAll(): void;
132
+ /**
133
+ * Removes stale WeakRefs from the internal array.
134
+ *
135
+ * WeakRefs whose targets have been garbage collected are filtered out
136
+ * to prevent unbounded growth of the depRefs array.
137
+ *
138
+ * @remarks
139
+ * - Called automatically every `cleanupThreshold` additions
140
+ * - Can be called manually for immediate cleanup
141
+ * - Time complexity: O(n) where n is the number of WeakRefs
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * // Force immediate cleanup
146
+ * manager.cleanup();
147
+ * ```
148
+ */
11
149
  cleanup(): void;
150
+ /**
151
+ * Gets the current number of live dependencies.
152
+ *
153
+ * @returns The count of dependencies that haven't been garbage collected
154
+ *
155
+ * @remarks
156
+ * - Triggers cleanup before counting for accurate results
157
+ * - Time complexity: O(n) due to cleanup
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * console.log(`Tracking ${manager.count} dependencies`);
162
+ * ```
163
+ */
12
164
  get count(): number;
165
+ /**
166
+ * Gets an array of all live dependencies.
167
+ *
168
+ * @returns Array of dependencies that haven't been garbage collected
169
+ *
170
+ * @remarks
171
+ * - Returns a new array (safe to modify)
172
+ * - Does not trigger cleanup (may include some stale refs)
173
+ * - Time complexity: O(n)
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * const deps = manager.getDependencies();
178
+ * deps.forEach(dep => console.log(dep));
179
+ * ```
180
+ */
13
181
  getDependencies(): Dependency[];
182
+ /**
183
+ * Gets the internal WeakMap for advanced use cases.
184
+ *
185
+ * @returns The internal dependency -> unsubscribe WeakMap
186
+ *
187
+ * @remarks
188
+ * - Returns the actual internal map (not a copy)
189
+ * - Modifications will affect the manager's state
190
+ * - Use with caution in production code
191
+ *
192
+ * @example
193
+ * ```typescript
194
+ * const map = manager.getDepMap();
195
+ * const unsubscribe = map.get(someDependency);
196
+ * ```
197
+ */
14
198
  getDepMap(): WeakMap<Dependency, () => void>;
199
+ /**
200
+ * Sets the threshold for automatic cleanup triggering.
201
+ *
202
+ * @param threshold - Number of additions before cleanup (minimum 1)
203
+ *
204
+ * @remarks
205
+ * - Lower values mean more frequent cleanup (less memory, more CPU)
206
+ * - Higher values mean less frequent cleanup (more memory, less CPU)
207
+ * - Default is 100, suitable for most use cases
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * // More aggressive cleanup for memory-constrained environments
212
+ * manager.setCleanupThreshold(50);
213
+ *
214
+ * // Less frequent cleanup for performance-critical paths
215
+ * manager.setCleanupThreshold(500);
216
+ * ```
217
+ */
15
218
  setCleanupThreshold(threshold: number): void;
16
219
  }
17
220
  //# sourceMappingURL=dependency-manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dependency-manager.d.ts","sourceRoot":"","sources":["../../src/tracking/dependency-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,gBAAgB,CAAO;IAC/B,OAAO,CAAC,QAAQ,CAAK;IAErB,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,IAAI,GAAG,IAAI;IAe7D,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO;IAc1C,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO;IAIvC,cAAc,IAAI,IAAI;IAmBtB,OAAO,IAAI,IAAI;IAIf,IAAI,KAAK,IAAI,MAAM,CAGlB;IAED,eAAe,IAAI,UAAU,EAAE;IAW/B,SAAS,IAAI,OAAO,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC;IAI5C,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAG7C"}
1
+ {"version":3,"file":"dependency-manager.d.ts","sourceRoot":"","sources":["../../src/tracking/dependency-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBAAa,iBAAiB;IAC5B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAyC;IAEvD;;;OAGG;IACH,OAAO,CAAC,OAAO,CAA6B;IAE5C;;;OAGG;IACH,OAAO,CAAC,gBAAgB,CAAO;IAE/B;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAK;IAErB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,IAAI,GAAG,IAAI;IAe7D;;;;;;;;;;;;;;;;;;OAkBG;IACH,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO;IAc1C;;;;;;;;;;;;;;;OAeG;IACH,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO;IAIvC;;;;;;;;;;;;;;;;OAgBG;IACH,cAAc,IAAI,IAAI;IAmBtB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,IAAI,IAAI;IAIf;;;;;;;;;;;;;OAaG;IACH,IAAI,KAAK,IAAI,MAAM,CAGlB;IAED;;;;;;;;;;;;;;;OAeG;IACH,eAAe,IAAI,UAAU,EAAE;IAW/B;;;;;;;;;;;;;;;OAeG;IACH,SAAS,IAAI,OAAO,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC;IAI5C;;;;;;;;;;;;;;;;;;OAkBG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAG7C"}
@@ -1,2 +1,25 @@
1
+ /**
2
+ * Executes a function without tracking any reactive dependencies.
3
+ *
4
+ * This utility allows reading atom values without establishing
5
+ * a dependency relationship, useful for accessing values that
6
+ * shouldn't trigger recomputation when they change.
7
+ *
8
+ * @template T - The return type of the function
9
+ * @param fn - The function to execute without tracking
10
+ * @returns The result of the executed function
11
+ * @throws {AtomError} If the callback is not a function
12
+ * @throws {AtomError} If an error occurs during execution
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const count = atom(0);
17
+ * const doubled = computed(() => {
18
+ * // This read will NOT be tracked as a dependency
19
+ * const untrackedValue = untracked(() => count.value);
20
+ * return untrackedValue * 2;
21
+ * });
22
+ * ```
23
+ */
1
24
  export declare function untracked<T>(fn: () => T): T;
2
25
  //# sourceMappingURL=untracked.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"untracked.d.ts","sourceRoot":"","sources":["../../src/tracking/untracked.ts"],"names":[],"mappings":"AAGA,wBAAgB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAe3C"}
1
+ {"version":3,"file":"untracked.d.ts","sourceRoot":"","sources":["../../src/tracking/untracked.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAe3C"}
@@ -1,14 +1,85 @@
1
1
  import { DebugConfig } from '../types';
2
2
  /**
3
- * Symbols for debug metadata to avoid property name collisions
3
+ * Symbol key for storing debug display name on reactive objects.
4
+ *
5
+ * @remarks
6
+ * Using symbols prevents property name collisions with user-defined properties.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const atom = createAtom(0);
11
+ * console.log(atom[DEBUG_NAME]); // "atom_1"
12
+ * ```
4
13
  */
5
14
  export declare const DEBUG_NAME: unique symbol;
15
+ /**
16
+ * Symbol key for storing unique identifier on reactive objects.
17
+ *
18
+ * @remarks
19
+ * Each reactive object (atom, computed, effect) receives a unique numeric ID
20
+ * for debugging and tracking purposes.
21
+ */
6
22
  export declare const DEBUG_ID: unique symbol;
23
+ /**
24
+ * Symbol key for storing the type discriminator on reactive objects.
25
+ *
26
+ * @remarks
27
+ * Possible values: 'atom' | 'computed' | 'effect'
28
+ */
7
29
  export declare const DEBUG_TYPE: unique symbol;
8
30
  /**
9
- * Sentinel value to distinguish "no default value" from undefined
31
+ * Sentinel value to distinguish "no default value provided" from `undefined`.
32
+ *
33
+ * @remarks
34
+ * This allows computed values to differentiate between:
35
+ * - User explicitly passing `undefined` as default
36
+ * - User not providing any default value
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const hasDefault = options.defaultValue !== NO_DEFAULT_VALUE;
41
+ * ```
10
42
  */
11
43
  export declare const NO_DEFAULT_VALUE: unique symbol;
44
+ /**
45
+ * Debug configuration instance with runtime utilities.
46
+ *
47
+ * Provides development-time features including:
48
+ * - Circular dependency detection (direct and indirect)
49
+ * - Large dependency graph warnings
50
+ * - Debug metadata attachment for inspection
51
+ *
52
+ * @remarks
53
+ * Most features are only active when `NODE_ENV === 'development'`
54
+ * to avoid performance overhead in production builds.
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * // Check for circular dependencies
59
+ * debug.checkCircular(dependencyAtom, computedAtom);
60
+ *
61
+ * // Warn about potential issues
62
+ * debug.warn(count > 100, 'Large dependency count detected');
63
+ *
64
+ * // Attach debug info to a reactive object
65
+ * debug.attachDebugInfo(atom, 'atom', 42);
66
+ * ```
67
+ */
12
68
  export declare const debug: DebugConfig;
69
+ /**
70
+ * Generates a unique numeric identifier for reactive objects.
71
+ *
72
+ * @returns A unique positive integer, incrementing with each call
73
+ *
74
+ * @remarks
75
+ * IDs are globally unique within a single runtime session.
76
+ * The counter resets when the module is reloaded.
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * const atomId = generateId(); // 1
81
+ * const computedId = generateId(); // 2
82
+ * ```
83
+ */
13
84
  export declare const generateId: () => number;
14
85
  //# sourceMappingURL=debug.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../src/utils/debug.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;GAEG;AACH,eAAO,MAAM,UAAU,eAAsB,CAAC;AAC9C,eAAO,MAAM,QAAQ,eAAe,CAAC;AACrC,eAAO,MAAM,UAAU,eAAiB,CAAC;AAEzC;;GAEG;AACH,eAAO,MAAM,gBAAgB,eAA2B,CAAC;AAEzD,eAAO,MAAM,KAAK,EAAE,WA0DnB,CAAC;AAGF,eAAO,MAAM,UAAU,QAAO,MAAkB,CAAC"}
1
+ {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../src/utils/debug.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU,EAAE,OAAO,MAA4B,CAAC;AAE7D;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,EAAE,OAAO,MAAqB,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,UAAU,EAAE,OAAO,MAAuB,CAAC;AAExD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,EAAE,OAAO,MAAiC,CAAC;AAmBxE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,KAAK,EAAE,WAsKnB,CAAC;AASF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,UAAU,QAAO,MAAkB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@but212/atom-effect",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
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
6
  "main": "dist/index.cjs",