@but212/atom-effect 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -45
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +59 -65
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/constants.ts","../src/errors/errors.ts","../src/errors/messages.ts","../src/scheduler/scheduler.ts","../src/scheduler/batch.ts","../src/tracking/context.ts","../src/tracking/untracked.ts","../src/utils/debug.ts","../src/utils/subscriber-manager.ts","../src/core/atom/atom.ts","../src/epoch.ts","../src/types/internal.ts","../src/pool.ts","../src/core/computed/index.ts","../src/core/effect/effect.ts","../src/utils/type-guards.ts"],"sourcesContent":["/**\n * @fileoverview Constants and configuration for atom-effect library\n * @description Centralized constants for async states, bit flags, and performance tuning\n */\n\n/**\n * Async computation states for computed atoms\n */\nexport const AsyncState = {\n IDLE: 'idle' as const,\n PENDING: 'pending' as const,\n RESOLVED: 'resolved' as const,\n REJECTED: 'rejected' as const,\n};\n\n/**\n * Bit flags for effect state management\n * Using bit flags for efficient state checks (O(1) operations)\n */\nexport const EFFECT_STATE_FLAGS = {\n DISPOSED: 1 << 0, // 0001 - Effect has been disposed\n EXECUTING: 1 << 1, // 0010 - Effect is currently executing\n} as const;\n\n/**\n * Bit flags for computed atom state management\n * Enables fast state transitions and checks without multiple boolean fields\n */\nexport const COMPUTED_STATE_FLAGS = {\n DIRTY: 1 << 0, // 0001 - Needs recomputation\n IDLE: 1 << 1, // 0010 - Initial state, not computed yet\n PENDING: 1 << 2, // 0100 - Async computation in progress\n RESOLVED: 1 << 3, // 1000 - Successfully computed\n REJECTED: 1 << 4, // 10000 - Computation failed\n RECOMPUTING: 1 << 5, // 100000 - Currently recomputing\n HAS_ERROR: 1 << 6, // 1000000 - Has error state\n} as const;\n\n/**\n * Object pool configuration\n * Controls memory management and GC pressure reduction\n */\nexport const POOL_CONFIG = {\n /** Maximum number of pooled objects to prevent memory bloat */\n MAX_SIZE: 1000,\n /** Number of objects to pre-allocate for performance-critical paths */\n WARMUP_SIZE: 100,\n} as const;\n\n/**\n * Scheduler configuration\n * Controls batching behavior and performance limits\n */\nexport const SCHEDULER_CONFIG = {\n /** Maximum effect executions per second to detect infinite loops */\n MAX_EXECUTIONS_PER_SECOND: 100,\n /** Threshold for cleaning up old execution timestamps */\n CLEANUP_THRESHOLD: 100,\n} as const;\n\n/**\n * Debug configuration defaults\n */\nexport const DEBUG_CONFIG = {\n /** Maximum dependencies before warning about large dependency graphs */\n MAX_DEPENDENCIES: 1000,\n /** Enable infinite loop detection warnings */\n WARN_INFINITE_LOOP: true,\n} as const;\n\n/**\n * Maximum Small Integer (Smi) value in V8 (31-bit signed integer)\n * Used for IDs and Versions to prevent HeapNumber allocation\n */\nexport const SMI_MAX = 0x3fffffff;\n","/**\n * @fileoverview Error class hierarchy for atom-effect library\n * @description Structured error classes with cause tracking and recoverability flags\n */\n\n/**\n * Base error class for all atom-effect errors\n *\n * Provides enhanced error information including:\n * - Original cause tracking for error chains\n * - Recoverability flag for error handling strategies\n * - Timestamp for debugging and logging\n *\n * @example\n * ```ts\n * throw new AtomError('Invalid state', originalError, false);\n * ```\n */\nexport class AtomError extends Error {\n /** Original error that caused this error, if any */\n cause: Error | null;\n /** Whether this error can be recovered from */\n recoverable: boolean;\n /** When this error occurred */\n timestamp: Date;\n\n /**\n * Creates a new AtomError\n * @param message - Error message describing what went wrong\n * @param cause - Original error that caused this error\n * @param recoverable - Whether the operation can be retried\n */\n constructor(message: string, cause: Error | null = null, recoverable: boolean = true) {\n super(message);\n this.name = 'AtomError';\n this.cause = cause;\n this.recoverable = recoverable;\n this.timestamp = new Date();\n }\n}\n\n/**\n * Error thrown during computed value computation\n *\n * Computed errors are considered recoverable by default since they typically\n * result from transient data issues rather than programming errors.\n */\nexport class ComputedError extends AtomError {\n /**\n * Creates a new ComputedError\n * @param message - Error message\n * @param cause - Original error\n */\n constructor(message: string, cause: Error | null = null) {\n super(message, cause, true);\n this.name = 'ComputedError';\n }\n}\n\n/**\n * Error thrown during effect execution\n *\n * Effect errors are considered non-recoverable by default since effects\n * typically represent critical side effects that shouldn't fail silently.\n */\nexport class EffectError extends AtomError {\n /**\n * Creates a new EffectError\n * @param message - Error message\n * @param cause - Original error\n */\n constructor(message: string, cause: Error | null = null) {\n super(message, cause, false);\n this.name = 'EffectError';\n }\n}\n\n/**\n * Error thrown by the scheduler system\n *\n * Scheduler errors indicate fundamental issues with the batching/scheduling\n * mechanism and are considered non-recoverable.\n */\nexport class SchedulerError extends AtomError {\n /**\n * Creates a new SchedulerError\n * @param message - Error message\n * @param cause - Original error\n */\n constructor(message: string, cause: Error | null = null) {\n super(message, cause, false);\n this.name = 'SchedulerError';\n }\n}\n\n/**\n * Wraps an unknown error in the appropriate AtomError subclass\n *\n * Provides consistent error handling by:\n * - Preserving original error information in the cause field\n * - Adding contextual information about where the error occurred\n * - Returning existing AtomErrors unchanged\n * - Handling various error types (TypeError, ReferenceError, etc.)\n *\n * @param error - Unknown error to wrap\n * @param ErrorClass - AtomError subclass to use for wrapping\n * @param context - Context string describing where the error occurred\n * @returns Wrapped error with contextual information\n *\n * @example\n * ```ts\n * try {\n * computeFn();\n * } catch (err) {\n * throw wrapError(err, ComputedError, 'computation phase');\n * }\n * ```\n */\nexport function wrapError(\n error: unknown,\n ErrorClass: typeof AtomError,\n context: string\n): AtomError {\n if (error instanceof TypeError) {\n return new ErrorClass(`Type error (${context}): ${error.message}`, error);\n }\n if (error instanceof ReferenceError) {\n return new ErrorClass(`Reference error (${context}): ${error.message}`, error);\n }\n if (error instanceof AtomError) {\n return error;\n }\n\n // Handle other error types\n const errorMessage = error instanceof Error ? error.message : String(error);\n const cause = error instanceof Error ? error : null;\n return new ErrorClass(`Unexpected error (${context}): ${errorMessage}`, cause);\n}\n\n/**\n * Type guard to check if a value is a Promise\n *\n * Uses duck-typing to detect Promise-like objects by checking for\n * the presence of a `then` method.\n *\n * @template T - The type the Promise resolves to\n * @param value - Value to check\n * @returns True if value has a `then` method (is Promise-like)\n *\n * @example\n * ```ts\n * const result = computeFn();\n * if (isPromise(result)) {\n * await result;\n * }\n * ```\n */\nexport function isPromise<T>(value: unknown): value is Promise<T> {\n return (\n value !== null &&\n value !== undefined &&\n typeof (value as { then?: unknown }).then === 'function'\n );\n}\n","/**\n * @fileoverview Centralized error messages for better maintainability\n * @description All error messages in English for international accessibility\n * @module errors/messages\n */\n\n/**\n * Centralized error message constants for the atom-effect library.\n *\n * @description\n * Provides consistent, maintainable error messages across the library.\n * All messages are in English for international accessibility.\n *\n * @remarks\n * - Computed errors: Related to computed atom creation and execution\n * - Atom errors: Related to atom subscription and notification\n * - Effect errors: Related to effect lifecycle and cleanup\n * - Debug warnings: Non-critical warnings for debugging\n *\n * @example\n * ```ts\n * import { ERROR_MESSAGES } from './messages';\n *\n * if (typeof fn !== 'function') {\n * throw new Error(ERROR_MESSAGES.COMPUTED_MUST_BE_FUNCTION);\n * }\n * ```\n */\nexport const ERROR_MESSAGES = {\n // ─────────────────────────────────────────────────────────────────\n // Computed errors\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Error thrown when computed() receives a non-function argument.\n */\n COMPUTED_MUST_BE_FUNCTION: 'Computed function must be a function',\n\n /**\n * Error thrown when subscribe() receives a non-function listener.\n */\n COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION: 'Subscriber listener must be a function',\n\n /**\n * Error thrown when accessing a pending async computed without a default value.\n */\n COMPUTED_ASYNC_PENDING_NO_DEFAULT: 'Async computation is pending. No default value provided',\n\n /**\n * Error thrown when a synchronous computed computation fails.\n */\n COMPUTED_COMPUTATION_FAILED: 'Computed computation failed',\n\n /**\n * Error thrown when an asynchronous computed computation fails.\n */\n COMPUTED_ASYNC_COMPUTATION_FAILED: 'Async computed computation failed',\n\n /**\n * Error thrown when subscribing to a dependency fails.\n */\n COMPUTED_DEPENDENCY_SUBSCRIPTION_FAILED: 'Failed to subscribe to dependency',\n\n // ─────────────────────────────────────────────────────────────────\n // Atom errors\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Error thrown when atom.subscribe() receives a non-function listener.\n */\n ATOM_SUBSCRIBER_MUST_BE_FUNCTION: 'Subscription listener must be a function',\n\n /**\n * Error thrown when the atom subscriber notification process fails.\n */\n ATOM_SUBSCRIBER_EXECUTION_FAILED: 'Error occurred while executing atom subscribers',\n\n /**\n * Error logged when an individual subscriber throws during notification.\n * @remarks This error is caught and logged to prevent cascading failures.\n */\n ATOM_INDIVIDUAL_SUBSCRIBER_FAILED: 'Error during individual atom subscriber execution',\n\n // ─────────────────────────────────────────────────────────────────\n // Effect errors\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Error thrown when effect() receives a non-function argument.\n */\n EFFECT_MUST_BE_FUNCTION: 'Effect function must be a function',\n\n /**\n * Error thrown when an effect's execution fails.\n */\n EFFECT_EXECUTION_FAILED: 'Effect execution failed',\n\n /**\n * Error thrown when an effect's cleanup function fails.\n */\n EFFECT_CLEANUP_FAILED: 'Effect cleanup function execution failed',\n\n // ─────────────────────────────────────────────────────────────────\n // Debug warnings\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Warning message for large dependency graphs.\n *\n * @param count - The number of dependencies detected\n * @returns Formatted warning message with dependency count\n *\n * @example\n * ```ts\n * console.warn(ERROR_MESSAGES.LARGE_DEPENDENCY_GRAPH(150));\n * // Output: \"Large dependency graph detected: 150 dependencies\"\n * ```\n */\n LARGE_DEPENDENCY_GRAPH: (count: number): string =>\n `Large dependency graph detected: ${count} dependencies`,\n\n /**\n * Warning logged when attempting to unsubscribe a non-existent listener.\n */\n UNSUBSCRIBE_NON_EXISTENT: 'Attempted to unsubscribe a non-existent listener',\n\n /**\n * Error logged when the onError callback itself throws an error.\n * @remarks This prevents cascading failures from masking the original error.\n */\n CALLBACK_ERROR_IN_ERROR_HANDLER: 'Error occurred during onError callback execution',\n} as const;\n","import { SchedulerError } from '../errors/errors';\n\n/**\n * Scheduler for managing reactive updates and batching operations.\n *\n * The Scheduler is responsible for coordinating when reactive computations\n * are executed. It supports both immediate (microtask) execution and\n * batched synchronous execution for optimal performance.\n *\n * Key features:\n * - Deduplication of callbacks via Set\n * - Nested batch support with depth tracking\n * - Infinite loop protection with configurable iteration limit\n * - Error isolation to prevent one callback from breaking others\n *\n * @example\n * ```typescript\n * // Schedule a callback for microtask execution\n * scheduler.schedule(() => console.log('Updated!'));\n *\n * // Batch multiple updates\n * scheduler.startBatch();\n * scheduler.schedule(() => console.log('Update 1'));\n * scheduler.schedule(() => console.log('Update 2'));\n * scheduler.endBatch(); // Both execute synchronously here\n * ```\n */\n/**\n * Phases of the scheduler execution cycle.\n */\nexport enum SchedulerPhase {\n IDLE = 0,\n BATCHING = 1,\n FLUSHING = 2,\n}\n\nexport type SchedulerJob = (() => void) & { _nextEpoch?: number };\n\nclass Scheduler {\n /** Queue of callbacks waiting for microtask execution */\n /** Queue buffers for double buffering optimization */\n private queueA: SchedulerJob[] = [];\n private queueB: SchedulerJob[] = [];\n\n /** Currently active queue receiving new tasks */\n private queue: SchedulerJob[] = this.queueA;\n private queueSize = 0;\n\n /** Epoch for O(1) deduplication */\n private _epoch = 0;\n\n /** Whether the scheduler is currently processing the queue */\n private isProcessing: boolean = false;\n\n /** Whether batching is currently active */\n public isBatching: boolean = false;\n\n /** Current nesting depth of batch operations */\n private batchDepth: number = 0;\n\n /** Array of callbacks queued during batching */\n private batchQueue: SchedulerJob[] = [];\n\n /** Current size of the batch queue (for array reuse) */\n private batchQueueSize = 0;\n\n /** Whether synchronous flush is in progress */\n private isFlushingSync: boolean = false;\n\n /** Maximum iterations allowed during flush to prevent infinite loops */\n private maxFlushIterations: number = 1000;\n\n /**\n * Gets the current phase of the scheduler.\n */\n get phase(): SchedulerPhase {\n if (this.isProcessing || this.isFlushingSync) {\n return SchedulerPhase.FLUSHING;\n }\n if (this.isBatching) {\n return SchedulerPhase.BATCHING;\n }\n return SchedulerPhase.IDLE;\n }\n\n /**\n * Schedules a callback for execution.\n *\n * If batching is active or a sync flush is in progress, the callback\n * is added to the batch queue. Otherwise, it's added to the main queue\n * and a flush is triggered via microtask.\n *\n * @param callback - The function to schedule for execution\n * @throws {SchedulerError} If callback is not a function\n *\n * @example\n * ```typescript\n * scheduler.schedule(() => {\n * // This runs in the next microtask (or sync if batching)\n * updateUI();\n * });\n * ```\n */\n schedule(callback: SchedulerJob): void {\n if (typeof callback !== 'function') {\n throw new SchedulerError('Scheduler callback must be a function');\n }\n\n // O(1) Unique dedup check\n if (callback._nextEpoch === this._epoch) return;\n callback._nextEpoch = this._epoch;\n\n if (this.isBatching || this.isFlushingSync) {\n this.batchQueue[this.batchQueueSize++] = callback;\n } else {\n this.queue[this.queueSize++] = callback;\n if (!this.isProcessing) {\n this.flush();\n }\n }\n }\n\n /**\n * Flushes the queue asynchronously via microtask.\n *\n * Executes all queued callbacks in a microtask, allowing the current\n * synchronous execution to complete first. Errors in individual\n * callbacks are caught and logged without interrupting others.\n *\n * @private\n * @remarks\n * This method is idempotent - calling it multiple times while\n * processing is active has no effect.\n */\n private flush(): void {\n if (this.isProcessing || this.queueSize === 0) return;\n\n this.isProcessing = true;\n\n // Double buffering: Swap queues to snapshot current tasks\n // This allows adding new tasks to the other queue while processing\n const jobs = this.queue;\n const count = this.queueSize;\n\n // Swap queues\n this.queue = this.queue === this.queueA ? this.queueB : this.queueA;\n this.queueSize = 0;\n\n // Increment epoch to invalidate previous task deduplication\n this._epoch++;\n\n queueMicrotask(() => {\n // Performance: Iterate Array by index\n for (let i = 0; i < count; i++) {\n try {\n jobs[i]?.();\n } catch (error) {\n console.error(\n new SchedulerError('Error occurred during scheduler execution', error as Error)\n );\n }\n }\n\n // Reuse array capacity\n jobs.length = 0;\n this.isProcessing = false;\n\n // If new tasks were added to the active queue (the one we swapped to), flush again\n if (this.queueSize > 0 && !this.isBatching) {\n this.flush();\n }\n });\n }\n\n /**\n * Flushes all queued callbacks synchronously.\n *\n * This method is called when a batch ends. It processes all callbacks\n * in the batch queue and main queue synchronously, allowing callbacks\n * to schedule additional callbacks that are processed in the same flush.\n *\n * @private\n * @remarks\n * - Includes infinite loop protection via maxFlushIterations\n * - Errors in callbacks are caught and logged individually\n * - The isFlushingSync flag prevents re-entrancy issues\n */\n private flushSync(): void {\n this.isFlushingSync = true;\n\n try {\n // Increment epoch first so batch jobs can pass the dedup check\n // (they were marked with the previous epoch during schedule())\n this._epoch++;\n\n if (this.batchQueueSize > 0) {\n for (let i = 0; i < this.batchQueueSize; i++) {\n // O(1) Unique dedup check for batch queue transfer\n const job = this.batchQueue[i]!;\n if (job._nextEpoch !== this._epoch) {\n job._nextEpoch = this._epoch;\n this.queue[this.queueSize++] = job;\n }\n }\n this.batchQueueSize = 0;\n }\n\n let iterations = 0;\n\n while (this.queueSize > 0) {\n if (++iterations > this.maxFlushIterations) {\n console.error(\n new SchedulerError(\n `Maximum flush iterations (${this.maxFlushIterations}) exceeded. ` +\n `Possible infinite loop in reactive dependencies. ` +\n `Consider increasing the limit with scheduler.setMaxFlushIterations()`\n )\n );\n // clear queue\n this.queueSize = 0;\n this.queue.length = 0;\n this.batchQueueSize = 0;\n break;\n }\n\n // Double buffering: Swap and process\n const jobs = this.queue;\n const count = this.queueSize;\n\n this.queue = this.queue === this.queueA ? this.queueB : this.queueA;\n this.queueSize = 0;\n this._epoch++;\n\n for (let i = 0; i < count; i++) {\n try {\n jobs[i]?.();\n } catch (error) {\n console.error(\n new SchedulerError('Error occurred during batch execution', error as Error)\n );\n }\n }\n\n jobs.length = 0;\n\n if (this.batchQueueSize > 0) {\n for (let i = 0; i < this.batchQueueSize; i++) {\n // Jobs scheduled during flush processing should always execute\n // (dedup was already done when they were added to batchQueue)\n this.queue[this.queueSize++] = this.batchQueue[i]!;\n }\n this.batchQueueSize = 0;\n }\n }\n } finally {\n this.isFlushingSync = false;\n }\n }\n\n /**\n * Starts a new batch operation.\n *\n * While batching is active, all scheduled callbacks are deferred\n * until endBatch() is called. Batches can be nested - only the\n * outermost endBatch() triggers execution.\n *\n * @example\n * ```typescript\n * scheduler.startBatch();\n * // All updates here are deferred\n * atom1.value = 'a';\n * atom2.value = 'b';\n * scheduler.endBatch(); // Both updates processed together\n * ```\n */\n startBatch(): void {\n this.batchDepth++;\n this.isBatching = true;\n }\n\n /**\n * Ends a batch operation.\n *\n * Decrements the batch depth counter. When depth reaches zero,\n * all queued callbacks are flushed synchronously and batching\n * is disabled.\n *\n * @remarks\n * Safe to call even if startBatch() wasn't called - depth is\n * clamped to zero minimum.\n *\n * @example\n * ```typescript\n * scheduler.startBatch();\n * try {\n * // ... batched operations\n * } finally {\n * scheduler.endBatch(); // Always end batch, even on error\n * }\n * ```\n */\n endBatch(): void {\n this.batchDepth = Math.max(0, this.batchDepth - 1);\n\n if (this.batchDepth === 0) {\n this.flushSync();\n this.isBatching = false;\n }\n }\n\n /**\n * Sets the maximum number of flush iterations allowed.\n *\n * This limit prevents infinite loops when reactive dependencies\n * form cycles. If exceeded, the queue is cleared and an error\n * is logged.\n *\n * @param max - Maximum iterations (must be at least 10)\n * @throws {SchedulerError} If max is less than 10\n *\n * @example\n * ```typescript\n * // Increase limit for complex dependency graphs\n * scheduler.setMaxFlushIterations(5000);\n * ```\n */\n setMaxFlushIterations(max: number): void {\n if (max < 10) {\n throw new SchedulerError('Max flush iterations must be at least 10');\n }\n this.maxFlushIterations = max;\n }\n}\n\n/** Global scheduler instance for reactive updates */\nexport const scheduler = new Scheduler();\n","import { AtomError } from '../errors/errors';\nimport { scheduler } from './scheduler';\n\n/**\n * Executes multiple reactive updates in a single batch.\n *\n * Batching groups multiple state changes together, deferring notifications\n * until all updates are complete. This prevents intermediate states from\n * triggering unnecessary recomputations and improves performance.\n *\n * @template T - The return type of the callback function\n * @param callback - The function containing batched updates\n * @returns The result of the callback function\n * @throws {AtomError} If the callback is not a function\n * @throws {AtomError} If an error occurs during batch execution\n *\n * @example\n * ```typescript\n * const firstName = atom('John');\n * const lastName = atom('Doe');\n *\n * // Without batching: triggers 2 separate updates\n * firstName.value = 'Jane';\n * lastName.value = 'Smith';\n *\n * // With batching: triggers 1 combined update\n * batch(() => {\n * firstName.value = 'Jane';\n * lastName.value = 'Smith';\n * });\n * ```\n */\nexport function batch<T>(callback: () => T): T {\n if (typeof callback !== 'function') {\n throw new AtomError('Batch callback must be a function');\n }\n\n scheduler.startBatch();\n\n try {\n return callback();\n } catch (error) {\n throw new AtomError('Error occurred during batch execution', error as Error);\n } finally {\n scheduler.endBatch();\n }\n}\n","import type { Listener } from './tracking.types';\n\n/**\n * Interface for the tracking context that manages dependency tracking.\n *\n * The tracking context is responsible for maintaining the current listener\n * during reactive computations, enabling automatic dependency collection.\n *\n * @interface TrackingContext\n */\nexport interface TrackingContext {\n /**\n * The currently active listener being tracked.\n * `null` when no tracking is in progress.\n */\n current: Listener | null;\n\n /**\n * Executes a function within a tracking context.\n *\n * Sets the provided listener as the current tracking target,\n * executes the function, and restores the previous context.\n *\n * @template T - The return type of the function\n * @param listener - The listener to set as current during execution\n * @param fn - The function to execute within the tracking context\n * @returns The result of the executed function\n *\n * @example\n * ```typescript\n * const result = trackingContext.run(myListener, () => {\n * // Any atom access here will be tracked\n * return someAtom.value + otherAtom.value;\n * });\n * ```\n */\n run<T>(listener: Listener, fn: () => T): T;\n\n /**\n * Gets the currently active listener.\n *\n * @returns The current listener or `null` if no tracking is active\n *\n * @example\n * ```typescript\n * const current = trackingContext.getCurrent();\n * if (current) {\n * // Dependency tracking is active\n * }\n * ```\n */\n getCurrent(): Listener | null;\n}\n\n/**\n * Global tracking context singleton for dependency tracking.\n *\n * This object manages the current listener during reactive computations,\n * enabling atoms and computed values to automatically track their dependencies.\n *\n * @remarks\n * - The context uses a stack-like behavior via the `run` method\n * - Nested `run` calls properly restore the previous context\n * - Thread-safe within a single JavaScript execution context\n *\n * @example\n * ```typescript\n * // Setting up tracking for a computed value\n * const value = trackingContext.run(computedListener, () => {\n * return atom1.value + atom2.value; // Both atoms are tracked\n * });\n *\n * // Checking if tracking is active\n * if (trackingContext.getCurrent()) {\n * // Register this atom as a dependency\n * }\n * ```\n */\nexport const trackingContext: TrackingContext = {\n /** @inheritdoc */\n current: null,\n\n /**\n * @inheritdoc\n * @throws Re-throws any error from the executed function after restoring context\n */\n run<T>(listener: Listener, fn: () => T): T {\n const prev = this.current;\n this.current = listener;\n try {\n return fn();\n } finally {\n this.current = prev;\n }\n },\n\n /** @inheritdoc */\n getCurrent(): Listener | null {\n return this.current;\n },\n};\n","import { AtomError } from '../errors/errors';\nimport { trackingContext } from './context';\n\n/**\n * Executes a function without tracking any reactive dependencies.\n *\n * This utility allows reading atom values without establishing\n * a dependency relationship, useful for accessing values that\n * shouldn't trigger recomputation when they change.\n *\n * @template T - The return type of the function\n * @param fn - The function to execute without tracking\n * @returns The result of the executed function\n * @throws {AtomError} If the callback is not a function\n * @throws {AtomError} If an error occurs during execution\n *\n * @example\n * ```typescript\n * const count = atom(0);\n * const doubled = computed(() => {\n * // This read will NOT be tracked as a dependency\n * const untrackedValue = untracked(() => count.value);\n * return untrackedValue * 2;\n * });\n * ```\n */\nexport function untracked<T>(fn: () => T): T {\n if (typeof fn !== 'function') {\n throw new AtomError('Untracked callback must be a function');\n }\n\n const prev = trackingContext.current;\n trackingContext.current = null;\n\n try {\n return fn();\n } catch (error) {\n throw new AtomError('Error occurred during untracked execution', error as Error);\n } finally {\n trackingContext.current = prev;\n }\n}\n","/**\n * @fileoverview Debug configuration and utilities\n *\n * This module provides development-time debugging tools for dependency tracking\n * and circular reference detection in the reactive state management system.\n *\n * @module utils/debug\n * @see {@link DebugConfig} for the configuration interface\n */\n\nimport { DEBUG_CONFIG } from '../constants';\nimport { ComputedError } from '../errors/errors';\nimport type { DebugConfig } from '../types';\n\n/**\n * Symbol key for storing debug display name on reactive objects.\n *\n * @remarks\n * Using symbols prevents property name collisions with user-defined properties.\n *\n * @example\n * ```typescript\n * const atom = createAtom(0);\n * console.log(atom[DEBUG_NAME]); // \"atom_1\"\n * ```\n */\nexport const DEBUG_NAME: unique symbol = Symbol('debugName');\n\n/**\n * Symbol key for storing unique identifier on reactive objects.\n *\n * @remarks\n * Each reactive object (atom, computed, effect) receives a unique numeric ID\n * for debugging and tracking purposes.\n */\nexport const DEBUG_ID: unique symbol = Symbol('id');\n\n/**\n * Symbol key for storing the type discriminator on reactive objects.\n *\n * @remarks\n * Possible values: 'atom' | 'computed' | 'effect'\n */\nexport const DEBUG_TYPE: unique symbol = Symbol('type');\n\n/**\n * Sentinel value to distinguish \"no default value provided\" from `undefined`.\n *\n * @remarks\n * This allows computed values to differentiate between:\n * - User explicitly passing `undefined` as default\n * - User not providing any default value\n *\n * @example\n * ```typescript\n * const hasDefault = options.defaultValue !== NO_DEFAULT_VALUE;\n * ```\n */\nexport const NO_DEFAULT_VALUE: unique symbol = Symbol('noDefaultValue');\n\n/**\n * Type guard for objects with a dependencies property.\n *\n * @param obj - The object to check\n * @returns True if the object has a Set-typed dependencies property\n *\n * @internal\n */\nfunction hasDependencies(obj: unknown): obj is { dependencies: Set<unknown> } {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n 'dependencies' in obj &&\n (obj as { dependencies: unknown }).dependencies instanceof Set\n );\n}\n\n/**\n * Debug configuration instance with runtime utilities.\n *\n * Provides development-time features including:\n * - Circular dependency detection (direct and indirect)\n * - Large dependency graph warnings\n * - Debug metadata attachment for inspection\n *\n * @remarks\n * Most features are only active when `NODE_ENV === 'development'`\n * to avoid performance overhead in production builds.\n *\n * @example\n * ```typescript\n * // Check for circular dependencies\n * debug.checkCircular(dependencyAtom, computedAtom);\n *\n * // Warn about potential issues\n * debug.warn(count > 100, 'Large dependency count detected');\n *\n * // Attach debug info to a reactive object\n * debug.attachDebugInfo(atom, 'atom', 42);\n * ```\n */\nexport const debug: DebugConfig = {\n /**\n * Whether debug mode is enabled.\n *\n * @remarks\n * Automatically set based on `NODE_ENV` environment variable.\n * Only `'development'` enables debug features.\n */\n enabled:\n typeof process !== 'undefined' && (process as NodeJS.Process).env?.NODE_ENV === 'development',\n\n /**\n * Maximum number of dependencies before warning.\n *\n * @see {@link DEBUG_CONFIG.MAX_DEPENDENCIES}\n */\n maxDependencies: DEBUG_CONFIG.MAX_DEPENDENCIES,\n\n /**\n * Whether to warn about potential infinite loops.\n *\n * @see {@link DEBUG_CONFIG.WARN_INFINITE_LOOP}\n */\n warnInfiniteLoop: DEBUG_CONFIG.WARN_INFINITE_LOOP,\n\n /**\n * Logs a warning message when condition is true and debug is enabled.\n *\n * @param condition - When true, the warning is logged\n * @param message - The warning message to display\n *\n * @example\n * ```typescript\n * debug.warn(deps.length > 100, 'Large dependency graph detected');\n * ```\n */\n warn(condition: boolean, message: string): void {\n if (this.enabled && condition) {\n console.warn(`[Atom Effect] ${message}`);\n }\n },\n\n /**\n * Checks for circular dependencies in the dependency graph.\n *\n * Detects two types of circular references:\n * 1. **Direct**: A depends on itself (A → A)\n * 2. **Indirect**: A depends on B which depends on A (A → B → A)\n *\n * @param dep - The dependency being added\n * @param current - The current reactive object adding the dependency\n * @param visited - Set of already visited nodes (for recursion)\n *\n * @throws {ComputedError} When a circular dependency is detected\n *\n * @remarks\n * - Direct circular detection runs in all environments\n * - Indirect circular detection only runs in development mode\n * - Uses depth-first traversal with O(n) time complexity\n *\n * @example\n * ```typescript\n * // This will throw for direct circular reference\n * debug.checkCircular(computedA, computedA);\n *\n * // This will throw for indirect circular reference (dev only)\n * // Given: A → B → C → A\n * debug.checkCircular(computedC, computedA);\n * ```\n */\n checkCircular(dep: unknown, current: unknown, visited = new Set<unknown>()): void {\n // Direct circular reference check (A→A) - Always checked even in production\n if (dep === current) {\n throw new ComputedError('Direct circular dependency detected');\n }\n\n // Indirect circular reference check only in development mode (for performance)\n if (!this.enabled) {\n return;\n }\n\n // Indirect circular reference check (A→B→C→A)\n if (visited.has(dep)) {\n throw new ComputedError('Indirect circular dependency detected');\n }\n\n visited.add(dep);\n\n // Recursively check nested dependencies using type guard\n if (hasDependencies(dep)) {\n for (const nestedDep of dep.dependencies) {\n this.checkCircular(nestedDep, current, visited);\n }\n }\n },\n\n /**\n * Attaches debug metadata to a reactive object.\n *\n * @param obj - The object to attach metadata to\n * @param type - The type of reactive object ('atom' | 'computed' | 'effect')\n * @param id - The unique identifier for this object\n *\n * @remarks\n * Only attaches metadata when debug mode is enabled.\n * Uses symbol keys to avoid property name collisions.\n *\n * @example\n * ```typescript\n * const atom = createAtomInternal(0);\n * debug.attachDebugInfo(atom, 'atom', 1);\n * // atom[DEBUG_NAME] === 'atom_1'\n * // atom[DEBUG_ID] === 1\n * // atom[DEBUG_TYPE] === 'atom'\n * ```\n */\n attachDebugInfo(obj: object, type: string, id: number): void {\n if (!this.enabled) {\n return;\n }\n\n const target = obj as Record<symbol, unknown>;\n target[DEBUG_NAME] = `${type}_${id}`;\n target[DEBUG_ID] = id;\n target[DEBUG_TYPE] = type;\n },\n\n /**\n * Retrieves the debug display name from a reactive object.\n *\n * @param obj - The object to get the name from\n * @returns The debug name (e.g., 'atom_1') or undefined if not set\n *\n * @example\n * ```typescript\n * const name = debug.getDebugName(myAtom);\n * console.log(`Updating ${name ?? 'unknown'}`);\n * ```\n */\n getDebugName(obj: unknown): string | undefined {\n if (obj !== null && typeof obj === 'object' && DEBUG_NAME in obj) {\n return (obj as Record<symbol, unknown>)[DEBUG_NAME] as string | undefined;\n }\n return undefined;\n },\n\n /**\n * Retrieves the debug type from a reactive object.\n *\n * @param obj - The object to get the type from\n * @returns The type ('atom' | 'computed' | 'effect') or undefined if not set\n *\n * @example\n * ```typescript\n * const type = debug.getDebugType(reactiveObj);\n * if (type === 'computed') {\n * // Handle computed-specific logic\n * }\n * ```\n */\n getDebugType(obj: unknown): string | undefined {\n if (obj !== null && typeof obj === 'object' && DEBUG_TYPE in obj) {\n return (obj as Record<symbol, unknown>)[DEBUG_TYPE] as string | undefined;\n }\n return undefined;\n },\n};\n\n/**\n * Counter for generating unique IDs.\n *\n * @internal\n */\nlet nextId = 1;\n\n/**\n * Generates a unique numeric identifier for reactive objects.\n *\n * @returns A unique positive integer, incrementing with each call\n *\n * @remarks\n * IDs are globally unique within a single runtime session.\n * The counter resets when the module is reloaded.\n *\n * @example\n * ```typescript\n * const atomId = generateId(); // 1\n * const computedId = generateId(); // 2\n * ```\n */\nexport const generateId = (): number => nextId++;\n","/**\n * @fileoverview Subscriber management utility\n * @description Manages subscribers with O(1) add/remove operations using Array + WeakMap\n */\n\n/**\n * Manages subscribers with optimized O(1) operations\n *\n * Uses a combination of Array (for iteration) and WeakMap (for O(1) lookup)\n * to provide both fast iteration and fast add/remove operations.\n *\n * Key optimizations:\n * - Array for cache-friendly sequential iteration\n * - WeakMap for O(1) lookup and automatic GC\n * - Swap-and-pop for O(1) removal\n * - Lazy initialization to save memory\n *\n * @template T - Subscriber type (any object type for WeakMap compatibility)\n *\n * @example\n * ```ts\n * const manager = new SubscriberManager<(value: number) => void>();\n *\n * // Add subscriber\n * const unsub = manager.add((val) => console.log(val));\n *\n * // Notify all\n * manager.notify(42);\n *\n * // Remove subscriber\n * unsub();\n * ```\n */\nexport class SubscriberManager<T extends object> {\n private subscribers: T[] | null = null;\n private subscriberIndex: WeakMap<T, number> | null = null;\n\n /**\n * Adds a subscriber and returns an unsubscribe function\n *\n * Performs lazy initialization on first subscriber.\n * Duplicate subscribers are ignored (idempotent).\n *\n * @param subscriber - Function to add as subscriber\n * @returns Unsubscribe function (O(1) removal)\n *\n * @example\n * ```ts\n * const unsub = manager.add((value) => console.log(value));\n * // Later...\n * unsub(); // Remove this subscriber\n * ```\n */\n add(subscriber: T): () => void {\n // Lazy initialization\n if (!this.subscribers) {\n this.subscribers = [];\n this.subscriberIndex = new WeakMap();\n }\n\n // Check for duplicates (O(1))\n if (this.subscriberIndex!.has(subscriber)) {\n // Already subscribed, return no-op unsubscribe\n return () => {};\n }\n\n // Add subscriber (O(1))\n const index = this.subscribers.length;\n this.subscribers.push(subscriber);\n this.subscriberIndex!.set(subscriber, index);\n\n // Return unsubscribe function with duplicate protection\n let isUnsubscribed = false;\n return () => {\n if (isUnsubscribed) return;\n isUnsubscribed = true;\n this.remove(subscriber);\n };\n }\n\n /**\n * Removes a subscriber using swap-and-pop optimization\n *\n * Time complexity: O(1)\n * - Swaps target with last element\n * - Pops last element\n * - Updates index mapping\n *\n * @param subscriber - Subscriber to remove\n * @returns True if removed, false if not found\n */\n remove(subscriber: T): boolean {\n if (!this.subscribers || !this.subscriberIndex) {\n return false;\n }\n\n const idx = this.subscriberIndex.get(subscriber);\n if (idx === undefined) {\n return false; // Not found\n }\n\n const lastIndex = this.subscribers.length - 1;\n\n // Swap with last element (O(1))\n if (idx !== lastIndex) {\n const lastSubscriber = this.subscribers[lastIndex]!;\n this.subscribers[idx] = lastSubscriber;\n this.subscriberIndex.set(lastSubscriber, idx);\n }\n\n // Pop last element (O(1))\n this.subscribers.pop();\n this.subscriberIndex.delete(subscriber);\n\n return true;\n }\n\n /**\n * Checks if a subscriber is registered\n *\n * @param subscriber - Subscriber to check\n * @returns True if registered\n */\n has(subscriber: T): boolean {\n return this.subscriberIndex?.has(subscriber) ?? false;\n }\n\n /**\n * Iterates over all subscribers with a callback\n *\n * Optimized for cache-friendly sequential access.\n * Errors in callbacks are propagated to the caller.\n *\n * @param fn - Callback to execute for each subscriber\n *\n * @example\n * ```ts\n * manager.forEach((subscriber) => {\n * subscriber(newValue, oldValue);\n * });\n * ```\n */\n forEach(fn: (subscriber: T, index: number) => void): void {\n if (!this.subscribers) return;\n\n for (let i = 0; i < this.subscribers.length; i++) {\n fn(this.subscribers[i]!, i);\n }\n }\n\n /**\n * Safely iterates over subscribers with error handling\n *\n * Catches and logs errors from individual callbacks to prevent\n * one failing subscriber from breaking the entire notification chain.\n *\n * @param fn - Callback to execute for each subscriber\n * @param onError - Optional error handler for each callback error\n */\n forEachSafe(fn: (subscriber: T, index: number) => void, onError?: (error: Error) => void): void {\n if (!this.subscribers) return;\n\n for (let i = 0; i < this.subscribers.length; i++) {\n try {\n fn(this.subscribers[i]!, i);\n } catch (error) {\n if (onError) {\n onError(error as Error);\n } else {\n console.error('[SubscriberManager] Error in subscriber callback:', error);\n }\n }\n }\n }\n\n /**\n * Gets the current number of subscribers\n *\n * @returns Number of active subscribers\n */\n get size(): number {\n return this.subscribers?.length ?? 0;\n }\n\n /**\n * Checks if there are any subscribers\n *\n * @returns True if at least one subscriber exists\n */\n get hasSubscribers(): boolean {\n return this.size > 0;\n }\n\n /**\n * Clears all subscribers\n *\n * Removes all subscribers and releases memory.\n * Subsequent operations will re-initialize lazily.\n */\n clear(): void {\n if (this.subscribers) {\n this.subscribers.length = 0;\n }\n this.subscriberIndex = null;\n this.subscribers = null;\n }\n\n /**\n * Gets a copy of all subscribers as an array\n *\n * Useful for debugging or manual iteration.\n * Returns empty array if no subscribers.\n *\n * @returns Array of all subscribers\n */\n toArray(): T[] {\n return this.subscribers ? [...this.subscribers] : [];\n }\n}\n","/**\n * @fileoverview atom: Core reactive state primitive\n *\n * Atoms are the fundamental building blocks of the reactive system.\n * They hold mutable state and automatically notify subscribers when their value changes.\n *\n * @example\n * ```ts\n * const count = atom(0);\n * count.value = 1; // Triggers subscribers\n * console.log(count.peek()); // 1 (without tracking)\n * ```\n */\n\nimport { SMI_MAX } from '../../constants';\nimport { AtomError } from '../../errors/errors';\nimport { ERROR_MESSAGES } from '../../errors/messages';\nimport { scheduler } from '../../scheduler';\nimport { trackingContext } from '../../tracking';\nimport type { AtomOptions, Subscriber, WritableAtom } from '../../types';\nimport { debug, generateId } from '../../utils/debug';\nimport { SubscriberManager } from '../../utils/subscriber-manager';\n\n/**\n * Internal implementation of the WritableAtom interface.\n *\n * @template T - The type of value stored in the atom\n *\n * @remarks\n * This class manages reactive state with optimized subscriber management.\n * It supports both function-based and object-based subscribers, and handles\n * synchronous or batched notifications based on configuration.\n */\nclass AtomImpl<T> implements WritableAtom<T> {\n // === Smi Fields (Fixed Order for V8 Hidden Class) ===\n /** Unique numerical identifier (Smi) */\n readonly id: number;\n\n /** Version counter for change detection (Smi) */\n version: number;\n\n /** Internal flags (Smi) */\n flags: number;\n\n /** Last seen epoch for dependency collection (Smi) */\n _lastSeenEpoch: number;\n\n // === Object Fields ===\n /** Current value stored in the atom */\n private _value: T;\n\n /** Manager for function-based subscribers */\n private readonly _functionSubscribers: SubscriberManager<(newValue?: T, oldValue?: T) => void>;\n\n /** Manager for object-based subscribers with execute method */\n private readonly _objectSubscribers: SubscriberManager<Subscriber>;\n\n /** Whether notifications should be synchronous (bypass scheduler batching) */\n private readonly _sync: boolean;\n\n /** Bound notification method to avoid closure allocation */\n private readonly _notifyTask: () => void;\n\n /** Pending old value for coalesced notifications */\n private _pendingOldValue: T | undefined;\n\n /** Whether a notification task is currently scheduled */\n private _isNotificationScheduled: boolean = false;\n\n /**\n * Creates a new AtomImpl instance.\n *\n * @param initialValue - The initial value of the atom\n * @param sync - Whether to notify subscribers synchronously\n */\n constructor(initialValue: T, sync: boolean) {\n // 1. Smi Fields Initialization\n this.id = generateId() & SMI_MAX;\n this.version = 0;\n this.flags = 0;\n this._lastSeenEpoch = -1;\n\n // 2. Object Fields Initialization\n this._value = initialValue;\n this._functionSubscribers = new SubscriberManager();\n this._objectSubscribers = new SubscriberManager();\n this._sync = sync;\n this._notifyTask = this._flushNotifications.bind(this);\n\n debug.attachDebugInfo(this, 'atom', this.id);\n }\n\n /**\n * Gets the current value and registers the atom as a dependency\n * in the current tracking context.\n *\n * @returns The current value\n *\n * @remarks\n * This getter automatically tracks dependencies when accessed within\n * a computed or effect context.\n */\n get value(): T {\n const current = trackingContext.getCurrent();\n if (current !== null && current !== undefined) {\n this._track(current);\n }\n return this._value;\n }\n\n /**\n * Sets a new value and notifies all subscribers if the value changed.\n *\n * @param newValue - The new value to set\n *\n * @remarks\n * Uses Object.is for equality comparison. If the value is unchanged,\n * no notifications are sent. Notifications may be batched unless\n * sync mode is enabled.\n */\n set value(newValue: T) {\n if (Object.is(this._value, newValue)) return;\n\n const oldValue = this._value;\n // Smi masked increment\n this.version = (this.version + 1) & SMI_MAX;\n const currentVersion = this.version;\n this._value = newValue;\n\n if (!this._functionSubscribers.hasSubscribers && !this._objectSubscribers.hasSubscribers)\n return;\n\n this._notify(newValue, oldValue, currentVersion);\n }\n\n /**\n * Tracks the current context as a dependency of this atom.\n *\n * @param current - The current tracking context (function or object)\n *\n * @remarks\n * Handles both function-based trackers (with optional addDependency method)\n * and object-based trackers (with execute or addDependency methods).\n */\n private _track(current: unknown): void {\n if (typeof current === 'function') {\n const fnWithDep = current as { addDependency?: (dep: unknown) => void };\n if (fnWithDep.addDependency !== undefined) {\n fnWithDep.addDependency(this);\n } else {\n this._functionSubscribers.add(current as (newValue?: T, oldValue?: T) => void);\n }\n } else {\n const tracker = current as { execute?: () => void; addDependency?: (dep: unknown) => void };\n if (tracker.addDependency !== undefined) {\n tracker.addDependency(this);\n } else if (tracker.execute !== undefined) {\n this._objectSubscribers.add(tracker as Subscriber);\n }\n }\n }\n\n /**\n * Notifies all subscribers of a value change.\n *\n * @param newValue - The new value\n * @param oldValue - The previous value\n * @param currentVersion - The version at the time of change\n *\n * @remarks\n * Notifications are skipped if the version has changed (stale update).\n * Errors from individual subscribers are caught and logged without\n * interrupting other subscribers.\n */\n /**\n * Schedules a notification.\n * Uses coalescing: if a notification is already scheduled, we update the state\n * but don't schedule a new task. The pending task will see the latest value.\n */\n private _notify(_newValue: T, oldValue: T, _currentVersion: number): void {\n if (!this._isNotificationScheduled) {\n this._pendingOldValue = oldValue;\n this._isNotificationScheduled = true;\n // We don't need to store currentVersion because the flush task\n // will always read the latest version and value.\n }\n\n if (this._sync && !scheduler.isBatching) {\n this._flushNotifications();\n } else {\n scheduler.schedule(this._notifyTask);\n }\n }\n\n /**\n * Executes the pending notifications.\n * Bound to 'this' in constructor to avoid closure allocation.\n */\n private _flushNotifications(): void {\n if (!this._isNotificationScheduled) return;\n\n // Capture state and reset flags BEFORE notifying to handle re-entrancy\n const oldValue = this._pendingOldValue as T;\n const newValue = this._value;\n\n this._pendingOldValue = undefined;\n this._isNotificationScheduled = false;\n\n this._functionSubscribers.forEachSafe(\n (sub) => sub(newValue, oldValue),\n (err) =>\n console.error(new AtomError(ERROR_MESSAGES.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, err as Error))\n );\n\n this._objectSubscribers.forEachSafe(\n (sub) => sub.execute(),\n (err) =>\n console.error(new AtomError(ERROR_MESSAGES.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, err as Error))\n );\n }\n\n /**\n * Subscribes a listener function to value changes.\n *\n * @param listener - Function to call when the value changes\n * @returns An unsubscribe function\n * @throws {AtomError} If listener is not a function\n *\n * @example\n * ```ts\n * const unsub = myAtom.subscribe((newVal, oldVal) => {\n * console.log(`Changed from ${oldVal} to ${newVal}`);\n * });\n * // Later: unsub();\n * ```\n */\n subscribe(listener: (newValue?: T, oldValue?: T) => void): () => void {\n if (typeof listener !== 'function') {\n throw new AtomError(ERROR_MESSAGES.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);\n }\n return this._functionSubscribers.add(listener);\n }\n\n /**\n * Gets the current value without registering as a dependency.\n *\n * @returns The current value\n *\n * @remarks\n * Use this method when you need to read the value without\n * creating a reactive dependency (e.g., in event handlers).\n */\n peek(): T {\n return this._value;\n }\n\n /**\n * Disposes the atom, clearing all subscribers and releasing resources.\n *\n * @remarks\n * After disposal, the atom should not be used. The value is set to\n * undefined to help with garbage collection.\n */\n dispose(): void {\n this._functionSubscribers.clear();\n this._objectSubscribers.clear();\n this._value = undefined as T;\n }\n\n /**\n * Gets the total number of active subscribers.\n *\n * @returns The count of function and object subscribers combined\n */\n subscriberCount(): number {\n return this._functionSubscribers.size + this._objectSubscribers.size;\n }\n}\n\n/**\n * Creates a new atom with the given initial value.\n *\n * @template T - The type of value stored in the atom\n * @param initialValue - The initial value of the atom\n * @param options - Optional configuration options\n * @returns A writable atom instance\n *\n * @example\n * ```ts\n * // Basic usage\n * const count = atom(0);\n *\n * // With sync option for immediate notifications\n * const syncCount = atom(0, { sync: true });\n *\n * // Reading and writing\n * console.log(count.value); // 0\n * count.value = 5;\n * console.log(count.peek()); // 5 (non-tracking read)\n * ```\n */\nexport function atom<T>(initialValue: T, options: AtomOptions = {}): WritableAtom<T> {\n return new AtomImpl(initialValue, options.sync ?? false);\n}\n","import { SMI_MAX } from './constants';\n\nlet collectorEpoch = 0;\n\nexport function nextEpoch(): number {\n collectorEpoch = ((collectorEpoch + 1) | 0) & SMI_MAX;\n return collectorEpoch;\n}\n\nexport function currentEpoch(): number {\n return collectorEpoch;\n}\n","export const __DEV__ = process.env.NODE_ENV !== 'production';\n\n// Scheduler & Atom interfaces to prevent circular deps\nexport interface IScheduler {\n markDirty(atom: any): void;\n scheduleNotify(atom: any): void;\n}\n\nexport interface IAtom {\n readonly id: number;\n version: number;\n _internalNotifySubscribers(): void;\n recompute?(): void;\n}\n\nexport interface PoolStats {\n acquired: number;\n released: number;\n rejected: { frozen: number; tooLarge: number; poolFull: number };\n leaked: number;\n poolSize: number;\n}\n","import type { Dependency, Subscriber } from './types';\nimport type { PoolStats } from './types/internal';\nimport { __DEV__ } from './types/internal';\n\n// ⚡ Shared Constants\nexport const EMPTY_DEPS: readonly Dependency[] = Object.freeze([]);\nexport const EMPTY_SUBS: readonly Subscriber[] = Object.freeze([]);\n\n/**\n * Generic Array Pool (Type-safe pooling for different array types)\n */\nclass ArrayPool<T> {\n private pool: T[][] = [];\n private readonly maxPoolSize = 50;\n private readonly maxReusableCapacity = 256;\n\n private stats = __DEV__\n ? {\n acquired: 0,\n released: 0,\n rejected: { frozen: 0, tooLarge: 0, poolFull: 0 },\n }\n : null;\n\n acquire(): T[] {\n if (__DEV__ && this.stats) this.stats.acquired++;\n return this.pool.pop() ?? [];\n }\n\n release(arr: T[], emptyConst?: readonly T[]): void {\n // ⚡ 1. Reference check first\n if (emptyConst && arr === emptyConst) return;\n\n // ⚡ 2. Frozen check\n if (Object.isFrozen(arr)) {\n if (__DEV__ && this.stats) this.stats.rejected.frozen++;\n return;\n }\n\n // 3. Size check\n if (arr.length > this.maxReusableCapacity) {\n if (__DEV__ && this.stats) this.stats.rejected.tooLarge++;\n return;\n }\n\n // 4. Pool capacity check\n if (this.pool.length >= this.maxPoolSize) {\n if (__DEV__ && this.stats) this.stats.rejected.poolFull++;\n return;\n }\n\n // 5. Normal release\n arr.length = 0;\n this.pool.push(arr);\n if (__DEV__ && this.stats) this.stats.released++;\n }\n\n getStats(): PoolStats | null {\n if (!__DEV__ || !this.stats) return null;\n const { acquired, released, rejected } = this.stats;\n const totalRejected = rejected.frozen + rejected.tooLarge + rejected.poolFull;\n return {\n acquired,\n released,\n rejected,\n leaked: acquired - released - totalRejected,\n poolSize: this.pool.length,\n };\n }\n\n reset(): void {\n this.pool.length = 0;\n if (__DEV__ && this.stats) {\n this.stats.acquired = 0;\n this.stats.released = 0;\n this.stats.rejected = { frozen: 0, tooLarge: 0, poolFull: 0 };\n }\n }\n}\n\n// ⚡ Per-type Pool Instances (V8 Shape Optimization)\nexport const depArrayPool = new ArrayPool<Dependency>();\nexport const subArrayPool = new ArrayPool<Subscriber>();\n","/**\n * @fileoverview computed: Derived reactive state with automatic dependency tracking\n * @description Creates computed values that automatically update when dependencies change (sync/async support)\n * @optimized Class-based architecture with cache locality and branchless patterns\n */\n\nimport { AsyncState, COMPUTED_STATE_FLAGS, SMI_MAX } from '../../constants';\nimport { nextEpoch } from '../../epoch';\nimport type { AtomError } from '../../errors/errors';\nimport { ComputedError, isPromise, wrapError } from '../../errors/errors';\nimport { ERROR_MESSAGES } from '../../errors/messages';\nimport { depArrayPool, EMPTY_DEPS } from '../../pool';\nimport { type SchedulerJob, scheduler } from '../../scheduler';\nimport { trackingContext } from '../../tracking';\nimport type { DependencyTracker } from '../../tracking/tracking.types';\n\nimport type {\n AsyncStateType,\n ComputedAtom,\n ComputedOptions,\n Dependency,\n Subscriber,\n} from '../../types';\nimport { debug, generateId, NO_DEFAULT_VALUE } from '../../utils/debug';\nimport { SubscriberManager } from '../../utils/subscriber-manager';\n\ntype TrackableListener = (() => void) & {\n addDependency: (dep: unknown) => void;\n};\n\n/**\n * Optimized ComputedAtom implementation with class-based architecture\n *\n * Key optimizations:\n * - Cache-friendly field layout (hot fields first)\n * - Inline bit flags (no separate class instance)\n * - Branchless fast path for value access\n * - Reduced indirection and closure overhead\n *\n * @template T - The type of the computed value\n */\nclass ComputedAtomImpl<T> implements ComputedAtom<T> {\n // === Smi Fields (Fixed Order for V8 Hidden Class) ===\n /** Unique numerical identifier (Smi) */\n readonly id: number;\n\n /** Version counter for change detection (Smi) */\n version: number;\n\n /** Internal flags (Smi) */\n flags: number;\n\n /** Last seen epoch for dependency collection (Smi) */\n _lastSeenEpoch: number;\n\n // === HOT PATH: Most frequently accessed fields (cache line 1) ===\n private _value: T;\n private _stateFlags: number;\n\n // === WARM PATH: Frequently accessed fields (cache line 2) ===\n private _error: AtomError | null;\n private _promiseId: number;\n private readonly _equal: (a: T, b: T) => boolean;\n\n // === COLD PATH: Infrequently accessed fields ===\n private readonly _fn: () => T | Promise<T>;\n private readonly _defaultValue: T;\n private readonly _hasDefaultValue: boolean;\n private readonly _onError: ((error: Error) => void) | null;\n private readonly _functionSubscribers: SubscriberManager<() => void>;\n private readonly _objectSubscribers: SubscriberManager<Subscriber>;\n private _dependencies: Dependency[];\n private readonly _subscriptions: Map<number, () => void>;\n\n private readonly _recomputeJob: SchedulerJob;\n private readonly _notifyJob: SchedulerJob;\n\n private readonly _trackable: TrackableListener;\n // private readonly _id: number; // Replaced by public id\n private readonly MAX_PROMISE_ID: number;\n\n constructor(fn: () => T | Promise<T>, options: ComputedOptions<T> = {}) {\n if (typeof fn !== 'function') {\n throw new ComputedError(ERROR_MESSAGES.COMPUTED_MUST_BE_FUNCTION);\n }\n\n // 1. Smi Fields Initialization\n this.id = generateId() & SMI_MAX;\n this.version = 0;\n this.flags = 0;\n this._lastSeenEpoch = -1;\n\n // 2. Fixed order initialization (HOT PATH first)\n this._value = undefined as T;\n this._stateFlags = COMPUTED_STATE_FLAGS.DIRTY | COMPUTED_STATE_FLAGS.IDLE;\n\n // WARM PATH\n this._error = null;\n this._promiseId = 0;\n this._equal = options.equal ?? Object.is;\n\n // COLD PATH & Constants\n this._fn = fn;\n this._defaultValue = 'defaultValue' in options ? options.defaultValue : (NO_DEFAULT_VALUE as T);\n this._hasDefaultValue = this._defaultValue !== (NO_DEFAULT_VALUE as T);\n this._onError = options.onError ?? null;\n this.MAX_PROMISE_ID = Number.MAX_SAFE_INTEGER - 1;\n\n // Managers & Structures\n this._functionSubscribers = new SubscriberManager<() => void>();\n this._objectSubscribers = new SubscriberManager<Subscriber>();\n\n // Optimized Dependency Management\n this._dependencies = EMPTY_DEPS as Dependency[];\n this._subscriptions = new Map();\n\n this._recomputeJob = () => {\n if (this._isDirty()) {\n try {\n this._recompute();\n } catch {\n // Error already handled\n }\n }\n };\n\n this._notifyJob = () => {\n this._functionSubscribers.forEachSafe(\n (subscriber) => subscriber(),\n (err) => console.error(err)\n );\n\n this._objectSubscribers.forEachSafe(\n (subscriber) => subscriber.execute(),\n (err) => console.error(err)\n );\n };\n\n // Trackable closure for dependency collection\n // We bind it once to avoid allocation during recompute\n this._trackable = Object.assign(() => this._markDirty(), {\n addDependency: (_dep: unknown) => {\n // This is called by Atom.value getter via trackingContext\n // We'll handle the actual collection logic inside recompute's context\n // but here we just need to ensure it works if called directly?\n // Actually, trackingContext.run sets the current collector.\n // When Atom calls _track(current), current is this._trackable.\n // But we need the *active* collector buffer.\n // We can store the active buffer in a temporary field or rely on the fact\n // that _recompute sets up the collection environment.\n // See recompute implementation below.\n },\n });\n\n debug.attachDebugInfo(this as unknown as ComputedAtom<T>, 'computed', this.id);\n\n if (debug.enabled) {\n const debugObj = this as unknown as ComputedAtom<T> & {\n subscriberCount: () => number;\n isDirty: () => boolean;\n dependencies: Dependency[];\n stateFlags: string;\n };\n debugObj.subscriberCount = () =>\n this._functionSubscribers.size + this._objectSubscribers.size;\n debugObj.isDirty = () => this._isDirty();\n debugObj.dependencies = this._dependencies;\n debugObj.stateFlags = this._getFlagsAsString();\n }\n\n // Lazy check - normalized access\n if (options.lazy === false) {\n try {\n this._recompute();\n } catch {\n // Ignore initial computation failure for non-lazy computed\n }\n }\n }\n\n // === PUBLIC API ===\n\n get value(): T {\n // Branchless fast path: single bitwise check for (resolved AND not dirty)\n const isFastPath =\n (this._stateFlags & (COMPUTED_STATE_FLAGS.RESOLVED | COMPUTED_STATE_FLAGS.DIRTY)) ===\n COMPUTED_STATE_FLAGS.RESOLVED;\n\n if (isFastPath) {\n this._registerTracking();\n return this._value;\n }\n\n // Slow path: state transition required\n const result = this._computeValue();\n this._registerTracking();\n return result;\n }\n\n subscribe(listener: () => void): () => void {\n if (typeof listener !== 'function') {\n throw new ComputedError(ERROR_MESSAGES.COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION);\n }\n return this._functionSubscribers.add(listener);\n }\n\n peek(): T {\n return this._value;\n }\n\n get state(): AsyncStateType {\n return this._getAsyncState();\n }\n\n get hasError(): boolean {\n return this._isRejected();\n }\n\n get lastError(): Error | null {\n return this._error;\n }\n\n get isPending(): boolean {\n return this._isPending();\n }\n\n get isResolved(): boolean {\n return this._isResolved();\n }\n\n invalidate(): void {\n this._markDirty();\n }\n\n dispose(): void {\n // Unsubscribe from all dependencies\n // Iterate stored subscriptions\n // We cannot iterate WeakMap, but we know which deps we have in _dependencies (if still holding them)\n // Wait, _syncDependencies iterates _dependencies.\n // So current _dependencies can be used to unsubscribe.\n\n if (this._dependencies !== EMPTY_DEPS) {\n for (const dep of this._dependencies) {\n const unsub = this._subscriptions.get(dep.id);\n if (unsub) unsub();\n this._subscriptions.delete(dep.id);\n }\n depArrayPool.release(this._dependencies);\n }\n this._dependencies = EMPTY_DEPS as Dependency[];\n\n this._functionSubscribers.clear();\n this._objectSubscribers.clear();\n this._stateFlags = COMPUTED_STATE_FLAGS.DIRTY | COMPUTED_STATE_FLAGS.IDLE;\n this._error = null;\n this._value = undefined as T;\n this._promiseId = (this._promiseId + 1) % this.MAX_PROMISE_ID;\n }\n\n // === PRIVATE: State Flag Operations (inlined for performance) ===\n\n private _isDirty(): boolean {\n return (this._stateFlags & COMPUTED_STATE_FLAGS.DIRTY) !== 0;\n }\n\n private _setDirty(): void {\n this._stateFlags |= COMPUTED_STATE_FLAGS.DIRTY;\n }\n\n private _clearDirty(): void {\n this._stateFlags &= ~COMPUTED_STATE_FLAGS.DIRTY;\n }\n\n private _isIdle(): boolean {\n return (this._stateFlags & COMPUTED_STATE_FLAGS.IDLE) !== 0;\n }\n\n private _setIdle(): void {\n this._stateFlags |= COMPUTED_STATE_FLAGS.IDLE;\n this._stateFlags &= ~(\n COMPUTED_STATE_FLAGS.PENDING |\n COMPUTED_STATE_FLAGS.RESOLVED |\n COMPUTED_STATE_FLAGS.REJECTED\n );\n }\n\n private _isPending(): boolean {\n return (this._stateFlags & COMPUTED_STATE_FLAGS.PENDING) !== 0;\n }\n\n private _setPending(): void {\n this._stateFlags |= COMPUTED_STATE_FLAGS.PENDING;\n this._stateFlags &= ~(\n COMPUTED_STATE_FLAGS.IDLE |\n COMPUTED_STATE_FLAGS.RESOLVED |\n COMPUTED_STATE_FLAGS.REJECTED\n );\n }\n\n private _isResolved(): boolean {\n return (this._stateFlags & COMPUTED_STATE_FLAGS.RESOLVED) !== 0;\n }\n\n private _setResolved(): void {\n this._stateFlags |= COMPUTED_STATE_FLAGS.RESOLVED;\n this._stateFlags &= ~(\n COMPUTED_STATE_FLAGS.IDLE |\n COMPUTED_STATE_FLAGS.PENDING |\n COMPUTED_STATE_FLAGS.REJECTED |\n COMPUTED_STATE_FLAGS.HAS_ERROR\n );\n }\n\n private _isRejected(): boolean {\n return (this._stateFlags & COMPUTED_STATE_FLAGS.REJECTED) !== 0;\n }\n\n private _setRejected(): void {\n this._stateFlags |= COMPUTED_STATE_FLAGS.REJECTED | COMPUTED_STATE_FLAGS.HAS_ERROR;\n this._stateFlags &= ~(\n COMPUTED_STATE_FLAGS.IDLE |\n COMPUTED_STATE_FLAGS.PENDING |\n COMPUTED_STATE_FLAGS.RESOLVED\n );\n }\n\n private _isRecomputing(): boolean {\n return (this._stateFlags & COMPUTED_STATE_FLAGS.RECOMPUTING) !== 0;\n }\n\n private _setRecomputing(value: boolean): void {\n if (value) {\n this._stateFlags |= COMPUTED_STATE_FLAGS.RECOMPUTING;\n } else {\n this._stateFlags &= ~COMPUTED_STATE_FLAGS.RECOMPUTING;\n }\n }\n\n private _getAsyncState(): AsyncStateType {\n if (this._isPending()) return AsyncState.PENDING;\n if (this._isResolved()) return AsyncState.RESOLVED;\n if (this._isRejected()) return AsyncState.REJECTED;\n return AsyncState.IDLE;\n }\n\n private _getFlagsAsString(): string {\n const states: string[] = [];\n if (this._isDirty()) states.push('DIRTY');\n if (this._isIdle()) states.push('IDLE');\n if (this._isPending()) states.push('PENDING');\n if (this._isResolved()) states.push('RESOLVED');\n if (this._isRejected()) states.push('REJECTED');\n if (this._isRecomputing()) states.push('RECOMPUTING');\n return states.join(' | ');\n }\n\n // === PRIVATE: Core Computation Logic ===\n\n private _computeValue(): T {\n if (this._isRecomputing()) return this._value;\n if (this._isPending()) return this._handlePending();\n if (this._isRejected()) return this._handleRejected();\n\n if (this._isDirty() || this._isIdle()) {\n this._recompute();\n if (this._isPending()) {\n return this._handlePending();\n }\n }\n\n return this._value;\n }\n\n private _recompute(): void {\n if (!this._isDirty() && this._isResolved()) {\n return;\n }\n\n this._setRecomputing(true);\n\n const prevDeps = this._dependencies;\n const nextDeps = depArrayPool.acquire();\n const epoch = nextEpoch();\n\n let depCount = 0;\n\n // Collector function (closure-free if possible, but we need closure for nextDeps capture)\n // To allow `_trackable.addDependency` to work, we need to wire it up.\n // We override `addDependency` of `_trackable` temporarily?\n // Or we use a scoped collector.\n\n const collect = (dep: Dependency) => {\n // O(1) deduplication check\n if (dep._lastSeenEpoch === epoch) return;\n dep._lastSeenEpoch = epoch;\n\n // Add to buffer\n if (depCount < nextDeps.length) {\n nextDeps[depCount] = dep;\n } else {\n nextDeps.push(dep);\n }\n depCount++;\n };\n\n // Store original addDependency to restore later (or use a dedicated collector object)\n const originalAdd = this._trackable.addDependency;\n this._trackable.addDependency = collect as (dep: unknown) => void;\n\n let committed = false;\n\n try {\n const result = trackingContext.run(this._trackable, this._fn);\n\n // Trim array to actual count\n nextDeps.length = depCount;\n\n if (isPromise(result)) {\n // Sync dependencies before awaiting\n this._syncDependencies(prevDeps, nextDeps, epoch);\n this._dependencies = nextDeps;\n committed = true;\n\n this._handleAsyncComputation(result);\n this._setRecomputing(false);\n return;\n }\n\n // Sync dependencies for synchronous result\n this._syncDependencies(prevDeps, nextDeps, epoch);\n this._dependencies = nextDeps;\n committed = true;\n\n this._handleSyncResult(result);\n } catch (err) {\n // On error, we must still sync dependencies that were collected up to the error point.\n // This ensures that if a dependency caused the error (or was accessed before),\n // we subscribe to it so we can recompute when it changes (recovery).\n\n nextDeps.length = depCount;\n this._syncDependencies(prevDeps, nextDeps, epoch);\n this._dependencies = nextDeps;\n committed = true;\n\n this._handleComputationError(err);\n } finally {\n this._trackable.addDependency = originalAdd;\n\n if (committed) {\n // Success: Release old deps\n if (prevDeps !== EMPTY_DEPS) {\n depArrayPool.release(prevDeps as Dependency[]);\n }\n } else {\n // Failure: Release new deps (unused)\n depArrayPool.release(nextDeps);\n }\n }\n }\n\n /**\n * Synchronizes subscriptions based on dependency changes.\n * O(N) Diff using Epoch.\n */\n private _syncDependencies(prevDeps: Dependency[], nextDeps: Dependency[], epoch: number): void {\n // 1. Unsubscribe removed dependencies\n if (prevDeps !== EMPTY_DEPS) {\n for (let i = 0; i < prevDeps.length; i++) {\n const dep = prevDeps[i];\n // Safety check for sparse arrays or strict null checks\n if (!dep) continue;\n\n // If lastSeenEpoch != epoch, it was NOT collected in this run -> Removed\n if (dep._lastSeenEpoch !== epoch) {\n const unsub = this._subscriptions.get(dep.id);\n if (unsub) {\n unsub();\n this._subscriptions.delete(dep.id);\n }\n }\n }\n }\n\n // 2. Subscribe to new dependencies\n for (let i = 0; i < nextDeps.length; i++) {\n const dep = nextDeps[i];\n if (!dep) continue;\n\n // Check if already subscribed\n if (!this._subscriptions.has(dep.id)) {\n // New dependency\n debug.checkCircular(dep, this as unknown as ComputedAtom<T>);\n // Subscription\n const unsub = dep.subscribe(() => this._markDirty());\n this._subscriptions.set(dep.id, unsub);\n }\n }\n }\n\n private _handleSyncResult(result: T): void {\n const shouldUpdate = !this._isResolved() || !this._equal(this._value, result);\n\n this._value = result;\n this._clearDirty();\n this._setResolved();\n this._error = null;\n this._setRecomputing(false);\n\n if (shouldUpdate) {\n this._notifySubscribers();\n }\n }\n\n private _handleAsyncComputation(promise: Promise<T>): void {\n this._setPending();\n\n // Branchless promise ID increment with overflow protection\n this._promiseId = this._promiseId >= this.MAX_PROMISE_ID ? 1 : this._promiseId + 1;\n const promiseId = this._promiseId;\n\n promise\n .then((resolvedValue) => {\n if (promiseId !== this._promiseId) return;\n this._handleAsyncResolution(resolvedValue);\n })\n .catch((err) => {\n if (promiseId !== this._promiseId) return;\n this._handleAsyncRejection(err);\n });\n }\n\n private _handleAsyncResolution(resolvedValue: T): void {\n const shouldUpdate = !this._isResolved() || !this._equal(this._value, resolvedValue);\n\n this._value = resolvedValue;\n this._clearDirty();\n this._setResolved();\n this._error = null;\n this._setRecomputing(false);\n\n if (shouldUpdate) {\n this._notifySubscribers();\n }\n }\n\n private _handleAsyncRejection(err: unknown): void {\n const error = wrapError(err, ComputedError, ERROR_MESSAGES.COMPUTED_ASYNC_COMPUTATION_FAILED);\n\n this._error = error;\n this._setRejected();\n this._clearDirty();\n this._setRecomputing(false);\n\n if (this._onError && typeof this._onError === 'function') {\n try {\n this._onError(error);\n } catch (callbackError) {\n console.error(ERROR_MESSAGES.CALLBACK_ERROR_IN_ERROR_HANDLER, callbackError);\n }\n }\n\n this._notifySubscribers();\n }\n\n private _handleComputationError(err: unknown): never {\n const error = wrapError(err, ComputedError, ERROR_MESSAGES.COMPUTED_COMPUTATION_FAILED);\n\n this._error = error;\n this._setRejected();\n this._clearDirty();\n this._setRecomputing(false);\n\n if (this._onError && typeof this._onError === 'function') {\n try {\n this._onError(error);\n } catch (callbackError) {\n console.error(ERROR_MESSAGES.CALLBACK_ERROR_IN_ERROR_HANDLER, callbackError);\n }\n }\n\n throw error;\n }\n\n private _handlePending(): T {\n if (this._hasDefaultValue) {\n return this._defaultValue;\n }\n throw new ComputedError(ERROR_MESSAGES.COMPUTED_ASYNC_PENDING_NO_DEFAULT);\n }\n\n private _handleRejected(): T {\n if (this._error?.recoverable && this._hasDefaultValue) {\n return this._defaultValue;\n }\n throw this._error;\n }\n\n // === PRIVATE: Dependency Management ===\n // (Replaced by _syncDependencies and inline pool logic)\n\n // === PRIVATE: Subscriber Management ===\n\n private _markDirty(): void {\n if (this._isRecomputing() || this._isDirty()) return;\n\n this._setDirty();\n this._setIdle();\n\n if (this._functionSubscribers.hasSubscribers || this._objectSubscribers.hasSubscribers) {\n scheduler.schedule(this._recomputeJob);\n }\n }\n\n private _notifySubscribers(): void {\n if (!this._functionSubscribers.hasSubscribers && !this._objectSubscribers.hasSubscribers) {\n return;\n }\n\n scheduler.schedule(this._notifyJob);\n }\n\n private _registerTracking(): void {\n const current = trackingContext.getCurrent();\n if (!current) return;\n\n // Check for addDependency first to support TrackableListener\n if (\n typeof current === 'object' &&\n current !== null &&\n (current as DependencyTracker).addDependency\n ) {\n (current as DependencyTracker).addDependency!(this as unknown as ComputedAtom<T>);\n } else if (typeof current === 'function') {\n const fnWithDep = current as TrackableListener;\n if (fnWithDep.addDependency) {\n fnWithDep.addDependency(this as unknown as ComputedAtom<T>);\n } else {\n this._functionSubscribers.add(current as () => void);\n }\n } else if ((current as DependencyTracker).execute) {\n this._objectSubscribers.add(current as Subscriber);\n }\n }\n}\n\n// Optimization: Freeze prototype to prevent shape changes\nObject.freeze(ComputedAtomImpl.prototype);\n\n/**\n * Creates a computed value that automatically tracks and reacts to dependencies\n *\n * Computed atoms are derived reactive state that:\n * - Automatically track dependencies accessed during computation\n * - Lazily recompute only when dependencies change (dirty checking)\n * - Support both synchronous and asynchronous computations\n * - Cache results until dependencies change (memoization)\n * - Use bit flags for efficient state management\n * - Provide async state tracking (idle/pending/resolved/rejected)\n *\n * @template T - The type of the computed value\n * @param fn - Computation function (can return T or Promise<T>)\n * @param options - Configuration options\n * @returns A readonly computed atom with automatic dependency tracking\n *\n * @example\n * ```ts\n * // Synchronous computed\n * const count = atom(0);\n * const doubled = computed(() => count.value * 2);\n *\n * // Asynchronous computed with default value\n * const userData = computed(\n * async () => fetch(`/api/user/${userId.value}`).then(r => r.json()),\n * { defaultValue: null }\n * );\n * ```\n */\nexport function computed<T>(fn: () => T, options?: ComputedOptions<T>): ComputedAtom<T>;\nexport function computed<T>(\n fn: () => Promise<T>,\n options: ComputedOptions<T> & { defaultValue: T }\n): ComputedAtom<T>;\nexport function computed<T>(\n fn: () => T | Promise<T>,\n options: ComputedOptions<T> = {}\n): ComputedAtom<T> {\n return new ComputedAtomImpl(fn, options) as unknown as ComputedAtom<T>;\n}\n","/**\n * @fileoverview Effect module for managing reactive side effects.\n *\n * This module provides a mechanism for creating and managing side effects\n * that automatically re-execute when their dependencies change. Effects\n * support cleanup functions, async operations, and infinite loop detection.\n */\n\nimport { EFFECT_STATE_FLAGS, SCHEDULER_CONFIG, SMI_MAX } from '../../constants';\nimport { nextEpoch } from '../../epoch';\nimport { EffectError, isPromise, wrapError } from '../../errors/errors';\nimport { ERROR_MESSAGES } from '../../errors/messages';\nimport { depArrayPool, EMPTY_DEPS } from '../../pool';\nimport { scheduler } from '../../scheduler';\nimport { type DependencyTracker, trackingContext } from '../../tracking';\nimport type { Dependency, EffectFunction, EffectObject, EffectOptions } from '../../types';\nimport { debug, generateId } from '../../utils/debug';\n\n/**\n * Internal implementation of the EffectObject interface.\n *\n * @remarks\n * This class manages reactive side effects with automatic dependency tracking,\n * cleanup handling, and infinite loop detection. It implements both EffectObject\n * for public API and DependencyTracker for integration with the tracking system.\n *\n * Key features:\n * - Automatic dependency tracking during execution\n * - Support for synchronous and scheduled (batched) execution\n * - Cleanup function support for resource management\n * - Infinite loop detection with configurable threshold\n * - Optional modification tracking for debugging\n *\n * @implements {EffectObject}\n * @implements {DependencyTracker}\n */\nclass EffectImpl implements EffectObject, DependencyTracker {\n // === Smi Fields (Fixed Order for V8 Hidden Class) ===\n private readonly _id: number;\n private _flags: number;\n // Effect is not a dependency, so it doesn't need _lastSeenEpoch for itself.\n // But we use _epoch during execution to track collected dependencies.\n private _currentEpoch: number;\n\n private readonly _fn: EffectFunction;\n private readonly _sync: boolean;\n private readonly _maxExecutions: number;\n private readonly _trackModifications: boolean;\n\n private _cleanup: (() => void) | null;\n\n // Optimized Dependency Management\n private _dependencies: Dependency[];\n private readonly _subscriptions: Map<number, () => void>;\n\n // Execution State\n private _nextDeps: Dependency[] | null;\n private readonly _modifiedDeps: Set<unknown>;\n private readonly _history: Float64Array;\n private _historyIdx: number;\n private _historyCount: number;\n private _executionCount: number;\n private readonly _historyCapacity: number;\n\n constructor(fn: EffectFunction, options: EffectOptions = {}) {\n this._id = generateId() & SMI_MAX;\n this._flags = 0;\n this._currentEpoch = -1;\n\n this._fn = fn;\n this._sync = options.sync ?? false;\n this._maxExecutions =\n options.maxExecutionsPerSecond ?? SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_SECOND;\n this._trackModifications = options.trackModifications ?? false;\n\n this._cleanup = null;\n\n // Dependencies\n this._dependencies = EMPTY_DEPS as Dependency[];\n this._subscriptions = new Map();\n this._nextDeps = null;\n\n this._modifiedDeps = new Set();\n\n this._historyCapacity = this._maxExecutions + 5;\n this._history = new Float64Array(this._historyCapacity);\n this._historyIdx = 0;\n this._historyCount = 0;\n this._executionCount = 0;\n\n debug.attachDebugInfo(this, 'effect', this._id);\n }\n\n /**\n * Manually triggers the effect to run.\n *\n * @throws {EffectError} If the effect has been disposed\n *\n * @remarks\n * This method is typically used when you need to force an effect to\n * re-execute outside of its normal dependency-triggered execution cycle.\n *\n * @example\n * ```typescript\n * const fx = effect(() => console.log(counter.value));\n * // Later, force re-execution:\n * fx.run();\n * ```\n */\n public run = (): void => {\n if (this.isDisposed) {\n throw new EffectError(ERROR_MESSAGES.EFFECT_MUST_BE_FUNCTION);\n }\n this.execute();\n };\n\n /**\n * Disposes of the effect, cleaning up all resources and subscriptions.\n *\n * @remarks\n * After disposal:\n * - The cleanup function is called (if any)\n * - All dependency subscriptions are removed\n * - Modification tracking descriptors are restored to their original state\n * - The effect will no longer execute\n *\n * This method is idempotent - calling it multiple times has no additional effect.\n *\n * @example\n * ```typescript\n * const fx = effect(() => console.log(counter.value));\n * // Later, when the effect is no longer needed:\n * fx.dispose();\n * ```\n */\n public dispose = (): void => {\n if (this.isDisposed) return;\n\n this._setDisposed();\n this._safeCleanup();\n\n // Unsubscribe all\n if (this._dependencies !== EMPTY_DEPS) {\n for (const dep of this._dependencies) {\n const unsub = this._subscriptions.get(dep.id);\n if (unsub) unsub();\n this._subscriptions.delete(dep.id);\n }\n depArrayPool.release(this._dependencies);\n this._dependencies = EMPTY_DEPS as Dependency[];\n }\n };\n\n /**\n * Adds a dependency to this effect's tracking list.\n *\n * @param dep - The dependency to track (must implement Dependency interface)\n *\n * @throws {EffectError} If subscription to the dependency fails\n *\n * @remarks\n * This method is called automatically by the tracking context when\n * a reactive value is accessed during effect execution. It sets up\n * a subscription so the effect re-executes when the dependency changes.\n *\n * If modification tracking is enabled and the dependency is an atom,\n * additional tracking is set up to detect read-after-write patterns.\n *\n * @internal\n */\n public addDependency = (dep: unknown): void => {\n // Stage 1: Collect into buffer (nextDeps)\n if (this.isExecuting && this._nextDeps) {\n const d = dep as Dependency;\n const epoch = this._currentEpoch;\n\n // O(1) deduplication via Epoch\n if (d._lastSeenEpoch === epoch) return;\n d._lastSeenEpoch = epoch;\n\n this._nextDeps.push(d);\n\n // Eagerly subscribe to catch synchronous updates\n if (!this._subscriptions.has(d.id)) {\n this._subscribeTo(d);\n }\n }\n };\n\n /**\n * Executes the effect function, tracking dependencies and managing cleanup.\n *\n * @remarks\n * This method performs the following steps:\n * 1. Checks if the effect is disposed or already executing (guards against re-entrancy)\n * 2. Records the execution timestamp for infinite loop detection\n * 3. Runs any existing cleanup function\n * 4. Clears previous dependency subscriptions\n * 5. Executes the effect function within a tracking context\n * 6. Handles both sync and async cleanup functions\n *\n * If the effect function returns a Promise, the cleanup function is extracted\n * from the resolved value. Errors during execution are caught and logged.\n *\n * @example\n * ```typescript\n * const fx = effect(() => {\n * console.log(counter.value);\n * return () => console.log('cleanup');\n * });\n * fx.execute(); // Manually trigger execution\n * ```\n */\n public execute = (): void => {\n if (this.isDisposed || this.isExecuting) return;\n\n const now = Date.now();\n this._recordExecution(now);\n\n this._setExecuting(true);\n this._safeCleanup();\n this._modifiedDeps.clear();\n\n const prevDeps = this._dependencies;\n const nextDeps = depArrayPool.acquire();\n const epoch = nextEpoch();\n\n this._nextDeps = nextDeps;\n this._currentEpoch = epoch;\n\n let committed = false;\n\n try {\n const result = trackingContext.run(this, this._fn);\n\n // Commit dependencies\n this._syncDependencies(prevDeps, epoch);\n this._dependencies = nextDeps;\n committed = true;\n\n this._checkLoopWarnings();\n\n if (isPromise(result)) {\n result\n .then((asyncCleanup) => {\n if (!this.isDisposed && typeof asyncCleanup === 'function') {\n this._cleanup = asyncCleanup;\n }\n })\n .catch((error) => {\n console.error(wrapError(error, EffectError, ERROR_MESSAGES.EFFECT_EXECUTION_FAILED));\n });\n } else {\n this._cleanup = typeof result === 'function' ? result : null;\n }\n } catch (error) {\n // Commit partial dependencies for recovery (eager subscription already happened)\n this._syncDependencies(prevDeps, epoch);\n this._dependencies = nextDeps;\n committed = true;\n\n console.error(wrapError(error, EffectError, ERROR_MESSAGES.EFFECT_EXECUTION_FAILED));\n this._cleanup = null;\n } finally {\n this._setExecuting(false);\n this._nextDeps = null;\n\n if (committed) {\n if (prevDeps !== EMPTY_DEPS) {\n depArrayPool.release(prevDeps);\n }\n } else {\n depArrayPool.release(nextDeps);\n }\n }\n };\n\n /**\n * Synchronizes subscriptions by unsubscribing from removed dependencies.\n * Uses epoch-based O(N) diff to identify stale dependencies.\n *\n * @param prevDeps - Previous dependency array\n * @param epoch - Current execution epoch for staleness detection\n */\n private _syncDependencies(prevDeps: Dependency[], epoch: number): void {\n if (prevDeps !== EMPTY_DEPS) {\n for (let i = 0; i < prevDeps.length; i++) {\n const dep = prevDeps[i];\n if (!dep) continue;\n\n if (dep._lastSeenEpoch !== epoch) {\n const unsub = this._subscriptions.get(dep.id);\n if (unsub) {\n unsub();\n this._subscriptions.delete(dep.id);\n }\n }\n }\n }\n }\n\n private _subscribeTo(dep: Dependency): void {\n try {\n const unsubscribe = dep.subscribe(() => {\n if (this._trackModifications && this.isExecuting) {\n this._modifiedDeps.add(dep);\n }\n\n if (this._sync) {\n this.execute();\n } else {\n scheduler.schedule(this.execute);\n }\n });\n this._subscriptions.set(dep.id, unsubscribe);\n } catch (error) {\n console.error(wrapError(error, EffectError, ERROR_MESSAGES.EFFECT_EXECUTION_FAILED));\n }\n }\n\n /**\n * Indicates whether this effect has been disposed.\n *\n * @returns `true` if the effect has been disposed, `false` otherwise\n *\n * @remarks\n * A disposed effect will not execute and cannot be reactivated.\n * Use this property to check if the effect is still active before\n * performing operations that depend on it.\n *\n * @example\n * ```typescript\n * const fx = effect(() => console.log(counter.value));\n * console.log(fx.isDisposed); // false\n * fx.dispose();\n * console.log(fx.isDisposed); // true\n * ```\n */\n get isDisposed(): boolean {\n return (this._flags & EFFECT_STATE_FLAGS.DISPOSED) !== 0;\n }\n\n /**\n * Returns the total number of times this effect has been executed.\n *\n * @returns The cumulative execution count since the effect was created\n *\n * @remarks\n * This counter is useful for debugging, testing, and monitoring\n * effect behavior. It increments on every execution, regardless\n * of whether the execution succeeds or fails.\n *\n * @example\n * ```typescript\n * const fx = effect(() => console.log(counter.value));\n * console.log(fx.executionCount); // 1 (initial execution)\n * counter.value = 10;\n * console.log(fx.executionCount); // 2\n * ```\n */\n get executionCount(): number {\n return this._executionCount;\n }\n\n /**\n * Indicates whether this effect is currently executing.\n *\n * @returns `true` if the effect is mid-execution, `false` otherwise\n *\n * @remarks\n * This property is used internally to prevent re-entrant execution\n * (an effect triggering itself during its own execution). It can\n * also be useful for debugging to understand the effect's state.\n *\n * @example\n * ```typescript\n * const fx = effect(() => {\n * console.log('executing:', fx.isExecuting); // true\n * });\n * console.log(fx.isExecuting); // false (after execution completes)\n * ```\n */\n get isExecuting(): boolean {\n return (this._flags & EFFECT_STATE_FLAGS.EXECUTING) !== 0;\n }\n\n /**\n * Sets the disposed flag on this effect.\n *\n * @remarks\n * This is a low-level method that only sets the bit flag.\n * Use the public `dispose()` method for proper cleanup.\n *\n * @internal\n */\n private _setDisposed(): void {\n this._flags |= EFFECT_STATE_FLAGS.DISPOSED;\n }\n\n /**\n * Sets or clears the executing flag on this effect.\n *\n * @param value - `true` to mark as executing, `false` to clear\n *\n * @remarks\n * Uses bitwise operations for efficient flag manipulation.\n * This flag prevents re-entrant execution of the effect.\n *\n * @internal\n */\n private _setExecuting(value: boolean): void {\n if (value) this._flags |= EFFECT_STATE_FLAGS.EXECUTING;\n else this._flags &= ~EFFECT_STATE_FLAGS.EXECUTING;\n }\n\n /**\n * Safely executes the cleanup function if one exists.\n *\n * @remarks\n * This method:\n * - Checks if a cleanup function exists and is callable\n * - Wraps the cleanup call in a try-catch to prevent cleanup errors\n * from breaking the effect lifecycle\n * - Logs any cleanup errors to the console\n * - Clears the cleanup reference after execution\n *\n * @internal\n */\n private _safeCleanup(): void {\n if (this._cleanup && typeof this._cleanup === 'function') {\n try {\n this._cleanup();\n } catch (error) {\n console.error(wrapError(error, EffectError, ERROR_MESSAGES.EFFECT_CLEANUP_FAILED));\n }\n this._cleanup = null;\n }\n }\n\n /**\n * Records an execution timestamp and checks for infinite loop conditions.\n *\n * @param now - The current timestamp in milliseconds (from `Date.now()`)\n *\n * @remarks\n * This method implements a circular buffer to track recent execution\n * timestamps. If the number of executions within the last second exceeds\n * `_maxExecutions`, the effect is disposed and an error is thrown (in debug mode)\n * or logged (in production mode).\n *\n * The circular buffer approach provides O(1) insertion and efficient\n * memory usage for tracking execution history.\n *\n * @throws {EffectError} In debug mode, throws when infinite loop is detected\n *\n * @internal\n */\n private _recordExecution(now: number): void {\n if (this._maxExecutions <= 0) return;\n\n const oneSecondAgo = now - 1000;\n\n this._history[this._historyIdx] = now;\n this._historyIdx = (this._historyIdx + 1) % this._historyCapacity;\n if (this._historyCount < this._historyCapacity) {\n this._historyCount++;\n }\n this._executionCount++;\n\n let count = 0;\n let idx = (this._historyIdx - 1 + this._historyCapacity) % this._historyCapacity;\n\n for (let i = 0; i < this._historyCount; i++) {\n if (this._history[idx]! < oneSecondAgo) {\n break;\n }\n count++;\n idx = (idx - 1 + this._historyCapacity) % this._historyCapacity;\n }\n\n if (count > this._maxExecutions) {\n const message = `Effect executed ${count} times within 1 second. Infinite loop suspected`;\n const error = new EffectError(message);\n\n this.dispose();\n console.error(error);\n\n if (debug.enabled) {\n throw error;\n }\n }\n }\n\n /**\n * Checks for and warns about potential infinite loop patterns.\n *\n * @remarks\n * When modification tracking is enabled and debug mode is active,\n * this method checks if any dependencies were both read and modified\n * during the effect execution. Such patterns often lead to infinite loops.\n *\n * Warnings are only emitted in debug mode to avoid performance overhead\n * in production.\n *\n * @internal\n */\n private _checkLoopWarnings(): void {\n if (this._trackModifications && debug.enabled) {\n const dependencies = this._dependencies;\n for (let i = 0; i < dependencies.length; i++) {\n const dep = dependencies[i];\n if (dep && this._modifiedDeps.has(dep)) {\n debug.warn(\n true,\n `Effect is reading a dependency (${\n debug.getDebugName(dep) || 'unknown'\n }) that it just modified. Infinite loop may occur`\n );\n }\n }\n }\n }\n}\n\n/**\n * Creates a reactive effect that automatically re-executes when its dependencies change.\n *\n * @param fn - The effect function to execute. May return a cleanup function\n * or a Promise that resolves to a cleanup function.\n * @param options - Configuration options for the effect\n * @param options.sync - If true, re-executes synchronously on dependency changes.\n * Defaults to false (scheduled/batched execution).\n * @param options.maxExecutionsPerSecond - Maximum executions per second before\n * infinite loop detection triggers.\n * Defaults to `SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_SECOND`.\n * @param options.trackModifications - If true, tracks and warns about dependencies\n * that are both read and modified. Defaults to false.\n *\n * @returns An {@link EffectObject} with `run()`, `dispose()`, and state properties\n *\n * @throws {EffectError} If `fn` is not a function\n *\n * @remarks\n * Effects are the primary way to perform side effects in response to reactive\n * state changes. They automatically track which reactive values (atoms, computed)\n * are accessed during execution and re-run when those values change.\n *\n * The effect function may return a cleanup function that will be called before\n * the next execution or when the effect is disposed. This is useful for\n * cleaning up subscriptions, timers, or other resources.\n *\n * @example\n * Basic usage:\n * ```typescript\n * const counter = atom(0);\n *\n * const fx = effect(() => {\n * console.log('Counter:', counter.value);\n * });\n * // Logs: \"Counter: 0\"\n *\n * counter.value = 1;\n * // Logs: \"Counter: 1\"\n *\n * fx.dispose(); // Stop the effect\n * ```\n *\n * @example\n * With cleanup function:\n * ```typescript\n * const fx = effect(() => {\n * const timer = setInterval(() => console.log('tick'), 1000);\n * return () => clearInterval(timer); // Cleanup\n * });\n * ```\n *\n * @example\n * Synchronous execution:\n * ```typescript\n * const fx = effect(\n * () => console.log(counter.value),\n * { sync: true }\n * );\n * ```\n */\nexport function effect(fn: EffectFunction, options: EffectOptions = {}): EffectObject {\n if (typeof fn !== 'function') {\n throw new EffectError(ERROR_MESSAGES.EFFECT_MUST_BE_FUNCTION);\n }\n\n const effectInstance = new EffectImpl(fn, options);\n\n effectInstance.execute();\n\n return effectInstance;\n}\n","import type { ComputedAtom, EffectObject, ReadonlyAtom } from '../types';\nimport { debug } from './debug';\n\nexport function isAtom(obj: unknown): obj is ReadonlyAtom {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n 'value' in obj &&\n 'subscribe' in obj &&\n typeof (obj as Record<string, unknown>).subscribe === 'function'\n );\n}\n\nexport function isComputed(obj: unknown): obj is ComputedAtom {\n if (debug.enabled) {\n const debugType = debug.getDebugType(obj);\n if (debugType) {\n return debugType === 'computed';\n }\n }\n return (\n isAtom(obj) &&\n 'invalidate' in obj &&\n typeof (obj as Record<string, unknown>).invalidate === 'function'\n );\n}\n\nexport function isEffect(obj: unknown): obj is EffectObject {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n 'dispose' in obj &&\n 'run' in obj &&\n typeof (obj as Record<string, unknown>).dispose === 'function' &&\n typeof (obj as Record<string, unknown>).run === 'function'\n );\n}\n"],"names":["AsyncState","EFFECT_STATE_FLAGS","COMPUTED_STATE_FLAGS","POOL_CONFIG","SCHEDULER_CONFIG","DEBUG_CONFIG","SMI_MAX","AtomError","message","cause","recoverable","ComputedError","EffectError","SchedulerError","wrapError","error","ErrorClass","context","errorMessage","isPromise","value","ERROR_MESSAGES","count","Scheduler","callback","jobs","i","job","iterations","max","scheduler","batch","trackingContext","listener","fn","prev","untracked","DEBUG_NAME","DEBUG_ID","DEBUG_TYPE","NO_DEFAULT_VALUE","hasDependencies","obj","debug","condition","dep","current","visited","nestedDep","type","id","target","nextId","generateId","SubscriberManager","subscriber","index","isUnsubscribed","idx","lastIndex","lastSubscriber","onError","AtomImpl","initialValue","sync","newValue","oldValue","currentVersion","fnWithDep","tracker","_newValue","_currentVersion","sub","err","atom","options","collectorEpoch","nextEpoch","__DEV__","EMPTY_DEPS","ArrayPool","arr","emptyConst","acquired","released","rejected","totalRejected","depArrayPool","ComputedAtomImpl","_dep","debugObj","result","unsub","states","prevDeps","nextDeps","epoch","depCount","collect","originalAdd","committed","shouldUpdate","promise","promiseId","resolvedValue","callbackError","computed","EffectImpl","d","now","asyncCleanup","unsubscribe","oneSecondAgo","dependencies","effect","effectInstance","isAtom","isComputed","debugType","isEffect"],"mappings":"gFAQO,MAAMA,EAAa,CACxB,KAAM,OACN,QAAS,UACT,SAAU,WACV,SAAU,UACZ,EAMaC,EAAqB,CAChC,SAAU,EACV,UAAW,CACb,EAMaC,EAAuB,CAClC,MAAO,EACP,KAAM,EACN,QAAS,EACT,SAAU,EACV,SAAU,GACV,YAAa,GACb,UAAW,EACb,EAMaC,EAAc,CAEzB,SAAU,IAEV,YAAa,GACf,EAMaC,EAAmB,CAE9B,0BAA2B,IAE3B,kBAAmB,GACrB,EAKaC,EAAe,CAE1B,iBAAkB,IAElB,mBAAoB,EACtB,EAMaC,EAAU,WCxDhB,MAAMC,UAAkB,KAAM,CAcnC,YAAYC,EAAiBC,EAAsB,KAAMC,EAAuB,GAAM,CACpF,MAAMF,CAAO,EACb,KAAK,KAAO,YACZ,KAAK,MAAQC,EACb,KAAK,YAAcC,EACnB,KAAK,cAAgB,IACvB,CACF,CAQO,MAAMC,UAAsBJ,CAAU,CAM3C,YAAYC,EAAiBC,EAAsB,KAAM,CACvD,MAAMD,EAASC,EAAO,EAAI,EAC1B,KAAK,KAAO,eACd,CACF,CAQO,MAAMG,UAAoBL,CAAU,CAMzC,YAAYC,EAAiBC,EAAsB,KAAM,CACvD,MAAMD,EAASC,EAAO,EAAK,EAC3B,KAAK,KAAO,aACd,CACF,CAQO,MAAMI,UAAuBN,CAAU,CAM5C,YAAYC,EAAiBC,EAAsB,KAAM,CACvD,MAAMD,EAASC,EAAO,EAAK,EAC3B,KAAK,KAAO,gBACd,CACF,CAyBO,SAASK,EACdC,EACAC,EACAC,EACW,CACX,GAAIF,aAAiB,UACnB,OAAO,IAAIC,EAAW,eAAeC,CAAO,MAAMF,EAAM,OAAO,GAAIA,CAAK,EAE1E,GAAIA,aAAiB,eACnB,OAAO,IAAIC,EAAW,oBAAoBC,CAAO,MAAMF,EAAM,OAAO,GAAIA,CAAK,EAE/E,GAAIA,aAAiBR,EACnB,OAAOQ,EAIT,MAAMG,EAAeH,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,EACpEN,EAAQM,aAAiB,MAAQA,EAAQ,KAC/C,OAAO,IAAIC,EAAW,qBAAqBC,CAAO,MAAMC,CAAY,GAAIT,CAAK,CAC/E,CAoBO,SAASU,EAAaC,EAAqC,CAChE,OACEA,GAAU,MAEV,OAAQA,EAA6B,MAAS,UAElD,CCvIO,MAAMC,EAAiB,CAQ5B,0BAA2B,uCAK3B,qCAAsC,yCAKtC,kCAAmC,0DAKnC,4BAA6B,8BAK7B,kCAAmC,oCAKnC,wCAAyC,oCASzC,iCAAkC,2CAKlC,iCAAkC,kDAMlC,kCAAmC,oDASnC,wBAAyB,qCAKzB,wBAAyB,0BAKzB,sBAAuB,2CAkBvB,uBAAyBC,GACvB,oCAAoCA,CAAK,gBAK3C,yBAA0B,mDAM1B,gCAAiC,kDACnC,EC7FA,MAAMC,CAAU,CAAhB,aAAA,CAGE,KAAQ,OAAyB,CAAA,EACjC,KAAQ,OAAyB,CAAA,EAGjC,KAAQ,MAAwB,KAAK,OACrC,KAAQ,UAAY,EAGpB,KAAQ,OAAS,EAGjB,KAAQ,aAAwB,GAGhC,KAAO,WAAsB,GAG7B,KAAQ,WAAqB,EAG7B,KAAQ,WAA6B,CAAA,EAGrC,KAAQ,eAAiB,EAGzB,KAAQ,eAA0B,GAGlC,KAAQ,mBAA6B,GAAA,CAKrC,IAAI,OAAwB,CAC1B,OAAI,KAAK,cAAgB,KAAK,eACrB,EAEL,KAAK,WACA,EAEF,CACT,CAoBA,SAASC,EAA8B,CACrC,GAAI,OAAOA,GAAa,WACtB,MAAM,IAAIX,EAAe,uCAAuC,EAI9DW,EAAS,aAAe,KAAK,SACjCA,EAAS,WAAa,KAAK,OAEvB,KAAK,YAAc,KAAK,eAC1B,KAAK,WAAW,KAAK,gBAAgB,EAAIA,GAEzC,KAAK,MAAM,KAAK,WAAW,EAAIA,EAC1B,KAAK,cACR,KAAK,MAAA,GAGX,CAcQ,OAAc,CACpB,GAAI,KAAK,cAAgB,KAAK,YAAc,EAAG,OAE/C,KAAK,aAAe,GAIpB,MAAMC,EAAO,KAAK,MACZH,EAAQ,KAAK,UAGnB,KAAK,MAAQ,KAAK,QAAU,KAAK,OAAS,KAAK,OAAS,KAAK,OAC7D,KAAK,UAAY,EAGjB,KAAK,SAEL,eAAe,IAAM,CAEnB,QAASI,EAAI,EAAGA,EAAIJ,EAAOI,IACzB,GAAI,CACFD,EAAKC,CAAC,IAAA,CACR,OAASX,EAAO,CACd,QAAQ,MACN,IAAIF,EAAe,4CAA6CE,CAAc,CAAA,CAElF,CAIFU,EAAK,OAAS,EACd,KAAK,aAAe,GAGhB,KAAK,UAAY,GAAK,CAAC,KAAK,YAC9B,KAAK,MAAA,CAET,CAAC,CACH,CAeQ,WAAkB,CACxB,KAAK,eAAiB,GAEtB,GAAI,CAKF,GAFA,KAAK,SAED,KAAK,eAAiB,EAAG,CAC3B,QAASC,EAAI,EAAGA,EAAI,KAAK,eAAgBA,IAAK,CAE5C,MAAMC,EAAM,KAAK,WAAWD,CAAC,EACzBC,EAAI,aAAe,KAAK,SAC1BA,EAAI,WAAa,KAAK,OACtB,KAAK,MAAM,KAAK,WAAW,EAAIA,EAEnC,CACA,KAAK,eAAiB,CACxB,CAEA,IAAIC,EAAa,EAEjB,KAAO,KAAK,UAAY,GAAG,CACzB,GAAI,EAAEA,EAAa,KAAK,mBAAoB,CAC1C,QAAQ,MACN,IAAIf,EACF,6BAA6B,KAAK,kBAAkB,mIAAA,CAGtD,EAGF,KAAK,UAAY,EACjB,KAAK,MAAM,OAAS,EACpB,KAAK,eAAiB,EACtB,KACF,CAGA,MAAMY,EAAO,KAAK,MACZH,EAAQ,KAAK,UAEnB,KAAK,MAAQ,KAAK,QAAU,KAAK,OAAS,KAAK,OAAS,KAAK,OAC7D,KAAK,UAAY,EACjB,KAAK,SAEL,QAASI,EAAI,EAAGA,EAAIJ,EAAOI,IACzB,GAAI,CACFD,EAAKC,CAAC,IAAA,CACR,OAASX,EAAO,CACd,QAAQ,MACN,IAAIF,EAAe,wCAAyCE,CAAc,CAAA,CAE9E,CAKF,GAFAU,EAAK,OAAS,EAEV,KAAK,eAAiB,EAAG,CAC3B,QAASC,EAAI,EAAGA,EAAI,KAAK,eAAgBA,IAGvC,KAAK,MAAM,KAAK,WAAW,EAAI,KAAK,WAAWA,CAAC,EAElD,KAAK,eAAiB,CACxB,CACF,CACF,QAAA,CACE,KAAK,eAAiB,EACxB,CACF,CAkBA,YAAmB,CACjB,KAAK,aACL,KAAK,WAAa,EACpB,CAuBA,UAAiB,CACf,KAAK,WAAa,KAAK,IAAI,EAAG,KAAK,WAAa,CAAC,EAE7C,KAAK,aAAe,IACtB,KAAK,UAAA,EACL,KAAK,WAAa,GAEtB,CAkBA,sBAAsBG,EAAmB,CACvC,GAAIA,EAAM,GACR,MAAM,IAAIhB,EAAe,0CAA0C,EAErE,KAAK,mBAAqBgB,CAC5B,CACF,CAGO,MAAMC,EAAY,IAAIP,EC/StB,SAASQ,EAASP,EAAsB,CAC7C,GAAI,OAAOA,GAAa,WACtB,MAAM,IAAIjB,EAAU,mCAAmC,EAGzDuB,EAAU,WAAA,EAEV,GAAI,CACF,OAAON,EAAA,CACT,OAAST,EAAO,CACd,MAAM,IAAIR,EAAU,wCAAyCQ,CAAc,CAC7E,QAAA,CACEe,EAAU,SAAA,CACZ,CACF,CCgCO,MAAME,EAAmC,CAE9C,QAAS,KAMT,IAAOC,EAAoBC,EAAgB,CACzC,MAAMC,EAAO,KAAK,QAClB,KAAK,QAAUF,EACf,GAAI,CACF,OAAOC,EAAA,CACT,QAAA,CACE,KAAK,QAAUC,CACjB,CACF,EAGA,YAA8B,CAC5B,OAAO,KAAK,OACd,CACF,EC1EO,SAASC,EAAaF,EAAgB,CAC3C,GAAI,OAAOA,GAAO,WAChB,MAAM,IAAI3B,EAAU,uCAAuC,EAG7D,MAAM4B,EAAOH,EAAgB,QAC7BA,EAAgB,QAAU,KAE1B,GAAI,CACF,OAAOE,EAAA,CACT,OAASnB,EAAO,CACd,MAAM,IAAIR,EAAU,4CAA6CQ,CAAc,CACjF,QAAA,CACEiB,EAAgB,QAAUG,CAC5B,CACF,CCfO,MAAME,SAAmC,WAAW,EAS9CC,SAAiC,IAAI,EAQrCC,SAAmC,MAAM,EAezCC,SAAyC,gBAAgB,EAUtE,SAASC,EAAgBC,EAAqD,CAC5E,OACEA,IAAQ,MACR,OAAOA,GAAQ,UACf,iBAAkBA,GACjBA,EAAkC,wBAAwB,GAE/D,CA0BO,MAAMC,EAAqB,CAQhC,QACE,OAAO,QAAY,KAAgB,QAA2B,KAAK,WAAa,cAOlF,gBAAiBtC,EAAa,iBAO9B,iBAAkBA,EAAa,mBAa/B,KAAKuC,EAAoBpC,EAAuB,CAC1C,KAAK,SAAWoC,GAClB,QAAQ,KAAK,iBAAiBpC,CAAO,EAAE,CAE3C,EA8BA,cAAcqC,EAAcC,EAAkBC,EAAU,IAAI,IAAsB,CAEhF,GAAIF,IAAQC,EACV,MAAM,IAAInC,EAAc,qCAAqC,EAI/D,GAAK,KAAK,QAKV,IAAIoC,EAAQ,IAAIF,CAAG,EACjB,MAAM,IAAIlC,EAAc,uCAAuC,EAMjE,GAHAoC,EAAQ,IAAIF,CAAG,EAGXJ,EAAgBI,CAAG,EACrB,UAAWG,KAAaH,EAAI,aAC1B,KAAK,cAAcG,EAAWF,EAASC,CAAO,EAGpD,EAsBA,gBAAgBL,EAAaO,EAAcC,EAAkB,CAC3D,GAAI,CAAC,KAAK,QACR,OAGF,MAAMC,EAAST,EACfS,EAAOd,CAAU,EAAI,GAAGY,CAAI,IAAIC,CAAE,GAClCC,EAAOb,CAAQ,EAAIY,EACnBC,EAAOZ,CAAU,EAAIU,CACvB,EAcA,aAAaP,EAAkC,CAC7C,GAAIA,IAAQ,MAAQ,OAAOA,GAAQ,UAAYL,KAAcK,EAC3D,OAAQA,EAAgCL,CAAU,CAGtD,EAgBA,aAAaK,EAAkC,CAC7C,GAAIA,IAAQ,MAAQ,OAAOA,GAAQ,UAAYH,KAAcG,EAC3D,OAAQA,EAAgCH,CAAU,CAGtD,CACF,EAOA,IAAIa,EAAS,EAiBN,MAAMC,EAAa,IAAcD,IClQjC,MAAME,CAAoC,CAA1C,aAAA,CACL,KAAQ,YAA0B,KAClC,KAAQ,gBAA6C,IAAA,CAkBrD,IAAIC,EAA2B,CAQ7B,GANK,KAAK,cACR,KAAK,YAAc,CAAA,EACnB,KAAK,oBAAsB,SAIzB,KAAK,gBAAiB,IAAIA,CAAU,EAEtC,MAAO,IAAM,CAAC,EAIhB,MAAMC,EAAQ,KAAK,YAAY,OAC/B,KAAK,YAAY,KAAKD,CAAU,EAChC,KAAK,gBAAiB,IAAIA,EAAYC,CAAK,EAG3C,IAAIC,EAAiB,GACrB,MAAO,IAAM,CACPA,IACJA,EAAiB,GACjB,KAAK,OAAOF,CAAU,EACxB,CACF,CAaA,OAAOA,EAAwB,CAC7B,GAAI,CAAC,KAAK,aAAe,CAAC,KAAK,gBAC7B,MAAO,GAGT,MAAMG,EAAM,KAAK,gBAAgB,IAAIH,CAAU,EAC/C,GAAIG,IAAQ,OACV,MAAO,GAGT,MAAMC,EAAY,KAAK,YAAY,OAAS,EAG5C,GAAID,IAAQC,EAAW,CACrB,MAAMC,EAAiB,KAAK,YAAYD,CAAS,EACjD,KAAK,YAAYD,CAAG,EAAIE,EACxB,KAAK,gBAAgB,IAAIA,EAAgBF,CAAG,CAC9C,CAGA,YAAK,YAAY,IAAA,EACjB,KAAK,gBAAgB,OAAOH,CAAU,EAE/B,EACT,CAQA,IAAIA,EAAwB,CAC1B,OAAO,KAAK,iBAAiB,IAAIA,CAAU,GAAK,EAClD,CAiBA,QAAQrB,EAAkD,CACxD,GAAK,KAAK,YAEV,QAASR,EAAI,EAAGA,EAAI,KAAK,YAAY,OAAQA,IAC3CQ,EAAG,KAAK,YAAYR,CAAC,EAAIA,CAAC,CAE9B,CAWA,YAAYQ,EAA4C2B,EAAwC,CAC9F,GAAK,KAAK,YAEV,QAASnC,EAAI,EAAGA,EAAI,KAAK,YAAY,OAAQA,IAC3C,GAAI,CACFQ,EAAG,KAAK,YAAYR,CAAC,EAAIA,CAAC,CAC5B,OAASX,EAAO,CACV8C,EACFA,EAAQ9C,CAAc,EAEtB,QAAQ,MAAM,oDAAqDA,CAAK,CAE5E,CAEJ,CAOA,IAAI,MAAe,CACjB,OAAO,KAAK,aAAa,QAAU,CACrC,CAOA,IAAI,gBAA0B,CAC5B,OAAO,KAAK,KAAO,CACrB,CAQA,OAAc,CACR,KAAK,cACP,KAAK,YAAY,OAAS,GAE5B,KAAK,gBAAkB,KACvB,KAAK,YAAc,IACrB,CAUA,SAAe,CACb,OAAO,KAAK,YAAc,CAAC,GAAG,KAAK,WAAW,EAAI,CAAA,CACpD,CACF,CCzLA,MAAM+C,CAAuC,CA0C3C,YAAYC,EAAiBC,EAAe,CAR5C,KAAQ,yBAAoC,GAU1C,KAAK,GAAKX,IAAe/C,EACzB,KAAK,QAAU,EACf,KAAK,MAAQ,EACb,KAAK,eAAiB,GAGtB,KAAK,OAASyD,EACd,KAAK,qBAAuB,IAAIT,EAChC,KAAK,mBAAqB,IAAIA,EAC9B,KAAK,MAAQU,EACb,KAAK,YAAc,KAAK,oBAAoB,KAAK,IAAI,EAErDrB,EAAM,gBAAgB,KAAM,OAAQ,KAAK,EAAE,CAC7C,CAYA,IAAI,OAAW,CACb,MAAMG,EAAUd,EAAgB,WAAA,EAChC,OAAIc,GAAY,MACd,KAAK,OAAOA,CAAO,EAEd,KAAK,MACd,CAYA,IAAI,MAAMmB,EAAa,CACrB,GAAI,OAAO,GAAG,KAAK,OAAQA,CAAQ,EAAG,OAEtC,MAAMC,EAAW,KAAK,OAEtB,KAAK,QAAW,KAAK,QAAU,EAAK5D,EACpC,MAAM6D,EAAiB,KAAK,QAC5B,KAAK,OAASF,EAEV,GAAC,KAAK,qBAAqB,gBAAkB,CAAC,KAAK,mBAAmB,iBAG1E,KAAK,QAAQA,EAAUC,EAAUC,CAAc,CACjD,CAWQ,OAAOrB,EAAwB,CACrC,GAAI,OAAOA,GAAY,WAAY,CACjC,MAAMsB,EAAYtB,EACdsB,EAAU,gBAAkB,OAC9BA,EAAU,cAAc,IAAI,EAE5B,KAAK,qBAAqB,IAAItB,CAA+C,CAEjF,KAAO,CACL,MAAMuB,EAAUvB,EACZuB,EAAQ,gBAAkB,OAC5BA,EAAQ,cAAc,IAAI,EACjBA,EAAQ,UAAY,QAC7B,KAAK,mBAAmB,IAAIA,CAAqB,CAErD,CACF,CAmBQ,QAAQC,EAAcJ,EAAaK,EAA+B,CACnE,KAAK,2BACR,KAAK,iBAAmBL,EACxB,KAAK,yBAA2B,IAK9B,KAAK,OAAS,CAACpC,EAAU,WAC3B,KAAK,oBAAA,EAELA,EAAU,SAAS,KAAK,WAAW,CAEvC,CAMQ,qBAA4B,CAClC,GAAI,CAAC,KAAK,yBAA0B,OAGpC,MAAMoC,EAAW,KAAK,iBAChBD,EAAW,KAAK,OAEtB,KAAK,iBAAmB,OACxB,KAAK,yBAA2B,GAEhC,KAAK,qBAAqB,YACvBO,GAAQA,EAAIP,EAAUC,CAAQ,EAC9BO,GACC,QAAQ,MAAM,IAAIlE,EAAUc,EAAe,kCAAmCoD,CAAY,CAAC,CAAA,EAG/F,KAAK,mBAAmB,YACrBD,GAAQA,EAAI,QAAA,EACZC,GACC,QAAQ,MAAM,IAAIlE,EAAUc,EAAe,kCAAmCoD,CAAY,CAAC,CAAA,CAEjG,CAiBA,UAAUxC,EAA4D,CACpE,GAAI,OAAOA,GAAa,WACtB,MAAM,IAAI1B,EAAUc,EAAe,gCAAgC,EAErE,OAAO,KAAK,qBAAqB,IAAIY,CAAQ,CAC/C,CAWA,MAAU,CACR,OAAO,KAAK,MACd,CASA,SAAgB,CACd,KAAK,qBAAqB,MAAA,EAC1B,KAAK,mBAAmB,MAAA,EACxB,KAAK,OAAS,MAChB,CAOA,iBAA0B,CACxB,OAAO,KAAK,qBAAqB,KAAO,KAAK,mBAAmB,IAClE,CACF,CAwBO,SAASyC,EAAQX,EAAiBY,EAAuB,GAAqB,CACnF,OAAO,IAAIb,EAASC,EAAcY,EAAQ,MAAQ,EAAK,CACzD,CC7SA,IAAIC,EAAiB,EAEd,SAASC,GAAoB,CAClC,OAAAD,GAAmBA,EAAiB,EAAK,GAAKtE,EACvCsE,CACT,CCPO,MAAME,EAAU,QAAQ,IAAI,WAAa,aCKnCC,EAAoC,OAAO,OAAO,EAAE,EAMjE,MAAMC,CAAa,CAAnB,aAAA,CACE,KAAQ,KAAc,CAAA,EACtB,KAAiB,YAAc,GAC/B,KAAiB,oBAAsB,IAEvC,KAAQ,MAAQF,EACZ,CACE,SAAU,EACV,SAAU,EACV,SAAU,CAAE,OAAQ,EAAG,SAAU,EAAG,SAAU,CAAA,CAAE,EAElD,IAAA,CAEJ,SAAe,CACb,OAAIA,GAAW,KAAK,OAAO,KAAK,MAAM,WAC/B,KAAK,KAAK,IAAA,GAAS,CAAA,CAC5B,CAEA,QAAQG,EAAUC,EAAiC,CAEjD,GAAI,EAAAA,GAAcD,IAAQC,GAG1B,IAAI,OAAO,SAASD,CAAG,EAAG,CACpBH,GAAW,KAAK,OAAO,KAAK,MAAM,SAAS,SAC/C,MACF,CAGA,GAAIG,EAAI,OAAS,KAAK,oBAAqB,CACrCH,GAAW,KAAK,OAAO,KAAK,MAAM,SAAS,WAC/C,MACF,CAGA,GAAI,KAAK,KAAK,QAAU,KAAK,YAAa,CACpCA,GAAW,KAAK,OAAO,KAAK,MAAM,SAAS,WAC/C,MACF,CAGAG,EAAI,OAAS,EACb,KAAK,KAAK,KAAKA,CAAG,EACdH,GAAW,KAAK,OAAO,KAAK,MAAM,WACxC,CAEA,UAA6B,CAC3B,GAAI,CAACA,GAAW,CAAC,KAAK,MAAO,OAAO,KACpC,KAAM,CAAE,SAAAK,EAAU,SAAAC,EAAU,SAAAC,CAAA,EAAa,KAAK,MACxCC,EAAgBD,EAAS,OAASA,EAAS,SAAWA,EAAS,SACrE,MAAO,CACL,SAAAF,EACA,SAAAC,EACA,SAAAC,EACA,OAAQF,EAAWC,EAAWE,EAC9B,SAAU,KAAK,KAAK,MAAA,CAExB,CAEA,OAAc,CACZ,KAAK,KAAK,OAAS,EACfR,GAAW,KAAK,QAClB,KAAK,MAAM,SAAW,EACtB,KAAK,MAAM,SAAW,EACtB,KAAK,MAAM,SAAW,CAAE,OAAQ,EAAG,SAAU,EAAG,SAAU,CAAA,EAE9D,CACF,CAGO,MAAMS,EAAe,IAAIP,ECxChC,MAAMQ,CAA+C,CAwCnD,YAAYtD,EAA0ByC,EAA8B,GAAI,CACtE,GAAI,OAAOzC,GAAO,WAChB,MAAM,IAAIvB,EAAcU,EAAe,yBAAyB,EAyElE,GArEA,KAAK,GAAKgC,IAAe/C,EACzB,KAAK,QAAU,EACf,KAAK,MAAQ,EACb,KAAK,eAAiB,GAGtB,KAAK,OAAS,OACd,KAAK,YAAcJ,EAAqB,MAAQA,EAAqB,KAGrE,KAAK,OAAS,KACd,KAAK,WAAa,EAClB,KAAK,OAASyE,EAAQ,OAAS,OAAO,GAGtC,KAAK,IAAMzC,EACX,KAAK,cAAgB,iBAAkByC,EAAUA,EAAQ,aAAgBnC,EACzE,KAAK,iBAAmB,KAAK,gBAAmBA,EAChD,KAAK,SAAWmC,EAAQ,SAAW,KACnC,KAAK,eAAiB,OAAO,iBAAmB,EAGhD,KAAK,qBAAuB,IAAIrB,EAChC,KAAK,mBAAqB,IAAIA,EAG9B,KAAK,cAAgByB,EACrB,KAAK,mBAAqB,IAE1B,KAAK,cAAgB,IAAM,CACzB,GAAI,KAAK,WACP,GAAI,CACF,KAAK,WAAA,CACP,MAAQ,CAER,CAEJ,EAEA,KAAK,WAAa,IAAM,CACtB,KAAK,qBAAqB,YACvBxB,GAAeA,EAAA,EACfkB,GAAQ,QAAQ,MAAMA,CAAG,CAAA,EAG5B,KAAK,mBAAmB,YACrBlB,GAAeA,EAAW,QAAA,EAC1BkB,GAAQ,QAAQ,MAAMA,CAAG,CAAA,CAE9B,EAIA,KAAK,WAAa,OAAO,OAAO,IAAM,KAAK,aAAc,CACvD,cAAgBgB,GAAkB,CAUlC,CAAA,CACD,EAED9C,EAAM,gBAAgB,KAAoC,WAAY,KAAK,EAAE,EAEzEA,EAAM,QAAS,CACjB,MAAM+C,EAAW,KAMjBA,EAAS,gBAAkB,IACzB,KAAK,qBAAqB,KAAO,KAAK,mBAAmB,KAC3DA,EAAS,QAAU,IAAM,KAAK,SAAA,EAC9BA,EAAS,aAAe,KAAK,cAC7BA,EAAS,WAAa,KAAK,kBAAA,CAC7B,CAGA,GAAIf,EAAQ,OAAS,GACnB,GAAI,CACF,KAAK,WAAA,CACP,MAAQ,CAER,CAEJ,CAIA,IAAI,OAAW,CAMb,IAHG,KAAK,aAAezE,EAAqB,SAAWA,EAAqB,UAC1EA,EAAqB,SAGrB,YAAK,kBAAA,EACE,KAAK,OAId,MAAMyF,EAAS,KAAK,cAAA,EACpB,YAAK,kBAAA,EACEA,CACT,CAEA,UAAU1D,EAAkC,CAC1C,GAAI,OAAOA,GAAa,WACtB,MAAM,IAAItB,EAAcU,EAAe,oCAAoC,EAE7E,OAAO,KAAK,qBAAqB,IAAIY,CAAQ,CAC/C,CAEA,MAAU,CACR,OAAO,KAAK,MACd,CAEA,IAAI,OAAwB,CAC1B,OAAO,KAAK,eAAA,CACd,CAEA,IAAI,UAAoB,CACtB,OAAO,KAAK,YAAA,CACd,CAEA,IAAI,WAA0B,CAC5B,OAAO,KAAK,MACd,CAEA,IAAI,WAAqB,CACvB,OAAO,KAAK,WAAA,CACd,CAEA,IAAI,YAAsB,CACxB,OAAO,KAAK,YAAA,CACd,CAEA,YAAmB,CACjB,KAAK,WAAA,CACP,CAEA,SAAgB,CAOd,GAAI,KAAK,gBAAkB8C,EAAY,CACrC,UAAWlC,KAAO,KAAK,cAAe,CACpC,MAAM+C,EAAQ,KAAK,eAAe,IAAI/C,EAAI,EAAE,EACxC+C,GAAOA,EAAA,EACX,KAAK,eAAe,OAAO/C,EAAI,EAAE,CACnC,CACA0C,EAAa,QAAQ,KAAK,aAAa,CACzC,CACA,KAAK,cAAgBR,EAErB,KAAK,qBAAqB,MAAA,EAC1B,KAAK,mBAAmB,MAAA,EACxB,KAAK,YAAc7E,EAAqB,MAAQA,EAAqB,KACrE,KAAK,OAAS,KACd,KAAK,OAAS,OACd,KAAK,YAAc,KAAK,WAAa,GAAK,KAAK,cACjD,CAIQ,UAAoB,CAC1B,OAAQ,KAAK,YAAcA,EAAqB,SAAW,CAC7D,CAEQ,WAAkB,CACxB,KAAK,aAAeA,EAAqB,KAC3C,CAEQ,aAAoB,CAC1B,KAAK,aAAe,EACtB,CAEQ,SAAmB,CACzB,OAAQ,KAAK,YAAcA,EAAqB,QAAU,CAC5D,CAEQ,UAAiB,CACvB,KAAK,aAAeA,EAAqB,KACzC,KAAK,aAAe,GAKtB,CAEQ,YAAsB,CAC5B,OAAQ,KAAK,YAAcA,EAAqB,WAAa,CAC/D,CAEQ,aAAoB,CAC1B,KAAK,aAAeA,EAAqB,QACzC,KAAK,aAAe,GAKtB,CAEQ,aAAuB,CAC7B,OAAQ,KAAK,YAAcA,EAAqB,YAAc,CAChE,CAEQ,cAAqB,CAC3B,KAAK,aAAeA,EAAqB,SACzC,KAAK,aAAe,GAMtB,CAEQ,aAAuB,CAC7B,OAAQ,KAAK,YAAcA,EAAqB,YAAc,CAChE,CAEQ,cAAqB,CAC3B,KAAK,aAAeA,EAAqB,SAAWA,EAAqB,UACzE,KAAK,aAAe,GAKtB,CAEQ,gBAA0B,CAChC,OAAQ,KAAK,YAAcA,EAAqB,eAAiB,CACnE,CAEQ,gBAAgBkB,EAAsB,CACxCA,EACF,KAAK,aAAelB,EAAqB,YAEzC,KAAK,aAAe,GAExB,CAEQ,gBAAiC,CACvC,OAAI,KAAK,aAAqBF,EAAW,QACrC,KAAK,cAAsBA,EAAW,SACtC,KAAK,cAAsBA,EAAW,SACnCA,EAAW,IACpB,CAEQ,mBAA4B,CAClC,MAAM6F,EAAmB,CAAA,EACzB,OAAI,KAAK,SAAA,GAAYA,EAAO,KAAK,OAAO,EACpC,KAAK,QAAA,GAAWA,EAAO,KAAK,MAAM,EAClC,KAAK,WAAA,GAAcA,EAAO,KAAK,SAAS,EACxC,KAAK,YAAA,GAAeA,EAAO,KAAK,UAAU,EAC1C,KAAK,YAAA,GAAeA,EAAO,KAAK,UAAU,EAC1C,KAAK,eAAA,GAAkBA,EAAO,KAAK,aAAa,EAC7CA,EAAO,KAAK,KAAK,CAC1B,CAIQ,eAAmB,CACzB,OAAI,KAAK,iBAAyB,KAAK,OACnC,KAAK,WAAA,EAAqB,KAAK,eAAA,EAC/B,KAAK,YAAA,EAAsB,KAAK,gBAAA,GAEhC,KAAK,SAAA,GAAc,KAAK,aAC1B,KAAK,WAAA,EACD,KAAK,cACA,KAAK,eAAA,EAIT,KAAK,MACd,CAEQ,YAAmB,CACzB,GAAI,CAAC,KAAK,SAAA,GAAc,KAAK,cAC3B,OAGF,KAAK,gBAAgB,EAAI,EAEzB,MAAMC,EAAW,KAAK,cAChBC,EAAWR,EAAa,QAAA,EACxBS,EAAQnB,EAAA,EAEd,IAAIoB,EAAW,EAOf,MAAMC,EAAWrD,GAAoB,CAE/BA,EAAI,iBAAmBmD,IAC3BnD,EAAI,eAAiBmD,EAGjBC,EAAWF,EAAS,OACtBA,EAASE,CAAQ,EAAIpD,EAErBkD,EAAS,KAAKlD,CAAG,EAEnBoD,IACF,EAGME,EAAc,KAAK,WAAW,cACpC,KAAK,WAAW,cAAgBD,EAEhC,IAAIE,EAAY,GAEhB,GAAI,CACF,MAAMT,EAAS3D,EAAgB,IAAI,KAAK,WAAY,KAAK,GAAG,EAK5D,GAFA+D,EAAS,OAASE,EAEd9E,EAAUwE,CAAM,EAAG,CAErB,KAAK,kBAAkBG,EAAUC,EAAUC,CAAK,EAChD,KAAK,cAAgBD,EACrBK,EAAY,GAEZ,KAAK,wBAAwBT,CAAM,EACnC,KAAK,gBAAgB,EAAK,EAC1B,MACF,CAGA,KAAK,kBAAkBG,EAAUC,EAAUC,CAAK,EAChD,KAAK,cAAgBD,EACrBK,EAAY,GAEZ,KAAK,kBAAkBT,CAAM,CAC/B,OAASlB,EAAK,CAKZsB,EAAS,OAASE,EAClB,KAAK,kBAAkBH,EAAUC,EAAUC,CAAK,EAChD,KAAK,cAAgBD,EACrBK,EAAY,GAEZ,KAAK,wBAAwB3B,CAAG,CAClC,QAAA,CACE,KAAK,WAAW,cAAgB0B,EAE5BC,EAEEN,IAAaf,GACfQ,EAAa,QAAQO,CAAwB,EAI/CP,EAAa,QAAQQ,CAAQ,CAEjC,CACF,CAMQ,kBAAkBD,EAAwBC,EAAwBC,EAAqB,CAE7F,GAAIF,IAAaf,EACf,QAASrD,EAAI,EAAGA,EAAIoE,EAAS,OAAQpE,IAAK,CACxC,MAAMmB,EAAMiD,EAASpE,CAAC,EAEtB,GAAKmB,GAGDA,EAAI,iBAAmBmD,EAAO,CAChC,MAAMJ,EAAQ,KAAK,eAAe,IAAI/C,EAAI,EAAE,EACxC+C,IACFA,EAAA,EACA,KAAK,eAAe,OAAO/C,EAAI,EAAE,EAErC,CACF,CAIF,QAASnB,EAAI,EAAGA,EAAIqE,EAAS,OAAQrE,IAAK,CACxC,MAAMmB,EAAMkD,EAASrE,CAAC,EACtB,GAAKmB,GAGD,CAAC,KAAK,eAAe,IAAIA,EAAI,EAAE,EAAG,CAEpCF,EAAM,cAAcE,EAAK,IAAkC,EAE3D,MAAM+C,EAAQ/C,EAAI,UAAU,IAAM,KAAK,YAAY,EACnD,KAAK,eAAe,IAAIA,EAAI,GAAI+C,CAAK,CACvC,CACF,CACF,CAEQ,kBAAkBD,EAAiB,CACzC,MAAMU,EAAe,CAAC,KAAK,YAAA,GAAiB,CAAC,KAAK,OAAO,KAAK,OAAQV,CAAM,EAE5E,KAAK,OAASA,EACd,KAAK,YAAA,EACL,KAAK,aAAA,EACL,KAAK,OAAS,KACd,KAAK,gBAAgB,EAAK,EAEtBU,GACF,KAAK,mBAAA,CAET,CAEQ,wBAAwBC,EAA2B,CACzD,KAAK,YAAA,EAGL,KAAK,WAAa,KAAK,YAAc,KAAK,eAAiB,EAAI,KAAK,WAAa,EACjF,MAAMC,EAAY,KAAK,WAEvBD,EACG,KAAME,GAAkB,CACnBD,IAAc,KAAK,YACvB,KAAK,uBAAuBC,CAAa,CAC3C,CAAC,EACA,MAAO/B,GAAQ,CACV8B,IAAc,KAAK,YACvB,KAAK,sBAAsB9B,CAAG,CAChC,CAAC,CACL,CAEQ,uBAAuB+B,EAAwB,CACrD,MAAMH,EAAe,CAAC,KAAK,YAAA,GAAiB,CAAC,KAAK,OAAO,KAAK,OAAQG,CAAa,EAEnF,KAAK,OAASA,EACd,KAAK,YAAA,EACL,KAAK,aAAA,EACL,KAAK,OAAS,KACd,KAAK,gBAAgB,EAAK,EAEtBH,GACF,KAAK,mBAAA,CAET,CAEQ,sBAAsB5B,EAAoB,CAChD,MAAM1D,EAAQD,EAAU2D,EAAK9D,EAAeU,EAAe,iCAAiC,EAO5F,GALA,KAAK,OAASN,EACd,KAAK,aAAA,EACL,KAAK,YAAA,EACL,KAAK,gBAAgB,EAAK,EAEtB,KAAK,UAAY,OAAO,KAAK,UAAa,WAC5C,GAAI,CACF,KAAK,SAASA,CAAK,CACrB,OAAS0F,EAAe,CACtB,QAAQ,MAAMpF,EAAe,gCAAiCoF,CAAa,CAC7E,CAGF,KAAK,mBAAA,CACP,CAEQ,wBAAwBhC,EAAqB,CACnD,MAAM1D,EAAQD,EAAU2D,EAAK9D,EAAeU,EAAe,2BAA2B,EAOtF,GALA,KAAK,OAASN,EACd,KAAK,aAAA,EACL,KAAK,YAAA,EACL,KAAK,gBAAgB,EAAK,EAEtB,KAAK,UAAY,OAAO,KAAK,UAAa,WAC5C,GAAI,CACF,KAAK,SAASA,CAAK,CACrB,OAAS0F,EAAe,CACtB,QAAQ,MAAMpF,EAAe,gCAAiCoF,CAAa,CAC7E,CAGF,MAAM1F,CACR,CAEQ,gBAAoB,CAC1B,GAAI,KAAK,iBACP,OAAO,KAAK,cAEd,MAAM,IAAIJ,EAAcU,EAAe,iCAAiC,CAC1E,CAEQ,iBAAqB,CAC3B,GAAI,KAAK,QAAQ,aAAe,KAAK,iBACnC,OAAO,KAAK,cAEd,MAAM,KAAK,MACb,CAOQ,YAAmB,CACrB,KAAK,eAAA,GAAoB,KAAK,aAElC,KAAK,UAAA,EACL,KAAK,SAAA,GAED,KAAK,qBAAqB,gBAAkB,KAAK,mBAAmB,iBACtES,EAAU,SAAS,KAAK,aAAa,EAEzC,CAEQ,oBAA2B,CAC7B,CAAC,KAAK,qBAAqB,gBAAkB,CAAC,KAAK,mBAAmB,gBAI1EA,EAAU,SAAS,KAAK,UAAU,CACpC,CAEQ,mBAA0B,CAChC,MAAMgB,EAAUd,EAAgB,WAAA,EAChC,GAAKc,EAGL,GACE,OAAOA,GAAY,UACnBA,IAAY,MACXA,EAA8B,cAE9BA,EAA8B,cAAe,IAAkC,UACvE,OAAOA,GAAY,WAAY,CACxC,MAAMsB,EAAYtB,EACdsB,EAAU,cACZA,EAAU,cAAc,IAAkC,EAE1D,KAAK,qBAAqB,IAAItB,CAAqB,CAEvD,MAAYA,EAA8B,SACxC,KAAK,mBAAmB,IAAIA,CAAqB,CAErD,CACF,CAGA,OAAO,OAAO0C,EAAiB,SAAS,EAoCjC,SAASkB,EACdxE,EACAyC,EAA8B,GACb,CACjB,OAAO,IAAIa,EAAiBtD,EAAIyC,CAAO,CACzC,CC3oBA,MAAMgC,CAAsD,CA4B1D,YAAYzE,EAAoByC,EAAyB,GAAI,CA6C7D,KAAO,IAAM,IAAY,CACvB,GAAI,KAAK,WACP,MAAM,IAAI/D,EAAYS,EAAe,uBAAuB,EAE9D,KAAK,QAAA,CACP,EAqBA,KAAO,QAAU,IAAY,CAC3B,GAAI,MAAK,aAET,KAAK,aAAA,EACL,KAAK,aAAA,EAGD,KAAK,gBAAkB0D,GAAY,CACrC,UAAWlC,KAAO,KAAK,cAAe,CACpC,MAAM+C,EAAQ,KAAK,eAAe,IAAI/C,EAAI,EAAE,EACxC+C,GAAOA,EAAA,EACX,KAAK,eAAe,OAAO/C,EAAI,EAAE,CACnC,CACA0C,EAAa,QAAQ,KAAK,aAAa,EACvC,KAAK,cAAgBR,CACvB,CACF,EAmBA,KAAO,cAAiBlC,GAAuB,CAE7C,GAAI,KAAK,aAAe,KAAK,UAAW,CACtC,MAAM+D,EAAI/D,EACJmD,EAAQ,KAAK,cAGnB,GAAIY,EAAE,iBAAmBZ,EAAO,OAChCY,EAAE,eAAiBZ,EAEnB,KAAK,UAAU,KAAKY,CAAC,EAGhB,KAAK,eAAe,IAAIA,EAAE,EAAE,GAC/B,KAAK,aAAaA,CAAC,CAEvB,CACF,EA0BA,KAAO,QAAU,IAAY,CAC3B,GAAI,KAAK,YAAc,KAAK,YAAa,OAEzC,MAAMC,EAAM,KAAK,IAAA,EACjB,KAAK,iBAAiBA,CAAG,EAEzB,KAAK,cAAc,EAAI,EACvB,KAAK,aAAA,EACL,KAAK,cAAc,MAAA,EAEnB,MAAMf,EAAW,KAAK,cAChBC,EAAWR,EAAa,QAAA,EACxBS,EAAQnB,EAAA,EAEd,KAAK,UAAYkB,EACjB,KAAK,cAAgBC,EAErB,IAAII,EAAY,GAEhB,GAAI,CACF,MAAMT,EAAS3D,EAAgB,IAAI,KAAM,KAAK,GAAG,EAGjD,KAAK,kBAAkB8D,EAAUE,CAAK,EACtC,KAAK,cAAgBD,EACrBK,EAAY,GAEZ,KAAK,mBAAA,EAEDjF,EAAUwE,CAAM,EAClBA,EACG,KAAMmB,GAAiB,CAClB,CAAC,KAAK,YAAc,OAAOA,GAAiB,aAC9C,KAAK,SAAWA,EAEpB,CAAC,EACA,MAAO/F,GAAU,CAChB,QAAQ,MAAMD,EAAUC,EAAOH,EAAaS,EAAe,uBAAuB,CAAC,CACrF,CAAC,EAEH,KAAK,SAAW,OAAOsE,GAAW,WAAaA,EAAS,IAE5D,OAAS5E,EAAO,CAEd,KAAK,kBAAkB+E,EAAUE,CAAK,EACtC,KAAK,cAAgBD,EACrBK,EAAY,GAEZ,QAAQ,MAAMtF,EAAUC,EAAOH,EAAaS,EAAe,uBAAuB,CAAC,EACnF,KAAK,SAAW,IAClB,QAAA,CACE,KAAK,cAAc,EAAK,EACxB,KAAK,UAAY,KAEb+E,EACEN,IAAaf,GACfQ,EAAa,QAAQO,CAAQ,EAG/BP,EAAa,QAAQQ,CAAQ,CAEjC,CACF,EAlNE,KAAK,IAAM1C,IAAe/C,EAC1B,KAAK,OAAS,EACd,KAAK,cAAgB,GAErB,KAAK,IAAM4B,EACX,KAAK,MAAQyC,EAAQ,MAAQ,GAC7B,KAAK,eACHA,EAAQ,wBAA0BvE,EAAiB,0BACrD,KAAK,oBAAsBuE,EAAQ,oBAAsB,GAEzD,KAAK,SAAW,KAGhB,KAAK,cAAgBI,EACrB,KAAK,mBAAqB,IAC1B,KAAK,UAAY,KAEjB,KAAK,kBAAoB,IAEzB,KAAK,iBAAmB,KAAK,eAAiB,EAC9C,KAAK,SAAW,IAAI,aAAa,KAAK,gBAAgB,EACtD,KAAK,YAAc,EACnB,KAAK,cAAgB,EACrB,KAAK,gBAAkB,EAEvBpC,EAAM,gBAAgB,KAAM,SAAU,KAAK,GAAG,CAChD,CAiMQ,kBAAkBmD,EAAwBE,EAAqB,CACrE,GAAIF,IAAaf,EACf,QAASrD,EAAI,EAAGA,EAAIoE,EAAS,OAAQpE,IAAK,CACxC,MAAMmB,EAAMiD,EAASpE,CAAC,EACtB,GAAKmB,GAEDA,EAAI,iBAAmBmD,EAAO,CAChC,MAAMJ,EAAQ,KAAK,eAAe,IAAI/C,EAAI,EAAE,EACxC+C,IACFA,EAAA,EACA,KAAK,eAAe,OAAO/C,EAAI,EAAE,EAErC,CACF,CAEJ,CAEQ,aAAaA,EAAuB,CAC1C,GAAI,CACF,MAAMkE,EAAclE,EAAI,UAAU,IAAM,CAClC,KAAK,qBAAuB,KAAK,aACnC,KAAK,cAAc,IAAIA,CAAG,EAGxB,KAAK,MACP,KAAK,QAAA,EAELf,EAAU,SAAS,KAAK,OAAO,CAEnC,CAAC,EACD,KAAK,eAAe,IAAIe,EAAI,GAAIkE,CAAW,CAC7C,OAAShG,EAAO,CACd,QAAQ,MAAMD,EAAUC,EAAOH,EAAaS,EAAe,uBAAuB,CAAC,CACrF,CACF,CAoBA,IAAI,YAAsB,CACxB,OAAQ,KAAK,OAASpB,EAAmB,YAAc,CACzD,CAoBA,IAAI,gBAAyB,CAC3B,OAAO,KAAK,eACd,CAoBA,IAAI,aAAuB,CACzB,OAAQ,KAAK,OAASA,EAAmB,aAAe,CAC1D,CAWQ,cAAqB,CAC3B,KAAK,QAAUA,EAAmB,QACpC,CAaQ,cAAcmB,EAAsB,CACtCA,EAAO,KAAK,QAAUnB,EAAmB,UACxC,KAAK,QAAU,EACtB,CAeQ,cAAqB,CAC3B,GAAI,KAAK,UAAY,OAAO,KAAK,UAAa,WAAY,CACxD,GAAI,CACF,KAAK,SAAA,CACP,OAASc,EAAO,CACd,QAAQ,MAAMD,EAAUC,EAAOH,EAAaS,EAAe,qBAAqB,CAAC,CACnF,CACA,KAAK,SAAW,IAClB,CACF,CAoBQ,iBAAiBwF,EAAmB,CAC1C,GAAI,KAAK,gBAAkB,EAAG,OAE9B,MAAMG,EAAeH,EAAM,IAE3B,KAAK,SAAS,KAAK,WAAW,EAAIA,EAClC,KAAK,aAAe,KAAK,YAAc,GAAK,KAAK,iBAC7C,KAAK,cAAgB,KAAK,kBAC5B,KAAK,gBAEP,KAAK,kBAEL,IAAIvF,EAAQ,EACRoC,GAAO,KAAK,YAAc,EAAI,KAAK,kBAAoB,KAAK,iBAEhE,QAAShC,EAAI,EAAGA,EAAI,KAAK,eACnB,OAAK,SAASgC,CAAG,EAAKsD,GADYtF,IAItCJ,IACAoC,GAAOA,EAAM,EAAI,KAAK,kBAAoB,KAAK,iBAGjD,GAAIpC,EAAQ,KAAK,eAAgB,CAC/B,MAAMd,EAAU,mBAAmBc,CAAK,kDAClCP,EAAQ,IAAIH,EAAYJ,CAAO,EAKrC,GAHA,KAAK,QAAA,EACL,QAAQ,MAAMO,CAAK,EAEf4B,EAAM,QACR,MAAM5B,CAEV,CACF,CAeQ,oBAA2B,CACjC,GAAI,KAAK,qBAAuB4B,EAAM,QAAS,CAC7C,MAAMsE,EAAe,KAAK,cAC1B,QAASvF,EAAI,EAAGA,EAAIuF,EAAa,OAAQvF,IAAK,CAC5C,MAAMmB,EAAMoE,EAAavF,CAAC,EACtBmB,GAAO,KAAK,cAAc,IAAIA,CAAG,GACnCF,EAAM,KACJ,GACA,mCACEA,EAAM,aAAaE,CAAG,GAAK,SAC7B,kDAAA,CAGN,CACF,CACF,CACF,CA+DO,SAASqE,EAAOhF,EAAoByC,EAAyB,GAAkB,CACpF,GAAI,OAAOzC,GAAO,WAChB,MAAM,IAAItB,EAAYS,EAAe,uBAAuB,EAG9D,MAAM8F,EAAiB,IAAIR,EAAWzE,EAAIyC,CAAO,EAEjD,OAAAwC,EAAe,QAAA,EAERA,CACT,CChlBO,SAASC,EAAO1E,EAAmC,CACxD,OACEA,IAAQ,MACR,OAAOA,GAAQ,UACf,UAAWA,GACX,cAAeA,GACf,OAAQA,EAAgC,WAAc,UAE1D,CAEO,SAAS2E,EAAW3E,EAAmC,CAC5D,GAAIC,EAAM,QAAS,CACjB,MAAM2E,EAAY3E,EAAM,aAAaD,CAAG,EACxC,GAAI4E,EACF,OAAOA,IAAc,UAEzB,CACA,OACEF,EAAO1E,CAAG,GACV,eAAgBA,GAChB,OAAQA,EAAgC,YAAe,UAE3D,CAEO,SAAS6E,EAAS7E,EAAmC,CAC1D,OACEA,IAAQ,MACR,OAAOA,GAAQ,UACf,YAAaA,GACb,QAASA,GACT,OAAQA,EAAgC,SAAY,YACpD,OAAQA,EAAgC,KAAQ,UAEpD"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/constants.ts","../src/errors/errors.ts","../src/errors/messages.ts","../src/scheduler/scheduler.ts","../src/scheduler/batch.ts","../src/tracking/context.ts","../src/tracking/untracked.ts","../src/utils/debug.ts","../src/utils/subscriber-manager.ts","../src/core/atom/atom.ts","../src/epoch.ts","../src/types/internal.ts","../src/pool.ts","../src/core/computed/index.ts","../src/core/effect/effect.ts","../src/utils/type-guards.ts"],"sourcesContent":["/**\n * @fileoverview Constants and configuration for atom-effect library\n * @description Centralized constants for async states, bit flags, and performance tuning\n */\n\n/**\n * Async computation states for computed atoms\n */\nexport const AsyncState = {\n IDLE: 'idle' as const,\n PENDING: 'pending' as const,\n RESOLVED: 'resolved' as const,\n REJECTED: 'rejected' as const,\n};\n\n/**\n * Bit flags for effect state management\n * Using bit flags for efficient state checks (O(1) operations)\n */\nexport const EFFECT_STATE_FLAGS = {\n DISPOSED: 1 << 0, // 0001 - Effect has been disposed\n EXECUTING: 1 << 1, // 0010 - Effect is currently executing\n} as const;\n\n/**\n * Bit flags for computed atom state management\n * Enables fast state transitions and checks without multiple boolean fields\n */\nexport const COMPUTED_STATE_FLAGS = {\n DIRTY: 1 << 0, // 0001 - Needs recomputation\n IDLE: 1 << 1, // 0010 - Initial state, not computed yet\n PENDING: 1 << 2, // 0100 - Async computation in progress\n RESOLVED: 1 << 3, // 1000 - Successfully computed\n REJECTED: 1 << 4, // 10000 - Computation failed\n RECOMPUTING: 1 << 5, // 100000 - Currently recomputing\n HAS_ERROR: 1 << 6, // 1000000 - Has error state\n} as const;\n\n/**\n * Object pool configuration\n * Controls memory management and GC pressure reduction\n */\nexport const POOL_CONFIG = {\n /** Maximum number of pooled objects to prevent memory bloat */\n MAX_SIZE: 1000,\n /** Number of objects to pre-allocate for performance-critical paths */\n WARMUP_SIZE: 100,\n} as const;\n\n/**\n * Scheduler configuration\n * Controls batching behavior and performance limits\n */\nexport const SCHEDULER_CONFIG = {\n /** Maximum effect executions per second to detect infinite loops */\n MAX_EXECUTIONS_PER_SECOND: 100,\n /** Threshold for cleaning up old execution timestamps */\n CLEANUP_THRESHOLD: 100,\n} as const;\n\n/**\n * Debug configuration defaults\n */\nexport const DEBUG_CONFIG = {\n /** Maximum dependencies before warning about large dependency graphs */\n MAX_DEPENDENCIES: 1000,\n /** Enable infinite loop detection warnings */\n WARN_INFINITE_LOOP: true,\n} as const;\n\n/**\n * Maximum Small Integer (Smi) value in V8 (31-bit signed integer)\n * Used for IDs and Versions to prevent HeapNumber allocation\n */\nexport const SMI_MAX = 0x3fffffff;\n","/**\n * @fileoverview Error class hierarchy for atom-effect library\n * @description Structured error classes with cause tracking and recoverability flags\n */\n\n/**\n * Base error class for all atom-effect errors\n *\n * Provides enhanced error information including:\n * - Original cause tracking for error chains\n * - Recoverability flag for error handling strategies\n * - Timestamp for debugging and logging\n *\n * @example\n * ```ts\n * throw new AtomError('Invalid state', originalError, false);\n * ```\n */\nexport class AtomError extends Error {\n /** Original error that caused this error, if any */\n cause: Error | null;\n /** Whether this error can be recovered from */\n recoverable: boolean;\n /** When this error occurred */\n timestamp: Date;\n\n /**\n * Creates a new AtomError\n * @param message - Error message describing what went wrong\n * @param cause - Original error that caused this error\n * @param recoverable - Whether the operation can be retried\n */\n constructor(message: string, cause: Error | null = null, recoverable: boolean = true) {\n super(message);\n this.name = 'AtomError';\n this.cause = cause;\n this.recoverable = recoverable;\n this.timestamp = new Date();\n }\n}\n\n/**\n * Error thrown during computed value computation\n *\n * Computed errors are considered recoverable by default since they typically\n * result from transient data issues rather than programming errors.\n */\nexport class ComputedError extends AtomError {\n /**\n * Creates a new ComputedError\n * @param message - Error message\n * @param cause - Original error\n */\n constructor(message: string, cause: Error | null = null) {\n super(message, cause, true);\n this.name = 'ComputedError';\n }\n}\n\n/**\n * Error thrown during effect execution\n *\n * Effect errors are considered non-recoverable by default since effects\n * typically represent critical side effects that shouldn't fail silently.\n */\nexport class EffectError extends AtomError {\n /**\n * Creates a new EffectError\n * @param message - Error message\n * @param cause - Original error\n */\n constructor(message: string, cause: Error | null = null) {\n super(message, cause, false);\n this.name = 'EffectError';\n }\n}\n\n/**\n * Error thrown by the scheduler system\n *\n * Scheduler errors indicate fundamental issues with the batching/scheduling\n * mechanism and are considered non-recoverable.\n */\nexport class SchedulerError extends AtomError {\n /**\n * Creates a new SchedulerError\n * @param message - Error message\n * @param cause - Original error\n */\n constructor(message: string, cause: Error | null = null) {\n super(message, cause, false);\n this.name = 'SchedulerError';\n }\n}\n\n/**\n * Wraps an unknown error in the appropriate AtomError subclass\n *\n * Provides consistent error handling by:\n * - Preserving original error information in the cause field\n * - Adding contextual information about where the error occurred\n * - Returning existing AtomErrors unchanged\n * - Handling various error types (TypeError, ReferenceError, etc.)\n *\n * @param error - Unknown error to wrap\n * @param ErrorClass - AtomError subclass to use for wrapping\n * @param context - Context string describing where the error occurred\n * @returns Wrapped error with contextual information\n *\n * @example\n * ```ts\n * try {\n * computeFn();\n * } catch (err) {\n * throw wrapError(err, ComputedError, 'computation phase');\n * }\n * ```\n */\nexport function wrapError(\n error: unknown,\n ErrorClass: typeof AtomError,\n context: string\n): AtomError {\n if (error instanceof TypeError) {\n return new ErrorClass(`Type error (${context}): ${error.message}`, error);\n }\n if (error instanceof ReferenceError) {\n return new ErrorClass(`Reference error (${context}): ${error.message}`, error);\n }\n if (error instanceof AtomError) {\n return error;\n }\n\n // Handle other error types\n const errorMessage = error instanceof Error ? error.message : String(error);\n const cause = error instanceof Error ? error : null;\n return new ErrorClass(`Unexpected error (${context}): ${errorMessage}`, cause);\n}\n\n/**\n * Type guard to check if a value is a Promise\n *\n * Uses duck-typing to detect Promise-like objects by checking for\n * the presence of a `then` method.\n *\n * @template T - The type the Promise resolves to\n * @param value - Value to check\n * @returns True if value has a `then` method (is Promise-like)\n *\n * @example\n * ```ts\n * const result = computeFn();\n * if (isPromise(result)) {\n * await result;\n * }\n * ```\n */\nexport function isPromise<T>(value: unknown): value is Promise<T> {\n return (\n value !== null &&\n value !== undefined &&\n typeof (value as { then?: unknown }).then === 'function'\n );\n}\n","/**\n * @fileoverview Centralized error messages for better maintainability\n * @description All error messages in English for international accessibility\n * @module errors/messages\n */\n\n/**\n * Centralized error message constants for the atom-effect library.\n *\n * @description\n * Provides consistent, maintainable error messages across the library.\n * All messages are in English for international accessibility.\n *\n * @remarks\n * - Computed errors: Related to computed atom creation and execution\n * - Atom errors: Related to atom subscription and notification\n * - Effect errors: Related to effect lifecycle and cleanup\n * - Debug warnings: Non-critical warnings for debugging\n *\n * @example\n * ```ts\n * import { ERROR_MESSAGES } from './messages';\n *\n * if (typeof fn !== 'function') {\n * throw new Error(ERROR_MESSAGES.COMPUTED_MUST_BE_FUNCTION);\n * }\n * ```\n */\nexport const ERROR_MESSAGES = {\n // ─────────────────────────────────────────────────────────────────\n // Computed errors\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Error thrown when computed() receives a non-function argument.\n */\n COMPUTED_MUST_BE_FUNCTION: 'Computed function must be a function',\n\n /**\n * Error thrown when subscribe() receives a non-function listener.\n */\n COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION: 'Subscriber listener must be a function',\n\n /**\n * Error thrown when accessing a pending async computed without a default value.\n */\n COMPUTED_ASYNC_PENDING_NO_DEFAULT: 'Async computation is pending. No default value provided',\n\n /**\n * Error thrown when a synchronous computed computation fails.\n */\n COMPUTED_COMPUTATION_FAILED: 'Computed computation failed',\n\n /**\n * Error thrown when an asynchronous computed computation fails.\n */\n COMPUTED_ASYNC_COMPUTATION_FAILED: 'Async computed computation failed',\n\n /**\n * Error thrown when subscribing to a dependency fails.\n */\n COMPUTED_DEPENDENCY_SUBSCRIPTION_FAILED: 'Failed to subscribe to dependency',\n\n // ─────────────────────────────────────────────────────────────────\n // Atom errors\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Error thrown when atom.subscribe() receives a non-function listener.\n */\n ATOM_SUBSCRIBER_MUST_BE_FUNCTION: 'Subscription listener must be a function',\n\n /**\n * Error thrown when the atom subscriber notification process fails.\n */\n ATOM_SUBSCRIBER_EXECUTION_FAILED: 'Error occurred while executing atom subscribers',\n\n /**\n * Error logged when an individual subscriber throws during notification.\n * @remarks This error is caught and logged to prevent cascading failures.\n */\n ATOM_INDIVIDUAL_SUBSCRIBER_FAILED: 'Error during individual atom subscriber execution',\n\n // ─────────────────────────────────────────────────────────────────\n // Effect errors\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Error thrown when effect() receives a non-function argument.\n */\n EFFECT_MUST_BE_FUNCTION: 'Effect function must be a function',\n\n /**\n * Error thrown when an effect's execution fails.\n */\n EFFECT_EXECUTION_FAILED: 'Effect execution failed',\n\n /**\n * Error thrown when an effect's cleanup function fails.\n */\n EFFECT_CLEANUP_FAILED: 'Effect cleanup function execution failed',\n\n // ─────────────────────────────────────────────────────────────────\n // Debug warnings\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Warning message for large dependency graphs.\n *\n * @param count - The number of dependencies detected\n * @returns Formatted warning message with dependency count\n *\n * @example\n * ```ts\n * console.warn(ERROR_MESSAGES.LARGE_DEPENDENCY_GRAPH(150));\n * // Output: \"Large dependency graph detected: 150 dependencies\"\n * ```\n */\n LARGE_DEPENDENCY_GRAPH: (count: number): string =>\n `Large dependency graph detected: ${count} dependencies`,\n\n /**\n * Warning logged when attempting to unsubscribe a non-existent listener.\n */\n UNSUBSCRIBE_NON_EXISTENT: 'Attempted to unsubscribe a non-existent listener',\n\n /**\n * Error logged when the onError callback itself throws an error.\n * @remarks This prevents cascading failures from masking the original error.\n */\n CALLBACK_ERROR_IN_ERROR_HANDLER: 'Error occurred during onError callback execution',\n} as const;\n","import { SchedulerError } from '../errors/errors';\n\n/**\n * Scheduler for managing reactive updates and batching operations.\n *\n * The Scheduler is responsible for coordinating when reactive computations\n * are executed. It supports both immediate (microtask) execution and\n * batched synchronous execution for optimal performance.\n *\n * Key features:\n * - Deduplication of callbacks via Set\n * - Nested batch support with depth tracking\n * - Infinite loop protection with configurable iteration limit\n * - Error isolation to prevent one callback from breaking others\n *\n * @example\n * ```typescript\n * // Schedule a callback for microtask execution\n * scheduler.schedule(() => console.log('Updated!'));\n *\n * // Batch multiple updates\n * scheduler.startBatch();\n * scheduler.schedule(() => console.log('Update 1'));\n * scheduler.schedule(() => console.log('Update 2'));\n * scheduler.endBatch(); // Both execute synchronously here\n * ```\n */\n/**\n * Phases of the scheduler execution cycle.\n */\nexport enum SchedulerPhase {\n IDLE = 0,\n BATCHING = 1,\n FLUSHING = 2,\n}\n\nexport type SchedulerJob = (() => void) & { _nextEpoch?: number };\n\nclass Scheduler {\n /** Queue of callbacks waiting for microtask execution */\n /** Queue buffers for double buffering optimization */\n private queueA: SchedulerJob[] = [];\n private queueB: SchedulerJob[] = [];\n\n /** Currently active queue receiving new tasks */\n private queue: SchedulerJob[] = this.queueA;\n private queueSize = 0;\n\n /** Epoch for O(1) deduplication */\n private _epoch = 0;\n\n /** Whether the scheduler is currently processing the queue */\n private isProcessing: boolean = false;\n\n /** Whether batching is currently active */\n public isBatching: boolean = false;\n\n /** Current nesting depth of batch operations */\n private batchDepth: number = 0;\n\n /** Array of callbacks queued during batching */\n private batchQueue: SchedulerJob[] = [];\n\n /** Current size of the batch queue (for array reuse) */\n private batchQueueSize = 0;\n\n /** Whether synchronous flush is in progress */\n private isFlushingSync: boolean = false;\n\n /** Maximum iterations allowed during flush to prevent infinite loops */\n private maxFlushIterations: number = 1000;\n\n /**\n * Gets the current phase of the scheduler.\n */\n get phase(): SchedulerPhase {\n if (this.isProcessing || this.isFlushingSync) {\n return SchedulerPhase.FLUSHING;\n }\n if (this.isBatching) {\n return SchedulerPhase.BATCHING;\n }\n return SchedulerPhase.IDLE;\n }\n\n /**\n * Schedules a callback for execution.\n *\n * If batching is active or a sync flush is in progress, the callback\n * is added to the batch queue. Otherwise, it's added to the main queue\n * and a flush is triggered via microtask.\n *\n * @param callback - The function to schedule for execution\n * @throws {SchedulerError} If callback is not a function\n *\n * @example\n * ```typescript\n * scheduler.schedule(() => {\n * // This runs in the next microtask (or sync if batching)\n * updateUI();\n * });\n * ```\n */\n schedule(callback: SchedulerJob): void {\n if (typeof callback !== 'function') {\n throw new SchedulerError('Scheduler callback must be a function');\n }\n\n // O(1) Unique dedup check\n if (callback._nextEpoch === this._epoch) return;\n callback._nextEpoch = this._epoch;\n\n if (this.isBatching || this.isFlushingSync) {\n this.batchQueue[this.batchQueueSize++] = callback;\n } else {\n this.queue[this.queueSize++] = callback;\n if (!this.isProcessing) {\n this.flush();\n }\n }\n }\n\n /**\n * Flushes the queue asynchronously via microtask.\n *\n * Executes all queued callbacks in a microtask, allowing the current\n * synchronous execution to complete first. Errors in individual\n * callbacks are caught and logged without interrupting others.\n *\n * @private\n * @remarks\n * This method is idempotent - calling it multiple times while\n * processing is active has no effect.\n */\n private flush(): void {\n if (this.isProcessing || this.queueSize === 0) return;\n\n this.isProcessing = true;\n\n // Double buffering: Swap queues to snapshot current tasks\n // This allows adding new tasks to the other queue while processing\n const jobs = this.queue;\n const count = this.queueSize;\n\n // Swap queues\n this.queue = this.queue === this.queueA ? this.queueB : this.queueA;\n this.queueSize = 0;\n\n // Increment epoch to invalidate previous task deduplication\n this._epoch++;\n\n queueMicrotask(() => {\n // Performance: Iterate Array by index\n for (let i = 0; i < count; i++) {\n try {\n jobs[i]?.();\n } catch (error) {\n console.error(\n new SchedulerError('Error occurred during scheduler execution', error as Error)\n );\n }\n }\n\n // Reuse array capacity\n jobs.length = 0;\n this.isProcessing = false;\n\n // If new tasks were added to the active queue (the one we swapped to), flush again\n if (this.queueSize > 0 && !this.isBatching) {\n this.flush();\n }\n });\n }\n\n /**\n * Flushes all queued callbacks synchronously.\n *\n * This method is called when a batch ends. It processes all callbacks\n * in the batch queue and main queue synchronously, allowing callbacks\n * to schedule additional callbacks that are processed in the same flush.\n *\n * @private\n * @remarks\n * - Includes infinite loop protection via maxFlushIterations\n * - Errors in callbacks are caught and logged individually\n * - The isFlushingSync flag prevents re-entrancy issues\n */\n private flushSync(): void {\n this.isFlushingSync = true;\n\n try {\n // Increment epoch first so batch jobs can pass the dedup check\n // (they were marked with the previous epoch during schedule())\n this._epoch++;\n\n if (this.batchQueueSize > 0) {\n for (let i = 0; i < this.batchQueueSize; i++) {\n // O(1) Unique dedup check for batch queue transfer\n const job = this.batchQueue[i]!;\n if (job._nextEpoch !== this._epoch) {\n job._nextEpoch = this._epoch;\n this.queue[this.queueSize++] = job;\n }\n }\n this.batchQueueSize = 0;\n }\n\n let iterations = 0;\n\n while (this.queueSize > 0) {\n if (++iterations > this.maxFlushIterations) {\n console.error(\n new SchedulerError(\n `Maximum flush iterations (${this.maxFlushIterations}) exceeded. ` +\n `Possible infinite loop in reactive dependencies. ` +\n `Consider increasing the limit with scheduler.setMaxFlushIterations()`\n )\n );\n // clear queue\n this.queueSize = 0;\n this.queue.length = 0;\n this.batchQueueSize = 0;\n break;\n }\n\n // Double buffering: Swap and process\n const jobs = this.queue;\n const count = this.queueSize;\n\n this.queue = this.queue === this.queueA ? this.queueB : this.queueA;\n this.queueSize = 0;\n this._epoch++;\n\n for (let i = 0; i < count; i++) {\n try {\n jobs[i]?.();\n } catch (error) {\n console.error(\n new SchedulerError('Error occurred during batch execution', error as Error)\n );\n }\n }\n\n jobs.length = 0;\n\n if (this.batchQueueSize > 0) {\n for (let i = 0; i < this.batchQueueSize; i++) {\n // Jobs scheduled during flush processing should always execute\n // (dedup was already done when they were added to batchQueue)\n this.queue[this.queueSize++] = this.batchQueue[i]!;\n }\n this.batchQueueSize = 0;\n }\n }\n } finally {\n this.isFlushingSync = false;\n }\n }\n\n /**\n * Starts a new batch operation.\n *\n * While batching is active, all scheduled callbacks are deferred\n * until endBatch() is called. Batches can be nested - only the\n * outermost endBatch() triggers execution.\n *\n * @example\n * ```typescript\n * scheduler.startBatch();\n * // All updates here are deferred\n * atom1.value = 'a';\n * atom2.value = 'b';\n * scheduler.endBatch(); // Both updates processed together\n * ```\n */\n startBatch(): void {\n this.batchDepth++;\n this.isBatching = true;\n }\n\n /**\n * Ends a batch operation.\n *\n * Decrements the batch depth counter. When depth reaches zero,\n * all queued callbacks are flushed synchronously and batching\n * is disabled.\n *\n * @remarks\n * Safe to call even if startBatch() wasn't called - depth is\n * clamped to zero minimum.\n *\n * @example\n * ```typescript\n * scheduler.startBatch();\n * try {\n * // ... batched operations\n * } finally {\n * scheduler.endBatch(); // Always end batch, even on error\n * }\n * ```\n */\n endBatch(): void {\n this.batchDepth = Math.max(0, this.batchDepth - 1);\n\n if (this.batchDepth === 0) {\n this.flushSync();\n this.isBatching = false;\n }\n }\n\n /**\n * Sets the maximum number of flush iterations allowed.\n *\n * This limit prevents infinite loops when reactive dependencies\n * form cycles. If exceeded, the queue is cleared and an error\n * is logged.\n *\n * @param max - Maximum iterations (must be at least 10)\n * @throws {SchedulerError} If max is less than 10\n *\n * @example\n * ```typescript\n * // Increase limit for complex dependency graphs\n * scheduler.setMaxFlushIterations(5000);\n * ```\n */\n setMaxFlushIterations(max: number): void {\n if (max < 10) {\n throw new SchedulerError('Max flush iterations must be at least 10');\n }\n this.maxFlushIterations = max;\n }\n}\n\n/** Global scheduler instance for reactive updates */\nexport const scheduler = new Scheduler();\n","import { AtomError } from '../errors/errors';\nimport { scheduler } from './scheduler';\n\n/**\n * Executes multiple reactive updates in a single batch.\n *\n * Batching groups multiple state changes together, deferring notifications\n * until all updates are complete. This prevents intermediate states from\n * triggering unnecessary recomputations and improves performance.\n *\n * @template T - The return type of the callback function\n * @param callback - The function containing batched updates\n * @returns The result of the callback function\n * @throws {AtomError} If the callback is not a function\n * @throws {AtomError} If an error occurs during batch execution\n *\n * @example\n * ```typescript\n * const firstName = atom('John');\n * const lastName = atom('Doe');\n *\n * // Without batching: triggers 2 separate updates\n * firstName.value = 'Jane';\n * lastName.value = 'Smith';\n *\n * // With batching: triggers 1 combined update\n * batch(() => {\n * firstName.value = 'Jane';\n * lastName.value = 'Smith';\n * });\n * ```\n */\nexport function batch<T>(callback: () => T): T {\n if (typeof callback !== 'function') {\n throw new AtomError('Batch callback must be a function');\n }\n\n scheduler.startBatch();\n\n try {\n return callback();\n } catch (error) {\n throw new AtomError('Error occurred during batch execution', error as Error);\n } finally {\n scheduler.endBatch();\n }\n}\n","import type { Listener } from './tracking.types';\n\n/**\n * Interface for the tracking context that manages dependency tracking.\n *\n * The tracking context is responsible for maintaining the current listener\n * during reactive computations, enabling automatic dependency collection.\n *\n * @interface TrackingContext\n */\nexport interface TrackingContext {\n /**\n * The currently active listener being tracked.\n * `null` when no tracking is in progress.\n */\n current: Listener | null;\n\n /**\n * Executes a function within a tracking context.\n *\n * Sets the provided listener as the current tracking target,\n * executes the function, and restores the previous context.\n *\n * @template T - The return type of the function\n * @param listener - The listener to set as current during execution\n * @param fn - The function to execute within the tracking context\n * @returns The result of the executed function\n *\n * @example\n * ```typescript\n * const result = trackingContext.run(myListener, () => {\n * // Any atom access here will be tracked\n * return someAtom.value + otherAtom.value;\n * });\n * ```\n */\n run<T>(listener: Listener, fn: () => T): T;\n\n /**\n * Gets the currently active listener.\n *\n * @returns The current listener or `null` if no tracking is active\n *\n * @example\n * ```typescript\n * const current = trackingContext.getCurrent();\n * if (current) {\n * // Dependency tracking is active\n * }\n * ```\n */\n getCurrent(): Listener | null;\n}\n\n/**\n * Global tracking context singleton for dependency tracking.\n *\n * This object manages the current listener during reactive computations,\n * enabling atoms and computed values to automatically track their dependencies.\n *\n * @remarks\n * - The context uses a stack-like behavior via the `run` method\n * - Nested `run` calls properly restore the previous context\n * - Thread-safe within a single JavaScript execution context\n *\n * @example\n * ```typescript\n * // Setting up tracking for a computed value\n * const value = trackingContext.run(computedListener, () => {\n * return atom1.value + atom2.value; // Both atoms are tracked\n * });\n *\n * // Checking if tracking is active\n * if (trackingContext.getCurrent()) {\n * // Register this atom as a dependency\n * }\n * ```\n */\nexport const trackingContext: TrackingContext = {\n /** @inheritdoc */\n current: null,\n\n /**\n * @inheritdoc\n * @throws Re-throws any error from the executed function after restoring context\n */\n run<T>(listener: Listener, fn: () => T): T {\n const prev = this.current;\n this.current = listener;\n try {\n return fn();\n } finally {\n this.current = prev;\n }\n },\n\n /** @inheritdoc */\n getCurrent(): Listener | null {\n return this.current;\n },\n};\n","import { AtomError } from '../errors/errors';\nimport { trackingContext } from './context';\n\n/**\n * Executes a function without tracking any reactive dependencies.\n *\n * This utility allows reading atom values without establishing\n * a dependency relationship, useful for accessing values that\n * shouldn't trigger recomputation when they change.\n *\n * @template T - The return type of the function\n * @param fn - The function to execute without tracking\n * @returns The result of the executed function\n * @throws {AtomError} If the callback is not a function\n * @throws {AtomError} If an error occurs during execution\n *\n * @example\n * ```typescript\n * const count = atom(0);\n * const doubled = computed(() => {\n * // This read will NOT be tracked as a dependency\n * const untrackedValue = untracked(() => count.value);\n * return untrackedValue * 2;\n * });\n * ```\n */\nexport function untracked<T>(fn: () => T): T {\n if (typeof fn !== 'function') {\n throw new AtomError('Untracked callback must be a function');\n }\n\n const prev = trackingContext.current;\n trackingContext.current = null;\n\n try {\n return fn();\n } catch (error) {\n throw new AtomError('Error occurred during untracked execution', error as Error);\n } finally {\n trackingContext.current = prev;\n }\n}\n","/**\n * @fileoverview Debug configuration and utilities\n *\n * This module provides development-time debugging tools for dependency tracking\n * and circular reference detection in the reactive state management system.\n *\n * @module utils/debug\n * @see {@link DebugConfig} for the configuration interface\n */\n\nimport { DEBUG_CONFIG } from '../constants';\nimport { ComputedError } from '../errors/errors';\nimport type { DebugConfig } from '../types';\n\n/**\n * Symbol key for storing debug display name on reactive objects.\n *\n * @remarks\n * Using symbols prevents property name collisions with user-defined properties.\n *\n * @example\n * ```typescript\n * const atom = createAtom(0);\n * console.log(atom[DEBUG_NAME]); // \"atom_1\"\n * ```\n */\nexport const DEBUG_NAME: unique symbol = Symbol('debugName');\n\n/**\n * Symbol key for storing unique identifier on reactive objects.\n *\n * @remarks\n * Each reactive object (atom, computed, effect) receives a unique numeric ID\n * for debugging and tracking purposes.\n */\nexport const DEBUG_ID: unique symbol = Symbol('id');\n\n/**\n * Symbol key for storing the type discriminator on reactive objects.\n *\n * @remarks\n * Possible values: 'atom' | 'computed' | 'effect'\n */\nexport const DEBUG_TYPE: unique symbol = Symbol('type');\n\n/**\n * Sentinel value to distinguish \"no default value provided\" from `undefined`.\n *\n * @remarks\n * This allows computed values to differentiate between:\n * - User explicitly passing `undefined` as default\n * - User not providing any default value\n *\n * @example\n * ```typescript\n * const hasDefault = options.defaultValue !== NO_DEFAULT_VALUE;\n * ```\n */\nexport const NO_DEFAULT_VALUE: unique symbol = Symbol('noDefaultValue');\n\n/**\n * Type guard for objects with a dependencies property.\n *\n * @param obj - The object to check\n * @returns True if the object has a Set-typed dependencies property\n *\n * @internal\n */\nfunction hasDependencies(obj: unknown): obj is { dependencies: Set<unknown> } {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n 'dependencies' in obj &&\n (obj as { dependencies: unknown }).dependencies instanceof Set\n );\n}\n\n/**\n * Debug configuration instance with runtime utilities.\n *\n * Provides development-time features including:\n * - Circular dependency detection (direct and indirect)\n * - Large dependency graph warnings\n * - Debug metadata attachment for inspection\n *\n * @remarks\n * Most features are only active when `NODE_ENV === 'development'`\n * to avoid performance overhead in production builds.\n *\n * @example\n * ```typescript\n * // Check for circular dependencies\n * debug.checkCircular(dependencyAtom, computedAtom);\n *\n * // Warn about potential issues\n * debug.warn(count > 100, 'Large dependency count detected');\n *\n * // Attach debug info to a reactive object\n * debug.attachDebugInfo(atom, 'atom', 42);\n * ```\n */\nexport const debug: DebugConfig = {\n /**\n * Whether debug mode is enabled.\n *\n * @remarks\n * Automatically set based on `NODE_ENV` environment variable.\n * Only `'development'` enables debug features.\n */\n enabled:\n typeof process !== 'undefined' && (process as NodeJS.Process).env?.NODE_ENV === 'development',\n\n /**\n * Maximum number of dependencies before warning.\n *\n * @see {@link DEBUG_CONFIG.MAX_DEPENDENCIES}\n */\n maxDependencies: DEBUG_CONFIG.MAX_DEPENDENCIES,\n\n /**\n * Whether to warn about potential infinite loops.\n *\n * @see {@link DEBUG_CONFIG.WARN_INFINITE_LOOP}\n */\n warnInfiniteLoop: DEBUG_CONFIG.WARN_INFINITE_LOOP,\n\n /**\n * Logs a warning message when condition is true and debug is enabled.\n *\n * @param condition - When true, the warning is logged\n * @param message - The warning message to display\n *\n * @example\n * ```typescript\n * debug.warn(deps.length > 100, 'Large dependency graph detected');\n * ```\n */\n warn(condition: boolean, message: string): void {\n if (this.enabled && condition) {\n console.warn(`[Atom Effect] ${message}`);\n }\n },\n\n /**\n * Checks for circular dependencies in the dependency graph.\n *\n * Detects two types of circular references:\n * 1. **Direct**: A depends on itself (A → A)\n * 2. **Indirect**: A depends on B which depends on A (A → B → A)\n *\n * @param dep - The dependency being added\n * @param current - The current reactive object adding the dependency\n * @param visited - Set of already visited nodes (for recursion)\n *\n * @throws {ComputedError} When a circular dependency is detected\n *\n * @remarks\n * - Direct circular detection runs in all environments\n * - Indirect circular detection only runs in development mode\n * - Uses depth-first traversal with O(n) time complexity\n *\n * @example\n * ```typescript\n * // This will throw for direct circular reference\n * debug.checkCircular(computedA, computedA);\n *\n * // This will throw for indirect circular reference (dev only)\n * // Given: A → B → C → A\n * debug.checkCircular(computedC, computedA);\n * ```\n */\n checkCircular(dep: unknown, current: unknown, visited = new Set<unknown>()): void {\n // Direct circular reference check (A→A) - Always checked even in production\n if (dep === current) {\n throw new ComputedError('Direct circular dependency detected');\n }\n\n // Indirect circular reference check only in development mode (for performance)\n if (!this.enabled) {\n return;\n }\n\n // Indirect circular reference check (A→B→C→A)\n if (visited.has(dep)) {\n throw new ComputedError('Indirect circular dependency detected');\n }\n\n visited.add(dep);\n\n // Recursively check nested dependencies using type guard\n if (hasDependencies(dep)) {\n for (const nestedDep of dep.dependencies) {\n this.checkCircular(nestedDep, current, visited);\n }\n }\n },\n\n /**\n * Attaches debug metadata to a reactive object.\n *\n * @param obj - The object to attach metadata to\n * @param type - The type of reactive object ('atom' | 'computed' | 'effect')\n * @param id - The unique identifier for this object\n *\n * @remarks\n * Only attaches metadata when debug mode is enabled.\n * Uses symbol keys to avoid property name collisions.\n *\n * @example\n * ```typescript\n * const atom = createAtomInternal(0);\n * debug.attachDebugInfo(atom, 'atom', 1);\n * // atom[DEBUG_NAME] === 'atom_1'\n * // atom[DEBUG_ID] === 1\n * // atom[DEBUG_TYPE] === 'atom'\n * ```\n */\n attachDebugInfo(obj: object, type: string, id: number): void {\n if (!this.enabled) {\n return;\n }\n\n const target = obj as Record<symbol, unknown>;\n target[DEBUG_NAME] = `${type}_${id}`;\n target[DEBUG_ID] = id;\n target[DEBUG_TYPE] = type;\n },\n\n /**\n * Retrieves the debug display name from a reactive object.\n *\n * @param obj - The object to get the name from\n * @returns The debug name (e.g., 'atom_1') or undefined if not set\n *\n * @example\n * ```typescript\n * const name = debug.getDebugName(myAtom);\n * console.log(`Updating ${name ?? 'unknown'}`);\n * ```\n */\n getDebugName(obj: unknown): string | undefined {\n if (obj !== null && typeof obj === 'object' && DEBUG_NAME in obj) {\n return (obj as Record<symbol, unknown>)[DEBUG_NAME] as string | undefined;\n }\n return undefined;\n },\n\n /**\n * Retrieves the debug type from a reactive object.\n *\n * @param obj - The object to get the type from\n * @returns The type ('atom' | 'computed' | 'effect') or undefined if not set\n *\n * @example\n * ```typescript\n * const type = debug.getDebugType(reactiveObj);\n * if (type === 'computed') {\n * // Handle computed-specific logic\n * }\n * ```\n */\n getDebugType(obj: unknown): string | undefined {\n if (obj !== null && typeof obj === 'object' && DEBUG_TYPE in obj) {\n return (obj as Record<symbol, unknown>)[DEBUG_TYPE] as string | undefined;\n }\n return undefined;\n },\n};\n\n/**\n * Counter for generating unique IDs.\n *\n * @internal\n */\nlet nextId = 1;\n\n/**\n * Generates a unique numeric identifier for reactive objects.\n *\n * @returns A unique positive integer, incrementing with each call\n *\n * @remarks\n * IDs are globally unique within a single runtime session.\n * The counter resets when the module is reloaded.\n *\n * @example\n * ```typescript\n * const atomId = generateId(); // 1\n * const computedId = generateId(); // 2\n * ```\n */\nexport const generateId = (): number => nextId++;\n","/**\n * @fileoverview Subscriber management utility\n * @description Manages subscribers with cache-friendly array-based operations\n */\n\n/**\n * Manages subscribers with optimized operations\n *\n * Uses a simple array for maximum cache locality.\n * For typical subscriber counts (<100), linear search outperforms\n * hash-based lookups due to cache friendliness.\n *\n * Key optimizations:\n * - Array for cache-friendly sequential iteration\n * - Swap-and-pop for O(1) removal (after linear search)\n * - Lazy initialization to save memory\n *\n * @template T - Subscriber type\n *\n * @example\n * ```ts\n * const manager = new SubscriberManager<(value: number) => void>();\n *\n * // Add subscriber\n * const unsub = manager.add((val) => console.log(val));\n *\n * // Notify all\n * manager.notify(42);\n *\n * // Remove subscriber\n * unsub();\n * ```\n */\nexport class SubscriberManager<T> {\n private subscribers: T[] | null = null;\n\n /**\n * Adds a subscriber and returns an unsubscribe function\n *\n * Performs lazy initialization on first subscriber.\n * Duplicate subscribers are ignored (idempotent).\n *\n * @param subscriber - Function to add as subscriber\n * @returns Unsubscribe function\n *\n * @example\n * ```ts\n * const unsub = manager.add((value) => console.log(value));\n * // Later...\n * unsub(); // Remove this subscriber\n * ```\n */\n add(subscriber: T): () => void {\n // Lazy initialization\n if (!this.subscribers) {\n this.subscribers = [];\n }\n\n // Check for duplicates (linear scan - fast for small arrays due to cache)\n if (this.subscribers.indexOf(subscriber) !== -1) {\n // Already subscribed, return no-op unsubscribe\n return () => {};\n }\n\n // Add subscriber\n this.subscribers.push(subscriber);\n\n // Return unsubscribe function with duplicate protection\n let isUnsubscribed = false;\n return () => {\n if (isUnsubscribed) return;\n isUnsubscribed = true;\n this.remove(subscriber);\n };\n }\n\n /**\n * Removes a subscriber using swap-and-pop optimization\n *\n * Linear search + O(1) swap-and-pop removal.\n * For small arrays, this is faster than hash-based approaches\n * due to cache locality.\n *\n * @param subscriber - Subscriber to remove\n * @returns True if removed, false if not found\n */\n remove(subscriber: T): boolean {\n if (!this.subscribers) {\n return false;\n }\n\n const idx = this.subscribers.indexOf(subscriber);\n if (idx === -1) {\n return false; // Not found\n }\n\n const lastIndex = this.subscribers.length - 1;\n\n // Swap with last element (O(1))\n if (idx !== lastIndex) {\n this.subscribers[idx] = this.subscribers[lastIndex]!;\n }\n\n // Pop last element (O(1))\n this.subscribers.pop();\n\n return true;\n }\n\n /**\n * Checks if a subscriber is registered\n *\n * @param subscriber - Subscriber to check\n * @returns True if registered\n */\n has(subscriber: T): boolean {\n if (!this.subscribers) return false;\n return this.subscribers.indexOf(subscriber) !== -1;\n }\n\n /**\n * Iterates over all subscribers with a callback\n *\n * Optimized for cache-friendly sequential access.\n * Errors in callbacks are propagated to the caller.\n *\n * @param fn - Callback to execute for each subscriber\n *\n * @example\n * ```ts\n * manager.forEach((subscriber) => {\n * subscriber(newValue, oldValue);\n * });\n * ```\n */\n forEach(fn: (subscriber: T, index: number) => void): void {\n if (!this.subscribers) return;\n\n for (let i = 0; i < this.subscribers.length; i++) {\n fn(this.subscribers[i]!, i);\n }\n }\n\n /**\n * Safely iterates over subscribers with error handling\n *\n * Catches and logs errors from individual callbacks to prevent\n * one failing subscriber from breaking the entire notification chain.\n *\n * @param fn - Callback to execute for each subscriber\n * @param onError - Optional error handler for each callback error\n */\n forEachSafe(fn: (subscriber: T, index: number) => void, onError?: (error: Error) => void): void {\n if (!this.subscribers) return;\n\n for (let i = 0; i < this.subscribers.length; i++) {\n try {\n fn(this.subscribers[i]!, i);\n } catch (error) {\n if (onError) {\n onError(error as Error);\n } else {\n console.error('[SubscriberManager] Error in subscriber callback:', error);\n }\n }\n }\n }\n\n /**\n * Gets the current number of subscribers\n *\n * @returns Number of active subscribers\n */\n get size(): number {\n return this.subscribers?.length ?? 0;\n }\n\n /**\n * Checks if there are any subscribers\n *\n * @returns True if at least one subscriber exists\n */\n get hasSubscribers(): boolean {\n return this.size > 0;\n }\n\n /**\n * Clears all subscribers\n *\n * Removes all subscribers and releases memory.\n * Subsequent operations will re-initialize lazily.\n */\n clear(): void {\n this.subscribers = null;\n }\n\n /**\n * Gets a copy of all subscribers as an array\n *\n * Useful for debugging or manual iteration.\n * Returns empty array if no subscribers.\n *\n * @returns Array of all subscribers\n */\n toArray(): T[] {\n return this.subscribers ? [...this.subscribers] : [];\n }\n}\n","/**\n * @fileoverview atom: Core reactive state primitive\n *\n * Atoms are the fundamental building blocks of the reactive system.\n * They hold mutable state and automatically notify subscribers when their value changes.\n *\n * @example\n * ```ts\n * const count = atom(0);\n * count.value = 1; // Triggers subscribers\n * console.log(count.peek()); // 1 (without tracking)\n * ```\n */\n\nimport { SMI_MAX } from '../../constants';\nimport { AtomError } from '../../errors/errors';\nimport { ERROR_MESSAGES } from '../../errors/messages';\nimport { scheduler } from '../../scheduler';\nimport { trackingContext } from '../../tracking';\nimport type { AtomOptions, Subscriber, WritableAtom } from '../../types';\nimport { debug, generateId } from '../../utils/debug';\nimport { SubscriberManager } from '../../utils/subscriber-manager';\n\n/**\n * Internal implementation of the WritableAtom interface.\n *\n * @template T - The type of value stored in the atom\n *\n * @remarks\n * This class manages reactive state with optimized subscriber management.\n * It supports both function-based and object-based subscribers, and handles\n * synchronous or batched notifications based on configuration.\n */\nclass AtomImpl<T> implements WritableAtom<T> {\n // === Smi Fields (Fixed Order for V8 Hidden Class) ===\n /** Unique numerical identifier (Smi) */\n readonly id: number;\n\n /** Version counter for change detection (Smi) */\n version: number;\n\n /** Internal flags (Smi) */\n flags: number;\n\n /** Last seen epoch for dependency collection (Smi) */\n _lastSeenEpoch: number;\n\n // === Object Fields ===\n /** Current value stored in the atom */\n private _value: T;\n\n /** Manager for function-based subscribers */\n private readonly _functionSubscribers: SubscriberManager<(newValue?: T, oldValue?: T) => void>;\n\n /** Manager for object-based subscribers with execute method */\n private readonly _objectSubscribers: SubscriberManager<Subscriber>;\n\n /** Whether notifications should be synchronous (bypass scheduler batching) */\n private readonly _sync: boolean;\n\n /** Bound notification method to avoid closure allocation */\n private readonly _notifyTask: () => void;\n\n /** Pending old value for coalesced notifications */\n private _pendingOldValue: T | undefined;\n\n /** Whether a notification task is currently scheduled */\n private _isNotificationScheduled: boolean = false;\n\n /**\n * Creates a new AtomImpl instance.\n *\n * @param initialValue - The initial value of the atom\n * @param sync - Whether to notify subscribers synchronously\n */\n constructor(initialValue: T, sync: boolean) {\n // 1. Smi Fields Initialization\n this.id = generateId() & SMI_MAX;\n this.version = 0;\n this.flags = 0;\n this._lastSeenEpoch = -1;\n\n // 2. Object Fields Initialization\n this._value = initialValue;\n this._functionSubscribers = new SubscriberManager();\n this._objectSubscribers = new SubscriberManager();\n this._sync = sync;\n this._notifyTask = this._flushNotifications.bind(this);\n\n debug.attachDebugInfo(this, 'atom', this.id);\n }\n\n /**\n * Gets the current value and registers the atom as a dependency\n * in the current tracking context.\n *\n * @returns The current value\n *\n * @remarks\n * This getter automatically tracks dependencies when accessed within\n * a computed or effect context.\n */\n get value(): T {\n const current = trackingContext.getCurrent();\n if (current !== null && current !== undefined) {\n this._track(current);\n }\n return this._value;\n }\n\n /**\n * Sets a new value and notifies all subscribers if the value changed.\n *\n * @param newValue - The new value to set\n *\n * @remarks\n * Uses Object.is for equality comparison. If the value is unchanged,\n * no notifications are sent. Notifications may be batched unless\n * sync mode is enabled.\n */\n set value(newValue: T) {\n if (Object.is(this._value, newValue)) return;\n\n const oldValue = this._value;\n // Smi masked increment\n this.version = (this.version + 1) & SMI_MAX;\n const currentVersion = this.version;\n this._value = newValue;\n\n if (!this._functionSubscribers.hasSubscribers && !this._objectSubscribers.hasSubscribers)\n return;\n\n this._notify(newValue, oldValue, currentVersion);\n }\n\n /**\n * Tracks the current context as a dependency of this atom.\n *\n * @param current - The current tracking context (function or object)\n *\n * @remarks\n * Handles both function-based trackers (with optional addDependency method)\n * and object-based trackers (with execute or addDependency methods).\n */\n private _track(current: unknown): void {\n if (typeof current === 'function') {\n const fnWithDep = current as { addDependency?: (dep: unknown) => void };\n if (fnWithDep.addDependency !== undefined) {\n fnWithDep.addDependency(this);\n } else {\n this._functionSubscribers.add(current as (newValue?: T, oldValue?: T) => void);\n }\n } else {\n const tracker = current as { execute?: () => void; addDependency?: (dep: unknown) => void };\n if (tracker.addDependency !== undefined) {\n tracker.addDependency(this);\n } else if (tracker.execute !== undefined) {\n this._objectSubscribers.add(tracker as Subscriber);\n }\n }\n }\n\n /**\n * Notifies all subscribers of a value change.\n *\n * @param newValue - The new value\n * @param oldValue - The previous value\n * @param currentVersion - The version at the time of change\n *\n * @remarks\n * Notifications are skipped if the version has changed (stale update).\n * Errors from individual subscribers are caught and logged without\n * interrupting other subscribers.\n */\n /**\n * Schedules a notification.\n * Uses coalescing: if a notification is already scheduled, we update the state\n * but don't schedule a new task. The pending task will see the latest value.\n */\n private _notify(_newValue: T, oldValue: T, _currentVersion: number): void {\n if (!this._isNotificationScheduled) {\n this._pendingOldValue = oldValue;\n this._isNotificationScheduled = true;\n // We don't need to store currentVersion because the flush task\n // will always read the latest version and value.\n }\n\n if (this._sync && !scheduler.isBatching) {\n this._flushNotifications();\n } else {\n scheduler.schedule(this._notifyTask);\n }\n }\n\n /**\n * Executes the pending notifications.\n * Bound to 'this' in constructor to avoid closure allocation.\n */\n private _flushNotifications(): void {\n if (!this._isNotificationScheduled) return;\n\n // Capture state and reset flags BEFORE notifying to handle re-entrancy\n const oldValue = this._pendingOldValue as T;\n const newValue = this._value;\n\n this._pendingOldValue = undefined;\n this._isNotificationScheduled = false;\n\n this._functionSubscribers.forEachSafe(\n (sub) => sub(newValue, oldValue),\n (err) =>\n console.error(new AtomError(ERROR_MESSAGES.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, err as Error))\n );\n\n this._objectSubscribers.forEachSafe(\n (sub) => sub.execute(),\n (err) =>\n console.error(new AtomError(ERROR_MESSAGES.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, err as Error))\n );\n }\n\n /**\n * Subscribes a listener function to value changes.\n *\n * @param listener - Function to call when the value changes\n * @returns An unsubscribe function\n * @throws {AtomError} If listener is not a function\n *\n * @example\n * ```ts\n * const unsub = myAtom.subscribe((newVal, oldVal) => {\n * console.log(`Changed from ${oldVal} to ${newVal}`);\n * });\n * // Later: unsub();\n * ```\n */\n subscribe(listener: (newValue?: T, oldValue?: T) => void): () => void {\n if (typeof listener !== 'function') {\n throw new AtomError(ERROR_MESSAGES.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);\n }\n return this._functionSubscribers.add(listener);\n }\n\n /**\n * Gets the current value without registering as a dependency.\n *\n * @returns The current value\n *\n * @remarks\n * Use this method when you need to read the value without\n * creating a reactive dependency (e.g., in event handlers).\n */\n peek(): T {\n return this._value;\n }\n\n /**\n * Disposes the atom, clearing all subscribers and releasing resources.\n *\n * @remarks\n * After disposal, the atom should not be used. The value is set to\n * undefined to help with garbage collection.\n */\n dispose(): void {\n this._functionSubscribers.clear();\n this._objectSubscribers.clear();\n this._value = undefined as T;\n }\n\n /**\n * Gets the total number of active subscribers.\n *\n * @returns The count of function and object subscribers combined\n */\n subscriberCount(): number {\n return this._functionSubscribers.size + this._objectSubscribers.size;\n }\n}\n\n/**\n * Creates a new atom with the given initial value.\n *\n * @template T - The type of value stored in the atom\n * @param initialValue - The initial value of the atom\n * @param options - Optional configuration options\n * @returns A writable atom instance\n *\n * @example\n * ```ts\n * // Basic usage\n * const count = atom(0);\n *\n * // With sync option for immediate notifications\n * const syncCount = atom(0, { sync: true });\n *\n * // Reading and writing\n * console.log(count.value); // 0\n * count.value = 5;\n * console.log(count.peek()); // 5 (non-tracking read)\n * ```\n */\nexport function atom<T>(initialValue: T, options: AtomOptions = {}): WritableAtom<T> {\n return new AtomImpl(initialValue, options.sync ?? false);\n}\n","import { SMI_MAX } from './constants';\n\nlet collectorEpoch = 0;\n\nexport function nextEpoch(): number {\n collectorEpoch = ((collectorEpoch + 1) | 0) & SMI_MAX;\n return collectorEpoch;\n}\n\nexport function currentEpoch(): number {\n return collectorEpoch;\n}\n","export const __DEV__ = process.env.NODE_ENV !== 'production';\n\n// Scheduler & Atom interfaces to prevent circular deps\nexport interface IScheduler<T> {\n markDirty(atom: T): void;\n scheduleNotify(atom: T): void;\n}\n\nexport interface IAtom {\n readonly id: number;\n version: number;\n _internalNotifySubscribers(): void;\n recompute?(): void;\n}\n\nexport interface PoolStats {\n acquired: number;\n released: number;\n rejected: { frozen: number; tooLarge: number; poolFull: number };\n leaked: number;\n poolSize: number;\n}\n","import type { Dependency, Subscriber } from './types';\nimport type { PoolStats } from './types/internal';\nimport { __DEV__ } from './types/internal';\n\n// ⚡ Shared Constants\nexport const EMPTY_DEPS: readonly Dependency[] = Object.freeze([]);\nexport const EMPTY_SUBS: readonly Subscriber[] = Object.freeze([]);\n\n/**\n * Generic Array Pool (Type-safe pooling for different array types)\n */\nclass ArrayPool<T> {\n private pool: T[][] = [];\n private readonly maxPoolSize = 50;\n private readonly maxReusableCapacity = 256;\n\n private stats = __DEV__\n ? {\n acquired: 0,\n released: 0,\n rejected: { frozen: 0, tooLarge: 0, poolFull: 0 },\n }\n : null;\n\n acquire(): T[] {\n if (__DEV__ && this.stats) this.stats.acquired++;\n return this.pool.pop() ?? [];\n }\n\n release(arr: T[], emptyConst?: readonly T[]): void {\n // ⚡ 1. Reference check first\n if (emptyConst && arr === emptyConst) return;\n\n // ⚡ 2. Frozen check\n if (Object.isFrozen(arr)) {\n if (__DEV__ && this.stats) this.stats.rejected.frozen++;\n return;\n }\n\n // 3. Size check\n if (arr.length > this.maxReusableCapacity) {\n if (__DEV__ && this.stats) this.stats.rejected.tooLarge++;\n return;\n }\n\n // 4. Pool capacity check\n if (this.pool.length >= this.maxPoolSize) {\n if (__DEV__ && this.stats) this.stats.rejected.poolFull++;\n return;\n }\n\n // 5. Normal release\n arr.length = 0;\n this.pool.push(arr);\n if (__DEV__ && this.stats) this.stats.released++;\n }\n\n getStats(): PoolStats | null {\n if (!__DEV__ || !this.stats) return null;\n const { acquired, released, rejected } = this.stats;\n const totalRejected = rejected.frozen + rejected.tooLarge + rejected.poolFull;\n return {\n acquired,\n released,\n rejected,\n leaked: acquired - released - totalRejected,\n poolSize: this.pool.length,\n };\n }\n\n reset(): void {\n this.pool.length = 0;\n if (__DEV__ && this.stats) {\n this.stats.acquired = 0;\n this.stats.released = 0;\n this.stats.rejected = { frozen: 0, tooLarge: 0, poolFull: 0 };\n }\n }\n}\n\n// ⚡ Per-type Pool Instances (V8 Shape Optimization)\nexport const depArrayPool = new ArrayPool<Dependency>();\nexport const subArrayPool = new ArrayPool<Subscriber>();\n","/**\n * @fileoverview computed: Derived reactive state with automatic dependency tracking\n * @description Creates computed values that automatically update when dependencies change (sync/async support)\n * @optimized Class-based architecture with cache locality and branchless patterns\n */\n\nimport { AsyncState, COMPUTED_STATE_FLAGS, SMI_MAX } from '../../constants';\nimport { nextEpoch } from '../../epoch';\nimport type { AtomError } from '../../errors/errors';\nimport { ComputedError, isPromise, wrapError } from '../../errors/errors';\nimport { ERROR_MESSAGES } from '../../errors/messages';\nimport { depArrayPool, EMPTY_DEPS } from '../../pool';\nimport { type SchedulerJob, scheduler } from '../../scheduler';\nimport { trackingContext } from '../../tracking';\nimport type { DependencyTracker } from '../../tracking/tracking.types';\n\nimport type {\n AsyncStateType,\n ComputedAtom,\n ComputedOptions,\n Dependency,\n Subscriber,\n} from '../../types';\nimport { debug, generateId, NO_DEFAULT_VALUE } from '../../utils/debug';\nimport { SubscriberManager } from '../../utils/subscriber-manager';\n\ntype TrackableListener = (() => void) & {\n addDependency: (dep: unknown) => void;\n};\n\n/**\n * Optimized ComputedAtom implementation with class-based architecture\n *\n * Key optimizations:\n * - Cache-friendly field layout (hot fields first)\n * - Inline bit flags (no separate class instance)\n * - Branchless fast path for value access\n * - Reduced indirection and closure overhead\n *\n * @template T - The type of the computed value\n */\nclass ComputedAtomImpl<T> implements ComputedAtom<T> {\n // === Smi Fields (Fixed Order for V8 Hidden Class) ===\n /** Unique numerical identifier (Smi) */\n readonly id: number;\n\n /** Version counter for change detection (Smi) */\n version: number;\n\n /** Internal flags (Smi) */\n flags: number;\n\n /** Last seen epoch for dependency collection (Smi) */\n _lastSeenEpoch: number;\n\n // === HOT PATH: Most frequently accessed fields (cache line 1) ===\n private _value: T;\n private _stateFlags: number;\n\n // === WARM PATH: Frequently accessed fields (cache line 2) ===\n private _error: AtomError | null;\n private _promiseId: number;\n private readonly _equal: (a: T, b: T) => boolean;\n\n // === COLD PATH: Infrequently accessed fields ===\n private readonly _fn: () => T | Promise<T>;\n private readonly _defaultValue: T;\n private readonly _hasDefaultValue: boolean;\n private readonly _onError: ((error: Error) => void) | null;\n private readonly _functionSubscribers: SubscriberManager<() => void>;\n private readonly _objectSubscribers: SubscriberManager<Subscriber>;\n private _dependencies: Dependency[];\n private readonly _subscriptions: Map<number, () => void>;\n\n private readonly _recomputeJob: SchedulerJob;\n private readonly _notifyJob: SchedulerJob;\n\n private readonly _trackable: TrackableListener;\n // private readonly _id: number; // Replaced by public id\n private readonly MAX_PROMISE_ID: number;\n\n constructor(fn: () => T | Promise<T>, options: ComputedOptions<T> = {}) {\n if (typeof fn !== 'function') {\n throw new ComputedError(ERROR_MESSAGES.COMPUTED_MUST_BE_FUNCTION);\n }\n\n // 1. Smi Fields Initialization\n this.id = generateId() & SMI_MAX;\n this.version = 0;\n this.flags = 0;\n this._lastSeenEpoch = -1;\n\n // 2. Fixed order initialization (HOT PATH first)\n this._value = undefined as T;\n this._stateFlags = COMPUTED_STATE_FLAGS.DIRTY | COMPUTED_STATE_FLAGS.IDLE;\n\n // WARM PATH\n this._error = null;\n this._promiseId = 0;\n this._equal = options.equal ?? Object.is;\n\n // COLD PATH & Constants\n this._fn = fn;\n this._defaultValue = 'defaultValue' in options ? options.defaultValue : (NO_DEFAULT_VALUE as T);\n this._hasDefaultValue = this._defaultValue !== (NO_DEFAULT_VALUE as T);\n this._onError = options.onError ?? null;\n this.MAX_PROMISE_ID = Number.MAX_SAFE_INTEGER - 1;\n\n // Managers & Structures\n this._functionSubscribers = new SubscriberManager<() => void>();\n this._objectSubscribers = new SubscriberManager<Subscriber>();\n\n // Optimized Dependency Management\n this._dependencies = EMPTY_DEPS as Dependency[];\n this._subscriptions = new Map();\n\n this._recomputeJob = () => {\n if (this._isDirty()) {\n try {\n this._recompute();\n } catch {\n // Error already handled\n }\n }\n };\n\n this._notifyJob = () => {\n this._functionSubscribers.forEachSafe(\n (subscriber) => subscriber(),\n (err) => console.error(err)\n );\n\n this._objectSubscribers.forEachSafe(\n (subscriber) => subscriber.execute(),\n (err) => console.error(err)\n );\n };\n\n // Trackable closure for dependency collection\n // We bind it once to avoid allocation during recompute\n this._trackable = Object.assign(() => this._markDirty(), {\n addDependency: (_dep: unknown) => {\n // This is called by Atom.value getter via trackingContext\n // We'll handle the actual collection logic inside recompute's context\n // but here we just need to ensure it works if called directly?\n // Actually, trackingContext.run sets the current collector.\n // When Atom calls _track(current), current is this._trackable.\n // But we need the *active* collector buffer.\n // We can store the active buffer in a temporary field or rely on the fact\n // that _recompute sets up the collection environment.\n // See recompute implementation below.\n },\n });\n\n debug.attachDebugInfo(this as unknown as ComputedAtom<T>, 'computed', this.id);\n\n if (debug.enabled) {\n const debugObj = this as unknown as ComputedAtom<T> & {\n subscriberCount: () => number;\n isDirty: () => boolean;\n dependencies: Dependency[];\n stateFlags: string;\n };\n debugObj.subscriberCount = () =>\n this._functionSubscribers.size + this._objectSubscribers.size;\n debugObj.isDirty = () => this._isDirty();\n debugObj.dependencies = this._dependencies;\n debugObj.stateFlags = this._getFlagsAsString();\n }\n\n // Lazy check - normalized access\n if (options.lazy === false) {\n try {\n this._recompute();\n } catch {\n // Ignore initial computation failure for non-lazy computed\n }\n }\n }\n\n // === PUBLIC API ===\n\n get value(): T {\n // Branchless fast path: single bitwise check for (resolved AND not dirty)\n const isFastPath =\n (this._stateFlags & (COMPUTED_STATE_FLAGS.RESOLVED | COMPUTED_STATE_FLAGS.DIRTY)) ===\n COMPUTED_STATE_FLAGS.RESOLVED;\n\n if (isFastPath) {\n this._registerTracking();\n return this._value;\n }\n\n // Slow path: state transition required\n const result = this._computeValue();\n this._registerTracking();\n return result;\n }\n\n subscribe(listener: () => void): () => void {\n if (typeof listener !== 'function') {\n throw new ComputedError(ERROR_MESSAGES.COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION);\n }\n return this._functionSubscribers.add(listener);\n }\n\n peek(): T {\n return this._value;\n }\n\n get state(): AsyncStateType {\n return this._getAsyncState();\n }\n\n get hasError(): boolean {\n return this._isRejected();\n }\n\n get lastError(): Error | null {\n return this._error;\n }\n\n get isPending(): boolean {\n return this._isPending();\n }\n\n get isResolved(): boolean {\n return this._isResolved();\n }\n\n invalidate(): void {\n this._markDirty();\n }\n\n dispose(): void {\n // Unsubscribe from all dependencies\n // Iterate stored subscriptions\n // We cannot iterate WeakMap, but we know which deps we have in _dependencies (if still holding them)\n // Wait, _syncDependencies iterates _dependencies.\n // So current _dependencies can be used to unsubscribe.\n\n if (this._dependencies !== EMPTY_DEPS) {\n for (const dep of this._dependencies) {\n const unsub = this._subscriptions.get(dep.id);\n if (unsub) unsub();\n this._subscriptions.delete(dep.id);\n }\n depArrayPool.release(this._dependencies);\n }\n this._dependencies = EMPTY_DEPS as Dependency[];\n\n this._functionSubscribers.clear();\n this._objectSubscribers.clear();\n this._stateFlags = COMPUTED_STATE_FLAGS.DIRTY | COMPUTED_STATE_FLAGS.IDLE;\n this._error = null;\n this._value = undefined as T;\n this._promiseId = (this._promiseId + 1) % this.MAX_PROMISE_ID;\n }\n\n // === PRIVATE: State Flag Operations (inlined for performance) ===\n\n private _isDirty(): boolean {\n return (this._stateFlags & COMPUTED_STATE_FLAGS.DIRTY) !== 0;\n }\n\n private _setDirty(): void {\n this._stateFlags |= COMPUTED_STATE_FLAGS.DIRTY;\n }\n\n private _clearDirty(): void {\n this._stateFlags &= ~COMPUTED_STATE_FLAGS.DIRTY;\n }\n\n private _isIdle(): boolean {\n return (this._stateFlags & COMPUTED_STATE_FLAGS.IDLE) !== 0;\n }\n\n private _setIdle(): void {\n this._stateFlags |= COMPUTED_STATE_FLAGS.IDLE;\n this._stateFlags &= ~(\n COMPUTED_STATE_FLAGS.PENDING |\n COMPUTED_STATE_FLAGS.RESOLVED |\n COMPUTED_STATE_FLAGS.REJECTED\n );\n }\n\n private _isPending(): boolean {\n return (this._stateFlags & COMPUTED_STATE_FLAGS.PENDING) !== 0;\n }\n\n private _setPending(): void {\n this._stateFlags |= COMPUTED_STATE_FLAGS.PENDING;\n this._stateFlags &= ~(\n COMPUTED_STATE_FLAGS.IDLE |\n COMPUTED_STATE_FLAGS.RESOLVED |\n COMPUTED_STATE_FLAGS.REJECTED\n );\n }\n\n private _isResolved(): boolean {\n return (this._stateFlags & COMPUTED_STATE_FLAGS.RESOLVED) !== 0;\n }\n\n private _setResolved(): void {\n this._stateFlags |= COMPUTED_STATE_FLAGS.RESOLVED;\n this._stateFlags &= ~(\n COMPUTED_STATE_FLAGS.IDLE |\n COMPUTED_STATE_FLAGS.PENDING |\n COMPUTED_STATE_FLAGS.REJECTED |\n COMPUTED_STATE_FLAGS.HAS_ERROR\n );\n }\n\n private _isRejected(): boolean {\n return (this._stateFlags & COMPUTED_STATE_FLAGS.REJECTED) !== 0;\n }\n\n private _setRejected(): void {\n this._stateFlags |= COMPUTED_STATE_FLAGS.REJECTED | COMPUTED_STATE_FLAGS.HAS_ERROR;\n this._stateFlags &= ~(\n COMPUTED_STATE_FLAGS.IDLE |\n COMPUTED_STATE_FLAGS.PENDING |\n COMPUTED_STATE_FLAGS.RESOLVED\n );\n }\n\n private _isRecomputing(): boolean {\n return (this._stateFlags & COMPUTED_STATE_FLAGS.RECOMPUTING) !== 0;\n }\n\n private _setRecomputing(value: boolean): void {\n if (value) {\n this._stateFlags |= COMPUTED_STATE_FLAGS.RECOMPUTING;\n } else {\n this._stateFlags &= ~COMPUTED_STATE_FLAGS.RECOMPUTING;\n }\n }\n\n private _getAsyncState(): AsyncStateType {\n if (this._isPending()) return AsyncState.PENDING;\n if (this._isResolved()) return AsyncState.RESOLVED;\n if (this._isRejected()) return AsyncState.REJECTED;\n return AsyncState.IDLE;\n }\n\n private _getFlagsAsString(): string {\n const states: string[] = [];\n if (this._isDirty()) states.push('DIRTY');\n if (this._isIdle()) states.push('IDLE');\n if (this._isPending()) states.push('PENDING');\n if (this._isResolved()) states.push('RESOLVED');\n if (this._isRejected()) states.push('REJECTED');\n if (this._isRecomputing()) states.push('RECOMPUTING');\n return states.join(' | ');\n }\n\n // === PRIVATE: Core Computation Logic ===\n\n private _computeValue(): T {\n if (this._isRecomputing()) return this._value;\n if (this._isPending()) return this._handlePending();\n if (this._isRejected()) return this._handleRejected();\n\n if (this._isDirty() || this._isIdle()) {\n this._recompute();\n if (this._isPending()) {\n return this._handlePending();\n }\n }\n\n return this._value;\n }\n\n private _recompute(): void {\n if (!this._isDirty() && this._isResolved()) {\n return;\n }\n\n this._setRecomputing(true);\n\n const prevDeps = this._dependencies;\n const nextDeps = depArrayPool.acquire();\n const epoch = nextEpoch();\n\n let depCount = 0;\n\n // Collector function (closure-free if possible, but we need closure for nextDeps capture)\n // To allow `_trackable.addDependency` to work, we need to wire it up.\n // We override `addDependency` of `_trackable` temporarily?\n // Or we use a scoped collector.\n\n const collect = (dep: Dependency) => {\n // O(1) deduplication check\n if (dep._lastSeenEpoch === epoch) return;\n dep._lastSeenEpoch = epoch;\n\n // Add to buffer\n if (depCount < nextDeps.length) {\n nextDeps[depCount] = dep;\n } else {\n nextDeps.push(dep);\n }\n depCount++;\n };\n\n // Store original addDependency to restore later (or use a dedicated collector object)\n const originalAdd = this._trackable.addDependency;\n this._trackable.addDependency = collect as (dep: unknown) => void;\n\n let committed = false;\n\n try {\n const result = trackingContext.run(this._trackable, this._fn);\n\n // Trim array to actual count\n nextDeps.length = depCount;\n\n if (isPromise(result)) {\n // Sync dependencies before awaiting\n this._syncDependencies(prevDeps, nextDeps, epoch);\n this._dependencies = nextDeps;\n committed = true;\n\n this._handleAsyncComputation(result);\n this._setRecomputing(false);\n return;\n }\n\n // Sync dependencies for synchronous result\n this._syncDependencies(prevDeps, nextDeps, epoch);\n this._dependencies = nextDeps;\n committed = true;\n\n this._handleSyncResult(result);\n } catch (err) {\n // On error, we must still sync dependencies that were collected up to the error point.\n // This ensures that if a dependency caused the error (or was accessed before),\n // we subscribe to it so we can recompute when it changes (recovery).\n\n nextDeps.length = depCount;\n this._syncDependencies(prevDeps, nextDeps, epoch);\n this._dependencies = nextDeps;\n committed = true;\n\n this._handleComputationError(err);\n } finally {\n this._trackable.addDependency = originalAdd;\n\n if (committed) {\n // Success: Release old deps\n if (prevDeps !== EMPTY_DEPS) {\n depArrayPool.release(prevDeps as Dependency[]);\n }\n } else {\n // Failure: Release new deps (unused)\n depArrayPool.release(nextDeps);\n }\n }\n }\n\n /**\n * Synchronizes subscriptions based on dependency changes.\n * O(N) Diff using Epoch.\n */\n private _syncDependencies(prevDeps: Dependency[], nextDeps: Dependency[], epoch: number): void {\n // 1. Unsubscribe removed dependencies\n if (prevDeps !== EMPTY_DEPS) {\n for (let i = 0; i < prevDeps.length; i++) {\n const dep = prevDeps[i];\n // Safety check for sparse arrays or strict null checks\n if (!dep) continue;\n\n // If lastSeenEpoch != epoch, it was NOT collected in this run -> Removed\n if (dep._lastSeenEpoch !== epoch) {\n const unsub = this._subscriptions.get(dep.id);\n if (unsub) {\n unsub();\n this._subscriptions.delete(dep.id);\n }\n }\n }\n }\n\n // 2. Subscribe to new dependencies\n for (let i = 0; i < nextDeps.length; i++) {\n const dep = nextDeps[i];\n if (!dep) continue;\n\n // Check if already subscribed\n if (!this._subscriptions.has(dep.id)) {\n // New dependency\n debug.checkCircular(dep, this as unknown as ComputedAtom<T>);\n // Subscription\n const unsub = dep.subscribe(() => this._markDirty());\n this._subscriptions.set(dep.id, unsub);\n }\n }\n }\n\n private _handleSyncResult(result: T): void {\n const shouldUpdate = !this._isResolved() || !this._equal(this._value, result);\n\n this._value = result;\n this._clearDirty();\n this._setResolved();\n this._error = null;\n this._setRecomputing(false);\n\n if (shouldUpdate) {\n this._notifySubscribers();\n }\n }\n\n private _handleAsyncComputation(promise: Promise<T>): void {\n this._setPending();\n\n // Branchless promise ID increment with overflow protection\n this._promiseId = this._promiseId >= this.MAX_PROMISE_ID ? 1 : this._promiseId + 1;\n const promiseId = this._promiseId;\n\n promise\n .then((resolvedValue) => {\n if (promiseId !== this._promiseId) return;\n this._handleAsyncResolution(resolvedValue);\n })\n .catch((err) => {\n if (promiseId !== this._promiseId) return;\n this._handleAsyncRejection(err);\n });\n }\n\n private _handleAsyncResolution(resolvedValue: T): void {\n const shouldUpdate = !this._isResolved() || !this._equal(this._value, resolvedValue);\n\n this._value = resolvedValue;\n this._clearDirty();\n this._setResolved();\n this._error = null;\n this._setRecomputing(false);\n\n if (shouldUpdate) {\n this._notifySubscribers();\n }\n }\n\n private _handleAsyncRejection(err: unknown): void {\n const error = wrapError(err, ComputedError, ERROR_MESSAGES.COMPUTED_ASYNC_COMPUTATION_FAILED);\n\n this._error = error;\n this._setRejected();\n this._clearDirty();\n this._setRecomputing(false);\n\n if (this._onError && typeof this._onError === 'function') {\n try {\n this._onError(error);\n } catch (callbackError) {\n console.error(ERROR_MESSAGES.CALLBACK_ERROR_IN_ERROR_HANDLER, callbackError);\n }\n }\n\n this._notifySubscribers();\n }\n\n private _handleComputationError(err: unknown): never {\n const error = wrapError(err, ComputedError, ERROR_MESSAGES.COMPUTED_COMPUTATION_FAILED);\n\n this._error = error;\n this._setRejected();\n this._clearDirty();\n this._setRecomputing(false);\n\n if (this._onError && typeof this._onError === 'function') {\n try {\n this._onError(error);\n } catch (callbackError) {\n console.error(ERROR_MESSAGES.CALLBACK_ERROR_IN_ERROR_HANDLER, callbackError);\n }\n }\n\n throw error;\n }\n\n private _handlePending(): T {\n if (this._hasDefaultValue) {\n return this._defaultValue;\n }\n throw new ComputedError(ERROR_MESSAGES.COMPUTED_ASYNC_PENDING_NO_DEFAULT);\n }\n\n private _handleRejected(): T {\n if (this._error?.recoverable && this._hasDefaultValue) {\n return this._defaultValue;\n }\n throw this._error;\n }\n\n // === PRIVATE: Dependency Management ===\n // (Replaced by _syncDependencies and inline pool logic)\n\n // === PRIVATE: Subscriber Management ===\n\n private _markDirty(): void {\n if (this._isRecomputing() || this._isDirty()) return;\n\n this._setDirty();\n this._setIdle();\n\n if (this._functionSubscribers.hasSubscribers || this._objectSubscribers.hasSubscribers) {\n scheduler.schedule(this._recomputeJob);\n }\n }\n\n private _notifySubscribers(): void {\n if (!this._functionSubscribers.hasSubscribers && !this._objectSubscribers.hasSubscribers) {\n return;\n }\n\n scheduler.schedule(this._notifyJob);\n }\n\n private _registerTracking(): void {\n const current = trackingContext.getCurrent();\n if (!current) return;\n\n // Check for addDependency first to support TrackableListener\n if (\n typeof current === 'object' &&\n current !== null &&\n (current as DependencyTracker).addDependency\n ) {\n (current as DependencyTracker).addDependency!(this as unknown as ComputedAtom<T>);\n } else if (typeof current === 'function') {\n const fnWithDep = current as TrackableListener;\n if (fnWithDep.addDependency) {\n fnWithDep.addDependency(this as unknown as ComputedAtom<T>);\n } else {\n this._functionSubscribers.add(current as () => void);\n }\n } else if ((current as DependencyTracker).execute) {\n this._objectSubscribers.add(current as Subscriber);\n }\n }\n}\n\n// Optimization: Freeze prototype to prevent shape changes\nObject.freeze(ComputedAtomImpl.prototype);\n\n/**\n * Creates a computed value that automatically tracks and reacts to dependencies\n *\n * Computed atoms are derived reactive state that:\n * - Automatically track dependencies accessed during computation\n * - Lazily recompute only when dependencies change (dirty checking)\n * - Support both synchronous and asynchronous computations\n * - Cache results until dependencies change (memoization)\n * - Use bit flags for efficient state management\n * - Provide async state tracking (idle/pending/resolved/rejected)\n *\n * @template T - The type of the computed value\n * @param fn - Computation function (can return T or Promise<T>)\n * @param options - Configuration options\n * @returns A readonly computed atom with automatic dependency tracking\n *\n * @example\n * ```ts\n * // Synchronous computed\n * const count = atom(0);\n * const doubled = computed(() => count.value * 2);\n *\n * // Asynchronous computed with default value\n * const userData = computed(\n * async () => fetch(`/api/user/${userId.value}`).then(r => r.json()),\n * { defaultValue: null }\n * );\n * ```\n */\nexport function computed<T>(fn: () => T, options?: ComputedOptions<T>): ComputedAtom<T>;\nexport function computed<T>(\n fn: () => Promise<T>,\n options: ComputedOptions<T> & { defaultValue: T }\n): ComputedAtom<T>;\nexport function computed<T>(\n fn: () => T | Promise<T>,\n options: ComputedOptions<T> = {}\n): ComputedAtom<T> {\n return new ComputedAtomImpl(fn, options) as unknown as ComputedAtom<T>;\n}\n","/**\n * @fileoverview Effect module for managing reactive side effects.\n *\n * This module provides a mechanism for creating and managing side effects\n * that automatically re-execute when their dependencies change. Effects\n * support cleanup functions, async operations, and infinite loop detection.\n */\n\nimport { EFFECT_STATE_FLAGS, SCHEDULER_CONFIG, SMI_MAX } from '../../constants';\nimport { nextEpoch } from '../../epoch';\nimport { EffectError, isPromise, wrapError } from '../../errors/errors';\nimport { ERROR_MESSAGES } from '../../errors/messages';\nimport { depArrayPool, EMPTY_DEPS } from '../../pool';\nimport { scheduler } from '../../scheduler';\nimport { type DependencyTracker, trackingContext } from '../../tracking';\nimport type { Dependency, EffectFunction, EffectObject, EffectOptions } from '../../types';\nimport { debug, generateId } from '../../utils/debug';\n\n/**\n * Internal implementation of the EffectObject interface.\n *\n * @remarks\n * This class manages reactive side effects with automatic dependency tracking,\n * cleanup handling, and infinite loop detection. It implements both EffectObject\n * for public API and DependencyTracker for integration with the tracking system.\n *\n * Key features:\n * - Automatic dependency tracking during execution\n * - Support for synchronous and scheduled (batched) execution\n * - Cleanup function support for resource management\n * - Infinite loop detection with configurable threshold\n * - Optional modification tracking for debugging\n *\n * @implements {EffectObject}\n * @implements {DependencyTracker}\n */\nclass EffectImpl implements EffectObject, DependencyTracker {\n // === Smi Fields (Fixed Order for V8 Hidden Class) ===\n private readonly _id: number;\n private _flags: number;\n // Effect is not a dependency, so it doesn't need _lastSeenEpoch for itself.\n // But we use _epoch during execution to track collected dependencies.\n private _currentEpoch: number;\n\n private readonly _fn: EffectFunction;\n private readonly _sync: boolean;\n private readonly _maxExecutions: number;\n private readonly _trackModifications: boolean;\n\n private _cleanup: (() => void) | null;\n\n // Optimized Dependency Management\n private _dependencies: Dependency[];\n private readonly _subscriptions: Map<number, () => void>;\n\n // Execution State\n private _nextDeps: Dependency[] | null;\n private readonly _modifiedDeps: Set<unknown>;\n private readonly _history: Float64Array;\n private _historyIdx: number;\n private _historyCount: number;\n private _executionCount: number;\n private readonly _historyCapacity: number;\n\n constructor(fn: EffectFunction, options: EffectOptions = {}) {\n this._id = generateId() & SMI_MAX;\n this._flags = 0;\n this._currentEpoch = -1;\n\n this._fn = fn;\n this._sync = options.sync ?? false;\n this._maxExecutions =\n options.maxExecutionsPerSecond ?? SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_SECOND;\n this._trackModifications = options.trackModifications ?? false;\n\n this._cleanup = null;\n\n // Dependencies\n this._dependencies = EMPTY_DEPS as Dependency[];\n this._subscriptions = new Map();\n this._nextDeps = null;\n\n this._modifiedDeps = new Set();\n\n this._historyCapacity = this._maxExecutions + 5;\n this._history = new Float64Array(this._historyCapacity);\n this._historyIdx = 0;\n this._historyCount = 0;\n this._executionCount = 0;\n\n debug.attachDebugInfo(this, 'effect', this._id);\n }\n\n /**\n * Manually triggers the effect to run.\n *\n * @throws {EffectError} If the effect has been disposed\n *\n * @remarks\n * This method is typically used when you need to force an effect to\n * re-execute outside of its normal dependency-triggered execution cycle.\n *\n * @example\n * ```typescript\n * const fx = effect(() => console.log(counter.value));\n * // Later, force re-execution:\n * fx.run();\n * ```\n */\n public run = (): void => {\n if (this.isDisposed) {\n throw new EffectError(ERROR_MESSAGES.EFFECT_MUST_BE_FUNCTION);\n }\n this.execute();\n };\n\n /**\n * Disposes of the effect, cleaning up all resources and subscriptions.\n *\n * @remarks\n * After disposal:\n * - The cleanup function is called (if any)\n * - All dependency subscriptions are removed\n * - Modification tracking descriptors are restored to their original state\n * - The effect will no longer execute\n *\n * This method is idempotent - calling it multiple times has no additional effect.\n *\n * @example\n * ```typescript\n * const fx = effect(() => console.log(counter.value));\n * // Later, when the effect is no longer needed:\n * fx.dispose();\n * ```\n */\n public dispose = (): void => {\n if (this.isDisposed) return;\n\n this._setDisposed();\n this._safeCleanup();\n\n // Unsubscribe all\n if (this._dependencies !== EMPTY_DEPS) {\n for (const dep of this._dependencies) {\n const unsub = this._subscriptions.get(dep.id);\n if (unsub) unsub();\n this._subscriptions.delete(dep.id);\n }\n depArrayPool.release(this._dependencies);\n this._dependencies = EMPTY_DEPS as Dependency[];\n }\n };\n\n /**\n * Adds a dependency to this effect's tracking list.\n *\n * @param dep - The dependency to track (must implement Dependency interface)\n *\n * @throws {EffectError} If subscription to the dependency fails\n *\n * @remarks\n * This method is called automatically by the tracking context when\n * a reactive value is accessed during effect execution. It sets up\n * a subscription so the effect re-executes when the dependency changes.\n *\n * If modification tracking is enabled and the dependency is an atom,\n * additional tracking is set up to detect read-after-write patterns.\n *\n * @internal\n */\n public addDependency = (dep: unknown): void => {\n // Stage 1: Collect into buffer (nextDeps)\n if (this.isExecuting && this._nextDeps) {\n const d = dep as Dependency;\n const epoch = this._currentEpoch;\n\n // O(1) deduplication via Epoch\n if (d._lastSeenEpoch === epoch) return;\n d._lastSeenEpoch = epoch;\n\n this._nextDeps.push(d);\n\n // Eagerly subscribe to catch synchronous updates\n if (!this._subscriptions.has(d.id)) {\n this._subscribeTo(d);\n }\n }\n };\n\n /**\n * Executes the effect function, tracking dependencies and managing cleanup.\n *\n * @remarks\n * This method performs the following steps:\n * 1. Checks if the effect is disposed or already executing (guards against re-entrancy)\n * 2. Records the execution timestamp for infinite loop detection\n * 3. Runs any existing cleanup function\n * 4. Clears previous dependency subscriptions\n * 5. Executes the effect function within a tracking context\n * 6. Handles both sync and async cleanup functions\n *\n * If the effect function returns a Promise, the cleanup function is extracted\n * from the resolved value. Errors during execution are caught and logged.\n *\n * @example\n * ```typescript\n * const fx = effect(() => {\n * console.log(counter.value);\n * return () => console.log('cleanup');\n * });\n * fx.execute(); // Manually trigger execution\n * ```\n */\n public execute = (): void => {\n if (this.isDisposed || this.isExecuting) return;\n\n const now = Date.now();\n this._recordExecution(now);\n\n this._setExecuting(true);\n this._safeCleanup();\n this._modifiedDeps.clear();\n\n const prevDeps = this._dependencies;\n const nextDeps = depArrayPool.acquire();\n const epoch = nextEpoch();\n\n this._nextDeps = nextDeps;\n this._currentEpoch = epoch;\n\n let committed = false;\n\n try {\n const result = trackingContext.run(this, this._fn);\n\n // Commit dependencies\n this._syncDependencies(prevDeps, epoch);\n this._dependencies = nextDeps;\n committed = true;\n\n this._checkLoopWarnings();\n\n if (isPromise(result)) {\n result\n .then((asyncCleanup) => {\n if (!this.isDisposed && typeof asyncCleanup === 'function') {\n this._cleanup = asyncCleanup;\n }\n })\n .catch((error) => {\n console.error(wrapError(error, EffectError, ERROR_MESSAGES.EFFECT_EXECUTION_FAILED));\n });\n } else {\n this._cleanup = typeof result === 'function' ? result : null;\n }\n } catch (error) {\n // Commit partial dependencies for recovery (eager subscription already happened)\n this._syncDependencies(prevDeps, epoch);\n this._dependencies = nextDeps;\n committed = true;\n\n console.error(wrapError(error, EffectError, ERROR_MESSAGES.EFFECT_EXECUTION_FAILED));\n this._cleanup = null;\n } finally {\n this._setExecuting(false);\n this._nextDeps = null;\n\n if (committed) {\n if (prevDeps !== EMPTY_DEPS) {\n depArrayPool.release(prevDeps);\n }\n } else {\n depArrayPool.release(nextDeps);\n }\n }\n };\n\n /**\n * Synchronizes subscriptions by unsubscribing from removed dependencies.\n * Uses epoch-based O(N) diff to identify stale dependencies.\n *\n * @param prevDeps - Previous dependency array\n * @param epoch - Current execution epoch for staleness detection\n */\n private _syncDependencies(prevDeps: Dependency[], epoch: number): void {\n if (prevDeps !== EMPTY_DEPS) {\n for (let i = 0; i < prevDeps.length; i++) {\n const dep = prevDeps[i];\n if (!dep) continue;\n\n if (dep._lastSeenEpoch !== epoch) {\n const unsub = this._subscriptions.get(dep.id);\n if (unsub) {\n unsub();\n this._subscriptions.delete(dep.id);\n }\n }\n }\n }\n }\n\n private _subscribeTo(dep: Dependency): void {\n try {\n const unsubscribe = dep.subscribe(() => {\n if (this._trackModifications && this.isExecuting) {\n this._modifiedDeps.add(dep);\n }\n\n if (this._sync) {\n this.execute();\n } else {\n scheduler.schedule(this.execute);\n }\n });\n this._subscriptions.set(dep.id, unsubscribe);\n } catch (error) {\n console.error(wrapError(error, EffectError, ERROR_MESSAGES.EFFECT_EXECUTION_FAILED));\n }\n }\n\n /**\n * Indicates whether this effect has been disposed.\n *\n * @returns `true` if the effect has been disposed, `false` otherwise\n *\n * @remarks\n * A disposed effect will not execute and cannot be reactivated.\n * Use this property to check if the effect is still active before\n * performing operations that depend on it.\n *\n * @example\n * ```typescript\n * const fx = effect(() => console.log(counter.value));\n * console.log(fx.isDisposed); // false\n * fx.dispose();\n * console.log(fx.isDisposed); // true\n * ```\n */\n get isDisposed(): boolean {\n return (this._flags & EFFECT_STATE_FLAGS.DISPOSED) !== 0;\n }\n\n /**\n * Returns the total number of times this effect has been executed.\n *\n * @returns The cumulative execution count since the effect was created\n *\n * @remarks\n * This counter is useful for debugging, testing, and monitoring\n * effect behavior. It increments on every execution, regardless\n * of whether the execution succeeds or fails.\n *\n * @example\n * ```typescript\n * const fx = effect(() => console.log(counter.value));\n * console.log(fx.executionCount); // 1 (initial execution)\n * counter.value = 10;\n * console.log(fx.executionCount); // 2\n * ```\n */\n get executionCount(): number {\n return this._executionCount;\n }\n\n /**\n * Indicates whether this effect is currently executing.\n *\n * @returns `true` if the effect is mid-execution, `false` otherwise\n *\n * @remarks\n * This property is used internally to prevent re-entrant execution\n * (an effect triggering itself during its own execution). It can\n * also be useful for debugging to understand the effect's state.\n *\n * @example\n * ```typescript\n * const fx = effect(() => {\n * console.log('executing:', fx.isExecuting); // true\n * });\n * console.log(fx.isExecuting); // false (after execution completes)\n * ```\n */\n get isExecuting(): boolean {\n return (this._flags & EFFECT_STATE_FLAGS.EXECUTING) !== 0;\n }\n\n /**\n * Sets the disposed flag on this effect.\n *\n * @remarks\n * This is a low-level method that only sets the bit flag.\n * Use the public `dispose()` method for proper cleanup.\n *\n * @internal\n */\n private _setDisposed(): void {\n this._flags |= EFFECT_STATE_FLAGS.DISPOSED;\n }\n\n /**\n * Sets or clears the executing flag on this effect.\n *\n * @param value - `true` to mark as executing, `false` to clear\n *\n * @remarks\n * Uses bitwise operations for efficient flag manipulation.\n * This flag prevents re-entrant execution of the effect.\n *\n * @internal\n */\n private _setExecuting(value: boolean): void {\n if (value) this._flags |= EFFECT_STATE_FLAGS.EXECUTING;\n else this._flags &= ~EFFECT_STATE_FLAGS.EXECUTING;\n }\n\n /**\n * Safely executes the cleanup function if one exists.\n *\n * @remarks\n * This method:\n * - Checks if a cleanup function exists and is callable\n * - Wraps the cleanup call in a try-catch to prevent cleanup errors\n * from breaking the effect lifecycle\n * - Logs any cleanup errors to the console\n * - Clears the cleanup reference after execution\n *\n * @internal\n */\n private _safeCleanup(): void {\n if (this._cleanup && typeof this._cleanup === 'function') {\n try {\n this._cleanup();\n } catch (error) {\n console.error(wrapError(error, EffectError, ERROR_MESSAGES.EFFECT_CLEANUP_FAILED));\n }\n this._cleanup = null;\n }\n }\n\n /**\n * Records an execution timestamp and checks for infinite loop conditions.\n *\n * @param now - The current timestamp in milliseconds (from `Date.now()`)\n *\n * @remarks\n * This method implements a circular buffer to track recent execution\n * timestamps. If the number of executions within the last second exceeds\n * `_maxExecutions`, the effect is disposed and an error is thrown (in debug mode)\n * or logged (in production mode).\n *\n * The circular buffer approach provides O(1) insertion and efficient\n * memory usage for tracking execution history.\n *\n * @throws {EffectError} In debug mode, throws when infinite loop is detected\n *\n * @internal\n */\n private _recordExecution(now: number): void {\n if (this._maxExecutions <= 0) return;\n\n const oneSecondAgo = now - 1000;\n\n this._history[this._historyIdx] = now;\n this._historyIdx = (this._historyIdx + 1) % this._historyCapacity;\n if (this._historyCount < this._historyCapacity) {\n this._historyCount++;\n }\n this._executionCount++;\n\n let count = 0;\n let idx = (this._historyIdx - 1 + this._historyCapacity) % this._historyCapacity;\n\n for (let i = 0; i < this._historyCount; i++) {\n if (this._history[idx]! < oneSecondAgo) {\n break;\n }\n count++;\n idx = (idx - 1 + this._historyCapacity) % this._historyCapacity;\n }\n\n if (count > this._maxExecutions) {\n const message = `Effect executed ${count} times within 1 second. Infinite loop suspected`;\n const error = new EffectError(message);\n\n this.dispose();\n console.error(error);\n\n if (debug.enabled) {\n throw error;\n }\n }\n }\n\n /**\n * Checks for and warns about potential infinite loop patterns.\n *\n * @remarks\n * When modification tracking is enabled and debug mode is active,\n * this method checks if any dependencies were both read and modified\n * during the effect execution. Such patterns often lead to infinite loops.\n *\n * Warnings are only emitted in debug mode to avoid performance overhead\n * in production.\n *\n * @internal\n */\n private _checkLoopWarnings(): void {\n if (this._trackModifications && debug.enabled) {\n const dependencies = this._dependencies;\n for (let i = 0; i < dependencies.length; i++) {\n const dep = dependencies[i];\n if (dep && this._modifiedDeps.has(dep)) {\n debug.warn(\n true,\n `Effect is reading a dependency (${\n debug.getDebugName(dep) || 'unknown'\n }) that it just modified. Infinite loop may occur`\n );\n }\n }\n }\n }\n}\n\n/**\n * Creates a reactive effect that automatically re-executes when its dependencies change.\n *\n * @param fn - The effect function to execute. May return a cleanup function\n * or a Promise that resolves to a cleanup function.\n * @param options - Configuration options for the effect\n * @param options.sync - If true, re-executes synchronously on dependency changes.\n * Defaults to false (scheduled/batched execution).\n * @param options.maxExecutionsPerSecond - Maximum executions per second before\n * infinite loop detection triggers.\n * Defaults to `SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_SECOND`.\n * @param options.trackModifications - If true, tracks and warns about dependencies\n * that are both read and modified. Defaults to false.\n *\n * @returns An {@link EffectObject} with `run()`, `dispose()`, and state properties\n *\n * @throws {EffectError} If `fn` is not a function\n *\n * @remarks\n * Effects are the primary way to perform side effects in response to reactive\n * state changes. They automatically track which reactive values (atoms, computed)\n * are accessed during execution and re-run when those values change.\n *\n * The effect function may return a cleanup function that will be called before\n * the next execution or when the effect is disposed. This is useful for\n * cleaning up subscriptions, timers, or other resources.\n *\n * @example\n * Basic usage:\n * ```typescript\n * const counter = atom(0);\n *\n * const fx = effect(() => {\n * console.log('Counter:', counter.value);\n * });\n * // Logs: \"Counter: 0\"\n *\n * counter.value = 1;\n * // Logs: \"Counter: 1\"\n *\n * fx.dispose(); // Stop the effect\n * ```\n *\n * @example\n * With cleanup function:\n * ```typescript\n * const fx = effect(() => {\n * const timer = setInterval(() => console.log('tick'), 1000);\n * return () => clearInterval(timer); // Cleanup\n * });\n * ```\n *\n * @example\n * Synchronous execution:\n * ```typescript\n * const fx = effect(\n * () => console.log(counter.value),\n * { sync: true }\n * );\n * ```\n */\nexport function effect(fn: EffectFunction, options: EffectOptions = {}): EffectObject {\n if (typeof fn !== 'function') {\n throw new EffectError(ERROR_MESSAGES.EFFECT_MUST_BE_FUNCTION);\n }\n\n const effectInstance = new EffectImpl(fn, options);\n\n effectInstance.execute();\n\n return effectInstance;\n}\n","import type { ComputedAtom, EffectObject, ReadonlyAtom } from '../types';\nimport { debug } from './debug';\n\nexport function isAtom(obj: unknown): obj is ReadonlyAtom {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n 'value' in obj &&\n 'subscribe' in obj &&\n typeof (obj as Record<string, unknown>).subscribe === 'function'\n );\n}\n\nexport function isComputed(obj: unknown): obj is ComputedAtom {\n if (debug.enabled) {\n const debugType = debug.getDebugType(obj);\n if (debugType) {\n return debugType === 'computed';\n }\n }\n return (\n isAtom(obj) &&\n 'invalidate' in obj &&\n typeof (obj as Record<string, unknown>).invalidate === 'function'\n );\n}\n\nexport function isEffect(obj: unknown): obj is EffectObject {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n 'dispose' in obj &&\n 'run' in obj &&\n typeof (obj as Record<string, unknown>).dispose === 'function' &&\n typeof (obj as Record<string, unknown>).run === 'function'\n );\n}\n"],"names":["AsyncState","EFFECT_STATE_FLAGS","COMPUTED_STATE_FLAGS","POOL_CONFIG","SCHEDULER_CONFIG","DEBUG_CONFIG","SMI_MAX","AtomError","message","cause","recoverable","ComputedError","EffectError","SchedulerError","wrapError","error","ErrorClass","context","errorMessage","isPromise","value","ERROR_MESSAGES","count","Scheduler","callback","jobs","i","job","iterations","max","scheduler","batch","trackingContext","listener","fn","prev","untracked","DEBUG_NAME","DEBUG_ID","DEBUG_TYPE","NO_DEFAULT_VALUE","hasDependencies","obj","debug","condition","dep","current","visited","nestedDep","type","id","target","nextId","generateId","SubscriberManager","subscriber","isUnsubscribed","idx","lastIndex","onError","AtomImpl","initialValue","sync","newValue","oldValue","currentVersion","fnWithDep","tracker","_newValue","_currentVersion","sub","err","atom","options","collectorEpoch","nextEpoch","__DEV__","EMPTY_DEPS","ArrayPool","arr","emptyConst","acquired","released","rejected","totalRejected","depArrayPool","ComputedAtomImpl","_dep","debugObj","result","unsub","states","prevDeps","nextDeps","epoch","depCount","collect","originalAdd","committed","shouldUpdate","promise","promiseId","resolvedValue","callbackError","computed","EffectImpl","d","now","asyncCleanup","unsubscribe","oneSecondAgo","dependencies","effect","effectInstance","isAtom","isComputed","debugType","isEffect"],"mappings":"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"}
|