@but212/atom-effect 0.31.0 → 0.32.0
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 +21 -11
- package/dist/atom-effect.min.js +1 -1
- package/dist/atom-effect.min.js.map +1 -1
- package/dist/constants.d.ts +157 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/core/atom.d.ts +19 -0
- package/dist/core/atom.d.ts.map +1 -0
- package/dist/core/base.d.ts +136 -0
- package/dist/core/base.d.ts.map +1 -0
- package/dist/core/buffers.d.ts +113 -0
- package/dist/core/buffers.d.ts.map +1 -0
- package/dist/core/computed.d.ts +84 -0
- package/dist/core/computed.d.ts.map +1 -0
- package/dist/core/effect.d.ts +52 -0
- package/dist/core/effect.d.ts.map +1 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/lens.d.ts +102 -0
- package/dist/core/lens.d.ts.map +1 -0
- package/dist/core/scheduler.d.ts +145 -0
- package/dist/core/scheduler.d.ts.map +1 -0
- package/dist/core/tracking.d.ts +123 -0
- package/dist/core/tracking.d.ts.map +1 -0
- package/dist/errors.d.ts +163 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -488
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +1053 -937
- package/dist/index.mjs.map +1 -1
- package/dist/symbols.d.ts +30 -0
- package/dist/symbols.d.ts.map +1 -0
- package/dist/types.d.ts +259 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/debug.d.ts +20 -0
- package/dist/utils/debug.d.ts.map +1 -0
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/type-guards.d.ts +81 -0
- package/dist/utils/type-guards.d.ts.map +1 -0
- package/package.json +14 -13
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../src/constants.ts","../src/errors.ts","../src/utils/debug.ts","../src/core/buffers.ts","../src/symbols.ts","../src/utils/type-guards.ts","../src/core/tracking.ts","../src/core/base.ts","../src/core/scheduler.ts","../src/core/atom.ts","../src/core/computed.ts","../src/core/effect.ts","../src/core/lens.ts"],"sourcesContent":["/**\n * Internal State Flags for ReactiveNode.\n *\n * Managed as a 31-bit integer field (V8 SMI optimization).\n *\n * Bit Layout:\n * [0-7] - Shared Core (Disposed, Computed marker, etc.)\n * [8-15] - Computed States (Dirty, Recomputing, etc.)\n * [16-23] - Async Lifecycle (Idle, Pending, Resolved, Rejected)\n * [24-30] - Primitive Specific (Atom Sync, Effect Executing, etc.)\n */\nconst FLAGS = {\n // --- Shared Core (0-7) ---\n DISPOSED: 1 << 0,\n IS_COMPUTED: 1 << 1,\n\n // --- Computed Flags (8-15) ---\n DIRTY: 1 << 8,\n RECOMPUTING: 1 << 9,\n HAS_ERROR: 1 << 10,\n FORCE_COMPUTE: 1 << 11,\n\n // --- Async States (16-23) ---\n IDLE: 1 << 16,\n PENDING: 1 << 17,\n RESOLVED: 1 << 18,\n REJECTED: 1 << 19,\n\n // --- Atom Specific (24-27) ---\n ATOM_SYNC: 1 << 24,\n ATOM_NOTIFICATION_SCHEDULED: 1 << 25,\n\n // --- Effect Specific (28-30) ---\n EFFECT_EXECUTING: 1 << 28,\n} as const;\n\n/**\n * Compound Masks for fast bitwise clearing/checking.\n */\nexport const STATE_MASKS = Object.freeze({\n /** Matches all bits related to async states (Idle, Pending, Resolved, Rejected). */\n ASYNC_STATE: FLAGS.IDLE | FLAGS.PENDING | FLAGS.RESOLVED | FLAGS.REJECTED,\n /** Matches all flags that indicate a computed node is dirty or recomputing. */\n COMPUTED_DIRTY_MASK: FLAGS.DIRTY | FLAGS.RECOMPUTING | FLAGS.FORCE_COMPUTE,\n});\n\n/**\n * Async operation states for public API and high-level checks.\n */\nexport const AsyncState = Object.freeze({\n IDLE: 'idle',\n PENDING: 'pending',\n RESOLVED: 'resolved',\n REJECTED: 'rejected',\n});\n\n/**\n * Effect flags.\n */\nexport const EFFECT_STATE_FLAGS = Object.freeze({\n DISPOSED: FLAGS.DISPOSED,\n EXECUTING: FLAGS.EFFECT_EXECUTING,\n});\n\n/**\n * Computed flags.\n */\nexport const COMPUTED_STATE_FLAGS = Object.freeze({\n DISPOSED: FLAGS.DISPOSED,\n IS_COMPUTED: FLAGS.IS_COMPUTED,\n DIRTY: FLAGS.DIRTY,\n IDLE: FLAGS.IDLE,\n PENDING: FLAGS.PENDING,\n RESOLVED: FLAGS.RESOLVED,\n REJECTED: FLAGS.REJECTED,\n RECOMPUTING: FLAGS.RECOMPUTING,\n HAS_ERROR: FLAGS.HAS_ERROR,\n FORCE_COMPUTE: FLAGS.FORCE_COMPUTE,\n});\n\n/**\n * Writable Atom Flags.\n */\nexport const ATOM_STATE_FLAGS = Object.freeze({\n DISPOSED: FLAGS.DISPOSED,\n SYNC: FLAGS.ATOM_SYNC,\n NOTIFICATION_SCHEDULED: FLAGS.ATOM_NOTIFICATION_SCHEDULED,\n});\n\n/**\n * Scheduler configuration.\n */\nexport const SCHEDULER_CONFIG = Object.freeze({\n // Infinite loop protection\n MAX_EXECUTIONS_PER_SECOND: 1000,\n MAX_EXECUTIONS_PER_EFFECT: 100,\n\n // Batch processing limits to prevent blocking the main thread for too long\n MAX_EXECUTIONS_PER_FLUSH: 10000,\n MAX_FLUSH_ITERATIONS: 1000,\n MIN_FLUSH_ITERATIONS: 10,\n\n // Memory management\n BATCH_QUEUE_SHRINK_THRESHOLD: 1000,\n});\n\n/**\n * V8 Small Integer (SMI) max value.\n */\nexport const SMI_MAX = 0x3fffffff;\n\n/**\n * Debugging thresholds.\n */\nexport const DEBUG_CONFIG = Object.freeze({\n WARN_INFINITE_LOOP: true,\n EFFECT_FREQUENCY_WINDOW: 1000,\n LOOP_THRESHOLD: 100,\n});\n\n/**\n * Computed configuration.\n */\nexport const COMPUTED_CONFIG = Object.freeze({\n MAX_PROMISE_ID: SMI_MAX,\n});\n\n/**\n * Epoch sentinel values.\n */\nexport const EPOCH_CONSTANTS = Object.freeze({\n /** Uninitialized epoch marker. Used as initial value before any flush has occurred. */\n UNINITIALIZED: -1,\n /** Minimum valid epoch value after a counter reset. */\n MIN: 1,\n});\n\nlet runtimeDebug = false;\ntry {\n runtimeDebug = !!(\n (typeof globalThis !== 'undefined' &&\n (globalThis as { __ATOM_DEBUG__?: boolean }).__ATOM_DEBUG__) ||\n (typeof sessionStorage !== 'undefined' && sessionStorage.getItem('__ATOM_DEBUG__') === 'true')\n );\n} catch {}\n\n/**\n * Development environment flag.\n */\nexport const IS_DEV =\n (typeof process !== 'undefined' && process.env && process.env.NODE_ENV !== 'production') ||\n (typeof __DEV__ !== 'undefined' && !!__DEV__) ||\n // @ts-expect-error: import.meta.env is Vite-specific and may not be defined in all environments\n (typeof import.meta !== 'undefined' && import.meta.env && import.meta.env.DEV) ||\n runtimeDebug;\n\n// Fallback declarations for global environment variables\ndeclare const __DEV__: boolean;\n\nexport const EMPTY_ERROR_ARRAY: readonly Error[] = Object.freeze([]);\n","/**\n * Structured JSON representation of an AtomError.\n */\nexport interface AtomErrorJSON {\n name: string;\n message: string;\n code?: string | undefined;\n recoverable: boolean;\n stack?: string | undefined;\n cause?: unknown | undefined;\n}\n\n/**\n * Constructor type for Atom errors.\n */\nexport type AtomErrorConstructor = new (\n message: string,\n cause?: unknown,\n recoverable?: boolean,\n code?: string\n) => AtomError;\n\n/**\n * Base error class for the Atom system.\n * Designed for high performance, traceability, and cycle protection.\n */\nexport class AtomError extends Error {\n override readonly name: string = 'AtomError';\n\n constructor(\n message: string,\n public readonly cause: unknown = null,\n public readonly recoverable: boolean = true,\n public readonly code?: string\n ) {\n super(message);\n\n // Maintain a stable object shape for V8\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Returns the entire error chain as an array.\n * Includes the circular node if a cycle is detected.\n */\n getChain(): Array<AtomError | Error | unknown> {\n const cause = this.cause;\n if (cause === null || cause === undefined) return [this];\n\n const chain: Array<AtomError | Error | unknown> = [this];\n let current: unknown = cause;\n let seen: Set<unknown> | null = null;\n\n while (current !== null && current !== undefined) {\n chain.push(current);\n\n // Cycle detection after push to include the circular node in the chain\n if (current === this || seen?.has(current)) break;\n\n if (current instanceof AtomError) {\n current = current.cause;\n } else if (current instanceof Error) {\n current = (current as { cause?: unknown }).cause;\n } else {\n break;\n }\n\n // Initialize deep cycle detection only for long chains to minimize allocations\n if (chain.length > 3) {\n if (seen === null) {\n seen = new Set(chain);\n } else {\n seen.add(current);\n }\n }\n }\n return chain;\n }\n\n /**\n * Serializes the error to a structured object for logging.\n * Protected against circular references.\n */\n toJSON(seen?: Set<unknown>): AtomErrorJSON {\n const s = seen ?? new Set<unknown>();\n if (s.has(this)) {\n return {\n name: this.name,\n message: '[Circular Reference]',\n recoverable: this.recoverable,\n code: this.code,\n };\n }\n s.add(this);\n\n let causeJson: unknown = this.cause;\n if (causeJson instanceof AtomError) {\n causeJson = causeJson.toJSON(s);\n } else if (causeJson instanceof Error) {\n causeJson = {\n name: causeJson.name,\n message: causeJson.message,\n stack: causeJson.stack,\n cause: (causeJson as { cause?: unknown }).cause,\n };\n }\n\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n recoverable: this.recoverable,\n stack: this.stack,\n cause: causeJson,\n };\n }\n\n /**\n * Internal helper to format wrapped messages consistently.\n */\n static format(source: string, context: string, message: string): string {\n return `${source} (${context}): ${message}`;\n }\n}\n\n/** Thrown when a computation fails. */\nexport class ComputedError extends AtomError {\n override readonly name = 'ComputedError';\n}\n\n/** Thrown when an effect execution or cleanup fails. */\nexport class EffectError extends AtomError {\n override readonly name = 'EffectError';\n constructor(message: string, cause: unknown = null, recoverable = false, code?: string) {\n super(message, cause, recoverable, code);\n }\n}\n\n/** Thrown by the execution engine or scheduler. */\nexport class SchedulerError extends AtomError {\n override readonly name = 'SchedulerError';\n constructor(message: string, cause: unknown = null, recoverable = false, code?: string) {\n super(message, cause, recoverable, code);\n }\n}\n\n/**\n * Registry of standardized error messages.\n */\nexport const ERROR_MESSAGES = {\n // Computed Errors\n COMPUTED_MUST_BE_FUNCTION: 'Computed target must be a function',\n COMPUTED_ASYNC_PENDING_NO_DEFAULT: 'Async computation pending with no default value',\n COMPUTED_COMPUTATION_FAILED: 'Computation execution failed',\n COMPUTED_ASYNC_COMPUTATION_FAILED: 'Async computation execution failed',\n COMPUTED_CIRCULAR_DEPENDENCY: 'Circular dependency detected',\n COMPUTED_DISPOSED: 'Attempted to access disposed computed',\n\n // Atom Errors\n ATOM_SUBSCRIBER_MUST_BE_FUNCTION: 'Subscriber must be a function or Subscriber object',\n ATOM_INDIVIDUAL_SUBSCRIBER_FAILED: 'Subscriber execution failed',\n\n // Effect Errors\n EFFECT_MUST_BE_FUNCTION: 'Effect target must be a function',\n EFFECT_EXECUTION_FAILED: 'Effect execution failed',\n EFFECT_CLEANUP_FAILED: 'Effect cleanup failed',\n EFFECT_DISPOSED: 'Attempted to run disposed effect',\n\n // Scheduler Errors\n SCHEDULER_FLUSH_OVERFLOW: (max: number, dropped: number): string =>\n `Maximum flush iterations (${max}) exceeded. ${dropped} jobs dropped. Possible infinite loop.`,\n\n // System / Debug\n CALLBACK_ERROR_IN_ERROR_HANDLER: 'Exception encountered in onError handler',\n EFFECT_FREQUENCY_LIMIT_EXCEEDED:\n 'Effect executed too frequently within 1 second. Suspected infinite loop.',\n SCHEDULER_CALLBACK_MUST_BE_FUNCTION: 'Scheduler callback must be a function',\n SCHEDULER_END_BATCH_WITHOUT_START: 'endBatch() called without matching startBatch(). Ignoring.',\n BATCH_CALLBACK_MUST_BE_FUNCTION: 'Batch callback must be a function',\n} as const;\n\n/**\n * Wraps any value into the Atom error hierarchy, preserving the trace and context.\n *\n * @param error - The raw error or object thrown.\n * @param ErrorClass - The specific AtomError subclass to use.\n * @param context - Human-readable description of where the error occurred.\n */\nexport function wrapError(\n error: unknown,\n ErrorClass: AtomErrorConstructor,\n context: string\n): AtomError {\n // 1. AtomError (Chainable Trace)\n if (error instanceof AtomError) {\n return new ErrorClass(\n `${error.name} (${context}): ${error.message}`,\n error,\n error.recoverable,\n error.code\n );\n }\n\n // 2. Native Error\n if (error instanceof Error) {\n return new ErrorClass(`${error.name || 'Error'} (${context}): ${error.message}`, error);\n }\n\n // 3. Unknown Types (Raw Preservation)\n return new ErrorClass(`Unexpected error (${context}): ${String(error)}`, error);\n}\n","import { DEBUG_CONFIG, IS_DEV } from '@/constants';\nimport type { DebugConfig, DependencyId } from '@/types';\n\n/**\n * Debug symbols used to store metadata on objects without interfering with their normal properties.\n * These are exported to allow external inspection or custom debugging tools.\n */\n\n/** Symbol used to store and retrieve a human-readable name for an atom or effect. */\nexport const DEBUG_NAME = Symbol('AtomEffect.DebugName');\n/** Symbol used to store and retrieve the unique internal ID. */\nexport const DEBUG_ID = Symbol('AtomEffect.Id');\n/** Symbol used to store and retrieve the type identifier (e.g., 'atom', 'effect'). */\nexport const DEBUG_TYPE = Symbol('AtomEffect.Type');\n/** Symbol used as a sentinel value to indicate that no default value was provided. */\nexport const NO_DEFAULT_VALUE = Symbol('AtomEffect.NoDefaultValue');\n\n/** @internal */\ninterface DebugMetadata {\n [DEBUG_NAME]?: string;\n [DEBUG_ID]?: DependencyId;\n [DEBUG_TYPE]?: string;\n}\n\n/** Log prefix for Atom Effect console messages. */\nconst PREFIX = '[Atom Effect]';\n\n/** Shared no-op function to reduce memory footprint and call overhead in production. */\nconst noop = () => {};\n\n/**\n * Optimized Debug controller implementation for development environments.\n * Provides active monitoring, logging, and inspection capabilities.\n *\n * @internal\n * @implements {DebugConfig}\n */\nclass DevDebugController implements DebugConfig {\n /** Whether debugging features are currently active. */\n public enabled = true;\n\n /** Whether to warn when a potential infinite loop is detected. */\n public warnInfiniteLoop = DEBUG_CONFIG.WARN_INFINITE_LOOP;\n\n /** Tracks the number of updates per dependency within a single execution scope. */\n private _updateCounts = new Map<DependencyId, number>();\n\n /**\n * Weakly references registered nodes to allow garbage collection while maintaining\n * a list for graph dumping.\n */\n private _nodeRegistry = new Map<DependencyId, WeakRef<object>>();\n\n /** Threshold for triggering an infinite loop warning. */\n private _threshold = DEBUG_CONFIG.LOOP_THRESHOLD;\n\n /** Prevents redundant cleanup scheduling. */\n private _cleanupScheduled = false;\n\n /**\n * Logs a warning message if the condition is met and debugging is enabled.\n *\n * @param cond - The condition to check.\n * @param msg - The message to log if the condition is true.\n */\n public warn = (cond: boolean, msg: string): void => {\n if (this.enabled && cond) console.warn(`${PREFIX} ${msg}`);\n };\n\n /**\n * Registers a node in the internal registry for tracking and graph generation.\n * Uses WeakRef to prevent memory leaks.\n *\n * @param node - The object/node to register, must have a unique DependencyId.\n */\n public registerNode = (node: object & { id: DependencyId }): void => {\n this._nodeRegistry.set(node.id, new WeakRef(node));\n };\n\n /**\n * Attaches debug metadata to a runtime object.\n *\n * @remarks\n * Optimized with direct property assignment instead of 'Object.defineProperties'\n * for significantly faster node initialization in hot paths.\n *\n * @param obj - The object to attach info to.\n * @param type - The type of the node (e.g., 'atom', 'selector', 'effect').\n * @param id - The unique internal identifier.\n * @param customName - Optional user-defined name for easier identification.\n */\n public attachDebugInfo = (\n obj: object,\n type: string,\n id: DependencyId,\n customName?: string\n ): void => {\n if (!this.enabled) return;\n\n // Use direct symbol access for peak V8 assignment performance\n const meta = obj as DebugMetadata;\n meta[DEBUG_NAME] = customName ?? `${type}_${id}`;\n meta[DEBUG_ID] = id;\n meta[DEBUG_TYPE] = type;\n\n this.registerNode(obj as { id: DependencyId });\n };\n\n /**\n * Tracks an update to a dependency and checks for infinite loops.\n * Counts are automatically reset at the end of the current microtask.\n *\n * @param id - The unique identifier of the dependency being updated.\n * @param name - An optional display name for the warning message.\n */\n public trackUpdate = (id: DependencyId, name?: string): void => {\n if (!this.enabled || !this.warnInfiniteLoop) return;\n\n const counts = this._updateCounts;\n const count = (counts.get(id) ?? 0) + 1;\n\n if (count > this._threshold) {\n this.warn(\n true,\n `Infinite loop detected for ${name ?? `dependency ${id}`}. Over ${this._threshold} updates in a single execution scope.`\n );\n } else {\n counts.set(id, count);\n }\n\n if (!this._cleanupScheduled) {\n this._cleanupScheduled = true;\n // Reset counts at the end of the current microtask using lightweight mechanism\n queueMicrotask(() => {\n this._updateCounts.clear();\n this._cleanupScheduled = false;\n });\n }\n };\n\n /**\n * Generates a snapshot of the current reactive graph.\n * Automatically prunes dead references from the registry.\n *\n * @returns An array of debug info objects for all currently alive nodes.\n */\n public dumpGraph = (): Record<string, unknown>[] => {\n const result: Record<string, unknown>[] = [];\n for (const [id, ref] of this._nodeRegistry) {\n const node = ref.deref();\n if (node) {\n result.push({\n id,\n name: this.getDebugName(node),\n type: this.getDebugType(node),\n updateCount: this._updateCounts.get(id) ?? 0,\n });\n } else {\n this._nodeRegistry.delete(id);\n this._updateCounts.delete(id);\n }\n }\n return result;\n };\n\n /**\n * Retrieves the debug name from an object if it exists.\n *\n * @param obj - the object to inspect.\n * @returns The human-readable name or undefined.\n */\n public getDebugName = (obj: object | null | undefined): string | undefined => {\n if (obj == null) return undefined;\n return (obj as DebugMetadata)[DEBUG_NAME];\n };\n\n /**\n * Retrieves the debug type from an object if it exists.\n *\n * @param obj - the object to inspect.\n * @returns The type identifier or undefined.\n */\n public getDebugType = (obj: object | null | undefined): string | undefined => {\n if (obj == null) return undefined;\n return (obj as DebugMetadata)[DEBUG_TYPE];\n };\n}\n\n/**\n * Inert implementation of the Debug controller for production environments.\n * All operations are no-ops using shared handlers for minimal overhead.\n *\n * @internal\n * @implements {DebugConfig}\n */\nconst ProdDebugController: DebugConfig = {\n enabled: false,\n warnInfiniteLoop: false,\n warn: noop,\n registerNode: noop,\n attachDebugInfo: noop,\n trackUpdate: noop,\n dumpGraph: () => [],\n getDebugName: () => undefined,\n getDebugType: () => undefined,\n};\n\n/**\n * The global debug singleton instance.\n * Automatically switches between development and production implementations.\n *\n * @public\n */\nexport const debug: DebugConfig = IS_DEV ? new DevDebugController() : ProdDebugController;\n\n/**\n * Internal counter for generating unique DependencyIds.\n * @private\n */\nlet nextId = 1;\n\n/**\n * Generates a unique, monotonically increasing integer ID.\n * Performance: Uses SMI bitwise optimization.\n *\n * @returns A fresh DependencyId.\n * @public\n */\nexport const generateId = (): DependencyId => (nextId++ | 0) as DependencyId;\n","// ── SlotBuffer ──────────────────────────────────────────────────────────\n\n/**\n * A ultra-high-performance, allocation-optimized container for reactive subscribers.\n *\n * Design Philosophy:\n * 1. Inline Storage: Uses 4 object properties (_s0.._s3) to store items directly.\n * Since >90% of reactive nodes have 1-4 subscribers, this avoids array creation entirely.\n * 2. Spill-over Model: Shifts to a lazy-allocated overflow array only when necessary.\n * 3. Size Duality: Distinguishes between Physical Boundary (_count) and Logical Size (_actualCount)\n * to support fast iteration while maintaining hole-reuse capabilities.\n */\nexport class SlotBuffer<T> {\n // Physical high-water mark first for better V8 object layout (numbers)\n /** Physical high-water mark. Indicates the highest index ever occupied + 1. */\n _count = 0;\n /** Logical element count. Number of non-null items currently in the buffer. */\n _actualCount = 0;\n\n // Direct property slots for ultra-fast access and zero allocation.\n _s0: T | null = null;\n _s1: T | null = null;\n _s2: T | null = null;\n _s3: T | null = null;\n\n /** Lazy overflow container for index >= 4. */\n _overflow: (T | null)[] | null = null;\n /** LIFO reuse-stack of freed overflow indices to maintain O(1) addition. */\n _freeIndices: number[] | null = null;\n\n // ── Internal Physical Primitives ──────────────────────────────────────\n\n /**\n * Low-level atomic write.\n * Does NOT update bookkeeping counters. Used as a building block for higher APIs.\n */\n protected _rawWrite(index: number, item: T | null): void {\n if (index < 4) {\n if (index === 0) this._s0 = item;\n else if (index === 1) this._s1 = item;\n else if (index === 2) this._s2 = item;\n else this._s3 = item;\n } else {\n if (this._overflow === null) this._overflow = [];\n const ov = this._overflow;\n ov[index - 4] = item;\n }\n }\n\n /**\n * Finds the first available hole or appends to the tail.\n * Returns the assigned physical index.\n */\n protected _rawAdd(item: T): number {\n if (this._s0 === null) {\n this._s0 = item;\n return 0;\n }\n if (this._s1 === null) {\n this._s1 = item;\n return 1;\n }\n if (this._s2 === null) {\n this._s2 = item;\n return 2;\n }\n if (this._s3 === null) {\n this._s3 = item;\n return 3;\n }\n\n if (this._overflow === null) this._overflow = [];\n const ov = this._overflow;\n const free = this._freeIndices;\n if (free !== null && free.length > 0) {\n const idx = free.pop()!;\n ov[idx] = item;\n return idx + 4;\n }\n ov.push(item);\n return 3 + ov.length;\n }\n\n /** Atomic swap of two physical slots. Essential for dependency relocation. */\n protected _rawSwap(idxA: number, idxB: number): void {\n if (idxA === idxB) return;\n const valA = this.getAt(idxA);\n const valB = this.getAt(idxB);\n this._rawWrite(idxA, valB);\n this._rawWrite(idxB, valA);\n }\n\n // ── Public API ────────────────────────────────────────────────────────\n\n /** Number of active (non-null) elements. */\n get size(): number {\n return this._actualCount;\n }\n /** Highest physical index + 1. */\n get physicalSize(): number {\n return this._count;\n }\n\n /** Retrieves item at the specified index. O(1). */\n getAt(index: number): T | null {\n if (index < 4) {\n if (index === 0) return this._s0;\n if (index === 1) return this._s1;\n if (index === 2) return this._s2;\n if (index === 3) return this._s3;\n return null;\n }\n const ov = this._overflow;\n return ov === null ? null : (ov[index - 4] ?? null);\n }\n\n /**\n * Sets item at index.\n * Forces recalculation of logic size and high-water mark reduction on nullification.\n */\n setAt(index: number, item: T | null): void {\n const old = this.getAt(index);\n if (old === item) return;\n\n this._rawWrite(index, item);\n\n // Sync logical count (Active items tracking)\n if (old === null) this._actualCount++;\n else if (item === null) this._actualCount--;\n\n // Sync physical high-water mark (Iteration boundary tracking)\n if (item !== null) {\n if (index >= this._count) this._count = index + 1;\n } else {\n this._shrinkPhysicalSizeFrom(index);\n }\n }\n\n /**\n * Shrinks high-water mark recursively from the tail.\n * Optimized to avoid getAt() overhead in tight loop.\n */\n private _shrinkPhysicalSizeFrom(index: number): void {\n if (index !== this._count - 1) return;\n this._count--;\n\n if (this._count > 4) {\n const ov = this._overflow!;\n while (this._count > 4 && ov[this._count - 5] === null) {\n this._count--;\n }\n }\n\n if (this._count === 4 && this._s3 === null) {\n this._count = 3;\n if (this._s2 === null) {\n this._count = 2;\n if (this._s1 === null) {\n this._count = 1;\n if (this._s0 === null) this._count = 0;\n }\n }\n }\n }\n\n /**\n * Truncates the buffer to a specific size.\n * Normalizes the high-water mark even if the current count is 0.\n */\n truncateFrom(index: number): void {\n // 1. Cleanup inline slots\n if (index <= 3) {\n if (index <= 3 && this._s3 !== null) {\n this._onItemRemoved(this._s3!);\n this._s3 = null;\n this._actualCount--;\n }\n if (index <= 2 && this._s2 !== null) {\n this._onItemRemoved(this._s2!);\n this._s2 = null;\n this._actualCount--;\n }\n if (index <= 1 && this._s1 !== null) {\n this._onItemRemoved(this._s1!);\n this._s1 = null;\n this._actualCount--;\n }\n if (index <= 0 && this._s0 !== null) {\n this._onItemRemoved(this._s0!);\n this._s0 = null;\n this._actualCount--;\n }\n }\n\n // 2. Cleanup overflow array\n const ov = this._overflow;\n if (ov !== null) {\n const ovStart = index > 4 ? index - 4 : 0;\n const len = ov.length;\n for (let i = ovStart; i < len; i++) {\n const item = ov[i];\n if (item !== null && item !== undefined) {\n this._onItemRemoved(item);\n ov[i] = null;\n this._actualCount--;\n }\n }\n if (index <= 4) {\n this._overflow = null;\n } else {\n ov.length = index - 4;\n }\n }\n\n this._count = index;\n if (this._actualCount < 0) this._actualCount = 0;\n this._freeIndices = null;\n }\n\n /**\n * Internal hook for resource cleanup (e.g. unsubscriptions).\n * @internal For use in DepSlotBuffer only.\n */\n protected _onItemRemoved(_item: T): void {}\n\n /** Appends an item to the buffer. Returns assigned index. O(1). */\n add(item: T): number {\n const idx = this._rawAdd(item);\n if (idx >= this._count) this._count = idx + 1;\n this._actualCount++;\n return idx;\n }\n\n /** Removes an item by reference. O(N). */\n remove(item: T): boolean {\n let idx = -1;\n if (this._s0 === item) idx = 0;\n else if (this._s1 === item) idx = 1;\n else if (this._s2 === item) idx = 2;\n else if (this._s3 === item) idx = 3;\n else {\n const ov = this._overflow;\n if (ov !== null) {\n idx = ov.indexOf(item);\n if (idx !== -1) idx += 4;\n }\n }\n\n if (idx !== -1) {\n this._rawWrite(idx, null);\n this._shrinkPhysicalSizeFrom(idx);\n this._actualCount--;\n if (idx >= 4) {\n if (this._freeIndices === null) this._freeIndices = [];\n const free = this._freeIndices;\n free.push(idx - 4);\n }\n return true;\n }\n return false;\n }\n\n /** O(N) presence check. */\n has(item: T): boolean {\n const actual = this._actualCount;\n if (actual === 0) return false;\n if (this._s0 === item || this._s1 === item || this._s2 === item || this._s3 === item)\n return true;\n const ov = this._overflow;\n if (ov !== null) return ov.indexOf(item) !== -1;\n return false;\n }\n\n /** Optimized iteration. Fast-path triggers when buffer is dense (no holes). */\n forEach(fn: (item: T) => void): void {\n const actual = this._actualCount;\n if (actual === 0) return;\n\n if (actual === this._count) {\n // Dense optimization: Avoid all null checks and property lookups\n fn(this._s0!);\n if (actual > 1) {\n fn(this._s1!);\n if (actual > 2) {\n fn(this._s2!);\n if (actual > 3) {\n fn(this._s3!);\n if (actual > 4) {\n const ov = this._overflow!;\n for (let i = 0, len = ov.length; i < len; i++) fn(ov[i]!);\n }\n }\n }\n }\n return;\n }\n\n // Sparse path: Unrolled for the first 4 slots\n let count = 0;\n if (this._s0 !== null) {\n fn(this._s0);\n if (++count >= actual) return;\n }\n if (this._s1 !== null) {\n fn(this._s1);\n if (++count >= actual) return;\n }\n if (this._s2 !== null) {\n fn(this._s2);\n if (++count >= actual) return;\n }\n if (this._s3 !== null) {\n fn(this._s3);\n if (++count >= actual) return;\n }\n\n const ov = this._overflow;\n if (ov !== null) {\n for (let i = 0, len = ov.length; i < len; i++) {\n const item = ov[i];\n if (item !== null && item !== undefined) {\n fn(item);\n if (++count >= actual) return;\n }\n }\n }\n }\n\n /** Elimination of all holes via in-place shifting. Zero-allocation. */\n compact(): void {\n const actual = this._actualCount;\n if (actual === this._count) return;\n\n if (actual === 0) {\n this.clear();\n return;\n }\n\n let writeIdx = 0;\n const limit = this._count;\n for (let readIdx = 0; readIdx < limit; readIdx++) {\n const item = this.getAt(readIdx);\n if (item !== null) {\n if (readIdx !== writeIdx) {\n this._rawWrite(writeIdx, item);\n this._rawWrite(readIdx, null);\n }\n writeIdx++;\n if (writeIdx === actual) break;\n }\n }\n\n this._count = actual;\n if (this._overflow !== null) {\n if (writeIdx <= 4) this._overflow = null;\n else this._overflow.length = writeIdx - 4;\n }\n this._freeIndices = null;\n }\n\n /** Complete reset and memory release. */\n clear(): void {\n this._s0 = this._s1 = this._s2 = this._s3 = null;\n this._count = 0;\n this._actualCount = 0;\n this._overflow = null;\n this._freeIndices = null;\n }\n\n dispose(): void {\n this.clear();\n }\n}\n\n// ── DepSlotBuffer ───────────────────────────────────────────────────────\n\nimport type { Dependency } from '@/types';\nimport type { DependencyLink } from './tracking';\n\n/**\n * Specialized high-speed buffer for Dependency Tracking Cycles.\n */\nexport class DepSlotBuffer extends SlotBuffer<DependencyLink> {\n private _map: Map<Dependency, number> | null = null;\n private readonly _SCAN_THRESHOLD = 32;\n\n hasComputeds = false;\n prepareTracking(): void {\n this.hasComputeds = false;\n }\n\n protected override _onItemRemoved(link: DependencyLink): void {\n link.unsub?.();\n }\n\n /** Synchronizes the Node->Index Map when setting entries directly. */\n override setAt(index: number, item: DependencyLink | null): void {\n const old = this.getAt(index);\n super.setAt(index, item);\n\n if (this._map !== null) {\n if (old !== null) this._map.delete(old.node);\n if (item !== null) this._map.set(item.node, index);\n }\n }\n\n /**\n * Finds and reuses a dependency from a previous cycle.\n * Optimized hot-path with unrolled search.\n */\n claimExisting(dep: Dependency, trackIndex: number): boolean {\n const length = this._count;\n if (length <= trackIndex) return false;\n\n // 1. Direct hit check (Unrolled for performance)\n let current: DependencyLink | null = null;\n if (trackIndex < 4) {\n if (trackIndex === 0) current = this._s0;\n else if (trackIndex === 1) current = this._s1;\n else if (trackIndex === 2) current = this._s2;\n else current = this._s3;\n } else {\n current = this._overflow![trackIndex - 4] ?? null;\n }\n\n if (current && current.node === dep && current.unsub) {\n current.version = dep.version;\n return true;\n }\n\n // 2. Map lookup\n if (this._map !== null || length - trackIndex > this._SCAN_THRESHOLD) {\n return this._claimViaMap(dep, trackIndex);\n }\n\n // 3. Sequential search: Unrolled for the first 4 slots\n let foundIdx = -1;\n let foundLink: DependencyLink | null = null;\n\n let i = trackIndex + 1;\n for (; i < 4 && i < length; i++) {\n const l = i === 1 ? this._s1 : i === 2 ? this._s2 : this._s3;\n if (l && l.node === dep && l.unsub) {\n foundIdx = i;\n foundLink = l;\n break;\n }\n }\n if (foundIdx === -1 && i < length) {\n const ov = this._overflow!;\n for (let j = i - 4, len = length - 4; j < len; j++) {\n const l = ov[j];\n if (l && l.node === dep && l.unsub) {\n foundIdx = j + 4;\n foundLink = l;\n break;\n }\n }\n }\n\n if (foundIdx !== -1) {\n foundLink!.version = dep.version;\n // Precise manual swap to avoid repeated index checks in _rawSwap\n this._rawWrite(trackIndex, foundLink);\n this._rawWrite(foundIdx, current);\n return true;\n }\n\n return false;\n }\n\n private _claimViaMap(dep: Dependency, trackIndex: number): boolean {\n if (this._map === null) this._map = this._initMap();\n const map = this._map;\n const existingIndex = map.get(dep);\n if (existingIndex === undefined || existingIndex < trackIndex) return false;\n\n const link = this.getAt(existingIndex);\n if (link === null || !link.unsub) return false;\n\n link.version = dep.version;\n\n if (existingIndex !== trackIndex) {\n const occupant = this.getAt(trackIndex);\n this._rawSwap(existingIndex, trackIndex);\n\n map.set(dep, trackIndex);\n if (occupant?.unsub) map.set(occupant.node, existingIndex);\n }\n return true;\n }\n\n private _initMap(): Map<Dependency, number> {\n const map = new Map<Dependency, number>();\n if (this._s0?.unsub) map.set(this._s0.node, 0);\n if (this._s1?.unsub) map.set(this._s1.node, 1);\n if (this._s2?.unsub) map.set(this._s2.node, 2);\n if (this._s3?.unsub) map.set(this._s3.node, 3);\n\n const ov = this._overflow;\n if (ov !== null) {\n for (let i = 0, len = ov.length; i < len; i++) {\n const link = ov[i];\n if (link?.unsub) map.set(link.node, i + 4);\n }\n }\n return map;\n }\n\n /**\n * Inserts a new link at trackIdx.\n * Optimized to avoid getAt/_rawWrite overhead.\n */\n insertNew(trackIdx: number, link: DependencyLink): void {\n let occupant: DependencyLink | null = null;\n if (trackIdx < 4) {\n if (trackIdx === 0) {\n occupant = this._s0;\n this._s0 = link;\n } else if (trackIdx === 1) {\n occupant = this._s1;\n this._s1 = link;\n } else if (trackIdx === 2) {\n occupant = this._s2;\n this._s2 = link;\n } else {\n occupant = this._s3;\n this._s3 = link;\n }\n } else {\n if (this._overflow === null) this._overflow = [];\n const ov = this._overflow;\n occupant = ov[trackIdx - 4] ?? null;\n ov[trackIdx - 4] = link;\n }\n\n if (occupant !== null) {\n const newIdx = this._rawAdd(occupant);\n if (newIdx >= this._count) this._count = newIdx + 1;\n if (this._map !== null && occupant.unsub) this._map.set(occupant.node, newIdx);\n }\n\n if (trackIdx >= this._count) this._count = trackIdx + 1;\n this._actualCount++;\n\n if (this._map !== null && link.unsub) this._map.set(link.node, trackIdx);\n }\n\n override add(item: DependencyLink): number {\n const idx = super.add(item);\n if (this._map !== null && item.unsub) this._map.set(item.node, idx);\n return idx;\n }\n\n override remove(_item: DependencyLink): boolean {\n throw new Error('remove() prohibited');\n }\n override compact(): void {}\n\n override truncateFrom(index: number): void {\n super.truncateFrom(index);\n if (this._map !== null) {\n this._map = null;\n }\n }\n\n disposeAll(): void {\n this.truncateFrom(0);\n this.hasComputeds = false;\n }\n}\n","/**\n * Global brand symbol for all reactive primitives.\n * Uses a bitwise mask for high-performance type identification.\n */\nexport const BRAND: unique symbol = Symbol.for('atom-effect/brand');\n\n/**\n * Bitwise flags for brand identification.\n */\nexport const BrandFlags = {\n Atom: 1 << 0,\n Writable: 1 << 1,\n Computed: 1 << 2,\n Effect: 1 << 3,\n} as const;\n","import { BRAND, BrandFlags } from '@/symbols';\nimport type { ComputedAtom, EffectObject, ReadonlyAtom, WritableAtom } from '@/types';\n\n/** @internal */\ninterface Branded {\n [BRAND]?: number;\n}\n\n/** @internal */\ninterface Thenable {\n then: unknown;\n}\n\n/**\n * Internal helper to check for a brand flag on objects or functions.\n * Optimized for high-performance bitwise identification.\n */\nfunction isBranded<T>(obj: unknown, flag: number): obj is T {\n if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) return false;\n\n // Bitwise AND check on the consolidated BRAND symbol\n return !!((obj as Branded)[BRAND]! & flag);\n}\n\n/**\n * Readonly atom check.\n */\nexport function isAtom(obj: unknown): obj is ReadonlyAtom {\n return isBranded(obj, BrandFlags.Atom);\n}\n\n/**\n * Writable atom check.\n */\nexport function isWritable(obj: unknown): obj is WritableAtom {\n return isBranded(obj, BrandFlags.Writable);\n}\n\n/**\n * Computed atom check.\n */\nexport function isComputed(obj: unknown): obj is ComputedAtom {\n return isBranded(obj, BrandFlags.Computed);\n}\n\n/**\n * Effect object check.\n */\nexport function isEffect(obj: unknown): obj is EffectObject {\n return isBranded(obj, BrandFlags.Effect);\n}\n\n/**\n * Promise check.\n * Includes a fast-path for native Promises and supports duck-typed thenables.\n * Optimized for non-promise dominance by providing an eager-exit for primitives.\n */\nexport function isPromise<T>(value: unknown): value is Promise<T> {\n // 1. Fast-path for native promises\n if (value instanceof Promise) return true;\n\n // 2. Eager-exit for primitives and null to avoid property indexing\n if (value === null || typeof value !== 'object') return false;\n\n // 3. Duck-typed thenable (supports 3rd party libs)\n return typeof (value as Thenable).then === 'function';\n}\n","import { IS_DEV } from '@/constants';\nimport type { Dependency, Subscriber } from '@/types';\nimport { debug } from '@/utils/debug';\nimport { isPromise } from '@/utils/type-guards';\n\n// ── Tracking Types ──────────────────────────────────────────────────────\n\n/**\n * Dependency consumer.\n * Objects implementing this can be registered as the current tracking target.\n */\nexport interface DependencySubscriber {\n /**\n * Registers a dependency to this subscriber.\n */\n addDependency(dep: Dependency): void;\n}\n\n/**\n * Executable unit.\n * Represents a reactive node or effect that can be re-run.\n */\nexport interface ExecutableSubscriber {\n execute(): void;\n}\n\n/**\n * Dependency tracker.\n * Combines dependency collection and execution capabilities.\n */\nexport interface DependencyTracker extends DependencySubscriber, ExecutableSubscriber {}\n\n/**\n * Trackable function.\n * A function that is also recognized as a dependency consumer.\n */\nexport type TrackableFunction = (() => void) & DependencySubscriber;\n\n// ── Dependency Link & Subscription ───────────────────────────────────────\n\n/**\n * Dependency graph edge.\n * Maintains the link between a subscriber and its dependency.\n */\nexport class DependencyLink {\n constructor(\n public node: Dependency,\n public version: number,\n /**\n * Unsubscribe cleanup function.\n * Default value ensures consistent V8 hidden class shape.\n */\n public unsub: (() => void) | undefined = undefined\n ) {}\n}\n\n/**\n * Subscription entry.\n * Encapsulates the notification logic for a dependency change.\n */\nexport class Subscription<T> {\n constructor(\n /**\n * Optional callback. Always initialized to maintain hidden class.\n */\n public fn: ((newValue?: T, oldValue?: T) => void) | undefined = undefined,\n /**\n * Optional subscriber. Always initialized to maintain hidden class.\n */\n public sub: Subscriber | undefined = undefined\n ) {}\n\n /**\n * Notifies the subscriber of a value change.\n *\n * @remarks\n * Optimized with inlined 'untracked' logic to eliminate closure allocation.\n */\n notify(newValue?: T, oldValue?: T): void {\n const fn = this.fn;\n const sub = this.sub;\n\n // Fast path: nothing to notify\n if (fn === undefined && sub === undefined) return;\n\n const ctx = trackingContext;\n const prev = ctx.current;\n\n // If already untracked, bypass context switching logic\n if (prev === null) {\n if (fn !== undefined) fn(newValue, oldValue);\n if (sub !== undefined) sub.execute();\n return;\n }\n\n // Context switch required for notification safety\n ctx.current = null;\n try {\n if (fn !== undefined) fn(newValue, oldValue);\n if (sub !== undefined) sub.execute();\n } finally {\n ctx.current = prev;\n }\n }\n}\n\n// ── Tracking Context ────────────────────────────────────────────────────\n\n/**\n * Tracking context implementation.\n * Manages the global stack of active dependency collectors.\n */\nclass TrackingContext {\n /** Active subscriber at the top of the stack. */\n public current: DependencySubscriber | null = null;\n\n /**\n * Executes a function within the scope of a specific subscriber.\n *\n * @param subscriber - The subscriber to collect dependencies for.\n * @param fn - The logic to execute.\n * @returns The result of `fn`.\n */\n public run<T>(subscriber: DependencySubscriber, fn: () => T): T {\n // Fast path: already in the correct context\n if (this.current === subscriber) {\n return fn();\n }\n\n const prev = this.current;\n this.current = subscriber;\n\n try {\n // Small production optimization: direct return\n if (!IS_DEV) return fn();\n\n const result = fn();\n\n // Async detection: check if the function returned a Promise\n debug.warn(\n isPromise(result),\n 'Detected Promise returned within tracking context. ' +\n 'Dependencies accessed after \"await\" will NOT be tracked. ' +\n 'Consider using synchronous tracking before the async boundary.'\n );\n\n return result;\n } finally {\n // Synchronous restoration is required for safety in multi-tasking environments\n this.current = prev;\n }\n }\n}\n\n/**\n * Global tracking context singleton.\n */\nexport const trackingContext = new TrackingContext();\n\n/**\n * Tracking context type.\n */\nexport type { TrackingContext };\n\n// ── Untracked ───────────────────────────────────────────────────────────\n\n/**\n * Executes a function without dependency tracking.\n *\n * @param fn - Function to execute.\n * @returns Result of `fn`.\n */\nexport function untracked<T>(fn: () => T): T {\n const ctx = trackingContext;\n const prev = ctx.current;\n\n // Optimized: Skip context switching if already untracked\n if (prev === null) {\n return fn();\n }\n\n ctx.current = null;\n try {\n return fn();\n } finally {\n ctx.current = prev;\n }\n}\n","import { COMPUTED_STATE_FLAGS, EPOCH_CONSTANTS, IS_DEV, SMI_MAX } from '@/constants';\nimport { AtomError, ERROR_MESSAGES, wrapError } from '@/errors';\nimport type { DependencyId, Subscriber } from '@/types';\nimport { generateId } from '@/utils/debug';\nimport { type DepSlotBuffer, SlotBuffer } from './buffers';\nimport { Subscription } from './tracking';\n\n/**\n * Unified base class for all reactive nodes (Atoms, Computeds, Effects).\n *\n * Optimized for V8 Hidden Class Monomorphism by having a single, consistent\n * object shape for all reactive logic.\n *\n * @template T - The type of value produced by this node (used for subscriptions).\n */\nexport abstract class ReactiveNode<T> {\n /** [Producer/Consumer] State flags */\n flags: number;\n /** [Producer/Consumer] Version counter */\n version: number;\n /** [Producer/Consumer] Last access epoch */\n _lastSeenEpoch: number;\n /** [Context] Scheduler epoch tag */\n _nextEpoch: number | undefined;\n /** [Debug] Unique ID for identify node in tracking maps */\n readonly id: DependencyId;\n\n /**\n * [Producer] Managed subscribers.\n */\n _slots: SlotBuffer<Subscription<T>> | null;\n\n /** [Producer] Re-entry guard for notification loop. */\n _notifying: number;\n\n /**\n * [Consumer] Managed dependencies.\n */\n _deps: DepSlotBuffer | null;\n /** [Consumer] O(1) Hot-path dependency index for rapid dirty checks. */\n _hotIndex: number;\n\n constructor() {\n // Reordered for V8 Hidden Class (integers/numbers first)\n this.flags = 0;\n this.version = 0;\n this._lastSeenEpoch = EPOCH_CONSTANTS.UNINITIALIZED;\n this._notifying = 0;\n this._hotIndex = -1;\n this.id = generateId() & SMI_MAX;\n\n // References/Nullable last\n this._nextEpoch = undefined;\n this._slots = null;\n this._deps = null;\n }\n\n /**\n * Whether the node has been disposed.\n * @internal\n */\n get isDisposed(): boolean {\n return (this.flags & COMPUTED_STATE_FLAGS.DISPOSED) !== 0; // Bit 0: DISPOSED\n }\n\n /**\n * Whether the node is a computed atom.\n * @internal\n */\n get isComputed(): boolean {\n return (this.flags & COMPUTED_STATE_FLAGS.IS_COMPUTED) !== 0; // Bit 1: IS_COMPUTED\n }\n\n /**\n * Whether the node currently has an error.\n * @internal\n */\n get hasError(): boolean {\n return false;\n }\n\n // ============================================================================\n // Producer Logic (Subscriber Management)\n // ============================================================================\n\n /**\n * Adds subscriber for notifications.\n */\n subscribe(listener: ((newValue?: T, oldValue?: T) => void) | Subscriber): () => void {\n const isFn = typeof listener === 'function';\n // [Guard Clause] 중첩 최소화 및 타입 안전성 확보\n if (!isFn && (listener === null || typeof (listener as Subscriber).execute !== 'function')) {\n throw wrapError(\n new TypeError('Invalid subscriber'),\n AtomError,\n ERROR_MESSAGES.ATOM_SUBSCRIBER_MUST_BE_FUNCTION\n );\n }\n\n let slots = this._slots;\n if (slots === null) {\n slots = new SlotBuffer<Subscription<T>>();\n this._slots = slots;\n }\n\n // Optimization: Skip duplicate check if empty\n if (slots.size > 0) {\n let duplicate = false;\n\n // Unrolled check using unified comparison to reduce branching\n // Since Subscription stores fn/sub and one is always undefined, we can check both\n if (\n (slots._s0 !== null && (slots._s0.fn === listener || slots._s0.sub === listener)) ||\n (slots._s1 !== null && (slots._s1.fn === listener || slots._s1.sub === listener)) ||\n (slots._s2 !== null && (slots._s2.fn === listener || slots._s2.sub === listener)) ||\n (slots._s3 !== null && (slots._s3.fn === listener || slots._s3.sub === listener))\n ) {\n duplicate = true;\n } else {\n const ov = slots._overflow;\n if (ov !== null) {\n const len = ov.length;\n // Hoisted invariant check (isFn) to avoid branching inside the loop\n if (isFn) {\n for (let i = 0; i < len; i++) {\n const s = ov[i];\n if (s !== null && s?.fn === listener) {\n duplicate = true;\n break;\n }\n }\n } else {\n for (let i = 0; i < len; i++) {\n const s = ov[i];\n if (s !== null && s?.sub === listener) {\n duplicate = true;\n break;\n }\n }\n }\n }\n }\n\n if (duplicate) {\n if (IS_DEV) console.warn(`[atom-effect] Duplicate subscription ignored on node ${this.id}`);\n return () => {};\n }\n }\n\n const link = new Subscription<T>(\n isFn ? (listener as (newValue?: T, oldValue?: T) => void) : undefined,\n !isFn ? (listener as Subscriber) : undefined\n );\n\n slots.add(link);\n return () => this._unsubscribe(link);\n }\n\n protected _unsubscribe(link: Subscription<T>): void {\n const slots = this._slots;\n if (slots === null) return;\n\n slots.remove(link);\n if (this._notifying === 0) {\n slots.compact();\n }\n }\n\n /**\n * Returns current subscriber count.\n */\n subscriberCount(): number {\n const slots = this._slots;\n return slots === null ? 0 : slots.size;\n }\n\n /**\n * Notifies all subscribers about a value update.\n */\n protected _notifySubscribers(newValue: T | undefined, oldValue: T | undefined): void {\n const slots = this._slots;\n if (slots === null || slots.size === 0) return;\n\n this._notifying++;\n try {\n // 1. Inline slots: Manual unroll for hot-path performance\n if (slots._s0 !== null) {\n try {\n slots._s0.notify(newValue, oldValue);\n } catch (e) {\n this._logNotifyError(e);\n }\n }\n if (slots._s1 !== null) {\n try {\n slots._s1.notify(newValue, oldValue);\n } catch (e) {\n this._logNotifyError(e);\n }\n }\n if (slots._s2 !== null) {\n try {\n slots._s2.notify(newValue, oldValue);\n } catch (e) {\n this._logNotifyError(e);\n }\n }\n if (slots._s3 !== null) {\n try {\n slots._s3.notify(newValue, oldValue);\n } catch (e) {\n this._logNotifyError(e);\n }\n }\n\n // 2. Overflow scan: Standard loop for performance\n const ov = slots._overflow;\n if (ov !== null) {\n for (let i = 0, len = ov.length; i < len; i++) {\n const sub = ov[i];\n if (sub !== null) {\n try {\n sub?.notify(newValue, oldValue);\n } catch (e) {\n this._logNotifyError(e);\n }\n }\n }\n }\n } finally {\n if (--this._notifying === 0) {\n slots.compact();\n }\n }\n }\n\n private _logNotifyError(err: unknown): void {\n console.error(wrapError(err, AtomError, ERROR_MESSAGES.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED));\n }\n\n // ============================================================================\n // Consumer Logic (Dependency Validation)\n // ============================================================================\n\n /**\n * Determines if the node is dirty by checking its dependency chain.\n * Optimized with O(1) hot-path check.\n */\n protected _isDirty(): boolean {\n const deps = this._deps;\n if (deps === null || deps.size === 0) return false;\n\n // Phase 1: Hot-path Check - O(1)\n const hotIndex = this._hotIndex;\n if (hotIndex !== -1) {\n const hotLink = deps.getAt(hotIndex);\n if (hotLink !== null && hotLink.node.version !== hotLink.version) {\n return true;\n }\n }\n\n // Phase 2: Standard Validation - O(N)\n return this._deepDirtyCheck();\n }\n\n /**\n * Deeply validates dependency versions.\n */\n protected abstract _deepDirtyCheck(): boolean;\n}\n","import { IS_DEV, SCHEDULER_CONFIG, SMI_MAX } from '@/constants';\nimport { ERROR_MESSAGES, SchedulerError } from '@/errors';\n\n// ── Epoch & Version Management ──────────────────────────────────────────\n\n/**\n * Global epoch counter used for job deduplication and tracking state consistency.\n */\nlet collectorEpoch = 0;\n\n/**\n * Returns the next tracking epoch.\n * Wraps around using SMI_MAX and reserves 0 for uninitialized state.\n */\nexport function nextEpoch(): number {\n const next = (collectorEpoch + 1) & SMI_MAX;\n collectorEpoch = next === 0 ? 1 : next;\n return collectorEpoch;\n}\n\n/**\n * Returns the current global tracking epoch.\n */\nexport function currentEpoch(): number {\n return collectorEpoch;\n}\n\n/**\n * Increments a version counter within SMI range.\n * Reservations: Avoids 0 to allow it as a 'never updated' marker.\n */\nexport function nextVersion(v: number): number {\n const next = (v + 1) & SMI_MAX;\n return next === 0 ? 1 : next;\n}\n\n/** Current number of executions in the active flush cycle. */\nexport let flushExecutionCount = 0;\nlet isFlushing = false;\nlet _flushEpoch = 0;\n\n/** Returns the epoch associated with the current flush cycle. */\nexport function currentFlushEpoch(): number {\n return _flushEpoch;\n}\n\n/**\n * Starts a new flush cycle.\n * @returns true if the cycle was successfully started, false if already flushing.\n */\nexport function startFlush(): boolean {\n if (isFlushing) {\n if (IS_DEV) {\n console.warn('startFlush() called during flush - ignored');\n }\n return false;\n }\n\n isFlushing = true;\n _flushEpoch = nextEpoch();\n flushExecutionCount = 0;\n return true;\n}\n\n/** Ends the current flush cycle. */\nexport function endFlush(): void {\n isFlushing = false;\n}\n\n/**\n * Runs a function within a managed flush scope.\n * Ensures the flush state is properly incremented and cleaned up.\n *\n * @param fn - The function to execute.\n * @returns The result of the function execution.\n */\nexport function runInFlushScope<T>(fn: () => T): T | undefined {\n const started = startFlush();\n try {\n return fn();\n } finally {\n if (started) endFlush();\n }\n}\n\n/**\n * Track total execution count within a flush.\n * Throws if the count exceeds configured safety limits to prevent hung processes.\n */\nexport function incrementFlushExecutionCount(): number {\n if (!isFlushing) return 0;\n\n const count = ++flushExecutionCount;\n if (count <= SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_FLUSH) {\n return count;\n }\n\n throw new Error(\n `[atom-effect] Infinite loop detected: flush execution count exceeded ${SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_FLUSH}`\n );\n}\n\n/** Resets all global flush-related states to their defaults. */\nexport function resetFlushState(): void {\n _flushEpoch = 0;\n flushExecutionCount = 0;\n isFlushing = false;\n}\n\n// ── Scheduler ───────────────────────────────────────────────────────────\n\nexport interface SchedulerJobObject {\n execute(): void;\n /** Internal tracking for deduplication within the same epoch. */\n _nextEpoch?: number | undefined;\n}\n\n/** Represents a job that can be executed by the scheduler via a function interface. */\nexport interface SchedulerJobFunction {\n (): void;\n /** Internal tracking for deduplication within the same epoch. */\n _nextEpoch?: number | undefined;\n}\n\n/** Union type representing any valid schedulable task. */\nexport type SchedulerJob = SchedulerJobFunction | SchedulerJobObject;\n\n/**\n * Core Scheduler that manages asynchronous and synchronous task execution.\n *\n * Features:\n * - Double buffering for stable queue processing.\n * - Automatic job deduplication via Epoch tagging.\n * - Nested batching support with automatic coalescence.\n * - Microsecond-level scheduling via queueMicrotask.\n */\nclass Scheduler {\n // SMI fields grouped at top for V8 layout optimization\n private _bufferIndex = 0;\n private _size = 0;\n private _epoch = 0;\n private _batchDepth = 0;\n private _batchQueueSize = 0;\n private _maxFlushIterations: number = SCHEDULER_CONFIG.MAX_FLUSH_ITERATIONS;\n\n // Booleans for compact state tracking\n private _isProcessing = false;\n private _isFlushingSync = false;\n\n // Pre-allocated buffers to avoid tuple access overhead\n private _buffer0: (SchedulerJob | undefined)[] = [];\n private _buffer1: (SchedulerJob | undefined)[] = [];\n /** Temporary holding area for jobs scheduled during an active batch or sync flush. */\n private _batchQueue: (SchedulerJob | undefined)[] = [];\n\n /** Optional callback fired when the scheduler drops jobs due to overflow. */\n onOverflow: ((droppedCount: number) => void) | null = null;\n\n private readonly _boundRunLoop = this._runLoop.bind(this);\n\n /** Returns the total number of pending jobs (active + batched). */\n get queueSize(): number {\n return this._size + this._batchQueueSize;\n }\n\n /** Returns true if the scheduler is currently within a `batch()` scope. */\n get isBatching(): boolean {\n return this._batchDepth > 0;\n }\n\n /**\n * Schedules a job for execution.\n * Jobs are deduplicated based on the current epoch.\n *\n * @param callback - The task to be executed.\n */\n schedule(callback: SchedulerJob): void {\n if (IS_DEV) {\n if (\n typeof callback !== 'function' &&\n (!callback || typeof (callback as SchedulerJobObject).execute !== 'function')\n ) {\n throw new SchedulerError(ERROR_MESSAGES.SCHEDULER_CALLBACK_MUST_BE_FUNCTION);\n }\n }\n\n const epoch = this._epoch;\n if (callback._nextEpoch === epoch) return;\n callback._nextEpoch = epoch;\n\n // If batching or sync flushing, move to batch queue to ensure order and coalescence.\n if (this._batchDepth > 0 || this._isFlushingSync) {\n this._batchQueue[this._batchQueueSize++] = callback;\n return;\n }\n\n const buffer = this._bufferIndex === 0 ? this._buffer0 : this._buffer1;\n buffer[this._size++] = callback;\n\n if (!this._isProcessing) {\n this._flush();\n }\n }\n\n /** Initiates an asynchronous flush via microtask. */\n private _flush(): void {\n if (this._isProcessing || (this._size === 0 && this._batchQueueSize === 0)) return;\n this._isProcessing = true;\n queueMicrotask(this._boundRunLoop);\n }\n\n /** Internal microtask execution loop. */\n private _runLoop(): void {\n try {\n if (this._size === 0 && this._batchQueueSize === 0) return;\n\n const started = startFlush();\n this._drainQueue();\n if (started) endFlush();\n } finally {\n this._isProcessing = false;\n }\n }\n\n /** Internal synchronous flush typically triggered at the end of a batch. */\n _flushSync(): void {\n if (this._size === 0 && this._batchQueueSize === 0) return;\n\n const prev = this._isFlushingSync;\n this._isFlushingSync = true;\n const started = startFlush();\n try {\n this._mergeBatchQueue();\n this._drainQueue();\n } finally {\n this._isFlushingSync = prev;\n if (started) endFlush();\n }\n }\n\n /**\n * Merges the temporal batch queue into the main active buffer.\n */\n private _mergeBatchQueue(): void {\n const queueSize = this._batchQueueSize;\n if (queueSize === 0) return;\n\n const epoch = ++this._epoch | 0;\n const bQueue = this._batchQueue;\n const targetBuffer = this._bufferIndex === 0 ? this._buffer0 : this._buffer1;\n let currentSize = this._size;\n\n for (let i = 0; i < queueSize; i++) {\n const job = bQueue[i]!;\n if (job._nextEpoch !== epoch) {\n job._nextEpoch = epoch;\n targetBuffer[currentSize++] = job;\n }\n bQueue[i] = undefined; // Immediate GC hint\n }\n\n this._size = currentSize;\n this._batchQueueSize = 0;\n // Shrink array if it grew significantly\n if (bQueue.length > SCHEDULER_CONFIG.BATCH_QUEUE_SHRINK_THRESHOLD) bQueue.length = 0;\n }\n\n /**\n * Continuous loop that drains both main and batch queues.\n */\n private _drainQueue(): void {\n let iterations = 0;\n while (this._size > 0 || this._batchQueueSize > 0) {\n if (++iterations > this._maxFlushIterations) {\n this._handleFlushOverflow();\n return;\n }\n\n if (this._batchQueueSize > 0) this._mergeBatchQueue();\n if (this._size > 0) this._processQueue();\n }\n }\n\n /** Executes all jobs currently in the primary buffer and swaps buffers. */\n private _processQueue(): void {\n const idx = this._bufferIndex;\n const jobs = idx === 0 ? this._buffer0 : this._buffer1;\n const count = this._size;\n\n // Buffer swapping & Epoch bump\n this._bufferIndex = idx ^ 1;\n this._size = 0;\n this._epoch = (this._epoch + 1) | 0;\n\n for (let i = 0; i < count; i++) {\n const job = jobs[i]!;\n jobs[i] = undefined; // Avoid memory leaks\n try {\n if (typeof job === 'function') {\n job();\n } else {\n job.execute();\n }\n } catch (e) {\n console.error(new SchedulerError('Error occurred during scheduler execution', e as Error));\n }\n }\n }\n\n /** Resets the scheduler state on infinite loop detection. */\n private _handleFlushOverflow(): void {\n const droppedCount = this._size + this._batchQueueSize;\n console.error(\n new SchedulerError(\n ERROR_MESSAGES.SCHEDULER_FLUSH_OVERFLOW(this._maxFlushIterations, droppedCount)\n )\n );\n\n this._size = 0;\n this._buffer0.length = 0;\n this._buffer1.length = 0;\n this._batchQueueSize = 0;\n this._batchQueue.length = 0;\n\n const onOverflow = this.onOverflow;\n if (onOverflow) {\n try {\n onOverflow(droppedCount);\n } catch {}\n }\n }\n\n /** Enters a new batching depth. */\n startBatch(): void {\n this._batchDepth++;\n }\n\n /** Decrements batching depth. */\n endBatch(): void {\n if (this._batchDepth === 0) {\n if (IS_DEV) console.warn(ERROR_MESSAGES.SCHEDULER_END_BATCH_WITHOUT_START);\n return;\n }\n\n if (--this._batchDepth === 0) {\n if (!this._isFlushingSync) {\n this._flushSync();\n }\n }\n }\n\n /** Configures the maximum safety iterations. */\n setMaxFlushIterations(max: number): void {\n if (max < SCHEDULER_CONFIG.MIN_FLUSH_ITERATIONS)\n throw new SchedulerError(\n `Max iterations must be at least ${SCHEDULER_CONFIG.MIN_FLUSH_ITERATIONS}`\n );\n this._maxFlushIterations = max;\n }\n}\n\n/** Global scheduler instance. */\nexport const scheduler = new Scheduler();\n\n/**\n * Groups multiple state updates into a single batch, delaying effects and computations\n * until the batch is closed.\n *\n * @param fn - The function containing state updates.\n * @returns The result of the function execution.\n * @throws {TypeError} If fn is not a function.\n */\nexport function batch<T>(fn: () => T): T {\n if (IS_DEV && typeof fn !== 'function') {\n throw new TypeError(ERROR_MESSAGES.BATCH_CALLBACK_MUST_BE_FUNCTION);\n }\n\n scheduler.startBatch();\n try {\n return fn();\n } finally {\n scheduler.endBatch();\n }\n}\n\nlet sharedNextTickPromise: Promise<void> | null = null;\n\n/**\n * Returns a promise that resolves after the next scheduler flush.\n * This can be used to wait for all asynchronous effects to be processed.\n *\n * @param fn - Optional callback to execute after the flush.\n * @returns A promise that resolves after the flush completes.\n */\nexport function aeNextTick(fn?: () => void): Promise<void> {\n if (fn) {\n return new Promise<void>((resolve, reject) => {\n scheduler.schedule(() => {\n try {\n fn();\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n });\n }\n\n if (sharedNextTickPromise) {\n return sharedNextTickPromise;\n }\n\n sharedNextTickPromise = new Promise<void>((resolve) => {\n scheduler.schedule(() => {\n sharedNextTickPromise = null;\n resolve();\n });\n });\n\n return sharedNextTickPromise;\n}\n","import { ATOM_STATE_FLAGS, IS_DEV } from '@/constants';\nimport { ReactiveNode } from '@/core/base';\nimport { BRAND, BrandFlags } from '@/symbols';\nimport type { AtomOptions, WritableAtom } from '@/types';\nimport { debug } from '@/utils/debug';\nimport { nextVersion, scheduler } from './scheduler';\nimport { trackingContext } from './tracking';\n\n/**\n * Internal {@link WritableAtom} implementation.\n */\nclass AtomImpl<T> extends ReactiveNode<T> implements WritableAtom<T> {\n private _value: T;\n /** Old value for notifications */\n private _pendingOldValue: T | undefined;\n /** Equality comparator */\n private _equal: (a: T, b: T) => boolean;\n\n /** @internal */\n readonly [BRAND] = BrandFlags.Atom | BrandFlags.Writable;\n\n constructor(initialValue: T, options: AtomOptions<T>) {\n super();\n this._value = initialValue;\n this._equal = options.equal ?? Object.is;\n\n if (options.sync) {\n this.flags |= ATOM_STATE_FLAGS.SYNC;\n }\n\n if (IS_DEV) {\n debug.attachDebugInfo(this, 'atom', this.id, options.name);\n }\n }\n\n /** @internal */\n get isNotificationScheduled(): boolean {\n return (this.flags & ATOM_STATE_FLAGS.NOTIFICATION_SCHEDULED) !== 0;\n }\n\n /** @internal */\n get isSync(): boolean {\n return (this.flags & ATOM_STATE_FLAGS.SYNC) !== 0;\n }\n\n get value(): T {\n const ctx = trackingContext.current;\n if (ctx != null) {\n ctx.addDependency(this);\n }\n return this._value;\n }\n\n set value(newValue: T) {\n const oldValue = this._value;\n if (this._equal(oldValue, newValue)) return;\n\n this._value = newValue;\n this.version = nextVersion(this.version);\n\n if (IS_DEV) {\n debug.trackUpdate(this.id, debug.getDebugName(this));\n }\n\n const currentFlags = this.flags;\n const SCHED_BIT = ATOM_STATE_FLAGS.NOTIFICATION_SCHEDULED;\n\n // 1. Guard: Skip if already scheduled or no subscribers\n if ((currentFlags & SCHED_BIT) !== 0) return;\n const slots = this._slots;\n if (slots === null || slots.size === 0) return;\n\n // 2. Schedule Notification\n this._pendingOldValue = oldValue;\n const nextFlags = currentFlags | SCHED_BIT;\n this.flags = nextFlags;\n\n // 3. Choice: Flush now or Schedule for later\n const SYNC_BIT = ATOM_STATE_FLAGS.SYNC;\n if ((nextFlags & SYNC_BIT) !== 0 && !scheduler.isBatching) {\n if (this._notifying === 0) {\n this._flushNotifications();\n }\n return;\n }\n\n scheduler.schedule(this);\n }\n\n /**\n * Executes scheduled notification.\n * @internal\n */\n execute(): void {\n this._flushNotifications();\n }\n\n /**\n * Triggers subscribers.\n */\n private _flushNotifications(): void {\n const SCHED_BIT = ATOM_STATE_FLAGS.NOTIFICATION_SCHEDULED;\n const DISP_BIT = ATOM_STATE_FLAGS.DISPOSED;\n const SYNC_BIT = ATOM_STATE_FLAGS.SYNC;\n const LOOP_MASK = SCHED_BIT | DISP_BIT;\n\n let flags = this.flags;\n // Loop to handle re-entrant sync updates in breadth-first order\n while ((flags & LOOP_MASK) === SCHED_BIT) {\n const oldValue = this._pendingOldValue as T;\n this._pendingOldValue = undefined;\n\n // Update bitwise state\n this.flags = flags &= ~SCHED_BIT;\n\n // Net-zero check: if value returned to original during batching, skip notification\n const currentVal = this._value;\n if (!this._equal(currentVal, oldValue)) {\n this._notifySubscribers(currentVal, oldValue);\n }\n\n flags = this.flags;\n // Only continue looping if we are in sync mode and not batching.\n if ((flags & SYNC_BIT) === 0 || scheduler.isBatching) {\n break;\n }\n }\n }\n\n peek(): T {\n return this._value;\n }\n\n dispose(): void {\n const flags = this.flags;\n const DISP_BIT = ATOM_STATE_FLAGS.DISPOSED;\n if ((flags & DISP_BIT) !== 0) return;\n\n this.flags = flags | DISP_BIT;\n this._slots?.clear();\n\n // Release references\n this._value = undefined as T;\n this._pendingOldValue = undefined;\n this._equal = Object.is; // Reset to default\n }\n\n protected override _deepDirtyCheck(): boolean {\n return false;\n }\n}\n\n/**\n * Creates a reactive atom holding mutable state.\n *\n * @param initialValue - The initial value of the atom.\n * @param options - Configuration options (sync: boolean).\n */\nexport function atom<T>(initialValue: T, options: AtomOptions = {}): WritableAtom<T> {\n return new AtomImpl(initialValue, options);\n}\n","import {\n AsyncState,\n COMPUTED_CONFIG,\n COMPUTED_STATE_FLAGS,\n EMPTY_ERROR_ARRAY,\n EPOCH_CONSTANTS,\n IS_DEV,\n} from '@/constants';\nimport { ReactiveNode } from '@/core/base';\nimport { ComputedError, ERROR_MESSAGES, wrapError } from '@/errors';\nimport { BRAND, BrandFlags } from '@/symbols';\nimport type {\n AsyncStateType,\n ComputedAtom,\n ComputedOptions,\n Dependency,\n Subscriber,\n} from '@/types';\nimport { debug, NO_DEFAULT_VALUE } from '@/utils/debug';\nimport { isPromise } from '@/utils/type-guards';\nimport { DepSlotBuffer } from './buffers';\nimport { nextEpoch, nextVersion } from './scheduler';\nimport { DependencyLink, trackingContext, untracked } from './tracking';\n\nconst {\n IDLE,\n DIRTY,\n PENDING,\n RESOLVED,\n REJECTED,\n HAS_ERROR,\n RECOMPUTING,\n DISPOSED,\n IS_COMPUTED,\n FORCE_COMPUTE,\n} = COMPUTED_STATE_FLAGS;\n\n/**\n * Computed atom implementation.\n */\nclass ComputedAtomImpl<T> extends ReactiveNode<T> implements ComputedAtom<T>, Subscriber {\n /** @internal */\n readonly [BRAND] = BrandFlags.Atom | BrandFlags.Computed;\n\n // Bookkeeping fields grouped at top for V8 SMI/Number optimization\n /** Promise tracking ID */\n private _promiseId = 0;\n private _trackEpoch: number = EPOCH_CONSTANTS.UNINITIALIZED;\n private _trackCount = 0;\n\n private _value: T;\n private _error: Error | null = null;\n\n /** Initialized in constructor. Unified node property. */\n _deps = new DepSlotBuffer();\n\n private readonly _equal: (a: T, b: T) => boolean;\n private readonly _computation: () => T | Promise<T>;\n private readonly _defaultValue: T;\n private readonly _onError: ((error: Error) => void) | null;\n\n constructor(computation: () => T | Promise<T>, options: ComputedOptions<T> = {}) {\n if (typeof computation !== 'function')\n throw new ComputedError(ERROR_MESSAGES.COMPUTED_MUST_BE_FUNCTION);\n super();\n\n this._value = undefined as T;\n // Start dirty so first access triggers computation\n this.flags = IS_COMPUTED | DIRTY | IDLE;\n this._equal = options.equal ?? Object.is;\n this._computation = computation;\n this._defaultValue = 'defaultValue' in options ? options.defaultValue : (NO_DEFAULT_VALUE as T);\n this._onError = options.onError ?? null;\n\n debug.attachDebugInfo(this, 'computed', this.id, options.name);\n\n // Eager evaluation if not lazy\n if (options.lazy === false) {\n try {\n this._recompute();\n } catch {\n /* _handleError already stored error and called onError */\n }\n }\n }\n\n /** @internal */\n get isDirty(): boolean {\n return (this.flags & DIRTY) !== 0;\n }\n\n /** @internal */\n get isRejected(): boolean {\n return (this.flags & REJECTED) !== 0;\n }\n\n /** @internal */\n get isRecomputing(): boolean {\n return (this.flags & RECOMPUTING) !== 0;\n }\n\n get value(): T {\n const context = trackingContext.current;\n if (context !== null) context.addDependency(this);\n\n const flags = this.flags;\n // 1. Fast path: Stable and Resolved. Masking multiple flags for single-branch optimization.\n if ((flags & (RESOLVED | DIRTY | IDLE | DISPOSED | RECOMPUTING)) === RESOLVED) {\n return this._value;\n }\n\n // 2. Exception paths (Disposed, Cycles)\n if ((flags & DISPOSED) !== 0) throw new ComputedError(ERROR_MESSAGES.COMPUTED_DISPOSED);\n\n if ((flags & RECOMPUTING) !== 0) {\n const defaultValue = this._defaultValue;\n if (defaultValue !== (NO_DEFAULT_VALUE as T)) return defaultValue;\n throw new ComputedError(ERROR_MESSAGES.COMPUTED_CIRCULAR_DEPENDENCY);\n }\n\n // 3. Evaluation path (Lazy Stale Check)\n if ((flags & (DIRTY | IDLE)) !== 0) {\n const dependencies = this._deps;\n // Force computation if idle, forced, has no deps (initial), or deep check failed\n const shouldRecompute =\n (flags & (IDLE | FORCE_COMPUTE)) !== 0 || dependencies.size === 0 || this._isDirty();\n\n if (!shouldRecompute) {\n this.flags &= ~DIRTY;\n } else {\n this._recompute();\n }\n if ((this.flags & RESOLVED) !== 0) return this._value;\n }\n\n // 4. Async/Error handled after recomputation check\n const defaultValue = this._defaultValue;\n const hasDefault = defaultValue !== (NO_DEFAULT_VALUE as T);\n\n if ((this.flags & PENDING) !== 0) {\n if (hasDefault) return defaultValue;\n throw new ComputedError(ERROR_MESSAGES.COMPUTED_ASYNC_PENDING_NO_DEFAULT);\n }\n\n if ((this.flags & REJECTED) !== 0) {\n if (hasDefault) return defaultValue;\n throw this._error;\n }\n\n return this._value;\n }\n\n peek(): T {\n return this._value;\n }\n\n get state(): AsyncStateType {\n const context = trackingContext.current;\n if (context !== null) context.addDependency(this);\n const flags = this.flags;\n if ((flags & RESOLVED) !== 0) return AsyncState.RESOLVED;\n if ((flags & PENDING) !== 0) return AsyncState.PENDING;\n if ((flags & REJECTED) !== 0) return AsyncState.REJECTED;\n return AsyncState.IDLE;\n }\n\n get hasError(): boolean {\n const context = trackingContext.current;\n if (context !== null) context.addDependency(this);\n\n const flags = this.flags;\n if ((flags & (REJECTED | HAS_ERROR)) !== 0) return true;\n\n const dependencies = this._deps;\n if (!dependencies.hasComputeds) return false;\n\n return untracked(() => {\n const size = dependencies.size;\n for (let i = 0; i < size; i++) {\n const link = dependencies.getAt(i);\n if (link?.node.hasError) return true;\n }\n return false;\n });\n }\n\n get isValid(): boolean {\n return !this.hasError;\n }\n\n get errors(): readonly Error[] {\n const context = trackingContext.current;\n if (context !== null) context.addDependency(this);\n\n const selfError = this._error;\n const dependencies = this._deps;\n\n if (!dependencies.hasComputeds) {\n if (selfError === null) return EMPTY_ERROR_ARRAY;\n return Object.freeze([selfError]);\n }\n\n const collected: Error[] = [];\n if (selfError !== null) collected.push(selfError);\n\n untracked(() => {\n const size = dependencies.size;\n for (let i = 0; i < size; i++) {\n const link = dependencies.getAt(i);\n const dependencyNode = link?.node;\n if (dependencyNode !== undefined && (dependencyNode.flags & IS_COMPUTED) !== 0) {\n this._accumulateErrors(dependencyNode as unknown as ComputedAtomImpl<unknown>, collected);\n }\n }\n });\n\n return collected.length === 0 ? EMPTY_ERROR_ARRAY : Object.freeze(collected);\n }\n\n private _accumulateErrors(dependency: ComputedAtomImpl<unknown>, collected: Error[]): void {\n const error = dependency._error;\n if (error !== null && !collected.includes(error)) {\n collected.push(error);\n }\n\n const dependencies = dependency._deps;\n if (!dependencies.hasComputeds) return;\n\n const size = dependencies.size;\n for (let i = 0; i < size; i++) {\n const link = dependencies.getAt(i);\n const node = link?.node;\n if (node !== undefined && (node.flags & IS_COMPUTED) !== 0) {\n this._accumulateErrors(node as unknown as ComputedAtomImpl<unknown>, collected);\n }\n }\n }\n\n get lastError(): Error | null {\n const context = trackingContext.current;\n if (context !== null) context.addDependency(this);\n return this._error;\n }\n\n get isPending(): boolean {\n const context = trackingContext.current;\n if (context !== null) context.addDependency(this);\n return (this.flags & PENDING) !== 0;\n }\n\n get isResolved(): boolean {\n const context = trackingContext.current;\n if (context !== null) context.addDependency(this);\n return (this.flags & RESOLVED) !== 0;\n }\n\n invalidate(): void {\n this.flags |= FORCE_COMPUTE;\n this._markDirty();\n }\n\n dispose(): void {\n const flags = this.flags;\n if ((flags & DISPOSED) !== 0) return;\n\n this._deps.disposeAll();\n\n if (this._slots !== null) {\n this._slots.clear();\n }\n this.flags = DISPOSED | DIRTY | IDLE;\n\n this._error = null;\n this._value = undefined as T;\n this._hotIndex = -1;\n }\n\n addDependency(dependency: Dependency): void {\n const trackEpoch = this._trackEpoch;\n if (dependency._lastSeenEpoch === trackEpoch) return;\n dependency._lastSeenEpoch = trackEpoch;\n\n const trackIndex = this._trackCount++;\n const dependencies = this._deps;\n\n // Unrolled hot-path check for existing dependencies\n let existing: DependencyLink | null = null;\n if (trackIndex < 4) {\n if (trackIndex === 0) existing = dependencies._s0;\n else if (trackIndex === 1) existing = dependencies._s1;\n else if (trackIndex === 2) existing = dependencies._s2;\n else existing = dependencies._s3;\n } else {\n const overflow = dependencies._overflow;\n if (overflow !== null) existing = overflow[trackIndex - 4] ?? null;\n }\n\n if (existing !== null && existing.node === dependency) {\n existing.version = dependency.version;\n } else if (dependencies.claimExisting(dependency, trackIndex)) {\n // Version and relocation handled inside claimExisting\n } else {\n const link = new DependencyLink(dependency, dependency.version, dependency.subscribe(this));\n dependencies.insertNew(trackIndex, link);\n }\n\n if ((dependency.flags & IS_COMPUTED) !== 0) {\n dependencies.hasComputeds = true;\n }\n }\n\n private _recompute(): void {\n if ((this.flags & RECOMPUTING) !== 0) return;\n this.flags = (this.flags | RECOMPUTING) & ~FORCE_COMPUTE;\n\n this._trackEpoch = nextEpoch();\n this._trackCount = 0;\n this._deps.prepareTracking();\n this._hotIndex = -1;\n\n let committed = false;\n try {\n const result = trackingContext.run(this, this._computation);\n this._deps.truncateFrom(this._trackCount);\n committed = true;\n\n if (isPromise(result)) {\n this._handleAsyncComputation(result);\n } else {\n this._finalizeResolution(result);\n }\n } catch (e) {\n if (!committed) {\n try {\n this._deps.truncateFrom(this._trackCount);\n } catch (commitError) {\n if (IS_DEV) {\n console.warn('[atom-effect] _commitDeps failed during error recovery:', commitError);\n }\n }\n }\n this._handleError(e as Error, ERROR_MESSAGES.COMPUTED_COMPUTATION_FAILED, true);\n } finally {\n this._trackEpoch = EPOCH_CONSTANTS.UNINITIALIZED;\n this._trackCount = 0;\n this.flags &= ~RECOMPUTING;\n }\n }\n\n private _handleAsyncComputation(promise: Promise<T>): void {\n this.flags = (this.flags | PENDING) & ~(IDLE | DIRTY | RESOLVED | REJECTED);\n this._notifySubscribers(undefined, undefined);\n\n this._promiseId = (this._promiseId + 1) % COMPUTED_CONFIG.MAX_PROMISE_ID;\n const promiseId = this._promiseId;\n\n promise.then(\n (result) => {\n if (promiseId !== this._promiseId) return;\n if (this._isDirty()) return this._markDirty();\n\n this._finalizeResolution(result);\n this._notifySubscribers(result, undefined);\n },\n (error) =>\n promiseId === this._promiseId &&\n this._handleError(error, ERROR_MESSAGES.COMPUTED_ASYNC_COMPUTATION_FAILED)\n );\n }\n\n private _handleError(error: unknown, message: string, shouldThrow = false): void {\n const wrappedError = wrapError(error, ComputedError, message);\n\n if (!this.isRejected || this._error !== wrappedError) {\n this.version = nextVersion(this.version);\n }\n\n this._error = wrappedError;\n this.flags = (this.flags & ~(IDLE | DIRTY | PENDING | RESOLVED)) | REJECTED | HAS_ERROR;\n\n if (this._onError) {\n try {\n this._onError(wrappedError);\n } catch (e) {\n console.error(ERROR_MESSAGES.CALLBACK_ERROR_IN_ERROR_HANDLER, e);\n }\n }\n\n this._notifySubscribers(undefined, undefined);\n if (shouldThrow) throw wrappedError;\n }\n\n private _finalizeResolution(value: T): void {\n const flags = this.flags;\n if ((flags & RESOLVED) === 0 || !this._equal(this._value, value)) {\n this.version = nextVersion(this.version);\n }\n\n this._value = value;\n this._error = null;\n this.flags = (flags | RESOLVED) & ~(IDLE | DIRTY | PENDING | REJECTED | HAS_ERROR);\n }\n\n execute(): void {\n this._markDirty();\n }\n\n /** @internal */\n _markDirty(): void {\n const flags = this.flags;\n if ((flags & (RECOMPUTING | DIRTY)) !== 0) return;\n this.flags = flags | DIRTY;\n debug.trackUpdate(this.id, debug.getDebugName(this));\n this._notifySubscribers(undefined, undefined);\n }\n\n /**\n * Deep dirty check for computations.\n * Optimized with hot-index caching and unrolled scanning.\n */\n protected override _deepDirtyCheck(): boolean {\n const dependencies = this._deps;\n const size = dependencies.size;\n const hotIndex = this._hotIndex;\n\n return untracked(() => {\n // 1. Try last known dirty dependency first\n if (hotIndex !== -1 && hotIndex < size) {\n const link = dependencies.getAt(hotIndex);\n if (link !== null && this._checkLinkDirty(link)) return true;\n }\n\n // 2. Scan from beginning, skipping hot entry\n for (let i = 0; i < size; i++) {\n if (i === hotIndex) continue;\n const link = dependencies.getAt(i);\n if (link !== null && this._checkLinkDirty(link)) {\n this._hotIndex = i;\n return true;\n }\n }\n\n this._hotIndex = -1;\n return false;\n });\n }\n\n private _checkLinkDirty(link: DependencyLink): boolean {\n const dependency = link.node;\n if ((dependency.flags & IS_COMPUTED) !== 0) {\n try {\n void (dependency as { value: unknown }).value;\n } catch {\n if (IS_DEV) console.warn(`[atom-effect] Dependency #${dependency.id} threw during check`);\n }\n }\n return dependency.version !== link.version;\n }\n}\n\n/**\n * Creates a computed value.\n * @param computation - Computation function\n * @param options - Options object\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);\n}\n","import {\n DEBUG_CONFIG,\n EFFECT_STATE_FLAGS,\n EPOCH_CONSTANTS,\n IS_DEV,\n SCHEDULER_CONFIG,\n} from '@/constants';\nimport { ReactiveNode } from '@/core/base';\nimport { EffectError, ERROR_MESSAGES, wrapError } from '@/errors';\nimport { BRAND, BrandFlags } from '@/symbols';\nimport type { Dependency, EffectFunction, EffectObject, EffectOptions } from '@/types';\nimport { debug } from '@/utils/debug';\nimport { isPromise } from '@/utils/type-guards';\nimport { DepSlotBuffer } from './buffers';\nimport {\n currentFlushEpoch,\n flushExecutionCount,\n incrementFlushExecutionCount,\n nextEpoch,\n scheduler,\n} from './scheduler';\nimport { DependencyLink, type DependencyTracker, trackingContext } from './tracking';\n\n/**\n * Effect implementation.\n */\nclass EffectImpl extends ReactiveNode<void> implements EffectObject, DependencyTracker {\n /** @internal */\n readonly [BRAND] = BrandFlags.Effect;\n\n // Bookkeeping fields grouped at top for V8 layout optimization\n private _currentEpoch: number = EPOCH_CONSTANTS.UNINITIALIZED;\n private _lastFlushEpoch: number = EPOCH_CONSTANTS.UNINITIALIZED;\n private _executionsInEpoch = 0;\n private _executionCount = 0;\n private _windowStart = 0;\n private _windowCount = 0;\n private _execId = 0;\n private _trackCount = 0;\n\n private _cleanup: (() => void) | null = null;\n /** Initialized in constructor to maintain God Class object shape */\n _deps = new DepSlotBuffer();\n\n /** Pre-allocated notify callback shared by all subscriptions */\n private readonly _notifyCallback: () => void;\n\n private readonly _onError: ((error: unknown) => void) | null;\n\n private readonly _fn: EffectFunction;\n private readonly _sync: boolean;\n private readonly _maxExecutions: number;\n private readonly _maxExecutionsPerFlush: number;\n\n constructor(fn: EffectFunction, options: EffectOptions = {}) {\n super();\n this._fn = fn;\n this._onError = options.onError ?? null;\n this._sync = options.sync ?? false;\n this._maxExecutions =\n options.maxExecutionsPerSecond ?? SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_SECOND;\n this._maxExecutionsPerFlush =\n options.maxExecutionsPerFlush ?? SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_EFFECT;\n\n // Pre-allocate callbacks once — eliminates per-dependency closure allocation\n if (this._sync) {\n this._notifyCallback = () => this.execute();\n } else {\n this._notifyCallback = () => scheduler.schedule(this);\n }\n\n debug.attachDebugInfo(this, 'effect', this.id, options.name);\n }\n\n public run(): void {\n if (this.isDisposed) {\n throw new EffectError(ERROR_MESSAGES.EFFECT_DISPOSED);\n }\n this.execute(true);\n }\n\n public dispose(): void {\n if (this.isDisposed) return;\n this.flags |= EFFECT_STATE_FLAGS.DISPOSED;\n\n this._execCleanup();\n this._deps?.disposeAll();\n }\n\n public addDependency(dep: Dependency): void {\n if ((this.flags & EFFECT_STATE_FLAGS.EXECUTING) === 0) return;\n\n if (dep._lastSeenEpoch === this._currentEpoch) return;\n dep._lastSeenEpoch = this._currentEpoch;\n\n const trackIndex = this._trackCount++;\n const deps = this._deps;\n const version = dep.version;\n\n // [Optimization] Fast-path lookup bypassing SlotBuffer.getAt() or switch statements\n let existing: DependencyLink | null = null;\n if (trackIndex < 4) {\n if (trackIndex === 0) existing = deps._s0;\n else if (trackIndex === 1) existing = deps._s1;\n else if (trackIndex === 2) existing = deps._s2;\n else existing = deps._s3;\n } else {\n const ov = deps._overflow;\n if (ov !== null) existing = ov[trackIndex - 4] ?? null;\n }\n\n if (existing !== null && existing.node === dep) {\n existing.version = version;\n } else if (!deps.claimExisting(dep, trackIndex)) {\n this._insertNewDependency(dep, trackIndex, version);\n }\n\n if (dep.isComputed && !deps.hasComputeds) {\n deps.hasComputeds = true;\n }\n }\n\n private _insertNewDependency(dep: Dependency, trackIndex: number, version: number): void {\n let link: DependencyLink;\n try {\n const unsubscribe = dep.subscribe(this._notifyCallback);\n link = new DependencyLink(dep, version, unsubscribe);\n } catch (error) {\n const wrapped = wrapError(error, EffectError, ERROR_MESSAGES.EFFECT_EXECUTION_FAILED);\n console.error(wrapped);\n if (this._onError) {\n try {\n this._onError(wrapped);\n } catch {}\n }\n link = new DependencyLink(dep, version, undefined);\n }\n\n this._deps.insertNew(trackIndex, link);\n }\n\n /**\n * Executes effect with tracking.\n */\n public execute(force = false): void {\n const flags = this.flags;\n // Guard: Combined bitwise check for efficiency\n if ((flags & (EFFECT_STATE_FLAGS.DISPOSED | EFFECT_STATE_FLAGS.EXECUTING)) !== 0) return;\n\n // Skip if not dirty or forced\n const deps = this._deps;\n if (!force && deps.physicalSize > 0 && !this._isDirty()) return;\n\n this._checkInfiniteLoops();\n debug.trackUpdate(this.id, debug.getDebugName(this));\n\n this.flags = flags | EFFECT_STATE_FLAGS.EXECUTING;\n this._execCleanup();\n\n this._currentEpoch = nextEpoch();\n this._trackCount = 0;\n deps.prepareTracking();\n this._hotIndex = -1;\n\n let committed = false;\n try {\n const result = trackingContext.run(this, this._fn);\n\n // Clean up any remaining trailing dependencies\n deps.truncateFrom(this._trackCount);\n committed = true;\n\n // Handle result\n if (typeof result === 'function') {\n this._cleanup = result as () => void;\n } else if (isPromise(result)) {\n this._handleAsyncResult(result);\n } else {\n this._cleanup = null;\n }\n } catch (error) {\n // Commit on error gracefully to maintain state for recovery\n if (!committed) {\n try {\n deps.truncateFrom(this._trackCount);\n } catch (commitErr) {\n if (IS_DEV) {\n console.warn('[atom-effect] _commitDeps failed during error recovery:', commitErr);\n }\n }\n }\n this._handleExecutionError(error);\n this._cleanup = null;\n } finally {\n this.flags &= ~EFFECT_STATE_FLAGS.EXECUTING;\n }\n }\n\n private _handleAsyncResult(promise: Promise<unknown>): void {\n const execId = ++this._execId;\n promise.then(\n (cleanup) => {\n if (execId !== this._execId || (this.flags & EFFECT_STATE_FLAGS.DISPOSED) !== 0) {\n if (typeof cleanup === 'function') {\n try {\n cleanup();\n } catch (e) {\n this._handleExecutionError(e, ERROR_MESSAGES.EFFECT_CLEANUP_FAILED);\n }\n }\n return;\n }\n if (typeof cleanup === 'function') this._cleanup = cleanup as () => void;\n },\n (err) => execId === this._execId && this._handleExecutionError(err)\n );\n }\n\n protected override _isDirty(): boolean {\n const deps = this._deps;\n const size = deps.size;\n if (size === 0) return false;\n\n // Fast path: Check hot index first without switching context\n const hotIndex = this._hotIndex;\n if (hotIndex !== -1 && hotIndex < size) {\n const link = deps.getAt(hotIndex);\n if (link !== null) {\n const dep = link.node;\n // Correctness: Only non-computed deps can skip context switch/deep check\n if (!dep.isComputed && dep.version !== link.version) return true;\n }\n }\n\n return this._deepDirtyCheck();\n }\n\n protected override _deepDirtyCheck(): boolean {\n const deps = this._deps;\n const size = deps.size;\n const hotIdx = this._hotIndex;\n\n const prevContext = trackingContext.current;\n trackingContext.current = null;\n\n try {\n // Priority 1: Check others with hotIdx skip\n for (let i = 0; i < size; i++) {\n if (i === hotIdx) continue;\n const link = deps.getAt(i);\n if (link === null) continue;\n\n const dep = link.node;\n if (dep.isComputed) {\n try {\n void (dep as { value: unknown }).value;\n } catch {\n if (IS_DEV) {\n console.warn(`[atom-effect] Dependency #${dep.id} error in check`);\n }\n }\n }\n\n if (dep.version !== link.version) {\n this._hotIndex = i;\n return true;\n }\n }\n this._hotIndex = -1;\n return false;\n } finally {\n trackingContext.current = prevContext;\n }\n }\n\n private _execCleanup(): void {\n const cleanup = this._cleanup;\n if (cleanup == null) return;\n this._cleanup = null;\n try {\n cleanup();\n } catch (error) {\n this._handleExecutionError(error, ERROR_MESSAGES.EFFECT_CLEANUP_FAILED);\n }\n }\n\n private _checkInfiniteLoops(): void {\n const epoch = currentFlushEpoch();\n if (this._lastFlushEpoch !== epoch) {\n this._lastFlushEpoch = epoch;\n this._executionsInEpoch = 0;\n }\n\n const executions = ++this._executionsInEpoch;\n if (executions > this._maxExecutionsPerFlush) this._throwInfiniteLoopError('per-effect');\n\n const globalExecutions = incrementFlushExecutionCount();\n if (globalExecutions > SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_FLUSH) {\n this._throwInfiniteLoopError('global');\n }\n\n this._executionCount++;\n\n if (IS_DEV) this._checkFrequencyLimit();\n }\n\n private _checkFrequencyLimit(): void {\n if (!Number.isFinite(this._maxExecutions)) return;\n\n const now = Date.now();\n if (now - this._windowStart >= DEBUG_CONFIG.EFFECT_FREQUENCY_WINDOW) {\n this._windowStart = now;\n this._windowCount = 1;\n return;\n }\n\n if (++this._windowCount > this._maxExecutions) {\n const err = new EffectError(ERROR_MESSAGES.EFFECT_FREQUENCY_LIMIT_EXCEEDED);\n this.dispose();\n this._handleExecutionError(err);\n throw err;\n }\n }\n\n get executionCount(): number {\n return this._executionCount;\n }\n get isExecuting(): boolean {\n return (this.flags & EFFECT_STATE_FLAGS.EXECUTING) !== 0;\n }\n\n private _throwInfiniteLoopError(type: 'per-effect' | 'global'): never {\n const error = new EffectError(\n `Infinite loop detected (${type}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${flushExecutionCount}`\n );\n this.dispose();\n console.error(error);\n throw error;\n }\n\n private _handleExecutionError(\n error: unknown,\n message: string = ERROR_MESSAGES.EFFECT_EXECUTION_FAILED\n ): void {\n const errorObj = wrapError(error, EffectError, message);\n console.error(errorObj);\n if (this._onError) {\n try {\n this._onError(errorObj);\n } catch (e) {\n console.error(wrapError(e, EffectError, ERROR_MESSAGES.CALLBACK_ERROR_IN_ERROR_HANDLER));\n }\n }\n }\n}\n\n/**\n * Creates and starts an effect.\n *\n * @param fn - Effect function.\n * @param options - Configuration options.\n * @returns Effect instance.\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 effectInstance.execute();\n\n return effectInstance;\n}\n","import { BRAND, BrandFlags } from '@/symbols';\nimport type { Paths, PathValue, WritableAtom } from '../types';\n\n/**\n * Internal recursive helper for creating deep immutable copies with structural sharing.\n * Optimized for performance: avoids Regex overhead and minimizes object allocations.\n */\nexport function setDeepValue(obj: unknown, keys: string[], index: number, value: unknown): unknown {\n if (index === keys.length) return value;\n\n const key = keys[index]!;\n // Fast string-based safety check instead of Regex\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') return obj;\n\n const isObj = obj != null && typeof obj === 'object';\n const curr = (isObj ? obj : {}) as Record<string, unknown>;\n const oldVal = curr[key];\n const newVal = setDeepValue(oldVal, keys, index + 1, value);\n\n // Return original if value is unchanged (structural sharing)\n if (Object.is(oldVal, newVal)) return obj;\n\n if (Array.isArray(curr)) {\n const copy = curr.slice();\n const idx = +key;\n // Check for valid array index (positive integer, non-empty)\n if (key.trim() !== '' && idx >= 0 && idx % 1 === 0) {\n copy[idx] = newVal;\n } else {\n (copy as unknown as Record<string, unknown>)[key] = newVal;\n }\n return copy;\n }\n\n const res = { ...curr };\n res[key] = newVal;\n return res;\n}\n\n/**\n * Helper to retrieve a nested value from an object/array at a given path.\n */\nexport function getPathValue(source: unknown, parts: string[]): unknown {\n let res = source;\n const len = parts.length;\n for (let i = 0; i < len; i++) {\n if (res == null) return undefined;\n const key = parts[i]!;\n // Performance: Fast string comparison avoids Regex overhead in hot paths\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') return undefined;\n res = (res as Record<string, unknown>)[key];\n }\n return res;\n}\n\n/**\n * Creates a two-way \"lens\" for a specific property path on an object-based atom.\n *\n * @example\n * const store = atom({ user: { name: 'Alice' } });\n * const nameLens = atomLens(store, 'user.name');\n * console.log(nameLens.value); // 'Alice'\n * nameLens.value = 'Bob'; // Updates store.user.name immutably\n */\nexport function atomLens<T extends object, P extends Paths<T>>(\n atom: WritableAtom<T>,\n path: P\n): WritableAtom<PathValue<T, P>> {\n const parts = path.includes('.') ? path.split('.') : [path];\n const unsubs = new Set<() => void>();\n const dispose = () => {\n unsubs.forEach((u) => u());\n unsubs.clear();\n };\n\n return {\n get value() {\n return getPathValue(atom.value, parts) as PathValue<T, P>;\n },\n set value(newVal: PathValue<T, P>) {\n const cur = atom.peek(),\n next = setDeepValue(cur, parts, 0, newVal);\n if (next !== cur) atom.value = next as T;\n },\n peek: () => getPathValue(atom.peek(), parts) as PathValue<T, P>,\n subscribe(listener: (nv: PathValue<T, P>, ov: PathValue<T, P>) => void) {\n // Local tracking of prevValue cuts getPathValue calls by 50% during root updates\n let prevValue = getPathValue(atom.peek(), parts) as PathValue<T, P>;\n\n const unsub = atom.subscribe((np) => {\n const nv = getPathValue(np, parts) as PathValue<T, P>;\n if (!Object.is(nv, prevValue)) {\n const ov = prevValue;\n prevValue = nv;\n listener(nv, ov);\n }\n });\n unsubs.add(unsub);\n return () => {\n unsub();\n unsubs.delete(unsub);\n };\n },\n subscriberCount: () => unsubs.size,\n dispose,\n [BRAND]: BrandFlags.Atom | BrandFlags.Writable,\n } as unknown as WritableAtom<PathValue<T, P>>;\n}\n\n/**\n * Composes an existing lens with a sub-path to create a deeper lens.\n */\nexport const composeLens = <T extends object, P extends Paths<T>>(lens: WritableAtom<T>, path: P) =>\n atomLens(lens, path);\n\n/**\n * Creates a lens factory bound to a specific atom.\n */\nexport const lensFor =\n <T extends object>(atom: WritableAtom<T>) =>\n <P extends Paths<T>>(path: P) =>\n atomLens(atom, path);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../src/constants.ts","../../utils/dist/index.js","../src/errors.ts","../src/symbols.ts","../src/utils/debug.ts","../src/core/buffers.ts","../src/core/tracking.ts","../src/core/base.ts","../src/core/scheduler.ts","../src/core/atom.ts","../src/utils/type-guards.ts","../src/utils/index.ts","../src/core/computed.ts","../src/core/effect.ts","../src/core/lens.ts"],"sourcesContent":["import type { SchedulerConfig } from './types';\n\n/**\n * Logic: Bitspace Partitioning\n * Defines the starting bit index for different node types and states.\n */\nconst OFFSET = {\n CORE: 0,\n COMPUTED: 8,\n ASYNC: 16,\n PRIMITIVE: 24,\n} as const satisfies Record<string, number>;\n\n/**\n * Internal bitmask flags for `ReactiveNode` state management.\n *\n * Logic: State Representation\n * Uses a single bit per state to allow for compound checks via bitwise OR (|)\n * and state transitions via bitwise XOR (^) or AND NOT (& ~).\n *\n * @internal\n */\nconst FLAGS = {\n // Shared Core (0-7)\n DISPOSED: 1 << (OFFSET.CORE + 0),\n IS_COMPUTED: 1 << (OFFSET.CORE + 1),\n\n // Computed Flags (8-15)\n DIRTY: 1 << (OFFSET.COMPUTED + 0),\n RECOMPUTING: 1 << (OFFSET.COMPUTED + 1),\n HAS_ERROR: 1 << (OFFSET.COMPUTED + 2),\n FORCE_COMPUTE: 1 << (OFFSET.COMPUTED + 3),\n\n // Async States (16-23)\n IDLE: 1 << (OFFSET.ASYNC + 0),\n PENDING: 1 << (OFFSET.ASYNC + 1),\n RESOLVED: 1 << (OFFSET.ASYNC + 2),\n REJECTED: 1 << (OFFSET.ASYNC + 3),\n\n // Atom Specific (24-27)\n ATOM_SYNC: 1 << (OFFSET.PRIMITIVE + 0),\n ATOM_NOTIFICATION_SCHEDULED: 1 << (OFFSET.PRIMITIVE + 1),\n\n // Effect Specific (28-30)\n EFFECT_EXECUTING: 1 << (OFFSET.PRIMITIVE + 4),\n} as const satisfies Record<string, number>;\n\n/**\n * Compound bitmasks for multi-state validation and bulk resets.\n *\n * Optimization: Bulk Validation\n * Using compound masks reduces the number of bitwise comparisons in hot paths\n * (e.g., checking if a node is in any async state).\n *\n * @internal\n */\nexport const STATE_MASKS = Object.freeze({\n /** Covers all asynchronous lifecycle states. */\n ASYNC_STATE: FLAGS.IDLE | FLAGS.PENDING | FLAGS.RESOLVED | FLAGS.REJECTED,\n /** Covers all states indicating a requirement for re-computation. */\n COMPUTED_DIRTY_MASK: FLAGS.DIRTY | FLAGS.RECOMPUTING | FLAGS.FORCE_COMPUTE,\n});\n\n/**\n * Asynchronous operation states for public API consumption.\n *\n * When to use:\n * - To verify or branch logic based on the status of an asynchronous atom or computed node.\n *\n * @example\n * ```typescript\n * import { AsyncState } from '@but212/atom-effect';\n *\n * if (userProfile.status === AsyncState.PENDING) {\n * showSpinner();\n * }\n * ```\n */\nexport const AsyncState = Object.freeze({\n IDLE: 'idle',\n PENDING: 'pending',\n RESOLVED: 'resolved',\n REJECTED: 'rejected',\n} satisfies Record<string, string>);\n\n/**\n * Logic: Shared State Interface\n * Defines the bitmask contract for Effect-type nodes.\n * @internal\n */\nexport const EFFECT_STATE_FLAGS = Object.freeze({\n DISPOSED: FLAGS.DISPOSED,\n EXECUTING: FLAGS.EFFECT_EXECUTING,\n});\n\n/**\n * Logic: Shared State Interface\n * Defines the bitmask contract for Computed-type nodes.\n * @internal\n */\nexport const COMPUTED_STATE_FLAGS = Object.freeze({\n DISPOSED: FLAGS.DISPOSED,\n IS_COMPUTED: FLAGS.IS_COMPUTED,\n DIRTY: FLAGS.DIRTY,\n IDLE: FLAGS.IDLE,\n PENDING: FLAGS.PENDING,\n RESOLVED: FLAGS.RESOLVED,\n REJECTED: FLAGS.REJECTED,\n RECOMPUTING: FLAGS.RECOMPUTING,\n HAS_ERROR: FLAGS.HAS_ERROR,\n FORCE_COMPUTE: FLAGS.FORCE_COMPUTE,\n});\n\n/**\n * Logic: Shared State Interface\n * Defines the bitmask contract for Atom-type nodes.\n * @internal\n */\nexport const ATOM_STATE_FLAGS = Object.freeze({\n DISPOSED: FLAGS.DISPOSED,\n SYNC: FLAGS.ATOM_SYNC,\n NOTIFICATION_SCHEDULED: FLAGS.ATOM_NOTIFICATION_SCHEDULED,\n});\n\n/**\n * Global configuration parameters for the Scheduler.\n *\n * Caution: Modification of these thresholds can lead to instability,\n * memory leaks, or execution overflows in complex dependency graphs.\n */\nexport const SCHEDULER_CONFIG = Object.freeze({\n /**\n * Reason: Prevents infinite loops or runaway effects from freezing the main thread.\n */\n MAX_EXECUTIONS_PER_SECOND: 1000,\n /**\n * Reason: Detects and stops circular dependencies within a single microtask.\n */\n MAX_EXECUTIONS_PER_EFFECT: 100,\n\n /**\n * Reason: Limits the total workload per flush to maintain frame-rate stability.\n */\n MAX_EXECUTIONS_PER_FLUSH: 10000,\n /**\n * Reason: Safety break for the drain-loop to prevent stack overflows or infinite flushing.\n */\n MAX_FLUSH_ITERATIONS: 1000,\n /**\n * Optimization: Batching\n * Ensures a minimum number of iterations are processed to allow for nested batched updates.\n */\n MIN_FLUSH_ITERATIONS: 10,\n\n /**\n * Optimization: Memory Pressure\n * Threshold for shrinking the internal batch queue to release memory back to the heap.\n */\n BATCH_QUEUE_SHRINK_THRESHOLD: 1000,\n} satisfies SchedulerConfig);\n\n/**\n * Optimization: V8 SMI (Small Integer) Limit\n *\n * Values within this range (up to 30-bit signed) are stored directly in CPU registers\n * by V8, bypassing heap allocation and boxing overhead.\n *\n * @internal\n */\nexport const SMI_MAX = 0x3fffffff;\n\n/**\n * Thresholds for development-time diagnostics.\n * @internal\n */\nexport const DEBUG_CONFIG = Object.freeze({\n /** Enables console warnings when potential infinite loops are detected. */\n WARN_INFINITE_LOOP: true,\n /** The time window (ms) for monitoring update frequency. */\n EFFECT_FREQUENCY_WINDOW: 1000,\n /** The update count limit before triggering a loop warning. */\n LOOP_THRESHOLD: 100,\n} satisfies Record<string, boolean | number>);\n\n/**\n * Sentinel values for epoch-based staleness tracking.\n *\n * Logic: Drift Detection\n * Epochs are used to determine if a dependency has changed since the last\n * computation without needing deep comparison.\n *\n * @internal\n */\nexport const EPOCH_CONSTANTS = Object.freeze({\n /** Initial state indicating no computation has occurred. */\n UNINITIALIZED: -1,\n /** Reset floor for epoch counters to avoid 0/falsy confusion. */\n MIN: 1,\n});\n\n/**\n * Logic: Runtime Debug Override\n * Checks for explicit debug flags in the global environment or session storage.\n */\nconst getRuntimeDebug = (): boolean => {\n try {\n return !!(\n (typeof globalThis !== 'undefined' &&\n (globalThis as unknown as { __ATOM_DEBUG__?: boolean }).__ATOM_DEBUG__) ||\n (typeof sessionStorage !== 'undefined' && sessionStorage.getItem('__ATOM_DEBUG__') === 'true')\n );\n } catch {\n return false;\n }\n};\n\n/**\n * Logic: Environment Metadata\n * Heuristic detection of bundler-injected development environment flags.\n */\nconst getImportMetaDev = (): boolean => {\n try {\n return !!(import.meta as unknown as { env?: { DEV?: boolean } }).env?.DEV;\n } catch {\n return false;\n }\n};\n\n/**\n * Logic: Multi-Environment Resolution\n * Aggregates signals from Node.js, Vite/Web-pack, ESM, and manual runtime overrides.\n */\nconst DEV_SIGNALS = {\n node: typeof process !== 'undefined' && process.env && process.env.NODE_ENV !== 'production',\n bundler: typeof __DEV__ !== 'undefined' && !!__DEV__,\n esm: typeof process === 'undefined' && getImportMetaDev(),\n runtime: getRuntimeDebug(),\n} as const;\n\n/**\n * Indicates if the library is running in a development environment.\n * When true, additional validation, diagnostic warnings, and loop protections are active.\n */\nexport const IS_DEV =\n DEV_SIGNALS.node || DEV_SIGNALS.bundler || DEV_SIGNALS.esm || DEV_SIGNALS.runtime;\n\ndeclare const __DEV__: boolean;\n\n/**\n * Optimization: Shared Immutable Empty State\n *\n * Constraint: Must remain immutable to prevent memory leaks and unexpected\n * side-effects in subscriber logic that expects an array structure.\n *\n * @internal\n */\nexport const EMPTY_ERROR_ARRAY: readonly Error[] = Object.freeze([]);\n","// src/symbols.ts\nvar OPTION_SYMBOL = /* @__PURE__ */ Symbol.for(\"atom-effect.Option\");\nvar RESULT_SYMBOL = /* @__PURE__ */ Symbol.for(\"atom-effect.Result\");\n\n// src/option.ts\nvar NONE = Object.freeze({\n ok: false,\n value: void 0,\n [OPTION_SYMBOL]: true\n});\nvar Option = {\n /**\n * Creates a {@link Some} instance holding the provided value.\n */\n some: (value) => ({\n ok: true,\n value,\n [OPTION_SYMBOL]: true\n }),\n /**\n * A constant representing the absence of a value.\n */\n none: NONE,\n /**\n * Type guard to check if an {@link Option} contains a value.\n */\n isSome: (opt) => opt.ok,\n /**\n * Type guard to check if an {@link Option} is empty.\n */\n isNone: (opt) => !opt.ok,\n /**\n * Returns the value if present, otherwise throws an error with the provided message.\n */\n expect: (opt, message) => {\n if (opt.ok) return opt.value;\n throw new Error(message);\n },\n /**\n * Extracts the inner value if present.\n */\n unwrap: (opt) => {\n if (!opt.ok) throw new Error(\"Option.unwrap() on None\");\n return opt.value;\n },\n /**\n * Returns the inner value if present, otherwise returns a fallback value.\n */\n unwrapOr: (opt, fallback) => opt.ok ? opt.value : fallback,\n /**\n * Returns the inner value if present, otherwise computes a fallback value.\n */\n unwrapOrElse: (opt, fn) => opt.ok ? opt.value : fn(),\n /**\n * Transforms the inner value using the provided function if present.\n */\n map: (opt, fn) => {\n if (!opt.ok) return opt;\n const next = fn(opt.value);\n return next === opt.value ? opt : Option.some(next);\n },\n /**\n * Chains a function that returns another {@link Option}.\n */\n andThen: (opt, fn) => opt.ok ? fn(opt.value) : opt,\n /**\n * Creates an {@link Option} from a value that might be `null` or `undefined`.\n */\n fromNullable: (value) => value == null ? NONE : Option.some(value),\n /**\n * Executes a branch handler based on whether the option is {@link Some} or {@link None}.\n */\n match: (opt, branches) => opt.ok ? branches.some(opt.value) : branches.none(),\n /**\n * Returns {@link None} if the inner value does not satisfy the predicate.\n */\n filter: (opt, predicate) => opt.ok && predicate(opt.value) ? opt : NONE,\n /**\n * Checks for strict equality between two options.\n */\n equals: (a, b) => {\n if (a === b) return true;\n if (a.ok !== b.ok) return false;\n return !a.ok || a.value === b.value;\n },\n /**\n * Converts an {@link Option} to a nullable type.\n */\n toNullable: (opt) => opt.ok ? opt.value : null,\n /**\n * Converts an {@link Option} to an undefined type.\n */\n toUndefined: (opt) => opt.ok ? opt.value : void 0\n};\n\n// src/result.ts\nvar VOID_SUCCESS = Object.freeze({\n ok: true,\n value: void 0,\n error: void 0,\n [RESULT_SYMBOL]: true\n});\nfunction toError(e) {\n if (e instanceof Error) return e;\n const message = typeof e === \"string\" ? e : String(e ?? \"Unknown error\");\n return new Error(message);\n}\nvar Result = {\n /**\n * Creates a successful Result.\n */\n ok: (value) => {\n if (value === void 0) return VOID_SUCCESS;\n return {\n ok: true,\n value,\n error: void 0,\n [RESULT_SYMBOL]: true\n };\n },\n /**\n * Creates a failed Result.\n */\n err: (error) => ({\n ok: false,\n value: void 0,\n error,\n [RESULT_SYMBOL]: true\n }),\n /**\n * Type guard for Ok variant.\n */\n isOk: (res) => res.ok,\n /**\n * Type guard for Err variant.\n */\n isErr: (res) => !res.ok,\n /**\n * Exhaustively handles both possible states of a Result.\n */\n match: (res, matcher) => res.ok ? matcher.ok(res.value) : matcher.err(res.error),\n /**\n * Extracts the value if Ok, otherwise throws the error.\n */\n unwrap: (res) => {\n if (!res.ok) throw res.error;\n return res.value;\n },\n /**\n * Extracts the value if Ok, otherwise throws with a custom message.\n */\n expect: (res, msg) => {\n if (!res.ok) throw new Error(msg);\n return res.value;\n },\n /**\n * Returns the value if Ok, otherwise returns the fallback value.\n */\n unwrapOr: (res, fallback) => res.ok ? res.value : fallback,\n /**\n * Returns the value if Ok, otherwise computes a fallback via the provided function.\n */\n unwrapOrElse: (res, fn) => res.ok ? res.value : fn(res.error),\n /**\n * Transforms the inner value using the provided function if Ok.\n * Optimization: Returns the original instance if the value remains unchanged.\n */\n map: (res, fn) => {\n if (!res.ok) return res;\n const next = fn(res.value);\n return next === res.value ? res : Result.ok(next);\n },\n /**\n * Transforms the inner error using the provided function if Err.\n */\n mapErr: (res, fn) => res.ok ? res : Result.err(fn(res.error)),\n /**\n * Chains a function that returns another Result if Ok.\n */\n andThen: (res, fn) => res.ok ? fn(res.value) : res,\n /**\n * Wraps a synchronous function call that might throw.\n */\n tryCatch: (fn) => {\n try {\n return Result.ok(fn());\n } catch (e) {\n return Result.err(toError(e));\n }\n },\n /**\n * Wraps an asynchronous operation into a Result-bearing Promise.\n */\n tryAsync: (fn) => {\n try {\n const p = fn();\n return Promise.resolve(p).then(\n (value) => Result.ok(value),\n (error) => Result.err(toError(error))\n );\n } catch (e) {\n return Promise.resolve(Result.err(toError(e)));\n }\n },\n /**\n * Converts a Result to an Option, dropping the error data.\n */\n toOption: (res) => res.ok ? Option.some(res.value) : Option.none\n};\n\n// src/slot-buffer.ts\nvar FIRST_FREE_INDEX = [\n 0,\n 1,\n 0,\n 2,\n 0,\n 1,\n 0,\n 3,\n 0,\n 1,\n 0,\n 2,\n 0,\n 1,\n 0,\n -1\n];\nvar FAST_CAPACITY = 4;\nvar FAST_MASK = 15;\nvar SlotBuffer = class {\n constructor() {\n this._count = 0;\n this._actualCount = 0;\n this._mask = 0;\n this._s0 = null;\n this._s1 = null;\n this._s2 = null;\n this._s3 = null;\n this._overflow = null;\n this._freeIndices = null;\n this._lockCount = 0;\n this._pendingCompact = false;\n }\n /**\n * Optimization: Find the first free fast slot (0-3) using bit scanning.\n * @returns Index 0-3, or -1 if all fast slots are occupied.\n */\n _firstFreeSlot(mask) {\n return FIRST_FREE_INDEX[mask & FAST_MASK];\n }\n /**\n * Logic: Low-level write that synchronizes the occupancy mask.\n * Caution: Does not update _actualCount or _count. Use setAt for high-level operations.\n */\n _rawWrite(index, item) {\n if (index < FAST_CAPACITY) {\n const bit = 1 << index;\n if (item === null) this._mask &= ~bit;\n else this._mask |= bit;\n if (index === 0) this._s0 = item;\n else if (index === 1) this._s1 = item;\n else if (index === 2) this._s2 = item;\n else if (index === 3) this._s3 = item;\n } else {\n if (!this._overflow) this._overflow = [];\n this._overflow[index - FAST_CAPACITY] = item;\n }\n }\n /** Logic: Finds a vacant slot (prioritizing fast lanes) and fills it. */\n _rawAdd(item) {\n const mask = this._mask;\n const fastIdx = this._firstFreeSlot(mask);\n if (fastIdx !== -1) {\n this._mask = mask | 1 << fastIdx;\n if (fastIdx === 0) this._s0 = item;\n else if (fastIdx === 1) this._s1 = item;\n else if (fastIdx === 2) this._s2 = item;\n else this._s3 = item;\n return fastIdx;\n }\n if (!this._overflow) this._overflow = [];\n const ov = this._overflow;\n const free = this._freeIndices;\n if (free?.length) {\n const reuseIdx = free.pop();\n ov[reuseIdx] = item;\n return reuseIdx + FAST_CAPACITY;\n }\n ov.push(item);\n return FAST_CAPACITY - 1 + ov.length;\n }\n /** Swap the contents of two slots. */\n _rawSwap(idxA, idxB) {\n if (idxA === idxB) return;\n const a = this.at(idxA);\n const b = this.at(idxB);\n this._rawWrite(idxA, b);\n this._rawWrite(idxB, a);\n }\n /** Physical capacity (including null gaps). Safe for manual indexed loops. */\n get length() {\n return this._count;\n }\n /** Logical size (number of non-null items). */\n get size() {\n return this._actualCount;\n }\n /**\n * Retrieves the item at the given index.\n * @returns The item, or null if the slot is empty or out of bounds.\n */\n at(index) {\n if (index < FAST_CAPACITY) {\n if (index === 0) return this._s0;\n if (index === 1) return this._s1;\n if (index === 2) return this._s2;\n if (index === 3) return this._s3;\n return null;\n }\n const ov = this._overflow;\n return ov ? ov[index - FAST_CAPACITY] ?? null : null;\n }\n /**\n * Updates the item at a specific index.\n * Caution: Manual indexing can create gaps. Use compact() if order/density matters.\n */\n setAt(index, item) {\n const old = this.at(index);\n if (old === item) return;\n this._rawWrite(index, item);\n if (old === null) this._actualCount++;\n else if (item === null) this._actualCount--;\n if (item !== null) {\n if (index >= this._count) this._count = index + 1;\n } else {\n this._shrinkPhysicalSizeFrom(index);\n }\n }\n /**\n * Optimization: Trims trailing nulls to keep iterations efficient.\n * Logic: Only triggers if the removed item was at the physical tail of the buffer.\n */\n _shrinkPhysicalSizeFrom(index) {\n if (index !== this._count - 1) return;\n this._count--;\n if (this._count > FAST_CAPACITY) {\n const ov = this._overflow;\n while (this._count > FAST_CAPACITY && ov[this._count - (FAST_CAPACITY + 1)] == null) {\n this._count--;\n }\n }\n if (this._count <= FAST_CAPACITY) {\n this._count = 32 - Math.clz32(this._mask);\n }\n }\n /**\n * Efficiently clears all items from the given index to the end.\n */\n truncateFrom(index) {\n const limit = this._count;\n if (index >= limit) return;\n for (let i = index; i < limit; i++) {\n if (this.at(i) !== null) this._actualCount--;\n }\n if (index < FAST_CAPACITY) {\n this._mask &= (1 << index) - 1;\n if (index <= 0) this._s0 = null;\n if (index <= 1) this._s1 = null;\n if (index <= 2) this._s2 = null;\n if (index <= 3) this._s3 = null;\n this._overflow = null;\n } else if (this._overflow) {\n this._overflow.length = index - FAST_CAPACITY;\n }\n this._count = index;\n this._freeIndices = null;\n }\n /**\n * Adds an item to the first available hole or appends it.\n * @returns The index where the item was stored.\n */\n push(item) {\n const idx = this._rawAdd(item);\n if (idx >= this._count) this._count = idx + 1;\n this._actualCount++;\n return idx;\n }\n /**\n * Removes an item by identity.\n * Optimization: Checks fast slots before scanning the overflow array.\n * @returns True if the item was found and removed.\n */\n remove(item) {\n if (this._actualCount === 0) return false;\n const m = this._mask;\n if (m & 1 && this._s0 === item) return this._removeAt(0);\n if (m & 2 && this._s1 === item) return this._removeAt(1);\n if (m & 4 && this._s2 === item) return this._removeAt(2);\n if (m & 8 && this._s3 === item) return this._removeAt(3);\n const ov = this._overflow;\n if (ov) {\n for (let i = 0, len = ov.length; i < len; i++) {\n if (ov[i] === item) {\n ov[i] = null;\n this._actualCount--;\n this._shrinkPhysicalSizeFrom(i + FAST_CAPACITY);\n if (!this._freeIndices) this._freeIndices = [];\n this._freeIndices.push(i);\n return true;\n }\n }\n }\n return false;\n }\n _removeAt(index) {\n this._rawWrite(index, null);\n this._actualCount--;\n this._shrinkPhysicalSizeFrom(index);\n return true;\n }\n /** Return true if the buffer contains the given item. */\n has(item) {\n if (this._actualCount === 0) return false;\n const m = this._mask;\n if (m & 1 && this._s0 === item) return true;\n if (m & 2 && this._s1 === item) return true;\n if (m & 4 && this._s2 === item) return true;\n if (m & 8 && this._s3 === item) return true;\n const ov = this._overflow;\n if (ov) {\n for (let i = 0, len = ov.length; i < len; i++) {\n if (ov[i] === item) return true;\n }\n }\n return false;\n }\n /**\n * Iterates through all non-null items in order.\n * Optimization: Uses the occupancy mask to skip null slots in the fast lane.\n */\n forEach(fn) {\n if (this._actualCount === 0) return;\n const m = this._mask;\n if (m & 1) fn(this._s0);\n if (m & 2) fn(this._s1);\n if (m & 4) fn(this._s2);\n if (m & 8) fn(this._s3);\n const ov = this._overflow;\n if (ov) {\n for (let i = 0, len = ov.length; i < len; i++) {\n const item = ov[i];\n if (item != null) fn(item);\n }\n }\n }\n /**\n * Returns true if at least one item satisfies the predicate.\n */\n some(predicate) {\n if (this._actualCount === 0) return false;\n const m = this._mask;\n if (m & 1 && predicate(this._s0)) return true;\n if (m & 2 && predicate(this._s1)) return true;\n if (m & 4 && predicate(this._s2)) return true;\n if (m & 8 && predicate(this._s3)) return true;\n const ov = this._overflow;\n if (ov) {\n for (let i = 0, len = ov.length; i < len; i++) {\n const item = ov[i];\n if (item != null && predicate(item)) return true;\n }\n }\n return false;\n }\n /**\n * Removes all gaps and shifts items toward the front.\n */\n compact() {\n if (this._lockCount > 0) {\n this._pendingCompact = true;\n return;\n }\n const actual = this._actualCount;\n const currentCount = this._count;\n if (actual === currentCount) return;\n if (actual === 0) {\n this.clear();\n return;\n }\n let writeIdx = 0;\n const ov = this._overflow;\n for (let readIdx = 0; readIdx < currentCount; readIdx++) {\n const item = this.at(readIdx);\n if (item !== null) {\n if (readIdx !== writeIdx) {\n this._rawWrite(writeIdx, item);\n this._rawWrite(readIdx, null);\n }\n if (++writeIdx === actual) break;\n }\n }\n this._count = actual;\n if (ov !== null) {\n if (writeIdx <= FAST_CAPACITY) this._overflow = null;\n else ov.length = writeIdx - FAST_CAPACITY;\n }\n this._freeIndices = null;\n this._pendingCompact = false;\n }\n /** Iteration lock. */\n lock() {\n this._lockCount++;\n }\n /** Iteration unlock. */\n unlock() {\n if (--this._lockCount === 0 && this._pendingCompact) {\n this.compact();\n }\n }\n /** Reset the buffer to an empty state. */\n clear() {\n this._s0 = this._s1 = this._s2 = this._s3 = null;\n this._count = 0;\n this._actualCount = 0;\n this._mask = 0;\n this._overflow = null;\n this._freeIndices = null;\n this._pendingCompact = false;\n }\n /** Alias for `clear`. */\n dispose() {\n this.clear();\n }\n /** @internal */\n get isLocked() {\n return this._lockCount > 0;\n }\n};\n\n// src/type-guard.ts\nfunction isPromise(value) {\n if (value instanceof Promise) return true;\n if (value === null || typeof value !== \"object\" && typeof value !== \"function\") {\n return false;\n }\n return typeof value.then === \"function\";\n}\nvar isOption = (val) => val != null && typeof val === \"object\" && val[OPTION_SYMBOL] === true;\nvar isResult = (val) => val != null && typeof val === \"object\" && val[RESULT_SYMBOL] === true;\n\n// src/index.ts\nvar hasOwn = Object.prototype.hasOwnProperty;\nfunction shallowEqual(a, b) {\n if (a === b) {\n return true;\n }\n if (a === null || b === null || typeof a !== \"object\" || typeof b !== \"object\") {\n return false;\n }\n const objA = a;\n const objB = b;\n const keysA = Object.keys(objA);\n if (keysA.length !== Object.keys(objB).length) {\n return false;\n }\n for (const key of keysA) {\n if (!hasOwn.call(objB, key) || !Object.is(objA[key], objB[key])) {\n return false;\n }\n }\n return true;\n}\nexport {\n Option,\n Result,\n SlotBuffer,\n hasOwn,\n isOption,\n isPromise,\n isResult,\n shallowEqual\n};\n","/**\n * A structured JSON representation of an `AtomError` for cross-context transport.\n */\nexport interface AtomErrorJSON {\n /** The specific name of the error class. */\n name: string;\n /** The human-readable error message. */\n message: string;\n /** Machine-readable error identifier. */\n code?: string | undefined;\n /** When true, the reactive engine may attempt re-execution. */\n recoverable: boolean;\n /** Trace information. */\n stack?: string | undefined;\n /** The underlying cause resolved into a plain object or primitive. */\n cause?: unknown | undefined;\n}\n\n/**\n * Constructor signature for system-branded error classes.\n * @internal\n */\nexport type AtomErrorConstructor = new (\n message: string,\n cause?: unknown,\n recoverable?: boolean,\n code?: string\n) => AtomError;\n\n/**\n * The base error class for the reactive system.\n *\n * Logic: Execution Context Traceability\n * Maintains a causal chain (`cause`) to allow developers to trace errors\n * through multiple layers of atoms, computed nodes, and effects.\n *\n * When to use:\n * - To define custom error categories within the engine.\n * - To wrap third-party errors with system-specific metadata.\n *\n * @example\n * ```typescript\n * import { AtomError } from '@but212/atom-effect';\n *\n * throw new AtomError(\n * 'Validation failed',\n * rawInput,\n * true,\n * 'ERR_VAL_001'\n * );\n * ```\n */\nexport class AtomError extends Error {\n override readonly name: string = 'AtomError';\n\n constructor(\n message: string,\n /** The raw value or error that triggered this instance. */\n public readonly cause: unknown = null,\n /**\n * Logic: Error Recovery\n * When true, indicate that the state might be corrected by a subsequent\n * update. When false, the node is considered permanently failed.\n */\n public readonly recoverable: boolean = true,\n /** Unique category identifier for programmatic handling. */\n public readonly code?: string\n ) {\n super(message);\n\n /**\n * Optimization: V8 Fast Path\n * Captures stack traces while maintaining a stable hidden class shape\n * for high-performance error object creation.\n */\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Retrieves the full sequence of causal errors.\n *\n * Logic: Trace Reconstruction\n * Recursively traverses the `.cause` property while protecting against\n * infinite loops caused by circular error chains.\n *\n * @returns Sequential array of errors, starting from the current instance.\n */\n getChain(): Array<AtomError | Error | unknown> {\n const chain: Array<AtomError | Error | unknown> = [];\n const seen = new Set<unknown>();\n let current: unknown = this;\n\n while (current != null && !seen.has(current)) {\n chain.push(current);\n seen.add(current);\n current = (current as { cause?: unknown })?.cause;\n }\n return chain;\n }\n\n /**\n * Logic: Safe Serialization\n * Converts the error into a plain JSON object.\n * Automatically replaces circular references with a sentinel message to\n * prevent serialization crashes in loggers.\n */\n toJSON(seen: Set<unknown> = new Set()): AtomErrorJSON {\n if (seen.has(this)) {\n return {\n name: this.name,\n message: '[Circular Reference]',\n recoverable: this.recoverable,\n code: this.code,\n };\n }\n seen.add(this);\n\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n recoverable: this.recoverable,\n stack: this.stack,\n cause: serializeErrorValue(this.cause, seen),\n };\n }\n\n /**\n * Formatting utility for internal diagnostic messages.\n * @internal\n */\n static format(source: string, context: string, message: string): string {\n return `${source} (${context}): ${message}`;\n }\n}\n\n/**\n * Thrown during the evaluation phase of a computed atom.\n */\nexport class ComputedError extends AtomError {\n override readonly name = 'ComputedError';\n}\n\n/**\n * Thrown during the execution or cleanup phase of a reactive effect.\n * Typically represents a side-effect failure.\n */\nexport class EffectError extends AtomError {\n override readonly name = 'EffectError';\n\n constructor(message: string, cause: unknown = null, recoverable = false, code?: string) {\n super(message, cause, recoverable, code);\n }\n}\n\n/**\n * Thrown by the internal engine when scheduling or flush limits are violated.\n */\nexport class SchedulerError extends AtomError {\n override readonly name = 'SchedulerError';\n\n constructor(message: string, cause: unknown = null, recoverable = false, code?: string) {\n super(message, cause, recoverable, code);\n }\n}\n\n/**\n * Central registry of standardized error messages.\n *\n * When to use:\n * - To ensure consistent diagnostic output.\n * - To identify specific failure conditions during unit testing.\n */\nexport const ERROR_MESSAGES = {\n // --- Computed Phase ---\n COMPUTED_MUST_BE_FUNCTION: 'Computed target must be a function',\n COMPUTED_ASYNC_PENDING_NO_DEFAULT: 'Async computation pending with no default value',\n COMPUTED_COMPUTATION_FAILED: 'Computation execution failed',\n COMPUTED_ASYNC_COMPUTATION_FAILED: 'Async computation execution failed',\n COMPUTED_CIRCULAR_DEPENDENCY: 'Circular dependency detected',\n COMPUTED_DISPOSED: 'Attempted to access disposed computed',\n\n // --- Atom Phase ---\n ATOM_SUBSCRIBER_MUST_BE_FUNCTION: 'Subscriber must be a function or Subscriber object',\n ATOM_INDIVIDUAL_SUBSCRIBER_FAILED: 'Subscriber execution failed',\n\n // --- Effect Phase ---\n EFFECT_MUST_BE_FUNCTION: 'Effect target must be a function',\n EFFECT_EXECUTION_FAILED: 'Effect execution failed',\n EFFECT_CLEANUP_FAILED: 'Effect cleanup failed',\n EFFECT_DISPOSED: 'Attempted to run disposed effect',\n\n // --- Engine/Scheduler Phase ---\n /** Returns a formatted message for flush overflow limits. */\n SCHEDULER_FLUSH_OVERFLOW: (max: number, dropped: number): string =>\n `Maximum flush iterations (${max}) exceeded. ${dropped} jobs dropped. Possible infinite loop.`,\n\n // --- System Diagnostics ---\n CALLBACK_ERROR_IN_ERROR_HANDLER: 'Exception encountered in onError handler',\n /** Logic: Loop Protection */\n EFFECT_FREQUENCY_LIMIT_EXCEEDED:\n 'Effect executed too frequently within 1 second. Suspected infinite loop.',\n SCHEDULER_CALLBACK_MUST_BE_FUNCTION: 'Scheduler callback must be a function',\n SCHEDULER_END_BATCH_WITHOUT_START: 'endBatch() called without matching startBatch(). Ignoring.',\n BATCH_CALLBACK_MUST_BE_FUNCTION: 'Batch callback must be a function',\n} as const satisfies Record<string, string | ((...args: number[]) => string)>;\n\n/**\n * Normalizes an unknown error into the system's error hierarchy.\n *\n * When to use:\n * - In `catch` blocks within the engine to ensure cross-module traceability.\n * - To wrap user-provided callbacks with appropriate context (e.g., 'Effect Phase').\n *\n * @param error - The raw error value to wrap.\n * @param ErrorClass - The targeted `AtomError` subclass.\n * @param context - Label describing the origin of the failure.\n *\n * @example\n * ```typescript\n * try {\n * fn();\n * } catch (err) {\n * throw wrapError(err, EffectError, 'Effect Execution');\n * }\n * ```\n */\nexport function wrapError(\n error: unknown,\n ErrorClass: AtomErrorConstructor,\n context: string\n): AtomError {\n const meta = getErrorMetadata(error);\n\n return new ErrorClass(\n AtomError.format(meta.name, context, meta.message),\n error,\n meta.recoverable,\n meta.code\n );\n}\n\n/**\n * Logic: Heuristic Metadata Extraction\n * Resolves standard properties from `AtomError`, `Error`, or raw values.\n * @internal\n */\nfunction getErrorMetadata(error: unknown) {\n if (error instanceof AtomError) {\n return {\n name: error.name,\n message: error.message,\n recoverable: error.recoverable,\n code: error.code,\n };\n }\n\n if (error instanceof Error) {\n return {\n name: error.name,\n message: error.message,\n recoverable: true,\n code: (error as unknown as Record<string, unknown>)?.code as string | undefined,\n };\n }\n\n return {\n name: 'Unexpected error',\n message: String(error),\n recoverable: true,\n code: undefined,\n };\n}\n\n/**\n * Logic: Circular Serialization\n * Recursively serializes the error cause tree into a plain object structure.\n * @internal\n */\nfunction serializeErrorValue(value: unknown, seen: Set<unknown>): unknown {\n if (value == null || typeof value !== 'object') return value;\n if (seen.has(value)) return '[Circular Reference]';\n\n if (value instanceof AtomError) return value.toJSON(seen);\n\n if (value instanceof Error) {\n seen.add(value);\n return {\n name: value.name,\n message: value.message,\n stack: value.stack,\n cause: serializeErrorValue((value as { cause?: unknown }).cause, seen),\n };\n }\n return value;\n}\n","/**\n * The global brand symbol used for type identification across all reactive primitives.\n *\n * Optimization: A single consolidated symbol is used to store multiple type markers\n * using bitwise flags. This strategy minimizes property lookup overhead and reduces\n * the overall object size by avoiding multiple type-specific properties.\n *\n * When to use:\n * - To access the internal type metadata of a reactive node.\n * - To implement custom branded objects that need to integrate with the reactive system.\n */\nexport const BRAND: unique symbol = Symbol.for('atom-effect/brand');\n\n/**\n * A collection of bitwise flags used for precise type discrimination.\n *\n * When to use:\n * - To identify the specific category of a reactive node (e.g., Atom, Computed, Effect).\n * - To verify the capabilities of a node (e.g., checking if it is writable).\n */\nexport const BrandFlags = {\n /** Indicates that the primitive is an atom (either Readonly or Writable). */\n Atom: 1 << 0,\n /** Indicates that the primitive supports write operations, such as `.set()` or `.update()`. */\n Writable: 1 << 1,\n /** Indicates that the primitive is a computed value with dependency tracking logic. */\n Computed: 1 << 2,\n /** Indicates that the primitive is an effect handle. */\n Effect: 1 << 3,\n} as const;\n","import { DEBUG_CONFIG, IS_DEV } from '@/constants';\nimport { BRAND, BrandFlags } from '@/symbols';\nimport type { DebugConfig, DependencyId } from '@/types';\n\n// ── Debug Symbols ────────────────────────────────────────────────────────\n\n/** Sentinel value used to distinguish between 'undefined' and 'not set'. */\nexport const NO_DEFAULT_VALUE = Symbol('AtomEffect.NoDefaultValue');\n\n/** @internal */\ninterface NodeMetadata {\n name: string;\n type: string;\n ref?: WeakRef<object>;\n}\n\nconst TYPE_BY_BRAND: Record<number, string> = {\n [BrandFlags.Atom]: 'atom',\n [BrandFlags.Computed]: 'computed',\n [BrandFlags.Effect]: 'effect',\n};\n\nconst BRAND_MASK = BrandFlags.Atom | BrandFlags.Computed | BrandFlags.Effect;\n\nconst PREFIX = '[Atom Effect]';\n\n/** Shared no-op function to reduce memory pressure in production. @internal */\nconst noop = () => {};\n\n/**\n * Controller for development-time diagnostics.\n *\n * Responsibilities:\n * - Detecting infinite reactive loops.\n * - Tracking the global dependency graph.\n * - Mapping unique IDs to human-readable names.\n *\n * @internal\n */\nclass DevDebugController implements DebugConfig {\n public enabled = true;\n\n /** If true, warns when a node updates too many times in one cycle. */\n public warnInfiniteLoop = DEBUG_CONFIG.WARN_INFINITE_LOOP;\n\n private _updateCounts = new Map<DependencyId, number>();\n\n /**\n * External storage for metadata.\n * Reason: Keeps the reactive objects 'thin' and prevents de-optimization.\n */\n private _registry = new Map<DependencyId, NodeMetadata>();\n\n /**\n * Enables full graph inspection via `dumpGraph()`.\n * Warning: High overhead. Only enable during deep debugging.\n */\n public trackGraph = false;\n\n /** Automatically purges metadata when a reactive node is garbage collected. */\n private _finalizer = new FinalizationRegistry((id: DependencyId) => {\n this._registry.delete(id);\n this._updateCounts.delete(id);\n });\n\n private _threshold = DEBUG_CONFIG.LOOP_THRESHOLD;\n\n private _cleanupScheduled = false;\n\n private _failedEvaluations = new Set<DependencyId>();\n private _failureCleanupScheduled = false;\n\n public warn(cond: boolean, msg: string): void {\n if (this.enabled && cond) {\n console.warn(`${PREFIX} ${msg}`);\n }\n }\n\n /**\n * Tracks a live node in the registry for graph visualization.\n */\n public registerNode(node: object & { id: DependencyId }): void {\n const id = node.id;\n const entry = this._getOrCreateMetadata(node, id);\n\n entry.ref = new WeakRef(node);\n this._finalizer.register(node, id);\n }\n\n /**\n * Links internal IDs to labels and types.\n */\n public attachDebugInfo(obj: object, type: string, id: DependencyId, customName?: string): void {\n if (!this.enabled || (customName === undefined && !this.trackGraph)) return;\n\n let entry = this._registry.get(id);\n if (!entry) {\n entry = { name: customName ?? `${type}_${id}`, type };\n this._registry.set(id, entry);\n } else {\n if (customName !== undefined) entry.name = customName;\n entry.type = type;\n }\n\n // Always register for finalization if we are keeping metadata to avoid memory leaks.\n // This also ensures entry.ref is populated for consistent dumpGraph() behavior.\n this.registerNode(obj as object & { id: DependencyId });\n }\n\n /**\n * Monitors update frequency to prevent UI hangs.\n *\n * Logic: Counts updates per node and resets via microtask.\n * If a node exceeds the threshold before the microtask runs, a loop is suspected.\n */\n public trackUpdate(id: DependencyId, name?: string): void {\n if (!this.enabled || !this.warnInfiniteLoop) return;\n\n const counts = this._updateCounts;\n const count = (counts.get(id) || 0) + 1;\n counts.set(id, count);\n\n if (count > this._threshold) {\n // Only warn once per cycle to prevent console spam.\n if (count === this._threshold + 1) {\n console.warn(\n `${PREFIX} Infinite loop detected for ${name ?? `dependency ${id}`}. ` +\n `Detected ${count} updates within a single execution scope, exceeding the threshold of ${this._threshold}.`\n );\n }\n }\n\n if (!this._cleanupScheduled) {\n this._cleanupScheduled = true;\n // Task scheduled at the end of the current execution cycle.\n queueMicrotask(this._resetUpdateCounts);\n }\n }\n\n private _resetUpdateCounts = (): void => {\n this._updateCounts.clear();\n this._cleanupScheduled = false;\n };\n\n /**\n * Logic: Warning Deduplication\n * Records evaluation failures during dirty checks and warns once per dependency per cycle.\n */\n public trackEvaluationFailure(id: DependencyId): void {\n if (!this.enabled || this._failedEvaluations.has(id)) return;\n\n this._failedEvaluations.add(id);\n console.warn(`${PREFIX} Dependency #${id} evaluation failed during dirty check.`);\n\n if (!this._failureCleanupScheduled) {\n this._failureCleanupScheduled = true;\n queueMicrotask(this._resetFailedEvaluations);\n }\n }\n\n private _resetFailedEvaluations = (): void => {\n this._failedEvaluations.clear();\n this._failureCleanupScheduled = false;\n };\n\n /**\n * Captures the current state of all active reactive nodes.\n *\n * Performance: O(N) where N is the number of live nodes.\n * Use sparingly.\n */\n public dumpGraph(): Record<string, unknown>[] {\n const registry = this._registry;\n if (registry.size === 0) return [];\n\n const result: Record<string, unknown>[] = [];\n const counts = this._updateCounts;\n\n for (const [id, meta] of registry) {\n if (this.trackGraph && meta.ref?.deref() === undefined) {\n continue;\n }\n result.push({\n id,\n name: meta.name,\n type: meta.type,\n updateCount: counts.get(id) ?? 0,\n });\n }\n return result;\n }\n\n public getDebugName(obj: object | null | undefined): string | undefined {\n if (!this.enabled || !obj) return undefined;\n const id = (obj as { id?: DependencyId }).id;\n if (id === undefined) return undefined;\n\n const meta = this._registry.get(id);\n if (meta) return meta.name;\n\n const type = this._getTypeFromBrand(obj) ?? 'unknown';\n return `${type}_${id}`;\n }\n\n public getDebugType(obj: object | null | undefined): string | undefined {\n if (!this.enabled || !obj) return undefined;\n const id = (obj as { id?: DependencyId }).id;\n if (id === undefined) return undefined;\n\n const meta = this._registry.get(id);\n if (meta) return meta.type;\n\n return this._getTypeFromBrand(obj);\n }\n\n private _getOrCreateMetadata(obj: object, id: DependencyId): NodeMetadata {\n let entry = this._registry.get(id);\n if (!entry) {\n const type = this._getTypeFromBrand(obj) ?? 'unknown';\n entry = { name: `${type}_${id}`, type };\n this._registry.set(id, entry);\n }\n return entry;\n }\n\n private _getTypeFromBrand(obj: object): string | undefined {\n const brand = (obj as { [BRAND]?: number })[BRAND];\n return brand !== undefined ? TYPE_BY_BRAND[brand & BRAND_MASK] : undefined;\n }\n}\n\n/**\n * Inert implementation for production.\n * Replaces all logic with no-ops to ensure the JIT compiler can optimize them away.\n */\nconst ProdDebugController: DebugConfig = {\n enabled: false,\n warnInfiniteLoop: false,\n trackGraph: false,\n warn: noop,\n registerNode: noop,\n attachDebugInfo: noop,\n trackUpdate: noop,\n dumpGraph: () => [],\n getDebugName: () => undefined,\n getDebugType: () => undefined,\n trackEvaluationFailure: noop,\n};\n\n/**\n * Global diagnostic hub.\n *\n * @example\n * ```typescript\n * import { debug } from '@but212/atom-effect';\n *\n * // View all active nodes in the console\n * console.table(debug.dumpGraph());\n * ```\n */\nexport const debug: DebugConfig = IS_DEV ? new DevDebugController() : ProdDebugController;\n\n/** @internal */\nlet nextId = 1;\n\n/**\n * Generates an internal unique ID for a reactive node.\n */\nexport const generateId = (): DependencyId => nextId++ as DependencyId;\n","import { SlotBuffer } from '@but212/atom-effect-utils';\nimport { COMPUTED_STATE_FLAGS, IS_DEV } from '@/constants';\nimport type { Dependency } from '@/types';\nimport { debug } from '@/utils/debug';\nimport type { DependencyLink } from './tracking';\n\n/** @internal */\nexport interface Indexer {\n get(dep: Dependency): number | undefined;\n set(dep: Dependency, index: number): void;\n delete(dep: Dependency): void;\n}\n\nconst NullIndexer: Indexer = {\n get: () => undefined,\n set: () => {},\n delete: () => {},\n};\n\nclass MapIndexer extends Map<Dependency, number> implements Indexer {}\n\n/**\n * Logic: Subscription Reconciliation State\n * Orchestrates the transition of dependencies between execution cycles.\n * @internal\n */\nexport interface DepBufferState {\n /**\n * Ordered sequence of active subscriptions.\n * Optimization: Uses SlotBuffer for contiguous memory and fast iteration.\n */\n slots: SlotBuffer<DependencyLink>;\n /**\n * Optimization: O(1) Lookup\n * Always present via Indexer interface to avoid branching.\n * Switched to NullIndexer when inactive.\n */\n map: Indexer;\n /**\n * Optimization: Skip Check\n * When false, indicates no computed nodes are present, allowing the engine\n * to skip recursive dirty validation.\n */\n hasComputeds: boolean;\n}\n\n/**\n * Factory for dependency buffers.\n * @internal\n */\nexport function createDepBuffer(): DepBufferState {\n return {\n slots: new SlotBuffer<DependencyLink>(),\n map: NullIndexer,\n hasComputeds: false,\n };\n}\n\n/**\n * Resets diagnostic flags before a new tracking phase.\n * @internal\n */\nexport function prepareTracking(state: DepBufferState): void {\n state.hasComputeds = false;\n}\n\n/**\n * Logic: Subscription Reuse (Claiming)\n * Attempts to locate and move an existing subscription to the current\n * tracking index.\n *\n * Why:\n * Re-attaching listeners is expensive. Reusing the `unsub` handle from a\n * previous run maintains the reactive connection without triggering\n * subscriber count changes.\n *\n * Strategy:\n * 1. Check if the current slot already holds the dependency (Fast Path).\n * 2. Look ahead using the lookup map or linear search.\n * 3. If found, swap the link to the front to preserve order for the next run.\n *\n * @internal\n */\nexport function claimExisting(state: DepBufferState, dep: Dependency, trackIndex: number): boolean {\n const { slots } = state;\n if (slots.length <= trackIndex) return false;\n\n const current = slots.at(trackIndex);\n // Optimization: Direct hit. Just synchronize the version to mark it as \"checked\".\n if (current?.node === dep && current.unsub) {\n current.version = dep.version;\n return true;\n }\n\n const existingIndex = _findExistingIndex(state, dep, trackIndex);\n if (existingIndex === -1) return false;\n\n const link = slots.at(existingIndex)!;\n link.version = dep.version;\n\n // Logic: Order Preservation\n // Swap the discovered link with whatever occupies the current track index.\n // This ensures \"live\" dependencies stay at the head of the buffer.\n const temp = slots.at(trackIndex);\n depBufferSetAt(state, trackIndex, link);\n depBufferSetAt(state, existingIndex, temp);\n return true;\n}\n\n/**\n * Logic: Heuristic Search\n * Switches between linear search and Map-based O(1) lookup based on buffer state.\n */\nfunction _findExistingIndex(state: DepBufferState, dep: Dependency, start: number): number {\n const idx = state.map.get(dep);\n if (idx !== undefined) return idx >= start ? idx : -1;\n\n const slots = state.slots;\n for (let i = start + 1, len = slots.length; i < len; i++) {\n const link = slots.at(i);\n if (link?.node === dep && link.unsub) return i;\n }\n return -1;\n}\n\n/**\n * Logic: Displaced Occupant Preservation\n * Inserts a new link at the current index. If an existing link is displaced,\n * it is pushed to the tail so it can be reclaimed later in the same cycle.\n * @internal\n */\nexport function insertNew(state: DepBufferState, trackIdx: number, link: DependencyLink): void {\n const occupant = state.slots.at(trackIdx);\n depBufferSetAt(state, trackIdx, link);\n\n if (occupant !== null) {\n depBufferPush(state, occupant);\n }\n}\n\n/**\n * Atomic mutation that synchronizes the O(1) lookup map with the slot buffer.\n * @internal\n */\nexport function depBufferSetAt(\n state: DepBufferState,\n index: number,\n item: DependencyLink | null\n): void {\n const old = state.slots.at(index);\n state.slots.setAt(index, item);\n\n if (old) state.map.delete(old.node);\n if (item?.unsub) {\n if (state.map === NullIndexer) state.map = new MapIndexer();\n state.map.set(item.node, index);\n }\n}\n\n/**\n * Atomic append operation that maintains the lookup map.\n * @internal\n */\nexport function depBufferPush(state: DepBufferState, item: DependencyLink): number {\n const idx = state.slots.push(item);\n if (item.unsub) {\n if (state.map === NullIndexer) state.map = new MapIndexer();\n state.map.set(item.node, idx);\n }\n return idx;\n}\n\n/**\n * Logic: Dirty Propagation Check\n * Determines if any dependency has transitioned to a new version.\n *\n * Strategy: Table-based Validation\n * Dispatches to the appropriate checker using a bitmask index.\n */\nconst DIRTY_CHECKERS = {\n // Atom path\n 0: (link) => link.node.version !== link.version,\n // Computed path\n [COMPUTED_STATE_FLAGS.IS_COMPUTED]: (link) => {\n const dep = link.node;\n try {\n // Trigger evaluation if dirty by accessing value.\n // This is the core of the recursive \"pull\" strategy.\n dep.value;\n } catch {\n // Logic: Silencing transient failures\n // If evaluation fails during a dirty check, we catch it here to prevent\n // interrupting the propagation cycle.\n if (IS_DEV) {\n debug.trackEvaluationFailure(dep.id);\n }\n }\n return dep.version !== link.version;\n },\n} satisfies Record<number, (link: DependencyLink) => boolean>;\n\n/**\n * Logic: Dirty Propagation Check\n * @internal\n */\nexport function isBufferDirty(state: DepBufferState): boolean {\n const slots = state.slots;\n const len = slots.length;\n if (slots.size === 0) return false;\n\n const checkers = DIRTY_CHECKERS;\n for (let i = 0; i < len; i++) {\n const link = slots.at(i);\n // Guard clause to reduce nesting and improve branch prediction\n if (!link) continue;\n // IS_COMPUTED bit check\n if (checkers[link.node.flags & COMPUTED_STATE_FLAGS.IS_COMPUTED]!(link)) return true;\n }\n return false;\n}\n\n/**\n * Logic: Push-Path Validation\n * A non-recursive check used during the notification phase to avoid\n * re-entrant computation cascades.\n *\n * It returns true if:\n * 1. Any dependency version has already changed.\n * 2. Any dependency is already marked as DIRTY.\n *\n * @internal\n */\nexport function isBufferShallowDirty(state: DepBufferState): boolean {\n const slots = state.slots;\n const len = slots.length;\n for (let i = 0; i < len; i++) {\n const link = slots.at(i);\n if (!link) continue;\n\n const dep = link.node;\n const version = dep.version;\n // Check for explicit version drift (already pulled changes)\n // or pending changes (push-based dirty signals)\n if (version !== link.version || (dep.flags & COMPUTED_STATE_FLAGS.DIRTY) !== 0) return true;\n }\n return false;\n}\n\n/**\n * Logic: Post-Tracking Cleanup\n * Removes and unsubscribes from all dependencies that were not reclaimed\n * during the last tracking cycle.\n *\n * Constraint: Memory Integrity\n * Failure to invoke `link.unsub()` results in \"Ghost Executions\" where\n * disposed or inactive nodes continue to react to state changes.\n *\n * @internal\n */\nexport function depBufferTruncateFrom(state: DepBufferState, index: number): void {\n const slots = state.slots;\n const len = slots.length;\n for (let i = index; i < len; i++) {\n const link = slots.at(i);\n if (link) {\n const unsub = link.unsub;\n if (unsub) {\n try {\n unsub();\n } catch (e) {\n if (IS_DEV) {\n console.error('[atom-effect] Unsubscribe failed:', e);\n }\n }\n }\n }\n }\n slots.truncateFrom(index);\n\n // Constraint: Phase Locality\n // The lookup map is only valid during the reconciliation phase.\n state.map = NullIndexer;\n}\n\n/**\n * Releases all subscriptions and resets the buffer to an empty state.\n * @internal\n */\nexport function disposeAll(state: DepBufferState): void {\n depBufferTruncateFrom(state, 0);\n state.hasComputeds = false;\n}\n","import type { Dependency, Subscriber } from '@/types';\n\n/**\n * Interface for nodes capable of recording reactive dependencies during execution.\n * @internal\n *\n * Reason: Decouples dependency collection from the specific node implementation,\n * allowing any object to participate in tracking as long as it can record dependencies.\n */\nexport interface DependencySubscriber {\n addDependency(dep: Dependency): void;\n}\n\n/**\n * Interface for nodes that can be scheduled for re-execution.\n * @internal\n *\n * Reason: Provides a unified interface for the scheduler to trigger updates\n * without knowing the internal logic of the node.\n */\nexport interface ExecutableSubscriber {\n execute(): void;\n}\n\n/**\n * Unified interface for nodes that both consume dependencies and execute logic.\n * (e.g., Effects, Computed Atoms, Observers)\n * @internal\n */\nexport interface DependencyTracker extends DependencySubscriber, ExecutableSubscriber {}\n\n/**\n * Represents a single directed edge in the dependency graph (Subscriber -> Dependency).\n * @internal\n *\n * Logic: Includes a version field to implement efficient stale checks.\n * If the dependency's version doesn't match this version, the subscriber may need re-evaluation.\n */\nexport interface DependencyLink {\n /** The node being watched. */\n node: Dependency;\n /** The version of the node when this link was established. */\n version: number;\n /** Cleanup function returned by the dependency. */\n unsub: (() => void) | undefined;\n}\n\n/** @internal */\nexport function createDependencyLink(\n node: Dependency,\n version: number,\n unsub: (() => void) | undefined = undefined\n): DependencyLink {\n return { node, version, unsub };\n}\n\n/**\n * A handle for an active listener on a reactive node.\n * Supports both raw callbacks and internal graph subscribers.\n * @internal\n */\nexport interface Subscription<T> {\n /** Raw callback for external listeners. */\n fn: ((newValue?: T, oldValue?: T) => void) | undefined;\n /** Internal subscriber for graph-based updates. */\n sub: Subscriber | undefined;\n}\n\n/** @internal */\nexport function createSubscription<T>(\n fn: ((newValue?: T, oldValue?: T) => void) | undefined = undefined,\n sub: Subscriber | undefined = undefined\n): Subscription<T> {\n return { fn, sub };\n}\n\n/** @internal */\nexport function notifySubscription<T>(\n subscription: Subscription<T> | null,\n newValue?: T,\n oldValue?: T\n): void {\n if (subscription === null) return;\n\n // Logic: Failure Isolation\n // Uses standard try/catch to avoid closure allocation overhead in the hot path.\n // Ensures a failing listener or subscriber does not interrupt the notification cycle.\n try {\n const { fn, sub } = subscription;\n if (fn !== undefined) fn(newValue, oldValue);\n if (sub !== undefined) sub.execute();\n } catch (e) {\n console.error('[atom-effect] Subscriber failed:', e);\n }\n}\n\n/**\n * Internal state for the reactive tracking system.\n * @internal\n *\n * Logic: Stack-based approach\n * The stack enables nested tracking. When a computed atom is read inside an effect,\n * the computed atom becomes the 'current' subscriber while it calculates its value,\n * and the effect is restored as 'current' after the computation finishes.\n */\nexport interface TrackingContext {\n stack: (DependencySubscriber | null)[];\n current: DependencySubscriber | null;\n}\n\n/** @internal */\nexport function createTrackingContext(): TrackingContext {\n return { stack: [], current: null };\n}\n\n/** @internal */\nexport function pushTrackingSubscriber(\n context: TrackingContext,\n subscriber: DependencySubscriber | null\n): void {\n context.stack.push(subscriber);\n context.current = subscriber;\n}\n\n/** @internal */\nexport function popTrackingSubscriber(context: TrackingContext): void {\n const stack = context.stack;\n stack.pop();\n const len = stack.length;\n context.current = len > 0 ? stack[len - 1]! : null;\n}\n\n/**\n * Resets the tracking stack to a specific depth.\n * @internal\n *\n * Reason: Used during error recovery or transaction rollbacks where\n * the execution stack might be corrupted or partially executed.\n */\nexport function rollbackTrackingSubscriber(context: TrackingContext, depth: number): void {\n const stack = context.stack;\n stack.length = depth;\n const len = stack.length;\n context.current = len > 0 ? stack[len - 1]! : null;\n}\n\n/**\n * Executes a function within the scope of a specific subscriber.\n * @internal\n */\nexport function runInTrackingContext<T>(\n context: TrackingContext,\n subscriber: DependencySubscriber,\n fn: () => T\n): T {\n // Optimization: Avoid redundant stack operations if already in the same context.\n if (context.current === subscriber) return fn();\n\n pushTrackingSubscriber(context, subscriber);\n try {\n return fn();\n } finally {\n popTrackingSubscriber(context);\n }\n}\n\n/** @internal */\nexport function resetTrackingContext(context: TrackingContext): void {\n context.stack.length = 0;\n context.current = null;\n}\n\nexport const trackingContext = createTrackingContext();\n\n/**\n * Executes a function scope where reactive dependencies are ignored.\n *\n * When to use:\n * - Accessing atom values inside an effect or computed without creating a dependency.\n * - Performing side-effects (logging, analytics) that shouldn't trigger re-runs.\n * - Breaking circular dependencies by reading a value \"silently\".\n *\n * @param fn - The function to execute in an untracked scope.\n * @returns The result of the function.\n *\n * @example\n * ```typescript\n * const count = atom(0);\n * effect(() => {\n * // This effect only runs when count changes.\n * const current = count.value;\n *\n * untracked(() => {\n * // This read does NOT create a dependency.\n * // It won't cause the effect to re-run if logging was reactive.\n * console.log('Logging untracked value:', count.value);\n * });\n * });\n * ```\n */\nexport function untracked<T>(fn: () => T): T {\n if (trackingContext.current === null) return fn();\n\n pushTrackingSubscriber(trackingContext, null);\n try {\n return fn();\n } finally {\n popTrackingSubscriber(trackingContext);\n }\n}\n","import { SlotBuffer } from '@but212/atom-effect-utils';\nimport { COMPUTED_STATE_FLAGS, EPOCH_CONSTANTS, IS_DEV, SMI_MAX } from '@/constants';\nimport { AtomError, ERROR_MESSAGES, wrapError } from '@/errors';\nimport type { DependencyId, Subscriber } from '@/types';\nimport { generateId } from '@/utils/debug';\nimport { type DepBufferState, isBufferDirty, isBufferShallowDirty } from './buffers';\nimport {\n createSubscription,\n notifySubscription,\n pushTrackingSubscriber,\n rollbackTrackingSubscriber,\n type Subscription,\n trackingContext,\n} from './tracking';\n\n/**\n * A unified base class for all reactive primitives, including Atoms, Computeds, and Effects.\n *\n * When to use:\n * - As an internal base for implementing new reactive primitives.\n * - When a custom primitive requires integration with the core dependency graph.\n *\n * Optimization:\n * Designed with a fixed field layout to maintain Hidden Class Monomorphism in V8.\n * Avoid adding dynamic properties to instances to prevent de-optimization.\n *\n * @template T - The type of value produced by the node, used for subscriber notifications.\n */\nexport abstract class ReactiveNode<T> {\n /**\n * Internal bitfield representing the current state (Dirty, Computed, Disposed).\n * Logic: Direct bitwise operations are used for high-frequency state checks.\n */\n flags: number;\n\n /**\n * A monotonically increasing counter representing the version of the node's value.\n * Logic: Allows consumers to quickly verify if their cached values are stale.\n */\n version: number;\n\n /**\n * The epoch ID of the last time this node was visited during a dependency walk.\n * Logic: Prevents redundant visits and infinite loops during graph traversal.\n */\n _lastSeenEpoch: number;\n\n /**\n * A tag used by the scheduler to deduplicate execution within a single flush cycle.\n * @internal\n */\n _nextEpoch: number | undefined;\n\n /**\n * Unique identifier used for debugging and graph traversal.\n * Optimization: Uses SMI (Small Integer) range for memory efficiency and faster comparisons.\n */\n readonly id: DependencyId;\n\n /**\n * Buffered storage for active subscribers.\n * Logic: Uses `SlotBuffer` to support O(1) removal and deferred structural updates.\n * @internal\n */\n _slots: SlotBuffer<Subscription<T>> | null;\n\n /**\n * Buffered storage for captured dependencies.\n * @internal\n */\n _deps: DepBufferState | null;\n\n constructor() {\n // Optimization: Field initialization order matches the class declaration\n // to strictly enforce V8 object layout consistency.\n this.flags = 0;\n this.version = 0;\n this._lastSeenEpoch = EPOCH_CONSTANTS.UNINITIALIZED;\n this._nextEpoch = undefined;\n this.id = generateId() & SMI_MAX;\n this._slots = null;\n this._deps = null;\n }\n\n /**\n * Indicates whether the node has been explicitly disposed.\n */\n get isDisposed(): boolean {\n return (this.flags & COMPUTED_STATE_FLAGS.DISPOSED) !== 0;\n }\n\n /**\n * Indicates whether the node is a computed atom.\n */\n get isComputed(): boolean {\n return (this.flags & COMPUTED_STATE_FLAGS.IS_COMPUTED) !== 0;\n }\n\n /**\n * Indicates whether the node is currently notifying subscribers.\n */\n get isNotifying(): boolean {\n return this._slots?.isLocked ?? false;\n }\n\n private _hasFlag(flag: number): boolean {\n return (this.flags & flag) !== 0;\n }\n\n /**\n * Indicates whether the node or its dependency sub-graph is currently in an error state.\n * @internal\n */\n get hasError(): boolean {\n return false;\n }\n\n // ============================================================================\n // Producer Logic (Subscriber Management)\n // ============================================================================\n\n /**\n * Registers a subscriber to be notified when the node's value changes.\n *\n * When to use:\n * - To observe value changes manually outside of reactive contexts (e.g., in UI adapters).\n *\n * @param listener - A callback function or a Subscriber object.\n * @returns A cleanup function to terminate the subscription.\n * @throws {AtomError} If the provided listener is not a function or a valid Subscriber.\n *\n * @example\n * ```typescript\n * const unsub = node.subscribe((next, prev) => {\n * console.log(`Value changed from ${prev} to ${next}`);\n * });\n *\n * // Later:\n * unsub();\n * ```\n */\n subscribe(listener: ((newValue?: T, oldValue?: T) => void) | Subscriber): () => void {\n // Optimization: Guard clause + Imperative logic for raw speed (avoids lookup table overhead)\n let link: Subscription<T> | undefined;\n\n if (typeof listener === 'function') {\n link = createSubscription(listener as (n?: T, o?: T) => void, undefined);\n } else if (listener != null && typeof (listener as Subscriber).execute === 'function') {\n link = createSubscription(undefined, listener as Subscriber);\n }\n\n if (!link) {\n throw wrapError(\n new TypeError('Invalid subscriber'),\n AtomError,\n ERROR_MESSAGES.ATOM_SUBSCRIBER_MUST_BE_FUNCTION\n );\n }\n\n let slots = this._slots;\n if (slots === null) {\n this._slots = slots = new SlotBuffer<Subscription<T>>();\n } else if (this._hasSubscription(listener)) {\n if (IS_DEV) console.warn(`[atom-effect] Duplicate subscription ignored on node ${this.id}`);\n return () => {};\n }\n\n slots.push(link);\n return () => this._unsubscribe(link as Subscription<T>);\n }\n\n private _hasSubscription(listener: unknown): boolean {\n const slots = this._slots;\n if (!slots || slots.size === 0) return false;\n\n // Optimization: Use early-exit some() to avoid redundant at() calls in a loop\n return slots.some((link) => link.fn === listener || link.sub === listener);\n }\n\n /**\n * Internal removal of a subscription link.\n *\n * Caution: Compaction is deferred if a notification loop is currently active to\n * prevent index shifting during iteration.\n */\n protected _unsubscribe(link: Subscription<T>): void {\n const slots = this._slots;\n if (slots !== null) {\n slots.remove(link);\n slots.compact();\n }\n }\n\n /**\n * Returns the number of active subscribers for this node.\n *\n * When to use:\n * - To monitor subscription health or detect leaks during development.\n */\n subscriberCount(): number {\n return this._slots?.size ?? 0;\n }\n\n /**\n * Dispatches notifications to all registered subscribers.\n *\n * Logic:\n * Increments the `_notifying` guard to protect the subscriber buffer from\n * structural changes during iteration. Error handling is encapsulated per subscriber\n * to ensure a single failing listener does not terminate the entire notification cycle.\n */\n protected _notifySubscribers(newValue: T | undefined, oldValue: T | undefined): void {\n const slots = this._slots;\n if (!slots || slots.size === 0) return;\n\n const depth = trackingContext.stack.length;\n pushTrackingSubscriber(trackingContext, null);\n slots.lock();\n try {\n slots.forEach((sub) => {\n notifySubscription(sub, newValue, oldValue);\n });\n } finally {\n rollbackTrackingSubscriber(trackingContext, depth);\n slots.unlock();\n }\n }\n\n // ============================================================================\n // Consumer Logic (Dependency Validation)\n // ============================================================================\n\n /**\n * Determines if the node requires re-evaluation due to dependency changes.\n * Logic: Checks the status of the cached dependency buffer.\n */\n protected _isDirty(): boolean {\n return this._deps ? isBufferDirty(this._deps) : false;\n }\n\n /**\n * Performs a shallow validation of immediate dependencies.\n * Logic: Used for fast path guards that must not trigger re-computation.\n * @internal\n */\n protected _isShallowDirty(): boolean {\n return this._deps ? isBufferShallowDirty(this._deps) : false;\n }\n\n /**\n * Performs an exhaustive validation of the full dependency chain.\n * Required for Computeds and Effects to handle deep dependency invalidation.\n */\n protected abstract _deepDirtyCheck(): boolean;\n}\n","import { IS_DEV, SCHEDULER_CONFIG, SMI_MAX } from '@/constants';\nimport { ERROR_MESSAGES, SchedulerError } from '@/errors';\nimport { resetTrackingContext, trackingContext } from './tracking';\n\n/**\n * Optimization: V8 SMI (Small Integer) optimization.\n * Wraps integers to stay within V8's SMI range (31-bit signed).\n *\n * Reason: Transitioning from SMIs to doubles (HeapNumbers) causes significant\n * de-optimization in hot paths like version checking.\n * @internal\n */\nconst nextSmi = (v: number): number => {\n const next = (v + 1) & SMI_MAX;\n return next === 0 ? 1 : next;\n};\n\n/**\n * Generates the next version number for stateful objects (Atoms).\n */\nexport function nextVersion(v: number): number {\n return nextSmi(v);\n}\n\nexport interface SchedulerJobObject {\n execute(): void;\n /** Internal epoch tracking to prevent redundant scheduling in a single cycle. @internal */\n _nextEpoch?: number | undefined;\n}\n\nexport interface SchedulerJobFunction {\n (): void;\n /** Internal epoch tracking to prevent redundant scheduling in a single cycle. @internal */\n _nextEpoch?: number | undefined;\n}\n\nexport type SchedulerJob = SchedulerJobFunction | SchedulerJobObject;\n\n/**\n * Bitwise state flags for the scheduler state machine.\n */\nconst S_IDLE = 0;\nconst S_PROCESSING = 1 << 0;\nconst S_FLUSHING_SYNC = 1 << 1;\nconst S_BATCHING = 1 << 2;\nconst MASK_DEFERRED = S_FLUSHING_SYNC | S_BATCHING;\n\n/**\n * Internal state for the scheduler.\n * @internal\n */\nexport interface SchedulerState {\n size: number;\n epoch: number;\n batchQueueSize: number;\n state: number;\n batchDepth: number;\n maxFlushIterations: number;\n sessionActive: boolean;\n sessionEpoch: number;\n sessionExecutionCount: number;\n /** Primary queue for the current flush cycle. */\n activeBuffer: (SchedulerJob | undefined)[];\n /** Secondary queue to collect new jobs scheduled during the current flush. */\n standbyBuffer: (SchedulerJob | undefined)[];\n /** Queue for jobs scheduled during a batch session. */\n batchBuffer: (SchedulerJob | undefined)[];\n onOverflow: ((droppedCount: number) => void) | null;\n}\n\n/**\n * Factory for scheduler state.\n * @internal\n */\nexport function createSchedulerState(): SchedulerState {\n return {\n size: 0,\n epoch: 0,\n batchQueueSize: 0,\n state: S_IDLE,\n batchDepth: 0,\n maxFlushIterations: SCHEDULER_CONFIG.MAX_FLUSH_ITERATIONS,\n sessionActive: false,\n sessionEpoch: 0,\n sessionExecutionCount: 0,\n activeBuffer: [],\n standbyBuffer: [],\n batchBuffer: [],\n onOverflow: null,\n };\n}\n\n/**\n * Logic: Batch Queue Consolidation\n * Moves jobs from the batch buffer to the active execution queue.\n * @internal\n */\nexport function schedulerMergeBatchQueue(state: SchedulerState, nextEpoch: () => number): void {\n const queueSize = state.batchQueueSize;\n if (queueSize === 0) return;\n\n const epoch = nextEpoch();\n const bQueue = state.batchBuffer;\n const targetBuffer = state.activeBuffer;\n let currentSize = state.size;\n\n for (let i = 0; i < queueSize; i++) {\n const job = bQueue[i]!;\n // Logic: Avoid redundant scheduling if the job is already marked for this epoch.\n if (job._nextEpoch !== epoch) {\n job._nextEpoch = epoch;\n targetBuffer[currentSize++] = job;\n }\n bQueue[i] = undefined;\n }\n\n state.size = currentSize;\n state.batchQueueSize = 0;\n\n // Optimization: Release memory if the buffer grew significantly.\n if (bQueue.length > SCHEDULER_CONFIG.BATCH_QUEUE_SHRINK_THRESHOLD) {\n bQueue.length = 0;\n }\n}\n\n/**\n * Logic: Recursive Queue Drainage\n * Continuously flushes the queues until no more jobs are pending.\n *\n * Caution: Subject to maxFlushIterations to prevent infinite loops from circular dependencies.\n * @internal\n */\nexport function schedulerDrainQueue(\n state: SchedulerState,\n nextEpoch: () => number,\n processQueue: (state: SchedulerState) => void,\n handleOverflow: (state: SchedulerState) => void\n): void {\n let iterations = 0;\n const max = state.maxFlushIterations;\n\n while (state.size > 0 || state.batchQueueSize > 0) {\n if (++iterations > max) {\n handleOverflow(state);\n return;\n }\n\n if (state.batchQueueSize > 0) {\n schedulerMergeBatchQueue(state, nextEpoch);\n }\n\n if (state.size > 0) {\n processQueue(state);\n }\n }\n}\n\n/**\n * Logic: Double-Buffering Job Execution\n * Swaps active/standby buffers to allow safe scheduling during execution.\n * @internal\n */\nexport function schedulerProcessQueue(state: SchedulerState, nextEpoch: () => number): void {\n const jobs = state.activeBuffer;\n const count = state.size;\n\n // Logic: Double-buffering swap.\n state.activeBuffer = state.standbyBuffer;\n state.standbyBuffer = jobs;\n state.size = 0;\n nextEpoch();\n\n for (let i = 0; i < count; i++) {\n const job = jobs[i]!;\n jobs[i] = undefined;\n\n // Logic: Failure Isolation.\n // Errors in one job should not prevent other jobs from executing.\n try {\n if (typeof job === 'function') job();\n else job.execute();\n } catch (e) {\n console.error(new SchedulerError('Error occurred during scheduler execution', e));\n }\n }\n}\n\n/**\n * Logic: Overflow Recovery\n * Cleans up state when the maximum flush iterations are exceeded.\n * @internal\n */\nexport function schedulerHandleFlushOverflow(state: SchedulerState): void {\n const droppedCount = state.size + state.batchQueueSize;\n console.error(\n new SchedulerError(\n ERROR_MESSAGES.SCHEDULER_FLUSH_OVERFLOW(state.maxFlushIterations, droppedCount)\n )\n );\n\n state.size = 0;\n state.activeBuffer.length = 0;\n state.standbyBuffer.length = 0;\n state.batchQueueSize = 0;\n state.batchBuffer.length = 0;\n\n if (state.onOverflow) {\n try {\n state.onOverflow(droppedCount);\n } catch {\n /* Suppress callback errors during overflow handling */\n }\n }\n}\n\n/** @internal */\nexport function schedulerNextEpoch(state: SchedulerState): number {\n state.epoch = nextSmi(state.epoch);\n return state.epoch;\n}\n\n/** @internal */\nexport function schedulerStartFlush(state: SchedulerState): boolean {\n if (state.sessionActive) {\n if (IS_DEV) console.warn('startFlush() called during flush - ignored');\n return false;\n }\n state.sessionActive = true;\n state.sessionEpoch = schedulerNextEpoch(state);\n state.sessionExecutionCount = 0;\n return true;\n}\n\n/** @internal */\nexport function schedulerEndFlush(state: SchedulerState): void {\n state.sessionActive = false;\n}\n\n/** @internal */\nexport function schedulerIncrementFlushExecutionCount(state: SchedulerState): number {\n if (!state.sessionActive) return 0;\n const count = ++state.sessionExecutionCount;\n if (count <= SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_FLUSH) return count;\n\n throw new Error(\n `[atom-effect] Infinite loop detected: flush execution count exceeded ${SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_FLUSH}`\n );\n}\n\n/** @internal */\nexport function schedulerResetFlushState(state: SchedulerState): void {\n state.sessionEpoch = 0;\n state.sessionExecutionCount = 0;\n state.sessionActive = false;\n}\n\n/**\n * Core scheduling logic. Decisions between microtask or synchronous flush are made here.\n * @internal\n */\nexport function schedulerSchedule(state: SchedulerState, callback: SchedulerJob): void {\n if (IS_DEV) {\n if (\n typeof callback !== 'function' &&\n (!callback || typeof (callback as SchedulerJobObject).execute !== 'function')\n ) {\n throw new SchedulerError(ERROR_MESSAGES.SCHEDULER_CALLBACK_MUST_BE_FUNCTION);\n }\n }\n\n // Optimization: Prevents a job from being added to the queue multiple times in the same epoch.\n if (callback._nextEpoch === state.epoch) return;\n callback._nextEpoch = state.epoch;\n\n // Logic: Queue selection based on current scheduler state.\n if ((state.state & MASK_DEFERRED) === 0) {\n state.activeBuffer[state.size++] = callback;\n } else {\n state.batchBuffer[state.batchQueueSize++] = callback;\n }\n\n // Logic: Microtask entry point.\n if ((state.state & S_PROCESSING) === 0) {\n state.state |= S_PROCESSING;\n queueMicrotask(() => {\n try {\n if (state.size === 0 && state.batchQueueSize === 0) return;\n const started = schedulerStartFlush(state);\n schedulerDrainQueue(\n state,\n () => schedulerNextEpoch(state),\n (s) => schedulerProcessQueue(s, () => schedulerNextEpoch(s)),\n (s) => schedulerHandleFlushOverflow(s)\n );\n if (started) schedulerEndFlush(state);\n } catch (e) {\n // Caution: Reset tracking context to prevent leaking reactive state after a crash.\n resetTrackingContext(trackingContext);\n throw e;\n } finally {\n state.state &= ~S_PROCESSING;\n }\n });\n }\n}\n\n/**\n * Forcefully flushes all pending jobs synchronously.\n * @internal\n */\nexport function schedulerFlushSync(state: SchedulerState): void {\n if (state.size === 0 && state.batchQueueSize === 0) return;\n\n const prevState = state.state;\n state.state |= S_FLUSHING_SYNC;\n const started = schedulerStartFlush(state);\n try {\n schedulerMergeBatchQueue(state, () => schedulerNextEpoch(state));\n schedulerDrainQueue(\n state,\n () => schedulerNextEpoch(state),\n (s) => schedulerProcessQueue(s, () => schedulerNextEpoch(s)),\n (s) => schedulerHandleFlushOverflow(s)\n );\n } finally {\n state.state = prevState;\n if (started) schedulerEndFlush(state);\n }\n}\n\n/** @internal */\nexport function schedulerStartBatch(state: SchedulerState): void {\n state.batchDepth++;\n state.state |= S_BATCHING;\n}\n\n/** @internal */\nexport function schedulerEndBatch(state: SchedulerState): void {\n if (state.batchDepth === 0) {\n if (IS_DEV) console.warn(ERROR_MESSAGES.SCHEDULER_END_BATCH_WITHOUT_START);\n return;\n }\n\n if (--state.batchDepth === 0) {\n state.state &= ~S_BATCHING;\n // Logic: Automatically trigger a sync flush at the end of the outermost batch\n // unless already flushing synchronously.\n if ((state.state & S_FLUSHING_SYNC) === 0) {\n schedulerFlushSync(state);\n }\n }\n}\n\n/** @internal */\nexport function schedulerSetMaxFlushIterations(state: SchedulerState, max: number): void {\n if (max < SCHEDULER_CONFIG.MIN_FLUSH_ITERATIONS)\n throw new SchedulerError(\n `Max iterations must be at least ${SCHEDULER_CONFIG.MIN_FLUSH_ITERATIONS}`\n );\n state.maxFlushIterations = max;\n}\n\n/** @internal */\nexport function schedulerIsBatching(state: SchedulerState): boolean {\n return (state.state & S_BATCHING) !== 0;\n}\n\n/** @internal */\nexport function schedulerQueueSize(state: SchedulerState): number {\n return state.size + state.batchQueueSize;\n}\n\nexport const scheduler = createSchedulerState();\n\nexport const nextEpoch = (): number => schedulerNextEpoch(scheduler);\nexport const currentEpoch = (): number => scheduler.epoch;\nexport const currentFlushEpoch = (): number => scheduler.sessionEpoch;\nexport const startFlush = (): boolean => schedulerStartFlush(scheduler);\nexport const endFlush = (): void => schedulerEndFlush(scheduler);\nexport const incrementFlushExecutionCount = (): number =>\n schedulerIncrementFlushExecutionCount(scheduler);\nexport const resetFlushState = (): void => schedulerResetFlushState(scheduler);\n\n/**\n * Groups multiple state updates into a single atomic change and flushes them synchronously.\n *\n * When to use:\n * - Ensuring that all effects triggered by state changes are executed immediately before the function returns (Synchronous Settlement).\n * - Creating a transactional scope where multiple updates are treated as one unit and settled predictably.\n *\n * @example\n * ```typescript\n * batch(() => {\n * atomA.set(1);\n * atomB.set(2);\n * });\n * // At this point, all triggered effects have already finished executing.\n * ```\n */\nexport function batch<T>(fn: () => T): T {\n if (IS_DEV && typeof fn !== 'function') {\n throw new TypeError(ERROR_MESSAGES.BATCH_CALLBACK_MUST_BE_FUNCTION);\n }\n\n schedulerStartBatch(scheduler);\n try {\n return fn();\n } finally {\n schedulerEndBatch(scheduler);\n }\n}\n\n/**\n * Scopes a function execution within a flush lifecycle.\n * Ensures the scheduler state is cleaned up even if the provided function throws.\n * @internal\n */\nexport function runInFlushScope<T>(fn: () => T): T | undefined {\n const started = startFlush();\n try {\n return fn();\n } finally {\n if (started) endFlush();\n }\n}\n\nlet sharedNextTickPromise: Promise<void> | null = null;\n\n/**\n * Returns a promise that resolves after the next scheduler flush.\n *\n * When to use:\n * - Waiting for effects to finish in tests after state updates.\n * - Synchronizing logic with the reactive system's \"settled\" state.\n *\n * @example\n * ```typescript\n * atom.set(100);\n * await aeNextTick();\n * // DOM or side effects are now guaranteed to be updated.\n * ```\n */\nexport function aeNextTick(fn?: () => void): Promise<void> {\n if (fn) {\n return new Promise<void>((resolve, reject) => {\n schedulerSchedule(scheduler, () => {\n try {\n fn();\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n });\n }\n\n if (sharedNextTickPromise) return sharedNextTickPromise;\n\n sharedNextTickPromise = new Promise<void>((resolve) => {\n schedulerSchedule(scheduler, () => {\n sharedNextTickPromise = null;\n resolve();\n });\n });\n\n return sharedNextTickPromise;\n}\n","import { ATOM_STATE_FLAGS, IS_DEV } from '@/constants';\nimport { ReactiveNode } from '@/core/base';\nimport { BRAND, BrandFlags } from '@/symbols';\nimport type { AtomOptions, WritableAtom } from '@/types';\nimport { debug } from '@/utils/debug';\nimport { nextVersion, scheduler, schedulerIsBatching, schedulerSchedule } from './scheduler';\nimport { trackingContext } from './tracking';\n\n/**\n * Internal implementation of a {@link WritableAtom}.\n *\n * Logic: Dependency Graph Integration\n * As a leaf node, it doesn't have dependencies of its own but serves as\n * a source for `Computed` and `Effect` nodes.\n *\n * @internal\n */\nclass AtomImpl<T> extends ReactiveNode<T> implements WritableAtom<T> {\n private _value: T;\n /** Optimization: Captured during mutation to allow net-zero suppression in batches. */\n private _pendingOldValue: T | undefined;\n private _equal: (a: T, b: T) => boolean;\n\n /** @internal */\n readonly [BRAND] = BrandFlags.Atom | BrandFlags.Writable;\n\n constructor(initialValue: T, options: AtomOptions<T>) {\n super();\n this._value = initialValue;\n this._equal = options.equal ?? Object.is;\n\n if (options.sync) {\n this.flags |= ATOM_STATE_FLAGS.SYNC;\n }\n\n debug.attachDebugInfo(this, 'atom', this.id, options.name);\n }\n\n /** @internal */\n get isNotificationScheduled(): boolean {\n return (this.flags & ATOM_STATE_FLAGS.NOTIFICATION_SCHEDULED) !== 0;\n }\n\n /** @internal */\n get isSync(): boolean {\n return (this.flags & ATOM_STATE_FLAGS.SYNC) !== 0;\n }\n\n /**\n * Retrieves the current value and registers a dependency if called in a reactive context.\n */\n get value(): T {\n trackingContext.current?.addDependency(this);\n return this._value;\n }\n\n set value(newValue: T) {\n if (this._equal(this._value, newValue)) return;\n\n const oldValue = this._value;\n this._value = newValue;\n this.version = nextVersion(this.version);\n\n if (IS_DEV) debug.trackUpdate(this.id, debug.getDebugName(this));\n\n this._scheduleNotification(oldValue);\n }\n\n private _scheduleNotification(oldValue: T): void {\n const flags = this.flags;\n const SCHED = ATOM_STATE_FLAGS.NOTIFICATION_SCHEDULED;\n\n if ((flags & SCHED) !== 0 || !this._slots?.length) return;\n\n this._pendingOldValue = oldValue;\n this.flags |= SCHED;\n\n if ((flags & ATOM_STATE_FLAGS.SYNC) !== 0 && !schedulerIsBatching(scheduler)) {\n if (!this.isNotifying) this._flushNotifications();\n } else {\n schedulerSchedule(scheduler, this);\n }\n }\n\n /**\n * @internal - Entry point for the global scheduler.\n */\n execute(): void {\n this._flushNotifications();\n }\n\n private _flushNotifications(): void {\n const SCHED = ATOM_STATE_FLAGS.NOTIFICATION_SCHEDULED;\n const MASK = SCHED | ATOM_STATE_FLAGS.DISPOSED;\n const isSyncActive =\n (this.flags & ATOM_STATE_FLAGS.SYNC) !== 0 && !schedulerIsBatching(scheduler);\n\n while ((this.flags & MASK) === SCHED) {\n const prev = this._pendingOldValue as T;\n const next = this._value;\n\n this._pendingOldValue = undefined;\n this.flags &= ~SCHED;\n\n if (!this._equal(next, prev)) {\n this._notifySubscribers(next, prev);\n }\n\n if (!isSyncActive) break;\n }\n }\n\n /**\n * Accesses the value without registering a dependency.\n *\n * When to use:\n * - In event handlers or outside reactive contexts where tracking is undesirable.\n */\n peek(): T {\n return this._value;\n }\n\n /**\n * Caution: Disposed atoms release their values and equality checks.\n * Subsequent access may result in undefined behavior or errors.\n */\n dispose(): void {\n const DISP = ATOM_STATE_FLAGS.DISPOSED;\n if ((this.flags & DISP) !== 0) return;\n\n this.flags |= DISP;\n this._slots?.clear();\n\n // Reason: Release references immediately to assist GC in large-scale state trees.\n this._value = undefined as T;\n this._pendingOldValue = undefined;\n this._equal = Object.is;\n }\n\n /**\n * Logic: Atoms are leaf nodes; they change only via explicit assignment,\n * so they never require upstream dirty checking.\n */\n protected override _deepDirtyCheck(): boolean {\n return false;\n }\n}\n\n/**\n * Creates a reactive atom holding mutable state.\n *\n * When to use:\n * - As a primary source of truth for local or global state.\n * - When state needs to be updated manually via `.value = ...`.\n *\n * @param initialValue - The starting value.\n * @param options - Configuration for custom equality or synchronous delivery.\n *\n * @example\n * ```typescript\n * const count = atom(0);\n * count.value++; // Triggers downstream updates\n * ```\n */\nexport function atom<T>(initialValue: T, options: AtomOptions<T> = {}): WritableAtom<T> {\n return new AtomImpl(initialValue, options);\n}\n","import { isPromise } from '@but212/atom-effect-utils';\nimport { BRAND, BrandFlags } from '@/symbols';\nimport type { ComputedAtom, EffectObject, ReadonlyAtom, WritableAtom } from '@/types';\n\n/** @internal */\ninterface Branded {\n [BRAND]?: number;\n}\n\n/**\n * Validates whether an object or function possesses a specific reactive brand flag.\n *\n * Logic: This helper utilizes a bitwise identity check on a single consolidated\n * `BRAND` symbol.\n *\n * Optimization: Bitwise checks are significantly faster than multiple property\n * lookups or `instanceof` checks, making this suitable for high-frequency use\n * within reactive execution loops.\n *\n * @param obj - The value to examine.\n * @param flag - The bitwise flag to check for.\n * @returns True if the value contains the specified flag.\n * @internal\n */\nfunction isBranded<T>(obj: unknown, flag: number): obj is T {\n if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) return false;\n\n return !!((obj as Branded)[BRAND]! & flag);\n}\n\n/**\n * Determines whether a value is a ReadonlyAtom.\n *\n * When to use:\n * - To validate user input in APIs that expect reactive atoms.\n * - To differentiate between raw values and reactive containers.\n *\n * @param obj - The value to check.\n * @returns True if the value is an atom.\n *\n * @example\n * ```typescript\n * import { isAtom } from '@but212/atom-effect';\n *\n * if (isAtom(maybeAtom)) {\n * console.log(maybeAtom.value);\n * }\n * ```\n */\nexport function isAtom(obj: unknown): obj is ReadonlyAtom {\n return isBranded(obj, BrandFlags.Atom);\n}\n\n/**\n * Determines whether a value is a WritableAtom.\n *\n * When to use:\n * - To verify if an atom can be modified via `.set()` or `.update()` before attempting the operation.\n *\n * @param obj - The value to check.\n * @returns True if the value is a writable atom.\n *\n * @example\n * ```typescript\n * import { isWritable } from '@but212/atom-effect';\n *\n * if (isWritable(maybeAtom)) {\n * maybeAtom.value = 123;\n * }\n * ```\n */\nexport function isWritable(obj: unknown): obj is WritableAtom {\n return isBranded(obj, BrandFlags.Writable);\n}\n\n/**\n * Determines whether a value is a ComputedAtom.\n *\n * When to use:\n * - To identify derived state containers that may have underlying dependencies.\n *\n * @param obj - The value to check.\n * @returns True if the value is a computed atom.\n *\n * @example\n * ```typescript\n * import { isComputed } from '@but212/atom-effect';\n *\n * if (isComputed(maybeAtom)) {\n * console.log('This atom is a derived value.');\n * }\n * ```\n */\nexport function isComputed(obj: unknown): obj is ComputedAtom {\n return isBranded(obj, BrandFlags.Computed);\n}\n\n/**\n * Determines whether a value is an EffectObject.\n *\n * When to use:\n * - To validate objects that manage reactive side-effects.\n *\n * @param obj - The value to check.\n * @returns True if the value is an effect handle.\n *\n * @example\n * ```typescript\n * import { isEffect } from '@but212/atom-effect';\n *\n * if (isEffect(maybeEffect)) {\n * maybeEffect.dispose();\n * }\n * ```\n */\nexport function isEffect(obj: unknown): obj is EffectObject {\n return isBranded(obj, BrandFlags.Effect);\n}\n\nexport { isPromise };\n","import type { Dependency, MergedDependencyValue } from '@/types';\n\n/**\n * Merges the values of multiple object-based atoms into a single object.\n * @internal\n *\n * @param atoms - List of atoms to merge.\n * @param peek - If true, uses .peek() instead of .value to avoid reactive tracking.\n * @returns A single object containing all properties from the input atoms.\n */\nexport function mergeAtomValues<T extends Dependency<unknown>[]>(\n atoms: T,\n peek = false\n): MergedDependencyValue<T> {\n const result = {} as MergedDependencyValue<T>;\n\n for (let i = 0; i < atoms.length; i++) {\n const val = peek ? atoms[i]!.peek() : atoms[i]!.value;\n if (val && typeof val === 'object') {\n Object.assign(result as object, val);\n }\n }\n\n return result;\n}\n\nexport { debug, NO_DEFAULT_VALUE } from './debug';\nexport { isAtom, isComputed, isEffect, isPromise, isWritable } from './type-guards';\n","import {\n AsyncState,\n COMPUTED_STATE_FLAGS,\n EMPTY_ERROR_ARRAY,\n EPOCH_CONSTANTS,\n IS_DEV,\n} from '@/constants';\nimport { ReactiveNode } from '@/core/base';\nimport { ComputedError, ERROR_MESSAGES, wrapError } from '@/errors';\nimport { BRAND, BrandFlags } from '@/symbols';\nimport type {\n AsyncStateType,\n ComputedAtom,\n ComputedOptions,\n Dependency,\n MergedDependencyValue,\n Subscriber,\n} from '@/types';\nimport { debug, mergeAtomValues, NO_DEFAULT_VALUE } from '@/utils';\nimport { isPromise } from '@/utils/type-guards';\nimport {\n claimExisting,\n createDepBuffer,\n type DepBufferState,\n depBufferTruncateFrom,\n disposeAll,\n insertNew,\n isBufferDirty,\n prepareTracking,\n} from './buffers';\nimport { nextEpoch, nextVersion } from './scheduler';\nimport {\n createDependencyLink,\n rollbackTrackingSubscriber,\n runInTrackingContext,\n trackingContext,\n untracked,\n} from './tracking';\n\nconst {\n IDLE,\n DIRTY,\n PENDING,\n RESOLVED,\n REJECTED,\n HAS_ERROR,\n RECOMPUTING,\n DISPOSED,\n IS_COMPUTED,\n FORCE_COMPUTE,\n} = COMPUTED_STATE_FLAGS;\n\nconst MASK_UNRESOLVED_ASYNC = PENDING | REJECTED;\nconst PATTERN_RECOMPUTE_NEEDED = IDLE | FORCE_COMPUTE;\nconst MASK_ERROR = REJECTED | HAS_ERROR;\nconst MASK_LIFECYCLE = IDLE | DIRTY | PENDING | RESOLVED | REJECTED | HAS_ERROR;\n\n/**\n * Logic: Pragmatic Physics Transitions\n * Pure bitmask descriptors for state transitions.\n * @internal\n */\nconst TRANSITION = {\n TO_RECOMPUTING: { clear: FORCE_COMPUTE, set: RECOMPUTING },\n TO_RESOLVED: { clear: MASK_LIFECYCLE | RECOMPUTING, set: RESOLVED },\n TO_PENDING: { clear: MASK_LIFECYCLE | RECOMPUTING, set: PENDING },\n TO_REJECTED: { clear: MASK_LIFECYCLE | RECOMPUTING, set: REJECTED | HAS_ERROR },\n} as const;\n\n/** @internal */\nconst apply = (f: number, t: { readonly clear: number; readonly set: number }) =>\n (f & ~t.clear) | t.set;\n\n/**\n * Logic: Computed Result Resolution\n * Determines the final value or error to return based on current flags and cache.\n * @internal\n */\nexport function resolveComputedResult<T>(\n flags: number,\n value: T,\n error: Error | null,\n defaultValue: T\n): T {\n if ((flags & RESOLVED) !== 0) return value;\n\n const hasDefault = defaultValue !== (NO_DEFAULT_VALUE as T);\n const asyncState = flags & MASK_UNRESOLVED_ASYNC;\n\n // Terminal/Non-async fallback\n if (asyncState === 0) return value;\n\n // Async handling priority\n if (hasDefault) return defaultValue;\n\n if (asyncState === REJECTED) {\n throw error ?? new Error('REJECTED without error');\n }\n\n throw new ComputedError(ERROR_MESSAGES.COMPUTED_ASYNC_PENDING_NO_DEFAULT);\n}\n\n/**\n * Logic: Re-computation Heuristics\n * Determines if a node requires re-evaluation based on its state and dependencies.\n * @internal\n */\nexport function shouldRecompute(flags: number, deps: DepBufferState): boolean {\n const isAwaitingAsync = (flags & MASK_UNRESOLVED_ASYNC) !== 0;\n\n return (\n (flags & PATTERN_RECOMPUTE_NEEDED) !== 0 ||\n isBufferDirty(deps) ||\n (!isAwaitingAsync && deps.slots.size === 0)\n );\n}\n\n/** @internal */\ninterface InternalComputedNode {\n readonly id: number;\n readonly flags: number;\n readonly lastError: Error | null;\n readonly _deps: DepBufferState | null;\n}\n\n/**\n * Logic: Iterative Graph Traversal\n * Crawls the dependency graph to collect errors.\n * @internal\n */\nexport function collectErrorsRecursive(\n startNode: InternalComputedNode,\n stopOnFirst: boolean\n): Error[] {\n const collected: Error[] = [];\n const seen = new Set<number>();\n\n const walk = (node: InternalComputedNode): boolean => {\n if (seen.has(node.id)) return false;\n seen.add(node.id);\n\n if ((node.flags & MASK_ERROR) !== 0) {\n collected.push(\n node.lastError ?? new Error('Internal Inconsistency: MASK_ERROR flag set but error is null')\n );\n if (stopOnFirst) return true;\n }\n\n const deps = node._deps;\n if (deps?.hasComputeds) {\n for (let i = 0, len = deps.slots.length; i < len; i++) {\n const link = deps.slots.at(i);\n if (link?.node.isComputed && walk(link.node as unknown as InternalComputedNode)) {\n return true;\n }\n }\n }\n return false;\n };\n\n walk(startNode);\n return collected;\n}\n\n/**\n * Implementation of a derived reactive value.\n * @internal\n */\nclass ComputedAtomImpl<T> extends ReactiveNode<T> implements ComputedAtom<T>, Subscriber {\n /** @internal */\n readonly [BRAND] = BrandFlags.Atom | BrandFlags.Computed;\n\n /** @internal */\n private _activeSessionId = 0;\n private _sessionCounter = 0;\n\n /** @internal */\n private _trackEpoch: number = EPOCH_CONSTANTS.UNINITIALIZED;\n /** @internal */\n private _trackCount = 0;\n\n private _value: T;\n private _error: Error | null = null;\n\n /**\n * Internal dependency buffer managing subscription reconciliation.\n * @internal\n */\n _deps = createDepBuffer();\n\n private readonly _equal: (a: T, b: T) => boolean;\n private readonly _computation: () => T | Promise<T>;\n private readonly _defaultValue: T;\n private readonly _onError: ((error: Error) => void) | null;\n\n constructor(computation: () => T | Promise<T>, options: ComputedOptions<T> = {}) {\n if (typeof computation !== 'function')\n throw new ComputedError(ERROR_MESSAGES.COMPUTED_MUST_BE_FUNCTION);\n super();\n\n this._value = undefined as T;\n // Initial State: Dirty and Idle to force evaluation on first access.\n this.flags = IS_COMPUTED | DIRTY | IDLE;\n this._equal = options.equal ?? Object.is;\n this._computation = computation;\n this._defaultValue = 'defaultValue' in options ? options.defaultValue : (NO_DEFAULT_VALUE as T);\n this._onError = options.onError ?? null;\n\n debug.attachDebugInfo(this, 'computed', this.id, options.name);\n\n if (options.lazy === false) {\n try {\n this._recompute();\n } catch {\n /* Error handling is isolated within _recompute */\n }\n }\n }\n\n get isDirty(): boolean {\n return (this.flags & DIRTY) !== 0;\n }\n\n get isRejected(): boolean {\n return (this.flags & REJECTED) !== 0;\n }\n\n get isRecomputing(): boolean {\n return (this.flags & RECOMPUTING) !== 0;\n }\n\n /**\n * Accesses the current value, triggering lazy evaluation if necessary.\n *\n * Logic: Pull-based Refresh\n * Accessing this property validates the entire dependency sub-graph.\n *\n * Caution: Circular Dependency\n * If a computed node is accessed during its own execution (RECOMPUTING),\n * it will either return a default value or throw a `ComputedError`.\n */\n get value(): T {\n trackingContext.current?.addDependency(this);\n\n if (this._isStable()) return this._value;\n\n this._ensureNotDisposed();\n\n if ((this.flags & RECOMPUTING) !== 0) {\n if (this._defaultValue !== (NO_DEFAULT_VALUE as T)) return this._defaultValue;\n throw new ComputedError(ERROR_MESSAGES.COMPUTED_CIRCULAR_DEPENDENCY);\n }\n\n if (shouldRecompute(this.flags, this._deps)) {\n this._recompute();\n } else {\n this.flags &= ~DIRTY;\n }\n\n return resolveComputedResult(this.flags, this._value, this._error, this._defaultValue);\n }\n\n /**\n * Logic: Stability Guard\n * A node is stable if it is RESOLVED and not marked DIRTY or currently computing.\n */\n private _isStable(): boolean {\n const STABLE_MASK = RESOLVED | DIRTY | IDLE | DISPOSED | RECOMPUTING;\n return (this.flags & STABLE_MASK) === RESOLVED;\n }\n\n private _ensureNotDisposed(): void {\n if ((this.flags & DISPOSED) !== 0) throw new ComputedError(ERROR_MESSAGES.COMPUTED_DISPOSED);\n }\n\n /**\n * Reads the current cached value without triggering evaluation.\n */\n peek(): T {\n return this._value;\n }\n\n /**\n * Returns the current lifecycle phase (IDLE, PENDING, RESOLVED, REJECTED).\n */\n get state(): AsyncStateType {\n trackingContext.current?.addDependency(this);\n const flags = this.flags;\n if ((flags & RESOLVED) !== 0) return AsyncState.RESOLVED;\n if ((flags & PENDING) !== 0) return AsyncState.PENDING;\n if ((flags & REJECTED) !== 0) return AsyncState.REJECTED;\n return AsyncState.IDLE;\n }\n\n /**\n * Logic: Untracked Deep Scan\n * Checks if any node in the dependency graph is in an error state.\n * Performed untracked to avoid creating excessive subscriptions to deep nodes.\n */\n get hasError(): boolean {\n trackingContext.current?.addDependency(this);\n\n if ((this.flags & MASK_ERROR) !== 0) return true;\n if (!this._deps.hasComputeds) return false;\n\n return untracked(() => collectErrorsRecursive(this, true).length > 0);\n }\n\n get isValid(): boolean {\n return !this.hasError;\n }\n\n /**\n * Collects all errors from the dependency sub-graph into a frozen array.\n */\n get errors(): readonly Error[] {\n trackingContext.current?.addDependency(this);\n\n if (!this._deps.hasComputeds) {\n return this._error ? Object.freeze([this._error]) : EMPTY_ERROR_ARRAY;\n }\n\n return untracked(() => Object.freeze(collectErrorsRecursive(this, false)));\n }\n\n get lastError(): Error | null {\n trackingContext.current?.addDependency(this);\n return this._error;\n }\n\n get isPending(): boolean {\n trackingContext.current?.addDependency(this);\n return (this.flags & PENDING) !== 0;\n }\n\n get isResolved(): boolean {\n trackingContext.current?.addDependency(this);\n return (this.flags & RESOLVED) !== 0;\n }\n\n /**\n * Manually flags the node for re-computation.\n */\n invalidate(): void {\n this.flags |= FORCE_COMPUTE;\n this._markDirty();\n }\n\n /**\n * Releases resources and marks the node as permanently inactive.\n * Logic: Disposed nodes enter a terminal DIRTY state.\n */\n dispose(): void {\n const flags = this.flags;\n if ((flags & DISPOSED) !== 0) return;\n\n disposeAll(this._deps);\n\n this._slots?.clear();\n this.flags = DISPOSED | DIRTY | IDLE;\n\n this._error = null;\n this._value = undefined as T;\n }\n\n /**\n * Logic: Subscription Reconciliation\n * Captures dependencies during the tracking phase. Reuses existing\n * subscription links (O(1) in the buffer) to minimize DOM/event thrashing.\n * @internal\n */\n addDependency(dependency: Dependency): void {\n const trackEpoch = this._trackEpoch;\n // Optimization: Deduplicate tracking within the same execution epoch.\n if (dependency._lastSeenEpoch === trackEpoch) return;\n dependency._lastSeenEpoch = trackEpoch;\n\n const trackIndex = this._trackCount++;\n const dependencies = this._deps;\n\n const existing = dependencies.slots.at(trackIndex);\n\n if (existing?.node === dependency) {\n existing.version = dependency.version;\n } else if (!claimExisting(dependencies, dependency, trackIndex)) {\n const link = createDependencyLink(dependency, dependency.version, dependency.subscribe(this));\n insertNew(dependencies, trackIndex, link);\n }\n\n if ((dependency.flags & IS_COMPUTED) !== 0) {\n dependencies.hasComputeds = true;\n }\n }\n\n /**\n * Logic: Tracked Execution Orchestrator\n * Wraps the computation in a tracking context to capture dependencies.\n */\n private _recompute(): void {\n // Constraint: Prevent synchronous re-entrancy.\n if ((this.flags & RECOMPUTING) !== 0) return;\n\n this.flags = apply(this.flags, TRANSITION.TO_RECOMPUTING);\n const prevDepth = trackingContext.stack.length;\n\n this._startTracking();\n\n let val: T | Promise<T> | undefined;\n let hasError = false;\n let errorToThrow: unknown;\n\n try {\n try {\n val = runInTrackingContext(trackingContext, this, this._computation);\n } catch (e) {\n rollbackTrackingSubscriber(trackingContext, prevDepth);\n throw e;\n }\n } catch (e) {\n hasError = true;\n errorToThrow = e;\n }\n\n if (hasError) {\n this._commitDeps();\n this._handleError(errorToThrow, ERROR_MESSAGES.COMPUTED_COMPUTATION_FAILED, false);\n } else {\n this._commitDeps();\n if (isPromise(val!)) {\n this._handleAsyncComputation(val as Promise<T>);\n } else {\n this._finalizeResolution(val as T);\n }\n }\n\n this._trackEpoch = EPOCH_CONSTANTS.UNINITIALIZED;\n this._trackCount = 0;\n this.flags &= ~RECOMPUTING;\n }\n\n private _startTracking(): void {\n this._trackEpoch = nextEpoch();\n this._trackCount = 0;\n prepareTracking(this._deps);\n }\n\n private _commitDeps(): void {\n try {\n depBufferTruncateFrom(this._deps, this._trackCount);\n } catch (commitError) {\n if (IS_DEV) {\n console.warn('[atom-effect] _commitDeps failed during error recovery:', commitError);\n }\n }\n }\n\n /**\n * Logic: Async Session Management\n * Orchestrates Promise resolution. Uses unique session IDs to discard\n * results from invalidated computations (Drift Detection).\n */\n private _handleAsyncComputation(promise: Promise<T>): void {\n this.flags = apply(this.flags, TRANSITION.TO_PENDING);\n this._notifySubscribers(undefined, undefined);\n\n const sessionId = ++this._sessionCounter;\n this._activeSessionId = sessionId;\n\n promise.then(\n (result) => {\n if (this._activeSessionId !== sessionId) return;\n\n // Constraint: If the node became dirty during the async wait,\n // defer resolution until the next read.\n if (this._isDirty()) return this._markDirty();\n\n this._finalizeResolution(result);\n this._notifySubscribers(result, undefined);\n },\n (error) => {\n if (this._activeSessionId !== sessionId) return;\n this._handleError(error, ERROR_MESSAGES.COMPUTED_ASYNC_COMPUTATION_FAILED);\n }\n );\n }\n\n private _handleError(error: unknown, message: string, shouldThrow = false): void {\n const wrappedError = wrapError(error, ComputedError, message);\n\n const oldError = this._error;\n if (!this.isRejected || oldError !== wrappedError) {\n this.version = nextVersion(this.version);\n }\n\n this._error = wrappedError;\n this.flags = apply(this.flags, TRANSITION.TO_REJECTED);\n\n if (this._onError) {\n try {\n this._onError(wrappedError);\n } catch (e) {\n console.error(ERROR_MESSAGES.CALLBACK_ERROR_IN_ERROR_HANDLER, e);\n }\n }\n\n this._notifySubscribers(undefined, undefined);\n if (shouldThrow) throw wrappedError;\n }\n\n /**\n * Logic: Version-Aware Resolution\n * Increments the node's version ONLY if the new value is structurally\n * different (via `_equal`). This prevents unnecessary downstream re-computes.\n */\n private _finalizeResolution(value: T): void {\n const flags = this.flags;\n if ((flags & RESOLVED) === 0 || !this._equal(this._value, value)) {\n this.version = nextVersion(this.version);\n }\n\n this._value = value;\n this._error = null;\n this.flags = apply(this.flags, TRANSITION.TO_RESOLVED);\n }\n\n /**\n * Implementation of the Subscriber interface for the global scheduler.\n * @internal\n */\n execute(): void {\n this._markDirty();\n }\n\n /**\n * Marks the node as DIRTY and propagates the notification to dependents.\n * @internal\n */\n _markDirty(): void {\n const flags = this.flags;\n // 1. Already recomputing or marked dirty (prevent redundant propagation)\n // 2. OR (Not forced to compute AND no changes detected in dependencies)\n if (\n (flags & (RECOMPUTING | DIRTY)) !== 0 ||\n (!(flags & FORCE_COMPUTE) && !this._isShallowDirty())\n ) {\n return;\n }\n\n this.flags = flags | DIRTY;\n debug.trackUpdate(this.id, debug.getDebugName(this));\n this._notifySubscribers(undefined, undefined);\n }\n\n /** @internal */\n protected override _deepDirtyCheck(): boolean {\n return isBufferDirty(this._deps);\n }\n}\n\n/**\n * Creates a reactive computation derived from other atoms or computed nodes.\n *\n * When to use:\n * - To define values that automatically update when their dependencies change.\n * - To optimize performance through caching of expensive calculations.\n * - To transform or aggregate raw state for UI presentation.\n *\n * @example\n * ```typescript\n * const count = atom(1);\n * const doubled = computed(() => count.value * 2);\n * ```\n */\nexport function computed<T>(fn: () => T, options?: ComputedOptions<T>): ComputedAtom<T>;\n/**\n * Creates an asynchronous reactive computation.\n *\n * When to use:\n * - For logic involving fetch, database queries, or long-running tasks.\n *\n * Attention:\n * A `defaultValue` is mandatory for async computations to provide a valid\n * state while the Promise is PENDING.\n *\n * @example\n * ```typescript\n * const user = computed(\n * async () => fetchUser(userId.value),\n * { defaultValue: null }\n * );\n * ```\n */\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);\n}\n\n/**\n * Combines multiple object-based atoms into a single computed atom with a flattened type.\n *\n * This utility merges the value types of all input atoms into a single\n * unified object type using the {@link Merge} utility.\n *\n * @param atoms - A variadic list of atoms or computed nodes to merge.\n *\n * @example\n * ```typescript\n * const a = atom({ x: 1 });\n * const b = atom({ y: 2 });\n * const c = computed(() => ({ z: 3 }));\n *\n * const combined = mergeAtoms(a, b, c);\n * // combined.value is { x: number; y: number; z: number }\n * ```\n */\nexport function mergeAtoms<T extends Dependency<unknown>[]>(\n ...atoms: T\n): ComputedAtom<MergedDependencyValue<T>> {\n return computed(() => mergeAtomValues(atoms));\n}\n","import {\n DEBUG_CONFIG,\n EFFECT_STATE_FLAGS,\n EPOCH_CONSTANTS,\n IS_DEV,\n SCHEDULER_CONFIG,\n} from '@/constants';\nimport { ReactiveNode } from '@/core/base';\nimport { EffectError, ERROR_MESSAGES, wrapError } from '@/errors';\nimport { BRAND, BrandFlags } from '@/symbols';\nimport type { Dependency, EffectFunction, EffectObject, EffectOptions } from '@/types';\nimport { debug } from '@/utils/debug';\nimport { isPromise } from '@/utils/type-guards';\nimport {\n claimExisting,\n createDepBuffer,\n depBufferTruncateFrom,\n disposeAll,\n insertNew,\n isBufferDirty,\n prepareTracking,\n} from './buffers';\nimport {\n currentFlushEpoch,\n incrementFlushExecutionCount,\n nextEpoch,\n scheduler,\n schedulerSchedule,\n} from './scheduler';\nimport {\n createDependencyLink,\n type DependencyTracker,\n rollbackTrackingSubscriber,\n runInTrackingContext,\n trackingContext,\n} from './tracking';\n\n/**\n * Internal state for tracking effect execution budgets.\n * @internal\n */\nexport interface EffectBudgetState {\n loopCount: number;\n lastFlushEpoch: number;\n windowCount: number;\n windowStart: number;\n totalExecutions: number;\n}\n\n/**\n * Factory for effect budget state.\n * @internal\n */\nexport function createEffectBudgetState(): EffectBudgetState {\n return {\n loopCount: 0,\n lastFlushEpoch: EPOCH_CONSTANTS.UNINITIALIZED,\n windowCount: 0,\n windowStart: 0,\n totalExecutions: 0,\n };\n}\n\n/**\n * Logic: Effect Budget Validation\n * Ensures an effect doesn't run too many times in a single flush cycle,\n * preventing infinite loops.\n * @internal\n */\nexport function validateEffectBudget(\n state: EffectBudgetState,\n maxExecutionsPerFlush: number,\n currentFlushEpoch: number,\n incrementGlobalFlushCount: () => number,\n onAbort: (type: 'per-effect' | 'global') => never\n): void {\n if (state.lastFlushEpoch !== currentFlushEpoch) {\n state.lastFlushEpoch = currentFlushEpoch;\n state.loopCount = 0;\n }\n\n if (++state.loopCount > maxExecutionsPerFlush) {\n onAbort('per-effect');\n }\n\n if (incrementGlobalFlushCount() > SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_FLUSH) {\n onAbort('global');\n }\n\n state.totalExecutions++;\n}\n\n/**\n * Logic: Frequency Limiter\n * Throttles effects that fire too rapidly in development mode.\n * @internal\n */\nexport function checkEffectFrequencyLimit(\n state: EffectBudgetState,\n maxExecutions: number,\n onLimitExceeded: () => never\n): void {\n if (!Number.isFinite(maxExecutions)) return;\n\n const now = Date.now();\n\n if (now - state.windowStart >= DEBUG_CONFIG.EFFECT_FREQUENCY_WINDOW) {\n state.windowStart = now;\n state.windowCount = 1;\n return;\n }\n\n if (++state.windowCount > maxExecutions) {\n onLimitExceeded();\n }\n}\n\n/**\n * Implementation of a reactive side-effect.\n * @internal\n */\nclass EffectImpl extends ReactiveNode<void> implements EffectObject, DependencyTracker {\n /** @internal */\n readonly [BRAND] = BrandFlags.Effect;\n\n /** @internal */\n private _trackEpoch = EPOCH_CONSTANTS.UNINITIALIZED as number;\n /** @internal */\n private _trackCount = 0;\n /** @internal */\n private _trackSessionId = 0;\n\n private _budget = createEffectBudgetState();\n\n /** Buffered storage for reconciled subscriptions. @internal */\n _deps = createDepBuffer();\n\n private _cleanup: (() => void) | null = null;\n\n private readonly _fn: EffectFunction;\n private readonly _onError: ((error: unknown) => void) | null;\n private readonly _notifyCallback: () => void;\n\n private readonly _sync: boolean;\n private readonly _maxExecutions: number;\n private readonly _maxExecutionsPerFlush: number;\n\n constructor(fn: EffectFunction, options: EffectOptions = {}) {\n super();\n this._fn = fn;\n this._onError = options.onError ?? null;\n this._sync = options.sync ?? false;\n this._maxExecutions =\n options.maxExecutionsPerSecond ?? SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_SECOND;\n this._maxExecutionsPerFlush =\n options.maxExecutionsPerFlush ?? SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_EFFECT;\n\n this._notifyCallback = this._sync\n ? () => this.execute()\n : () => schedulerSchedule(scheduler, this);\n\n debug.attachDebugInfo(this, 'effect', this.id, options.name);\n }\n\n // --- Public API ---\n\n public run(): void {\n if (this.isDisposed) throw new EffectError(ERROR_MESSAGES.EFFECT_DISPOSED);\n this.execute(true);\n }\n\n public dispose(): void {\n if (this.isDisposed) return;\n this.flags |= EFFECT_STATE_FLAGS.DISPOSED;\n\n this._execCleanup();\n if (this._deps) disposeAll(this._deps);\n }\n\n /** Total executions since initialization. */\n get executionCount(): number {\n return this._budget.totalExecutions;\n }\n\n /** True if the effect function is currently on the stack. */\n get isExecuting(): boolean {\n return (this.flags & EFFECT_STATE_FLAGS.EXECUTING) !== 0;\n }\n\n /** True if the effect has been stopped. */\n get isDisposed(): boolean {\n return (this.flags & EFFECT_STATE_FLAGS.DISPOSED) !== 0;\n }\n\n // --- Core Execution Pipeline ---\n\n /**\n * Main execution cycle of the effect.\n *\n * Logic: Lifecycle Orchestration\n * 1. Prepare: Check flags, budgets, and dirty state.\n * 2. Cleanup: Execute previous session's teardown.\n * 3. Track: Run user function within reactive context.\n * 4. Finalize: Commit dependencies and handle result/error.\n */\n public execute(force = false): void {\n if (!this._prepareExecution(force)) return;\n\n this._execCleanup();\n\n this._startTracking();\n const prevDepth = trackingContext.stack.length;\n\n let val: unknown;\n let hasError = false;\n let errorObj: unknown;\n\n try {\n try {\n val = runInTrackingContext(trackingContext, this, this._fn);\n } catch (e) {\n rollbackTrackingSubscriber(trackingContext, prevDepth);\n throw e;\n }\n } catch (e) {\n hasError = true;\n errorObj = e;\n }\n\n this._commitDeps();\n\n if (hasError) {\n this._handleExecutionError(errorObj);\n } else {\n this._handleResult(val);\n }\n\n this.flags &= ~EFFECT_STATE_FLAGS.EXECUTING;\n }\n\n private _prepareExecution(force: boolean): boolean {\n const flags = this.flags;\n if ((flags & (EFFECT_STATE_FLAGS.DISPOSED | EFFECT_STATE_FLAGS.EXECUTING)) !== 0) return false;\n\n // Logic: Skip execution if not forced and no actual changes detected.\n if (!(force || this._deps.slots.length === 0 || this._isDirty())) return false;\n\n this._validateBudget();\n debug.trackUpdate(this.id, debug.getDebugName(this));\n\n this.flags |= EFFECT_STATE_FLAGS.EXECUTING;\n return true;\n }\n\n // --- Dependency Management ---\n\n public addDependency(dep: Dependency): void {\n if (!this.isExecuting) return;\n\n if (dep._lastSeenEpoch === this._trackEpoch) return;\n dep._lastSeenEpoch = this._trackEpoch;\n\n const trackIndex = this._trackCount++;\n const deps = this._deps;\n const version = dep.version;\n\n const existing = deps.slots.at(trackIndex);\n\n if (existing?.node === dep) {\n existing.version = version;\n } else if (!claimExisting(deps, dep, trackIndex)) {\n this._insertNewDependency(dep, trackIndex, version);\n }\n\n if (dep.isComputed && !deps.hasComputeds) {\n deps.hasComputeds = true;\n }\n }\n\n private _insertNewDependency(dep: Dependency, trackIndex: number, version: number): void {\n const unsubscribe = dep.subscribe(this._notifyCallback);\n const link = createDependencyLink(dep, version, unsubscribe);\n insertNew(this._deps, trackIndex, link);\n }\n\n private _startTracking(): void {\n this._trackEpoch = nextEpoch();\n this._trackCount = 0;\n prepareTracking(this._deps);\n }\n\n private _commitDeps(): void {\n try {\n depBufferTruncateFrom(this._deps, this._trackCount);\n } catch (commitErr) {\n if (IS_DEV) {\n console.warn('[atom-effect] _commitDeps failed during error recovery:', commitErr);\n }\n }\n }\n\n // --- Result & Cleanup Handling ---\n\n private _handleResult(val: unknown): void {\n if (typeof val === 'function') {\n this._cleanup = val as () => void;\n } else if (isPromise(val)) {\n this._handleAsyncResult(val as Promise<undefined | (() => void)>);\n } else {\n this._cleanup = null;\n }\n }\n\n private _handleAsyncResult(promise: Promise<unknown>): void {\n const sessionId = ++this._trackSessionId;\n\n promise.then(\n (cleanup) => {\n if (this._trackSessionId !== sessionId || this.isDisposed) {\n if (typeof cleanup === 'function') {\n try {\n cleanup();\n } catch (e) {\n this._handleExecutionError(e, ERROR_MESSAGES.EFFECT_CLEANUP_FAILED);\n }\n }\n return;\n }\n\n if (typeof cleanup === 'function') this._cleanup = cleanup as () => void;\n },\n (err) => {\n if (this._trackSessionId === sessionId) {\n this._handleExecutionError(err);\n }\n }\n );\n }\n\n private _execCleanup(): void {\n const fn = this._cleanup;\n if (!fn) return;\n\n this._cleanup = null;\n\n try {\n fn();\n } catch (e) {\n this._handleExecutionError(e as Error, ERROR_MESSAGES.EFFECT_CLEANUP_FAILED);\n }\n }\n\n // --- Budget & Safeguards ---\n\n private _validateBudget(): void {\n validateEffectBudget(\n this._budget,\n this._maxExecutionsPerFlush,\n currentFlushEpoch(),\n incrementFlushExecutionCount,\n (type) => this._abortExecution(type)\n );\n\n if (IS_DEV) {\n checkEffectFrequencyLimit(this._budget, this._maxExecutions, () => {\n const err = new EffectError(ERROR_MESSAGES.EFFECT_FREQUENCY_LIMIT_EXCEEDED);\n this.dispose();\n this._handleExecutionError(err);\n throw err;\n });\n }\n }\n\n private _abortExecution(type: 'per-effect' | 'global'): never {\n const message =\n type === 'per-effect'\n ? `Infinite loop detected (per-effect): executed ${this._budget.loopCount} times in current flush.`\n : 'Infinite loop detected (global): exceeded total execution limit per flush.';\n\n const error = new EffectError(message);\n this.dispose();\n console.error(error);\n throw error;\n }\n\n private _handleExecutionError(\n error: unknown,\n message: string = ERROR_MESSAGES.EFFECT_EXECUTION_FAILED\n ): void {\n const errorObj = wrapError(error, EffectError, message);\n console.error(errorObj);\n\n if (this._onError) {\n try {\n this._onError(errorObj);\n } catch (e) {\n console.error(wrapError(e, EffectError, ERROR_MESSAGES.CALLBACK_ERROR_IN_ERROR_HANDLER));\n }\n }\n }\n\n /** @internal */\n protected override _isDirty(): boolean {\n return isBufferDirty(this._deps);\n }\n\n /** @internal */\n protected override _deepDirtyCheck(): boolean {\n return isBufferDirty(this._deps);\n }\n}\n\n/**\n * Creates a reactive side-effect.\n *\n * When to use:\n * - To synchronize reactive state with the DOM or external APIs.\n * - To perform logging or diagnostic tasks.\n * - To manage timers or subscriptions that depend on atom values.\n *\n * @example\n * ```typescript\n * const count = atom(0);\n * effect(() => {\n * const el = document.getElementById('display')!;\n * el.textContent = `Value: ${count.value}`;\n *\n * // Optional teardown\n * return () => console.log('Cleaning up effect...');\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 effectInstance.execute();\n\n return effectInstance;\n}\n","import { shallowEqual } from '@but212/atom-effect-utils';\nimport { BRAND, BrandFlags } from '@/symbols';\nimport type { Equal, MergedDependencyValue, WritableAtom } from '@/types';\nimport { mergeAtomValues } from '@/utils';\nimport { batch } from './scheduler';\n\n/**\n * Logic: Numeric Key Conversion\n * Casts numeric string literals to numbers for correct array index typing.\n */\nexport type StringKeyToNumber<S extends string> = S extends `${infer N extends number}` ? N : S;\n\n/**\n * Logic: Broad Index Detection\n * Detects if a type has a broad string indexer (e.g., Record<string, any>).\n */\nexport type HasBroadStringKey<T> = string extends keyof T ? true : false;\n\n/** @public */\nexport type StringIndexValue<T> = T extends Record<string, infer V> ? V : never;\n\n/** @public */\nexport type ArrayElement<T> = T extends readonly (infer U)[] ? U : never;\n\n/**\n * Constraint: Depth limit for recursive path generation to prevent TypeScript\n * recursion errors and IDE lag in complex schemas.\n */\nexport type MaxDepth = 8;\n\n/**\n * Logic: Recursion Termination\n * Types that stop the recursive path exploration.\n */\nexport type TerminalTypes =\n | Date\n | RegExp\n | Map<unknown, unknown>\n | Set<unknown>\n | Promise<unknown>\n | Function;\n\n/**\n * Computes a union of all valid dot-separated paths for type T.\n *\n * Constraint: If T has a broad string indexer, it returns `string` to avoid\n * infinite union generation.\n */\nexport type Paths<T, D extends unknown[] = []> =\n // biome-ignore lint/suspicious/noExplicitAny: 'any' check is required to prevent infinite recursion in paths\n Equal<T, any> extends true\n ? string\n : D['length'] extends MaxDepth\n ? never\n : T extends TerminalTypes\n ? never\n : T extends readonly unknown[]\n ? NonNullable<ArrayElement<T>> extends object\n ? `${number}` | `${number}.${Paths<NonNullable<ArrayElement<T>>, [...D, 1]>}`\n : `${number}`\n : T extends object\n ? HasBroadStringKey<T> extends true\n ? string\n : {\n [K in keyof T & (string | number)]: T[K] extends Function\n ? never\n : NonNullable<T[K]> extends object\n ? `${K}` | `${K}.${Paths<NonNullable<T[K]>, [...D, 1]>}`\n : `${K}`;\n }[keyof T & (string | number)]\n : never;\n\n/**\n * Resolves the type of a value at a given dot-path string.\n */\nexport type PathValue<T, P extends string> =\n // biome-ignore lint/suspicious/noExplicitAny: 'any' check is required for correct path resolution\n Equal<T, any> extends true\n ? // biome-ignore lint/suspicious/noExplicitAny: 'any' check is required for correct path resolution\n any\n : P extends `${infer K}.${infer Rest}`\n ? NonNullable<T> extends readonly unknown[]\n ? K extends `${number}`\n ? PathValue<NonNullable<ArrayElement<NonNullable<T>>>, Rest>\n : never\n : HasBroadStringKey<NonNullable<T>> extends true\n ? PathValue<NonNullable<StringIndexValue<NonNullable<T>>>, Rest>\n : StringKeyToNumber<K> extends keyof NonNullable<T>\n ? PathValue<\n NonNullable<NonNullable<T>[StringKeyToNumber<K> & keyof NonNullable<T>]>,\n Rest\n >\n : never\n : NonNullable<T> extends readonly unknown[]\n ? P extends `${number}`\n ? NonNullable<ArrayElement<NonNullable<T>>>\n : never\n : HasBroadStringKey<NonNullable<T>> extends true\n ? NonNullable<StringIndexValue<NonNullable<T>>>\n : StringKeyToNumber<P> extends keyof NonNullable<T>\n ? NonNullable<T>[StringKeyToNumber<P> & keyof NonNullable<T>]\n : never;\n\n/**\n * Security: Protects internal JS properties from being modified via dot-paths.\n */\nconst FORBIDDEN_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/**\n * @internal\n * Optimization: Structural Sharing\n * Creates a shallow copy of the container and updates one of its keys.\n * Ensures that unchanged sibling branches retain reference equality.\n */\nfunction cloneAndSet(container: object, key: string, value: unknown): object {\n if (Array.isArray(container)) {\n const next = [...container];\n (next as unknown as Record<string, unknown>)[key] = value;\n return next;\n }\n\n if (container instanceof Map) {\n const next = new Map(container);\n next.set(key, value);\n return next;\n }\n\n const proto = Object.getPrototypeOf(container);\n\n // Optimization: Fast-path for plain objects (the most common case)\n if (proto === Object.prototype || proto === null) {\n return { ...container, [key]: value };\n }\n\n // Reason: Ensures class instances maintain their prototype and methods\n // after an immutable update.\n const next = Object.create(proto);\n Object.assign(next, container);\n (next as Record<string, unknown>)[key] = value;\n return next;\n}\n\n// ============================================================================\n// Core Engine\n// ============================================================================\n\n/**\n * Core engine for recursive immutable deep updates.\n *\n * Optimization: Net-zero suppression\n * Returns the original object if the leaf value is identical (Object.is),\n * preventing unnecessary allocation and downstream notifications.\n *\n * @internal\n */\nexport function setDeepValue(obj: unknown, keys: string[], index: number, value: unknown): unknown {\n if (index === keys.length) return value;\n\n const key = keys[index]!;\n\n // Security: Prevent prototype pollution\n // Resilience: Guard against non-object targets in the path\n if (FORBIDDEN_KEYS.has(key) || obj == null || typeof obj !== 'object') {\n return obj;\n }\n\n // Logic: Heterogeneous Collection Support\n // Uniformly handles entries for both standard objects and Map instances.\n const oldVal = obj instanceof Map ? obj.get(key) : (obj as Record<string, unknown>)[key];\n const newVal = setDeepValue(oldVal, keys, index + 1, value);\n\n if (Object.is(oldVal, newVal)) {\n return obj;\n }\n\n return cloneAndSet(obj as object, key, newVal);\n}\n\n/**\n * Reads a value from a nested path.\n * Supports standard property access and Map.get().\n *\n * @internal\n */\nexport function getPathValue(source: unknown, parts: string[]): unknown {\n let res = source;\n const len = parts.length;\n for (let i = 0; i < len; i++) {\n if (res == null) return undefined;\n if (res instanceof Map) {\n res = res.get(parts[i]);\n } else {\n res = (res as Record<string, unknown>)[parts[i]!];\n }\n }\n return res;\n}\n/**\n * Creates a reactive, two-way Lens into a nested atom property.\n *\n * When to use:\n * - When a component only needs a specific sub-field of a complex state object.\n * - To implement \"noise filtering\": the lens only notifies subscribers if its\n * specific nested value changes, even if other parts of the root atom update.\n * - For type-safe deep state management.\n *\n * @param atom - The root WritableAtom to project from.\n * @param path - A dot-separated string representing the path to the nested property.\n *\n * @example\n * const user = atom({ profile: { name: 'Alice', score: 10 } });\n * const scoreLens = atomLens(user, 'profile.score');\n *\n * $.effect(() => console.log('Score:', scoreLens.value));\n * scoreLens.value = 20; // Propagates to 'user' atom.\n */\nexport function atomLens<T extends object, P extends Paths<T>>(\n atom: WritableAtom<T>,\n path: P\n): WritableAtom<PathValue<T, P>> {\n const parts = (path as string).split('.');\n\n // Security: Pre-validate path segments to prevent access to forbidden keys.\n const isDangerous = parts.some((p) => FORBIDDEN_KEYS.has(p));\n\n const listeners = new Set<(nv: unknown, ov: unknown) => void>();\n let sharedUnsub: (() => void) | null = null;\n let prevValue: unknown;\n\n const getValue = (source: unknown) => (isDangerous ? undefined : getPathValue(source, parts));\n\n /**\n * Logic: Noise Filtering\n * Only triggers lens subscribers if the resolved leaf value is different\n * from the previously tracked value.\n */\n const notify = () => {\n const nv = getValue(atom.peek());\n if (!Object.is(nv, prevValue)) {\n const ov = prevValue;\n prevValue = nv;\n listeners.forEach((l) => l(nv, ov));\n }\n };\n\n return {\n get value() {\n return getValue(atom.value);\n },\n set value(newVal: unknown) {\n if (isDangerous) return;\n const cur = atom.peek();\n const next = setDeepValue(cur, parts, 0, newVal);\n\n // Optimization: Only write to root if the mutation resulted in a new reference.\n if (next !== cur) {\n atom.value = next as T;\n }\n },\n peek: () => getValue(atom.peek()),\n subscribe(listener: (nv: unknown, ov: unknown) => void) {\n // Optimization: Lazy Subscription\n // The lens only subscribes to the root atom when it has its first listener.\n // It detaches automatically when the last listener disappears.\n if (listeners.size === 0) {\n prevValue = getValue(atom.peek());\n sharedUnsub = atom.subscribe(notify);\n }\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n if (listeners.size === 0 && sharedUnsub) {\n sharedUnsub();\n sharedUnsub = null;\n }\n };\n },\n subscriberCount: () => listeners.size,\n dispose: () => {\n sharedUnsub?.();\n sharedUnsub = null;\n listeners.clear();\n },\n [BRAND]: BrandFlags.Atom | BrandFlags.Writable,\n } as unknown as WritableAtom<PathValue<T, P>>;\n}\n\n/**\n * Chains a lens with a further sub-path to create a more specific lens.\n *\n * @example\n * const userLens = atomLens(rootAtom, 'user');\n * const nameLens = composeLens(userLens, 'name');\n */\nexport const composeLens = <T extends object, P extends Paths<T>>(lens: WritableAtom<T>, path: P) =>\n atomLens(lens, path);\n\n/**\n * Creates a factory function for generating multiple lenses from a single root atom.\n *\n * @example\n * const fromUser = lensFor(userAtom);\n * const nameLens = fromUser('name');\n * const ageLens = fromUser('age');\n */\nexport const lensFor =\n <T extends object>(atom: WritableAtom<T>) =>\n <P extends Paths<T>>(path: P) =>\n atomLens(atom, path);\n\n/**\n * Merges multiple writable lenses into a single unified lens with a flattened type.\n *\n * This utility combines the value types of all input lenses into a single\n * unified object type using the {@link Merge} utility.\n *\n * @param lenses - A variadic list of WritableAtoms (lenses).\n */\nexport function mergeLenses<L extends WritableAtom<unknown>[]>(\n ...lenses: L\n): WritableAtom<MergedDependencyValue<L>> {\n type MergedValue = MergedDependencyValue<L>;\n\n let prevValue: MergedValue | undefined;\n const listeners = new Set<(nv?: MergedValue, ov?: MergedValue) => void>();\n const unsubs: (() => void)[] = [];\n\n const notify = () => {\n const nv = mergeAtomValues(lenses, true) as MergedValue;\n if (!shallowEqual(nv, prevValue)) {\n const ov = prevValue;\n prevValue = nv;\n for (const listener of listeners) {\n listener(nv, ov);\n }\n }\n };\n\n return {\n get value() {\n return mergeAtomValues(lenses) as MergedValue;\n },\n set value(newVal: MergedValue) {\n batch(() => {\n for (let i = 0; i < lenses.length; i++) {\n lenses[i]!.value = newVal;\n }\n });\n },\n peek: () => mergeAtomValues(lenses, true) as MergedValue,\n subscribe: (listener: (nv?: MergedValue, ov?: MergedValue) => void) => {\n if (listeners.size === 0) {\n prevValue = mergeAtomValues(lenses, true) as MergedValue;\n for (let i = 0; i < lenses.length; i++) {\n unsubs.push(lenses[i]!.subscribe(notify));\n }\n }\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n if (listeners.size === 0) {\n for (const unsub of unsubs) unsub();\n unsubs.length = 0;\n }\n };\n },\n subscriberCount: () => listeners.size,\n dispose: () => {\n for (const unsub of unsubs) unsub();\n unsubs.length = 0;\n listeners.clear();\n },\n [BRAND]: BrandFlags.Atom | BrandFlags.Writable,\n } as unknown as WritableAtom<MergedValue>;\n}\n"],"mappings":"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"}
|