@context-action/core 0.9.0 โ†’ 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["contextWithErrors"],"sources":["../src/execution-modes.ts","../src/action-guard.ts","../src/concurrency/OperationQueue.ts","../src/errors.ts","../src/ActionRegister.ts","../src/react-helpers.ts"],"sourcesContent":["/**\n * @fileoverview Execution mode implementations for ActionRegister\n * \n * Provides three different execution strategies for action handler pipelines:\n * - Sequential: Execute handlers one after another in priority order\n * - Parallel: Execute all handlers simultaneously\n * - Race: First handler to complete wins, other started handlers keep running\n */\n\nimport type { \n HandlerRegistration, \n PipelineContext, \n PipelineController,\n HandlerError\n} from './types.js';\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n (typeof value === 'object' || typeof value === 'function') &&\n value !== null &&\n typeof (value as { then?: unknown }).then === 'function'\n );\n}\n\n/**\n * Create standardized error handling for handlers\n * \n * @param error - The error that occurred\n * @param registration - The handler registration that failed\n * @returns Standardized HandlerError object\n * \n * @internal\n */\nfunction handleExecutionError<T, R>(\n error: unknown,\n registration: HandlerRegistration<T, R>\n): HandlerError {\n const errorObj = error instanceof Error ? error : new Error(String(error));\n return {\n handlerId: registration.id,\n error: errorObj,\n timestamp: Date.now(),\n severity: registration.config.blocking ? 'blocking' : 'non-blocking'\n };\n}\n\n/**\n * Execute handlers in sequential mode (one after another)\n * \n * Executes action handlers one at a time in priority order (highest first).\n * Supports both blocking and non-blocking handlers, with proper abort and\n * termination handling. Handlers can modify payload for subsequent handlers\n * and jump to different priority levels.\n * \n * @template T - The payload type for the action\n * @template R - The result type for handlers\n * \n * @param context - Pipeline execution context containing handlers and state\n * @param createController - Factory function for creating pipeline controllers\n * \n * @throws {Error} When a blocking handler fails\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/dispatch-patterns\n * \n * @public\n */\nexport async function executeSequential<T, R = void>(\n context: PipelineContext<T, R>,\n createController: (registration: HandlerRegistration<T, R>, index: number) => PipelineController<T, R>\n): Promise<void> {\n\n let i = 0;\n const nonBlockingPromises: Array<Promise<unknown>> = [];\n const errors: HandlerError[] = [];\n \n while (i < context.handlers.length) {\n // Check for abort or termination\n if (context.aborted || context.terminated) {\n break;\n }\n\n const registration = context.handlers[i];\n if (!registration) {\n continue; // Skip if handler not found\n }\n context.currentIndex = i;\n const controller = createController(registration, i);\n\n try {\n // Check for abort before executing handler\n if (context.aborted) {\n break;\n }\n\n // ๐Ÿ”ง Fix: Check handler condition before execution\n if (registration.config.condition) {\n try {\n const shouldExecute = registration.config.condition(context.payload);\n if (!shouldExecute) {\n i++; // Skip this handler\n continue;\n }\n } catch {\n // If condition function throws, skip the handler\n i++;\n continue;\n }\n }\n\n (context.executedHandlers ??= []).push(registration);\n const result = registration.handler(context.payload, controller);\n const asyncResult = isPromiseLike(result) ? Promise.resolve(result) : undefined;\n const trackedResult = asyncResult && context.trackHandlerPromise\n ? context.trackHandlerPromise<unknown>(asyncResult)\n : asyncResult;\n\n if (registration.config.blocking) {\n // ๐Ÿ†• Blocking handlers: Wait for completion (sync or async)\n const handlerResult = trackedResult\n ? await trackedResult\n : result;\n if (handlerResult !== undefined && !context.terminated) {\n context.results.push(handlerResult as R);\n }\n } else {\n // ๐Ÿ†• Non-blocking handlers: Handle differently for sync vs async\n if (trackedResult) {\n // Non-blocking async: Track promise with error handling\n const promiseWithErrorHandling = trackedResult\n .then(asyncResult => {\n if (asyncResult !== undefined && !context.terminated) {\n context.results.push(asyncResult as R);\n }\n return asyncResult;\n })\n .catch(error => {\n // ๐Ÿ†• Non-blocking async handler error collection\n const handlerError = handleExecutionError(error, registration);\n errors.push({\n handlerId: handlerError.handlerId,\n error: handlerError.error,\n timestamp: handlerError.timestamp,\n severity: 'non-blocking'\n });\n return undefined; // Return undefined for failed non-blocking handlers\n });\n \n nonBlockingPromises.push(promiseWithErrorHandling);\n } else if (result !== undefined && !context.terminated) {\n // Non-blocking sync: Immediately collect result\n context.results.push(result as R);\n }\n }\n\n /** Check if pipeline was terminated by controller.return() */\n if (context.terminated) {\n break;\n }\n\n /** Handle jump to priority AFTER handler execution */\n if (context.jumpToPriority !== undefined) {\n // Check if we've exceeded maximum jumps to prevent infinite loops\n context.jumpCount = (context.jumpCount || 0) + 1;\n if (context.jumpCount > (context.maxJumps || 10)) {\n console.error(\n `[ActionRegister] ERROR: Maximum jump limit (${context.maxJumps || 10}) exceeded. ` +\n `Aborting to prevent infinite loop. Check your jumpToPriority logic and conditions.`\n );\n context.aborted = true;\n context.abortReason = `Maximum jump limit exceeded (${context.jumpCount} jumps)`;\n context.jumpToPriority = undefined;\n break;\n }\n\n // Find first handler with priority <= jumpToPriority\n const jumpIndex = context.handlers.findIndex(\n handler => (handler.config.priority || 0) <= context.jumpToPriority!\n );\n\n if (jumpIndex !== -1 && jumpIndex !== i) {\n if (jumpIndex < i) {\n // โš ๏ธ WARNING: Backward jump detected - risk of infinite loop!\n // Only allow backward jumps if handler has condition to prevent infinite loops\n const targetHandler = context.handlers[jumpIndex];\n if (targetHandler && !targetHandler.config.condition) {\n console.warn(\n `[ActionRegister] WARNING: Backward jumpToPriority to handler '${targetHandler.config.id || 'unnamed'}' without condition. ` +\n `This may cause infinite loops! Consider adding a condition to prevent re-execution. ` +\n `Jump count: ${context.jumpCount}/${context.maxJumps || 10}`\n );\n }\n }\n\n // Allow both forward and backward jumps\n i = jumpIndex;\n context.jumpToPriority = undefined;\n } else {\n // No valid jump target found, or jumping to same handler\n context.jumpToPriority = undefined;\n i++;\n }\n } else {\n i++;\n }\n\n } catch (error: unknown) {\n // ๐Ÿ”ง Fix: Handle errors gracefully and continue pipeline execution\n const handlerError = handleExecutionError(error, registration);\n errors.push(handlerError);\n\n // ๐Ÿ”ง Fix: Only fail pipeline for blocking handlers, let non-blocking continue\n if (registration.config.blocking) {\n throw handlerError.error;\n }\n\n // For non-blocking handlers, continue to next handler\n i++;\n }\n }\n \n // ๐Ÿ†• Wait for all non-blocking promises with error collection\n if (nonBlockingPromises.length > 0) {\n await Promise.allSettled(nonBlockingPromises);\n }\n\n // ๐Ÿ”ง Store collected errors in context for ExecutionResult with proper typing\n if (errors.length > 0) {\n // Convert to proper HandlerError format\n const handlerErrors: HandlerError[] = errors.map(err => ({\n handlerId: err.handlerId,\n error: err.error,\n timestamp: err.timestamp,\n severity: 'non-blocking' as const\n }));\n \n // Add to context with proper typing\n context.collectedErrors = handlerErrors;\n }\n}\n\n/**\n * Execute handlers in parallel mode (all at once)\n * \n * Executes all qualifying action handlers simultaneously using Promise.allSettled.\n * Supports both blocking and non-blocking handlers. Blocking handlers can still\n * fail the entire pipeline if they throw errors.\n * \n * @template T - The payload type for the action\n * @template R - The result type for handlers\n * \n * @param context - Pipeline execution context containing handlers and state\n * @param createController - Factory function for creating pipeline controllers\n * \n * @throws {Error} When any blocking handler fails\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/dispatch-patterns#parallel-execution\n * \n * @public\n */\nexport async function executeParallel<T, R = void>(\n context: PipelineContext<T, R>,\n createController: (registration: HandlerRegistration<T, R>, index: number) => PipelineController<T, R>\n): Promise<void> {\n\n /** All handlers are runnable */\n const runnableHandlers = context.handlers;\n\n /** Create promises for all handlers */\n const handlerPromises = runnableHandlers.map(async (registration, _index) => {\n const controller = createController(registration, _index);\n\n try {\n // ๐Ÿ”ง Fix: Check handler condition before execution\n if (registration.config.condition) {\n try {\n const shouldExecute = registration.config.condition(context.payload);\n if (!shouldExecute) {\n // Return a skipped result for conditions that don't pass\n return {\n success: true,\n handlerId: registration.id,\n result: undefined,\n terminated: false,\n skipped: true\n };\n }\n } catch {\n // If condition function throws, skip the handler\n return {\n success: true,\n handlerId: registration.id,\n result: undefined,\n terminated: false,\n skipped: true\n };\n }\n }\n\n (context.executedHandlers ??= []).push(registration);\n const result = registration.handler(context.payload, controller);\n \n const handlerResult = (\n isPromiseLike(result) ? await Promise.resolve(result) : result\n ) as R | undefined;\n \n /** Collect result if handler returned something and pipeline wasn't terminated */\n if (handlerResult !== undefined && !context.terminated) {\n context.results.push(handlerResult);\n }\n \n return { \n success: true, \n handlerId: registration.id, \n result: handlerResult,\n terminated: context.terminated \n };\n \n } catch (error: unknown) {\n // ๐Ÿ†• Consistent error object creation\n const handlerError = handleExecutionError(error, registration);\n \n if (handlerError.severity === 'blocking') {\n throw handlerError.error;\n }\n \n return { success: false, handlerId: registration.id, error: handlerError.error };\n }\n });\n\n const trackedHandlerPromises = context.trackHandlerPromise\n ? handlerPromises.map(promise => context.trackHandlerPromise!(promise))\n : handlerPromises;\n\n /** Wait for all handlers to complete */\n const results = await Promise.allSettled(trackedHandlerPromises);\n \n /** Check for any rejected blocking handlers */\n const failures = results.filter((result, index) => {\n if (result.status === 'rejected') {\n const registration = runnableHandlers[index];\n return registration?.config.blocking ?? false;\n }\n return false;\n });\n\n if (failures.length > 0) {\n const firstFailure = failures[0] as PromiseRejectedResult;\n throw firstFailure.reason;\n }\n\n /** Check if any handler terminated the pipeline */\n const terminatedResults = results.filter(result => \n result.status === 'fulfilled' && result.value.terminated\n );\n \n if (terminatedResults.length > 0) {\n context.terminated = true;\n // In parallel mode, we can't determine which handler's termination result to use,\n // so we use the first one that terminated\n const firstTerminated = terminatedResults[0] as PromiseFulfilledResult<{\n terminated: boolean;\n result: R | undefined;\n }>;\n context.terminationResult = firstTerminated.value.result;\n }\n}\n\n/**\n * Execute handlers in race mode (first to complete wins)\n * \n * Executes all qualifying handlers simultaneously using Promise.race, where\n * the first handler to complete determines the pipeline result. Other handlers\n * continue in the background and remain tracked for lifecycle cleanup; handlers\n * must observe the controller signal for cooperative external cancellation.\n * Useful for scenarios where you want the fastest response from multiple\n * equivalent handlers.\n * \n * @template T - The payload type for the action\n * @template R - The result type for handlers\n * \n * @param context - Pipeline execution context containing handlers and state\n * @param createController - Factory function for creating pipeline controllers\n * \n * @throws {Error} When the winning handler fails and is blocking\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/dispatch-patterns#race-execution\n * \n * @public\n */\nexport async function executeRace<T, R = void>(\n context: PipelineContext<T, R>,\n createController: (registration: HandlerRegistration<T, R>, index: number) => PipelineController<T, R>\n): Promise<void> {\n\n /** All handlers are runnable */\n const runnableHandlers = context.handlers;\n\n if (runnableHandlers.length === 0) {\n return;\n }\n\n /** Create promises for all handlers */\n const handlerPromises = runnableHandlers.map(async (registration, _index) => {\n const controller = createController(registration, _index);\n\n try {\n // ๐Ÿ”ง Fix: Check handler condition before execution\n if (registration.config.condition) {\n try {\n const shouldExecute = registration.config.condition(context.payload);\n if (!shouldExecute) {\n // Return a skipped result for conditions that don't pass\n return {\n success: true,\n handlerId: registration.id,\n registration,\n result: undefined,\n terminated: false,\n skipped: true\n };\n }\n } catch {\n // If condition function throws, skip the handler\n return {\n success: true,\n handlerId: registration.id,\n registration,\n result: undefined,\n terminated: false,\n skipped: true\n };\n }\n }\n\n (context.executedHandlers ??= []).push(registration);\n const result = registration.handler(context.payload, controller);\n \n const handlerResult = (\n isPromiseLike(result) ? await Promise.resolve(result) : result\n ) as R | undefined;\n \n return { \n success: true, \n handlerId: registration.id, \n registration,\n result: handlerResult,\n terminated: context.terminated\n };\n \n } catch (error: unknown) {\n // ๐Ÿ†• Consistent error object creation\n const handlerError = handleExecutionError(error, registration);\n return { success: false, handlerId: registration.id, error: handlerError.error, registration };\n }\n });\n\n const trackedHandlerPromises = context.trackHandlerPromise\n ? handlerPromises.map(promise => context.trackHandlerPromise!(promise))\n : handlerPromises;\n\n /** Race all handlers while retaining every loser for lifecycle draining. */\n const winner = await Promise.race(trackedHandlerPromises);\n\n /** If the winner failed and was blocking, throw the error */\n if (!winner.success && winner.registration?.config.blocking) {\n throw winner.error;\n }\n\n /** Collect result from the winning handler */\n if (winner.success && winner.result !== undefined) {\n context.results.push(winner.result);\n }\n\n /** Check if the winning handler terminated the pipeline */\n if (winner.success && winner.terminated) {\n context.terminated = true;\n context.terminationResult = winner.result;\n }\n}\n","/**\n * @fileoverview Action Guard system for debouncing, throttling and blocking\n * \n * Provides rate limiting and user experience optimization for actions through\n * debouncing (wait for pause) and throttling (limit frequency) mechanisms.\n * Used internally by ActionRegister to control action execution timing.\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/\n */\n\n\n/**\n * Action guard state tracking for debouncing and throttling\n * \n * Tracks timing and execution state for action execution control.\n * Maintains separate state for each action to enable independent\n * rate limiting per action type.\n * \n * @internal\n */\ninterface GuardState {\n /** Timestamp of last successful execution for throttling calculations */\n lastExecuted: number;\n \n /** Active debounce timer - cleared when new debounce requests arrive */\n debounceTimer: NodeJS.Timeout | undefined;\n \n /** Active throttle timer - tracks when throttle period will end */\n throttleTimer: NodeJS.Timeout | undefined;\n \n /** Flag indicating if action is currently in throttled state */\n isThrottled: boolean;\n \n /** Current debounce promise - reused for concurrent calls */\n debouncePromise: Promise<boolean> | undefined;\n \n /** Resolve function for current debounce promise */\n debounceResolve: ((value: boolean) => void) | undefined;\n}\n\n/**\n * Action Guard system for managing action execution timing\n * \n * Provides performance optimization and user experience enhancement through\n * debouncing and throttling mechanisms. Debouncing waits for a pause in calls\n * before executing, while throttling limits execution frequency.\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @example Manual Usage (Advanced)\n * ```typescript\n * const guard = new ActionGuard()\n * \n * // Manual debouncing\n * if (await guard.debounce('search', 300)) {\n * performSearch() // Only executes after 300ms pause\n * }\n * \n * // Manual throttling\n * if (guard.throttle('scroll', 100)) {\n * updateUI() // Max once per 100ms\n * }\n * ```\n * \n * @internal\n */\nexport class ActionGuard {\n private guards = new Map<string, GuardState>();\n private cleanupInterval: NodeJS.Timeout | undefined;\n private readonly autoCleanupEnabled: boolean;\n private readonly maxIdleTime: number = 60000; // 1 minute\n private readonly cleanupIntervalMs: number = 30000; // 30 seconds\n\n // ๐Ÿ”ง Performance optimization: Limit max guards to prevent unbounded growth\n private readonly maxGuards: number = 1000;\n // ๐Ÿ”ง Performance optimization: Track access order for LRU-style eviction\n private accessOrder: string[] = [];\n\n constructor(autoCleanup: boolean = true) {\n this.autoCleanupEnabled = autoCleanup;\n }\n\n /** Start cleanup only after the first guard is used. */\n private ensureAutoCleanup(): void {\n if (this.autoCleanupEnabled && !this.cleanupInterval) {\n this.startAutoCleanup();\n }\n }\n\n /**\n * Start automatic cleanup of idle guard states\n *\n * @internal\n */\n private startAutoCleanup(): void {\n if (this.cleanupInterval) return;\n\n this.cleanupInterval = setInterval(() => {\n this.performCleanup();\n }, this.cleanupIntervalMs);\n\n // A library-owned maintenance timer must not keep a Node.js process alive.\n this.cleanupInterval.unref?.();\n }\n\n private stopAutoCleanup(): void {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = undefined;\n }\n }\n\n /**\n * ๐Ÿ”ง Optimized cleanup with early exit and batched operations\n *\n * @internal\n */\n private performCleanup(): void {\n const guardCount = this.guards.size;\n\n // Early exit if no guards to clean\n if (guardCount === 0) {\n this.stopAutoCleanup();\n return;\n }\n\n const now = Date.now();\n const keysToDelete: string[] = [];\n\n // ๐Ÿ”ง Performance: Only iterate if cleanup is potentially needed\n // Skip cleanup if guard count is low and no guards are old enough\n if (guardCount <= 10) {\n // For small maps, check all entries\n this.guards.forEach((state, key) => {\n const isIdle = now - state.lastExecuted > this.maxIdleTime;\n const hasActiveTimers = state.debounceTimer || state.throttleTimer;\n\n if (isIdle && !hasActiveTimers) {\n keysToDelete.push(key);\n }\n });\n } else {\n // ๐Ÿ”ง Performance: For larger maps, use access order for LRU-style cleanup\n // Only check oldest entries first (more likely to be idle)\n const entriesToCheck = Math.min(this.accessOrder.length, Math.ceil(guardCount / 4));\n\n for (let i = 0; i < entriesToCheck; i++) {\n const key = this.accessOrder[i];\n if (!key) continue;\n\n const state = this.guards.get(key);\n if (!state) {\n // Key no longer exists, will be cleaned from accessOrder\n keysToDelete.push(key);\n continue;\n }\n\n const isIdle = now - state.lastExecuted > this.maxIdleTime;\n const hasActiveTimers = state.debounceTimer || state.throttleTimer;\n\n if (isIdle && !hasActiveTimers) {\n keysToDelete.push(key);\n }\n }\n }\n\n // Batch delete idle guards\n if (keysToDelete.length > 0) {\n keysToDelete.forEach(key => {\n this.guards.delete(key);\n // Remove from access order\n const accessIndex = this.accessOrder.indexOf(key);\n if (accessIndex !== -1) {\n this.accessOrder.splice(accessIndex, 1);\n }\n });\n\n // Optional debug logging for cleanup\n if (typeof process !== 'undefined' && process.env?.DEBUG_CONTEXT_ACTION) {\n console.debug(`[ActionGuard] Cleaned up ${keysToDelete.length} idle guards`);\n }\n\n if (this.guards.size === 0) {\n this.stopAutoCleanup();\n }\n }\n }\n\n /**\n * ๐Ÿ”ง Update access order for LRU tracking\n *\n * @internal\n */\n private updateAccessOrder(key: string): void {\n // Remove existing entry if present\n const existingIndex = this.accessOrder.indexOf(key);\n if (existingIndex !== -1) {\n this.accessOrder.splice(existingIndex, 1);\n }\n // Add to end (most recently accessed)\n this.accessOrder.push(key);\n }\n\n /**\n * ๐Ÿ”ง Evict oldest guards if max limit exceeded\n *\n * @internal\n */\n private evictIfNeeded(): void {\n if (this.guards.size >= this.maxGuards) {\n // Evict oldest 10% of guards\n const evictCount = Math.ceil(this.maxGuards * 0.1);\n const keysToEvict = this.accessOrder.slice(0, evictCount);\n\n keysToEvict.forEach(key => {\n const state = this.guards.get(key);\n // Clean up timers before eviction\n if (state) {\n if (state.debounceTimer) {\n clearTimeout(state.debounceTimer);\n if (state.debounceResolve) {\n state.debounceResolve(false);\n }\n }\n if (state.throttleTimer) {\n clearTimeout(state.throttleTimer);\n }\n }\n this.guards.delete(key);\n });\n\n // Remove from access order\n this.accessOrder = this.accessOrder.slice(evictCount);\n\n if (typeof process !== 'undefined' && process.env?.DEBUG_CONTEXT_ACTION) {\n console.debug(`[ActionGuard] Evicted ${evictCount} oldest guards due to limit`);\n }\n }\n }\n\n /**\n * Apply debouncing to an action\n * \n * Debouncing waits for a specified delay after the last call before allowing\n * execution. Each new call resets the timer. Useful for search inputs, resize\n * handlers, and other high-frequency user interactions.\n * \n * @param actionKey - Unique identifier for the action being debounced\n * @param debounceMs - Delay in milliseconds to wait after the last call\n * \n * @returns Promise resolving to true if execution should proceed, false if cancelled\n * \n * @example Search Input Debouncing\n * ```typescript\n * // Only search after user stops typing for 300ms\n * if (await guard.debounce('userSearch', 300)) {\n * performSearch(query)\n * }\n * ```\n * \n * @internal\n */\n async debounce(actionKey: string, debounceMs: number): Promise<boolean> {\n this.ensureAutoCleanup();\n\n // ๐Ÿ”ง Performance: Check for eviction before adding new guards\n this.evictIfNeeded();\n\n /** Get or create guard state for this action */\n let state = this.guards.get(actionKey);\n if (!state) {\n /** Initialize new guard state with default values */\n state = {\n lastExecuted: 0,\n isThrottled: false,\n debounceTimer: undefined as NodeJS.Timeout | undefined,\n throttleTimer: undefined as NodeJS.Timeout | undefined,\n debouncePromise: undefined as Promise<boolean> | undefined,\n debounceResolve: undefined as ((value: boolean) => void) | undefined,\n };\n this.guards.set(actionKey, state);\n }\n\n // ๐Ÿ”ง Performance: Update LRU access order\n this.updateAccessOrder(actionKey);\n\n /** Clear any existing debounce timer to restart the delay period */\n if (state.debounceTimer) {\n clearTimeout(state.debounceTimer);\n // Resolve previous debounce with false if exists\n if (state.debounceResolve) {\n state.debounceResolve(false);\n state.debounceResolve = undefined as ((value: boolean) => void) | undefined;\n }\n }\n\n /** Create new debounce promise */\n return new Promise<boolean>((resolve) => {\n // Store new resolve function\n state!.debounceResolve = resolve;\n \n // Set new timer\n state!.debounceTimer = setTimeout(() => {\n /** Clean up timer and resolver references */\n state!.debounceTimer = undefined as NodeJS.Timeout | undefined;\n state!.debounceResolve = undefined as ((value: boolean) => void) | undefined;\n /** Update last execution timestamp */\n state!.lastExecuted = Date.now();\n resolve(true);\n }, debounceMs);\n });\n }\n\n /**\n * Apply throttling to an action\n * \n * Throttling limits execution frequency by ensuring a minimum interval between\n * calls. Unlike debouncing, throttling executes immediately on the first call\n * and then blocks subsequent calls until the interval expires.\n * \n * @param actionKey - Unique identifier for the action being throttled\n * @param throttleMs - Minimum interval in milliseconds between executions\n * \n * @returns True if execution should proceed, false if currently throttled\n * \n * @example Scroll Handler Throttling\n * ```typescript\n * // Update scroll position max once per 100ms\n * if (guard.throttle('scrollUpdate', 100)) {\n * updateScrollPosition()\n * }\n * ```\n * \n * @internal\n */\n throttle(actionKey: string, throttleMs: number): boolean {\n this.ensureAutoCleanup();\n\n // ๐Ÿ”ง Performance: Check for eviction before adding new guards\n this.evictIfNeeded();\n\n /** Get or create guard state for this action */\n let state = this.guards.get(actionKey);\n if (!state) {\n /** Initialize new guard state with default values */\n state = {\n lastExecuted: 0,\n isThrottled: false,\n debounceTimer: undefined as NodeJS.Timeout | undefined,\n throttleTimer: undefined as NodeJS.Timeout | undefined,\n debouncePromise: undefined as Promise<boolean> | undefined,\n debounceResolve: undefined as ((value: boolean) => void) | undefined,\n };\n this.guards.set(actionKey, state);\n }\n\n // ๐Ÿ”ง Performance: Update LRU access order\n this.updateAccessOrder(actionKey);\n\n const now = Date.now();\n const timeSinceLastExecution = now - state.lastExecuted;\n\n /** Check if enough time has passed since last execution */\n /** If throttle period has elapsed, allow immediate execution */\n if (timeSinceLastExecution >= throttleMs) {\n /** Update execution timestamp and clear throttled state */\n state.lastExecuted = now;\n state.isThrottled = false;\n \n \n return true;\n }\n\n /** If already in throttled state, don't create duplicate timers */\n /** This prevents timer accumulation and unnecessary processing */\n if (state.isThrottled) {\n return false;\n }\n\n /** Set throttle timer to automatically clear the throttled state */\n /** Calculate remaining time until throttle period expires */\n state.isThrottled = true;\n const remainingTime = throttleMs - timeSinceLastExecution;\n \n /** Create timer to reset throttled state when period expires */\n state.throttleTimer = setTimeout(() => {\n /** Clear throttled state and timer reference */\n state!.isThrottled = false;\n state!.throttleTimer = undefined as NodeJS.Timeout | undefined;\n }, remainingTime);\n\n\n return false;\n }\n\n /**\n * Clear all guard state for a specific action\n * \n * Removes debounce and throttle timers for the specified action,\n * preventing memory leaks and allowing immediate re-execution.\n * \n * @param actionKey - Action identifier to clear guards for\n * \n * @internal\n */\n clearGuards(actionKey: string): void {\n const state = this.guards.get(actionKey);\n if (state) {\n // Clear debounce timer and cancel pending promises to prevent memory leaks\n if (state.debounceTimer) {\n clearTimeout(state.debounceTimer);\n if (state.debounceResolve) {\n state.debounceResolve(false);\n state.debounceResolve = undefined;\n }\n state.debounceTimer = undefined;\n }\n \n // Clear throttle timer to prevent memory leaks\n if (state.throttleTimer) {\n clearTimeout(state.throttleTimer);\n state.throttleTimer = undefined;\n }\n \n \n // Remove guard state from memory\n this.guards.delete(actionKey);\n const accessIndex = this.accessOrder.indexOf(actionKey);\n if (accessIndex !== -1) {\n this.accessOrder.splice(accessIndex, 1);\n }\n\n if (this.guards.size === 0) {\n this.stopAutoCleanup();\n }\n }\n }\n\n /**\n * Clear all guard states for all actions\n * \n * Removes all active debounce and throttle timers, useful for cleanup\n * when shutting down the action system or resetting state.\n * \n * @internal\n */\n clearAll(): void {\n \n /** Iterate through all guard states and clear their timers */\n /** This prevents memory leaks when clearing the entire guard system */\n this.guards.forEach((state) => {\n /** Clear any active debounce timers */\n if (state.debounceTimer) {\n clearTimeout(state.debounceTimer);\n // Cancel waiting debounce calls\n if (state.debounceResolve) {\n state.debounceResolve(false);\n }\n }\n /** Clear any active throttle timers */\n if (state.throttleTimer) {\n clearTimeout(state.throttleTimer);\n }\n });\n \n /** Remove all guard states from memory */\n this.guards.clear();\n this.accessOrder = [];\n this.stopAutoCleanup();\n }\n\n /**\n * Get current guard state for debugging purposes\n * \n * Returns the internal state for a specific action, including timer\n * information and execution timestamps.\n * \n * @param actionKey - Action identifier to inspect\n * @returns Guard state or undefined if no state exists\n * \n * @internal\n */\n getGuardState(actionKey: string): GuardState | undefined {\n return this.guards.get(actionKey);\n }\n\n /**\n * Get all active guard states for debugging purposes\n * \n * Returns a copy of all current guard states, useful for monitoring\n * and debugging rate limiting behavior across all actions.\n * \n * @returns Map of action keys to their guard states\n * \n * @internal\n */\n getAllGuardStates(): Map<string, GuardState> {\n return new Map(this.guards);\n }\n\n /**\n * ๐Ÿ†• Explicit destroy method for comprehensive cleanup\n * \n * Cleans up all timers, promises, and intervals to prevent memory leaks.\n * Should be called when ActionGuard is no longer needed.\n * \n * @internal\n */\n destroy(): void {\n // Clear all existing guards\n this.clearAll();\n }\n\n /**\n * ๐Ÿ†• Get statistics about active guards\n * \n * @returns Statistics about guard usage\n * \n * @internal\n */\n getStats(): { activeGuards: number; withTimers: number } {\n let withTimers = 0;\n this.guards.forEach(state => {\n if (state.debounceTimer || state.throttleTimer) {\n withTimers++;\n }\n });\n \n return {\n activeGuards: this.guards.size,\n withTimers\n };\n }\n}\n","/**\n * ๋™์‹œ์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์œ„ํ•œ ์ž‘์—… ํ ์‹œ์Šคํ…œ\n * \n * ๋ชจ๋“  ์ƒํƒœ ๋ณ€๊ฒฝ ์ž‘์—…์„ ์ง๋ ฌํ™”ํ•˜์—ฌ race condition์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.\n */\n\nexport interface QueuedOperation<T = unknown> {\n id: string;\n operation: () => T | Promise<T>;\n resolve: (value: T) => void;\n reject: (error: unknown) => void;\n priority?: number;\n timestamp: number;\n}\n\nexport interface QueuedOperationHandle<T> {\n promise: Promise<T>;\n /** Cancels only while the operation is still waiting in the queue. */\n cancel(reason?: unknown): boolean;\n}\n\n/**\n * ์ž‘์—… ํ ๊ด€๋ฆฌ์ž\n *\n * ํ•ต์‹ฌ ๊ธฐ๋Šฅ:\n * 1. ์ž‘์—… ์ง๋ ฌํ™” - ๋ชจ๋“  ์ž‘์—…์„ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰\n * 2. ์šฐ์„ ์ˆœ์œ„ ์ง€์› - ์ค‘์š”ํ•œ ์ž‘์—… ์šฐ์„  ์ฒ˜๋ฆฌ\n * 3. ์—๋Ÿฌ ์ฒ˜๋ฆฌ - ๊ฐœ๋ณ„ ์ž‘์—… ์‹คํŒจ๊ฐ€ ์ „์ฒด์— ์˜ํ–ฅ ์ฃผ์ง€ ์•Š์Œ\n * 4. ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ - ์™„๋ฃŒ๋œ ์ž‘์—… ์ž๋™ ์ •๋ฆฌ\n * 5. ๐Ÿ†• ๋™์‹œ์„ฑ ์ œ์–ด - maxConcurrency๋กœ ๋™์‹œ ์‹คํ–‰ ์ œํ•œ\n * 6. ๐Ÿ†• ๋น„๋™๊ธฐ ์ง€์› - Promise.all() ์™„๋ฒฝ ์ง€์›\n * 7. ๐Ÿ†• ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์ฒ˜๋ฆฌ - ํšจ์œจ์ ์ธ ํ ์ฒ˜๋ฆฌ ์‹œ์Šคํ…œ\n */\nexport class OperationQueue {\n private queue: Array<QueuedOperation<unknown>> = [];\n private processingPromise: Promise<void> | null = null;\n private operationCounter = 0;\n \n // ๐Ÿ†• Concurrency control\n private activeOperations = 0;\n private readonly maxConcurrency: number;\n \n constructor(\n private name: string = 'OperationQueue', \n maxConcurrency: number = 1\n ) {\n this.maxConcurrency = Math.max(1, maxConcurrency);\n }\n\n /**\n * ์ž‘์—…์„ ํ์— ์ถ”๊ฐ€ํ•˜๊ณ  ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜\n * \n * @param operation ์‹คํ–‰ํ•  ์ž‘์—…\n * @param priority ์šฐ์„ ์ˆœ์œ„ (๋†’์„์ˆ˜๋ก ๋จผ์ € ์‹คํ–‰)\n * @returns Promise๋กœ ๋ž˜ํ•‘๋œ ์ž‘์—… ๊ฒฐ๊ณผ\n */\n enqueue<T>(operation: () => T | Promise<T>, priority: number = 0): Promise<T> {\n return this.enqueueWithHandle(operation, priority).promise;\n }\n\n /** Enqueue an operation and retain a handle for pre-start cancellation. */\n enqueueWithHandle<T>(\n operation: () => T | Promise<T>,\n priority: number = 0\n ): QueuedOperationHandle<T> {\n let queuedOperation!: QueuedOperation<T>;\n const promise = new Promise<T>((resolve, reject) => {\n queuedOperation = {\n id: `${this.name}-${++this.operationCounter}`,\n operation,\n resolve,\n reject,\n priority,\n timestamp: Date.now()\n };\n\n\n // ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ์‚ฝ์ž… ์œ„์น˜ ๊ฒฐ์ • (๋†’์€ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ์•ž์ชฝ)\n let insertIndex = this.queue.length;\n for (let i = 0; i < this.queue.length; i++) {\n const item = this.queue[i];\n // ํ˜„์žฌ ์•„์ดํ…œ์˜ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ์ƒˆ ์•„์ดํ…œ๋ณด๋‹ค ๋‚ฎ์œผ๋ฉด, ์ƒˆ ์•„์ดํ…œ์„ ์•ž์— ์‚ฝ์ž…\n if (item && (item.priority || 0) < priority) {\n insertIndex = i;\n break;\n }\n }\n\n this.queue.splice(insertIndex, 0, queuedOperation as unknown as QueuedOperation<unknown>);\n\n // ํ ์ฒ˜๋ฆฌ ์‹œ์ž‘ (์ด๋ฏธ ์ฒ˜๋ฆฌ ์ค‘์ด๋ฉด ๋ฌด์‹œ๋จ)\n if (this.processingPromise) {\n // ์ด๋ฏธ ์ฒ˜๋ฆฌ ์ค‘์ด๋ผ๋ฉด, ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค์—๊ฒŒ ์ƒˆ๋กœ์šด ์ž‘์—…์ด ์ถ”๊ฐ€๋˜์—ˆ์Œ์„ ์•Œ๋ฆผ\n this.notifyNewOperation();\n }\n this.processQueue();\n });\n\n return {\n promise,\n cancel: (reason = new Error('Queue operation cancelled')) => {\n const index = this.queue.indexOf(queuedOperation as unknown as QueuedOperation<unknown>);\n if (index === -1) return false;\n\n this.queue.splice(index, 1);\n queuedOperation.reject(reason);\n this.notifyNewOperation();\n return true;\n },\n };\n }\n\n /**\n * ๐Ÿ†• ํ ์ฒ˜๋ฆฌ ๋ฉ”์ธ ๋กœ์ง - ๋™์‹œ์„ฑ ์ œ์–ด ๋ฐ ๋น„๋™๊ธฐ ์ง€์›\n *\n * ์ฃผ์š” ํŠน์ง•:\n * - maxConcurrency์— ๋”ฐ๋ผ ๋™์‹œ ์‹คํ–‰ ์ž‘์—… ์ˆ˜๋ฅผ ์ œํ•œํ•˜์—ฌ ๋™์‹œ์„ฑ ๋ฌธ์ œ ๋ฐฉ์ง€\n * - Promise.all() ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ์™„๋ฒฝํ•œ ์ˆœ์ฐจ์  ์‹คํ–‰ ๋ณด์žฅ\n * - ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์•Œ๋ฆผ ์‹œ์Šคํ…œ์œผ๋กœ ํšจ์œจ์ ์ธ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ\n * - ์ž‘์—… ์™„๋ฃŒ ์‹œ ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค์—๊ฒŒ ์ž๋™ ์•Œ๋ฆผ\n */\n private async processQueue(): Promise<void> {\n if (this.processingPromise) {\n // Wait for current processing to complete, then check if we need to process more\n await this.processingPromise;\n // After waiting, check if there are new items to process\n if (this.queue.length > 0 && !this.processingPromise) {\n return this.processQueue();\n }\n return;\n }\n\n this.processingPromise = this._doProcess();\n try {\n await this.processingPromise;\n } finally {\n this.processingPromise = null;\n }\n }\n \n private async _doProcess(): Promise<void> {\n while (this.queue.length > 0 || this.activeOperations > 0) {\n // ๐Ÿ†• ๋™์‹œ์„ฑ ์ œ์–ด: maxConcurrency ๋งŒํผ๋งŒ ๋™์‹œ ์‹คํ–‰\n while (this.queue.length > 0 && this.activeOperations < this.maxConcurrency) {\n const operation = this.queue.shift()!;\n\n // ๐Ÿ†• ๋น„๋™๊ธฐ ์ž‘์—… ์‹คํ–‰ (await๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ - ๋ณ‘๋ ฌ ์‹คํ–‰์„ ์œ„ํ•ด)\n this.startOperation(operation);\n }\n\n // ๐Ÿ†• ์‹คํ–‰ ์ค‘์ธ ์ž‘์—…์ด ์žˆ์œผ๋ฉด ํ•˜๋‚˜๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ\n if (this.activeOperations > 0) {\n await this.waitForAnyOperation();\n }\n }\n }\n\n /**\n * ๐Ÿ†• ๊ฐœ๋ณ„ ์ž‘์—…์„ ์‹œ์ž‘ํ•˜๊ณ  ์™„๋ฃŒ๋ฅผ ์ถ”์ \n */\n private startOperation(operation: QueuedOperation<unknown>): void {\n this.activeOperations++;\n\n // ๋น„๋™๊ธฐ๋กœ ์ž‘์—… ์‹คํ–‰\n this.executeOperation(operation)\n .finally(() => {\n this.activeOperations--;\n\n // ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค์—๊ฒŒ ์‹ ํ˜ธ ๋ณด๋‚ด๊ธฐ\n this.notifyOperationComplete();\n });\n }\n\n private pendingResolvers: Array<() => void> = [];\n\n /**\n * ๐Ÿ†• ํ•˜๋‚˜์˜ ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•˜๊ฑฐ๋‚˜ ์ƒˆ๋กœ์šด ์ž‘์—…์ด ์ถ”๊ฐ€๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ\n */\n private waitForAnyOperation(): Promise<void> {\n return new Promise<void>((resolve) => {\n this.pendingResolvers.push(resolve);\n });\n }\n\n /**\n * ๐Ÿ†• ์ž‘์—… ์™„๋ฃŒ ์‹ ํ˜ธ - ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋“ค์—๊ฒŒ ์•Œ๋ฆผ\n */\n private notifyOperationComplete(): void {\n // ๋Œ€๊ธฐ ์ค‘์ธ ๋ชจ๋“  ๋ฆฌ์กธ๋ฒ„๋ฅผ ๊นจ์šฐ๊ธฐ\n const resolvers = this.pendingResolvers.splice(0);\n resolvers.forEach(resolve => resolve());\n }\n\n /**\n * ๐Ÿ†• ์ƒˆ๋กœ์šด ์ž‘์—… ์ถ”๊ฐ€ ์‹ ํ˜ธ - processQueue์—์„œ ํ˜ธ์ถœ\n */\n private notifyNewOperation(): void {\n // ์ƒˆ๋กœ์šด ์ž‘์—…์ด ์ถ”๊ฐ€๋˜์—ˆ์œผ๋ฏ€๋กœ ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊นจ์›Œ์„œ ๋‹ค์‹œ ํ™•์ธํ•˜๋„๋ก ํ•จ\n this.notifyOperationComplete();\n }\n \n /**\n * ๐Ÿ†• ๊ฐœ๋ณ„ ์ž‘์—… ์‹คํ–‰ ๋กœ์ง\n */\n private async executeOperation(operation: QueuedOperation<unknown>): Promise<void> {\n try {\n // ์ž‘์—… ์‹คํ–‰ (๋™๊ธฐ/๋น„๋™๊ธฐ ๋ชจ๋‘ ์ง€์›)\n const result = await Promise.resolve(operation.operation());\n operation.resolve(result);\n } catch (error) {\n // ๊ฐœ๋ณ„ ์ž‘์—… ์‹คํŒจ๋Š” ์ „์ฒด ํ์— ์˜ํ–ฅ ์ฃผ์ง€ ์•Š์Œ\n operation.reject(error);\n }\n }\n\n /**\n * ๐Ÿ†• ํ˜„์žฌ ํ ์ƒํƒœ ์กฐํšŒ (๋””๋ฒ„๊น…์šฉ) - ๋™์‹œ์„ฑ ์ •๋ณด ํฌํ•จ\n */\n getQueueInfo() {\n return {\n name: this.name,\n queueLength: this.queue.length,\n isProcessing: Boolean(this.processingPromise),\n activeOperations: this.activeOperations,\n maxConcurrency: this.maxConcurrency,\n operations: this.queue.map(op => ({\n id: op.id,\n priority: op.priority,\n timestamp: op.timestamp\n }))\n };\n }\n \n /**\n * ๐Ÿ†• ๋™์‹œ์„ฑ ์„ค์ • ์กฐํšŒ\n */\n getConcurrencyInfo() {\n return {\n maxConcurrency: this.maxConcurrency,\n activeOperations: this.activeOperations,\n availableSlots: this.maxConcurrency - this.activeOperations,\n queuedOperations: this.queue.length,\n efficiency: this.activeOperations / this.maxConcurrency\n };\n }\n\n /**\n * ํ ๋น„์šฐ๊ธฐ (ํ…Œ์ŠคํŠธ์šฉ)\n */\n clear(options: { rejectPending?: boolean; reason?: unknown } = {}): void {\n const rejectPending = options.rejectPending ?? true;\n const reason = options.reason ?? new Error('Queue cleared');\n\n // Settle queued operations so callers are never left with pending promises.\n this.queue.forEach(operation => {\n if (rejectPending) {\n operation.reject(reason);\n } else {\n operation.resolve(undefined as never);\n }\n });\n\n this.queue = [];\n\n // ๋Œ€๊ธฐ ์ค‘์ธ ๋ฆฌ์กธ๋ฒ„๋“ค๋„ ์ •๋ฆฌ\n const resolvers = this.pendingResolvers.splice(0);\n resolvers.forEach(resolve => resolve());\n }\n\n /**\n * ํ ํฌ๊ธฐ ์กฐํšŒ\n */\n get size(): number {\n return this.queue.length;\n }\n\n /**\n * ์ฒ˜๋ฆฌ ์ค‘ ์—ฌ๋ถ€ ์กฐํšŒ \n */\n get processing(): boolean {\n return Boolean(this.processingPromise);\n }\n}\n","/**\n * Action Validation Errors\n *\n * Zod ์Šคํ‚ค๋งˆ ๊ธฐ๋ฐ˜ ๊ฒ€์ฆ ์‹คํŒจ ์‹œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ ํด๋ž˜์Šค๋“ค\n */\n\n// ============================================\n// Zod Error Compatible Types\n// ============================================\n\n/**\n * Zod Issue interface (loose typing for Zod 4 compatibility)\n */\nexport interface ZodIssueLike {\n message: string;\n path: readonly (string | number | symbol)[];\n code: string;\n}\n\n/**\n * Zod Error interface (loose typing for Zod 4 compatibility)\n * Accepts any object with these minimum required properties\n */\nexport interface ZodErrorLike {\n message: string;\n issues: readonly ZodIssueLike[];\n format?: () => unknown;\n flatten?: () => unknown;\n}\n\n// ============================================\n// Action Validation Error\n// ============================================\n\n/**\n * Action payload ๊ฒ€์ฆ ์‹คํŒจ ์—๋Ÿฌ\n *\n * dispatch ์‹œ Zod ์Šคํ‚ค๋งˆ ๊ฒ€์ฆ์ด ์‹คํŒจํ•˜๋ฉด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.\n * (validationMode๊ฐ€ 'strict'์ผ ๋•Œ๋งŒ throw)\n *\n * @example\n * ```typescript\n * try {\n * dispatch('updateUser', { id: '', name: 'John' });\n * } catch (error) {\n * if (error instanceof ActionValidationError) {\n * console.log('Action:', error.action);\n * console.log('Issues:', error.issues);\n * console.log('Formatted:', error.formattedErrors);\n * }\n * }\n * ```\n */\nexport class ActionValidationError extends Error {\n /** ์—๋Ÿฌ ์ด๋ฆ„ */\n override name = 'ActionValidationError';\n\n /** ์›๋ณธ Zod ์—๋Ÿฌ ๊ฐ์ฒด */\n public readonly zodError: unknown;\n\n /**\n * @param action - ๊ฒ€์ฆ ์‹คํŒจํ•œ action ์ด๋ฆ„\n * @param zodError - Zod ๊ฒ€์ฆ ์—๋Ÿฌ ๊ฐ์ฒด (ZodError compatible)\n */\n constructor(action: string, zodError: unknown) {\n const errorMessage =\n zodError && typeof zodError === 'object' && 'message' in zodError\n ? String((zodError as { message: unknown }).message)\n : 'Validation failed';\n\n const message = `Action \"${action}\" payload validation failed: ${errorMessage}`;\n super(message);\n\n this.action = action;\n this.zodError = zodError;\n\n // Error ์ƒ์† ์‹œ prototype chain ๋ณต์› (ES5 ํ˜ธํ™˜)\n Object.setPrototypeOf(this, ActionValidationError.prototype);\n }\n\n /** ๊ฒ€์ฆ ์‹คํŒจํ•œ action ์ด๋ฆ„ */\n public readonly action: string;\n\n /**\n * Zod ๊ฒ€์ฆ ์ด์Šˆ ๋ชฉ๋ก\n */\n get issues(): readonly ZodIssueLike[] {\n if (\n this.zodError &&\n typeof this.zodError === 'object' &&\n 'issues' in this.zodError &&\n Array.isArray((this.zodError as { issues: unknown }).issues)\n ) {\n return (this.zodError as { issues: readonly ZodIssueLike[] }).issues;\n }\n return [];\n }\n\n /**\n * ํฌ๋งท๋œ ์—๋Ÿฌ ๊ฐ์ฒด (ํ•„๋“œ๋ณ„ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€)\n */\n get formattedErrors(): unknown {\n if (\n this.zodError &&\n typeof this.zodError === 'object' &&\n 'format' in this.zodError &&\n typeof (this.zodError as { format: unknown }).format === 'function'\n ) {\n return (this.zodError as { format: () => unknown }).format();\n }\n return {};\n }\n\n /**\n * ํ”Œ๋žซ ์—๋Ÿฌ ๋งต (ํ•„๋“œ๋ช… โ†’ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋ฐฐ์—ด)\n */\n get flattenedErrors(): unknown {\n if (\n this.zodError &&\n typeof this.zodError === 'object' &&\n 'flatten' in this.zodError &&\n typeof (this.zodError as { flatten: unknown }).flatten === 'function'\n ) {\n return (this.zodError as { flatten: () => unknown }).flatten();\n }\n return { fieldErrors: {}, formErrors: [] };\n }\n\n /**\n * ์ฒซ ๋ฒˆ์งธ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€\n */\n get firstError(): string | undefined {\n return this.issues[0]?.message;\n }\n\n /**\n * ์—๋Ÿฌ ๋ฐœ์ƒ ํ•„๋“œ ๊ฒฝ๋กœ ๋ชฉ๋ก\n */\n get errorPaths(): string[] {\n return this.issues.map((issue) =>\n issue.path.map((p) => String(p)).join('.')\n );\n }\n\n /**\n * JSON ์ง๋ ฌํ™”\n */\n toJSON() {\n return {\n name: this.name,\n action: this.action,\n message: this.message,\n issues: this.issues,\n };\n }\n}\n\n/**\n * Raised when a dispatch exceeds its configured wall-clock timeout.\n * The underlying handler receives an aborted controller signal and the internal\n * queue keeps draining it safely, while the caller is released immediately with\n * this error.\n */\nexport class ActionTimeoutError extends Error {\n override name = 'ActionTimeoutError';\n\n constructor(\n public readonly action: string,\n public readonly timeout: number\n ) {\n super(`Action \"${action}\" timed out after ${timeout}ms`);\n Object.setPrototypeOf(this, ActionTimeoutError.prototype);\n }\n}\n\n/** Raised when work is submitted after an ActionRegister begins shutdown. */\nexport class ActionRegisterDestroyedError extends Error {\n override name = 'ActionRegisterDestroyedError';\n\n constructor(\n public readonly registerName: string,\n public readonly state: 'closing' | 'destroyed'\n ) {\n super(`ActionRegister \"${registerName}\" is ${state} and cannot accept new work`);\n Object.setPrototypeOf(this, ActionRegisterDestroyedError.prototype);\n }\n}\n\n// ============================================\n// Type Guard\n// ============================================\n\n/**\n * ActionValidationError ํƒ€์ž… ๊ฐ€๋“œ\n */\nexport function isActionValidationError(\n error: unknown\n): error is ActionValidationError {\n return error instanceof ActionValidationError;\n}\n\n/** ActionTimeoutError type guard. */\nexport function isActionTimeoutError(\n error: unknown\n): error is ActionTimeoutError {\n return error instanceof ActionTimeoutError;\n}\n\n/** ActionRegisterDestroyedError type guard. */\nexport function isActionRegisterDestroyedError(\n error: unknown\n): error is ActionRegisterDestroyedError {\n return error instanceof ActionRegisterDestroyedError;\n}\n","// biome-ignore-all lint/suspicious/noExplicitAny: heterogeneous runtime pipeline storage.\n\nimport {\n ActionPayloadMap,\n ActionHandler,\n HandlerConfig,\n HandlerRegistration,\n PipelineContext,\n PipelineController,\n ActionRegisterConfig,\n UnregisterFunction,\n ExecutionMode,\n ExecutionResult,\n ActionRegistryInfo,\n ActionHandlerStats,\n DispatchOptions,\n HandlerError,\n} from './types.js';\nimport { executeSequential, executeParallel, executeRace } from './execution-modes.js';\nimport { ActionGuard } from './action-guard.js';\nimport { OperationQueue } from './concurrency/OperationQueue.js';\nimport {\n ActionRegisterDestroyedError,\n ActionTimeoutError,\n ActionValidationError,\n} from './errors.js';\n\ntype DispatchHandlerPromises = Set<Promise<unknown>>;\n\n/**\n * Action Register for managing action handlers with priority-based execution\n * \n * Central action registration and dispatch system providing type-safe action pipeline management.\n * Supports sequential, parallel, and race execution modes with advanced handler filtering,\n * throttling, debouncing, and comprehensive result collection.\n * \n * @template TActionMap - Action payload mapping interface extending ActionPayloadMap\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/\n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/register-delegation\n * \n * @public\n */\n\nexport class ActionRegister<\n T extends ActionPayloadMap = Record<string, unknown>\n> {\n private pipelines = new Map<keyof T, Array<HandlerRegistration<any, any>>>();\n private readonly actionGuard: ActionGuard;\n private executionMode: ExecutionMode = 'sequential';\n private actionExecutionModes = new Map<keyof T, ExecutionMode>();\n \n // ๐Ÿ†• Advanced unregister function management system\n private unregisterFunctions = new Map<string, UnregisterFunction>();\n\n // ๐Ÿ”ง Fix: Track last registration timestamps for getActionStats\n private lastRegisteredTimestamps = new Map<keyof T, Date>();\n \n public readonly name: string;\n private readonly registryConfig: ActionRegisterConfig['registry'];\n\n // ๐Ÿ†• Performance optimizations\n private readonly isDebugMode: boolean;\n private readonly maxHandlersPerAction: number;\n\n // ๐Ÿ†• ๋™์‹œ์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์œ„ํ•œ ํ ์‹œ์Šคํ…œ (conditional)\n private dispatchQueue?: OperationQueue;\n\n // ๐Ÿ”ง Performance optimization: Fast handler ID generation counter\n private handlerIdCounter = 0;\n\n // ๐Ÿ”ง Performance optimization: PipelineController pool for object reuse\n private controllerPool: PipelineController<any, any>[] = [];\n\n private lifecycleState: 'active' | 'closing' | 'destroyed' = 'active';\n private readonly lifecycleController = new AbortController();\n private readonly activeDispatches = new Set<Promise<unknown>>();\n private readonly activeHandlerPromises = new Set<Promise<unknown>>();\n private destroyAsyncPromise: Promise<void> | undefined;\n private dispatchConstructionDepth = 0;\n\n // ๐Ÿ”ง Performance optimization: Cached Proxy instances for actions getters\n private _actionsProxy?: {\n [K in keyof T]: T[K] extends void\n ? (\n payload?: undefined,\n options?: DispatchOptions\n ) => Promise<void>\n : (payload: T[K], options?: DispatchOptions) => Promise<void>\n };\n private _actionsWithResultProxy?: {\n [K in keyof T]: T[K] extends void\n ? (\n payload?: undefined,\n options?: DispatchOptions\n ) => Promise<ExecutionResult<any>>\n : (payload: T[K], options?: DispatchOptions) => Promise<ExecutionResult<any>>\n };\n\n constructor(config: ActionRegisterConfig = {}) {\n this.name = config.name || 'ActionRegister';\n this.registryConfig = config.registry;\n this.maxHandlersPerAction = config.registry?.maxHandlersPerAction ?? 1000;\n \n // ๐Ÿ†• Environment variable check cached (performance optimization)\n this.isDebugMode = Boolean(\n this.registryConfig?.debug && \n process.env.NODE_ENV === 'development'\n );\n \n // Guard creation with improved cleanup handling\n this.actionGuard = new ActionGuard(this.registryConfig?.autoCleanup !== false);\n \n // ๐Ÿ†• Conditional queue system initialization\n if (config.registry?.useConcurrencyQueue !== false) {\n this.dispatchQueue = new OperationQueue(`${this.name}-Dispatch`);\n }\n \n if (this.registryConfig?.defaultExecutionMode) {\n this.executionMode = this.registryConfig.defaultExecutionMode;\n }\n \n this.log('ActionRegister initialized', {\n defaultExecutionMode: this.executionMode,\n autoCleanup: this.registryConfig?.autoCleanup !== false,\n concurrencyQueue: Boolean(this.dispatchQueue),\n debugMode: this.isDebugMode\n });\n }\n\n /**\n * ๐Ÿ†• Action-based dispatcher\n *\n * Provides function-based access to actions for more convenient dispatching.\n * Each action becomes a callable function that can be invoked directly.\n *\n * @example\n * ```typescript\n * interface MyActions extends ActionPayloadMap {\n * userLogin: { userId: string; email: string };\n * resetApp: void;\n * }\n * \n * const registry = new ActionRegister<MyActions>();\n * \n * // Function-based dispatching\n * await registry.actions.userLogin({ userId: '123', email: 'test@example.com' });\n * await registry.actions.resetApp();\n * await registry.actions.resetApp(undefined, { debounce: 100 });\n * ```\n * \n * @public\n */\n get actions(): {\n [K in keyof T]: T[K] extends void\n ? (\n payload?: undefined,\n options?: DispatchOptions\n ) => Promise<void>\n : (payload: T[K], options?: DispatchOptions) => Promise<void>\n } {\n // ๐Ÿ”ง Performance: Return cached Proxy instance\n if (!this._actionsProxy) {\n this._actionsProxy = new Proxy({} as any, {\n get: (_target, prop: string | symbol) => {\n // Type guard to ensure prop is a valid action key\n const actionKey = prop as keyof T;\n if (typeof prop === 'string' && this.pipelines.has(actionKey)) {\n return (\n payload?: T[typeof actionKey],\n options?: DispatchOptions\n ) => {\n return this.dispatch(\n actionKey,\n payload as T[typeof actionKey],\n options\n );\n };\n }\n return undefined;\n }\n });\n }\n return this._actionsProxy!;\n }\n\n /**\n * Actions-based dispatching with result collection\n * \n * Provides a function-based interface for dispatching actions with detailed execution results.\n * Each registered action becomes a callable function that returns ExecutionResult.\n * \n * @example\n * ```typescript\n * // Actions with payload\n * const result = await registry.actionsWithResult.userLogin({ userId: '123', email: 'user@example.com' });\n * \n * // Actions without payload\n * const result = await registry.actionsWithResult.userLogout();\n * const debouncedResult = await registry.actionsWithResult.userLogout(\n * undefined,\n * { debounce: 100 }\n * );\n * \n * // With options\n * const result = await registry.actionsWithResult.processData(\n * { data: { name: 'test' }, type: 'json' },\n * { executionMode: 'parallel' }\n * );\n * ```\n * \n * @returns Proxy object with action functions that return ExecutionResult\n */\n get actionsWithResult(): {\n [K in keyof T]: T[K] extends void\n ? (\n payload?: undefined,\n options?: DispatchOptions\n ) => Promise<ExecutionResult<any>>\n : (payload: T[K], options?: DispatchOptions) => Promise<ExecutionResult<any>>\n } {\n // ๐Ÿ”ง Performance: Return cached Proxy instance\n if (!this._actionsWithResultProxy) {\n this._actionsWithResultProxy = new Proxy({} as any, {\n get: (_target, prop: string | symbol) => {\n // Type guard to ensure prop is a valid action key\n const actionKey = prop as keyof T;\n if (typeof prop === 'string' && this.pipelines.has(actionKey)) {\n return (\n payload?: T[typeof actionKey],\n options?: DispatchOptions\n ) => {\n return this.dispatchWithResult(actionKey, payload, options);\n };\n }\n return undefined;\n }\n });\n }\n return this._actionsWithResultProxy!;\n }\n\n /**\n * Register an action handler with optional configuration\n * \n * @param action - The action type to register handler for\n * @param handler - The handler function to execute\n * @param config - Optional handler configuration including priority, tags, etc.\n * \n * @returns Unregister function to remove this handler\n * \n * @throws {Error} When maximum handlers limit is reached\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n register<K extends keyof T, R = void>(\n action: K,\n handler: ActionHandler<T[K], R>,\n config: HandlerConfig<T[K]> = {}\n ): UnregisterFunction {\n this.assertAcceptingWork();\n // ๐Ÿ”„ ์ž„์‹œ๋กœ ๊ธฐ์กด ๊ตฌํ˜„ ์œ ์ง€ํ•˜๋˜ ๊ฐœ์„ ๋œ ๋ฐฉ์‹ ์ ์šฉ\n // ๋™๊ธฐ์  API๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ๋‚ด๋ถ€์ ์œผ๋กœ๋งŒ ๋™์‹œ์„ฑ ๋ณดํ˜ธ\n \n // ๐Ÿ†• Optimized handler ID generation\n const handlerId = config.id || this.generateHandlerId(action);\n \n // ๐Ÿ†• Direct synchronous registration\n const unregisterFn = this._performRegistrationSync(action, handler, config, handlerId);\n \n return unregisterFn;\n }\n\n /**\n * ๐Ÿ†• Unified logging method with cached debug mode check\n */\n private log(message: string, data?: unknown, level: 'log' | 'warn' | 'error' = 'log') {\n if (this.isDebugMode) {\n const timestamp = new Date().toISOString();\n console[level](`๐ŸŽฏ [${timestamp}] [${this.name}] ${message}`, data || '');\n }\n }\n\n private assertAcceptingWork(): void {\n if (this.lifecycleState !== 'active') {\n throw new ActionRegisterDestroyedError(this.name, this.lifecycleState);\n }\n }\n\n private rejectedLifecyclePromise<R>(): Promise<R> {\n const error = new ActionRegisterDestroyedError(\n this.name,\n this.lifecycleState === 'active' ? 'destroyed' : this.lifecycleState\n );\n const rejected = Promise.reject<R>(error);\n void rejected.catch(() => {});\n return rejected;\n }\n\n /**\n * ๐Ÿ”ง Generate unique handler ID using optimized counter-based approach\n */\n private generateHandlerId<K extends keyof T>(action: K): string {\n // ๐Ÿ”ง Performance: Use simple counter instead of crypto.randomUUID()\n // This is safe for single-process apps and ~70% faster\n return `${String(action)}_${this.name}_${++this.handlerIdCounter}`;\n }\n\n /**\n * ๐Ÿ”ง Create and merge AbortSignal instances with proper cleanup\n * \n * @param options Dispatch options containing signal and autoAbort configuration\n * @returns [effectiveSignal, autoAbortController, cleanupFunction]\n */\n private createAbortSignal(options?: DispatchOptions): [\n AbortSignal | undefined, \n AbortController | undefined, \n () => void\n ] {\n const signals: AbortSignal[] = [];\n const cleanups: (() => void)[] = [];\n let autoAbortController: AbortController | undefined;\n\n // Add existing signal if provided\n if (options?.signal) {\n signals.push(options.signal);\n }\n\n // Create auto-abort controller if enabled\n if (options?.autoAbort?.enabled) {\n autoAbortController = new AbortController();\n signals.push(autoAbortController.signal);\n }\n\n // No signals to merge\n if (signals.length === 0) {\n return [undefined, autoAbortController, () => {}];\n }\n\n // Single signal - no merge needed\n if (signals.length === 1) {\n return [signals[0], autoAbortController, () => cleanups.forEach(c => c())];\n }\n\n // Multiple signals - use AbortSignal.any() if available, fallback to manual merge\n let effectiveSignal: AbortSignal;\n \n if (typeof (AbortSignal as any).any === 'function') {\n // Modern browsers with AbortSignal.any()\n effectiveSignal = (AbortSignal as any).any(signals);\n } else {\n // Fallback: Create controller and link all signals\n const mergedController = new AbortController();\n effectiveSignal = mergedController.signal;\n \n signals.forEach(signal => {\n if (signal.aborted) {\n mergedController.abort();\n } else {\n const abortHandler = () => mergedController.abort();\n signal.addEventListener('abort', abortHandler, { once: true });\n cleanups.push(() => signal.removeEventListener('abort', abortHandler));\n }\n });\n }\n\n const cleanup = () => {\n cleanups.forEach(c => {\n try {\n c();\n } catch (error) {\n this.log('Cleanup error during AbortSignal cleanup', error, 'warn');\n }\n });\n };\n\n return [effectiveSignal, autoAbortController, cleanup];\n }\n\n /**\n * ๐Ÿ†• Perform synchronous handler registration\n */\n private _performRegistrationSync<K extends keyof T, R = void>(\n action: K,\n handler: ActionHandler<T[K], R>,\n config: HandlerConfig<T[K]>,\n handlerId: string\n ): UnregisterFunction {\n // Create handler registration with defaults\n const registration: HandlerRegistration<T[K], R> = {\n handler,\n config: {\n priority: config.priority ?? 0,\n id: handlerId,\n blocking: config.blocking ?? false,\n once: config.once ?? false,\n debounce: config.debounce ?? undefined,\n throttle: config.throttle ?? undefined,\n replaceExisting: config.replaceExisting ?? true, // ๐Ÿ”ง Fix: Default to true for backward compatibility\n cleanup: config.cleanup, // ๐Ÿ”ง Preserve cleanup function from config\n condition: config.condition, // ๐Ÿ”ง Fix: Preserve condition function from config\n } as Required<HandlerConfig<T[K]>>,\n id: handlerId,\n };\n \n // Initialize pipeline if it doesn't exist\n if (!this.pipelines.has(action)) {\n this.pipelines.set(action, []);\n }\n\n const pipeline = this.pipelines.get(action)!;\n \n // Check handler limit\n if (pipeline.length >= this.maxHandlersPerAction) {\n console.warn(`Handler limit (${this.maxHandlersPerAction}) reached for action \"${String(action)}\". Registration ignored.`);\n return () => {}; // No-op unregister\n }\n const existingIndex = pipeline.findIndex(reg => reg.id === handlerId);\n\n // ๐Ÿ†• Enhanced duplicate ID handling with replaceExisting support and cleanup\n if (existingIndex !== -1) {\n const existing = pipeline[existingIndex];\n const existingUnregister = this.unregisterFunctions.get(handlerId);\n \n if (registration.config.replaceExisting) {\n // ๐Ÿ”ง Fix: Clean up existing handler properly without removing from pipeline\n\n // Call cleanup if available on the old handler\n if (existing?.config.cleanup && typeof existing.config.cleanup === 'function') {\n try {\n existing.config.cleanup();\n } catch (cleanupError) {\n this.log(`Cleanup error for replaced handler: ${String(action)}`, cleanupError, 'warn');\n }\n }\n\n // Clean up existing unregister function\n if (existingUnregister) {\n this.unregisterFunctions.delete(handlerId);\n }\n\n // Replace existing handler directly in pipeline\n pipeline[existingIndex] = registration;\n pipeline.sort((a, b) => b.config.priority - a.config.priority);\n // Cache disabled\n\n // ๐Ÿ”ง Fix: Update last registered timestamp when replacing\n this.lastRegisteredTimestamps.set(action, new Date());\n\n // Create new unregister function and store it\n const newUnregister = this.createUnregisterFunction(action, handlerId, registration);\n this.unregisterFunctions.set(handlerId, newUnregister);\n \n this.log(`Handler replaced: ${String(action)}`, {\n handlerId,\n priority: config.priority,\n totalHandlers: pipeline.length,\n hadExistingUnregister: Boolean(existingUnregister)\n });\n \n return newUnregister;\n } else {\n // Return existing unregister function or create a new one\n // At this point, existing is guaranteed to be defined because we're in the duplicate handler block\n if (!existing) {\n throw new Error('Internal error: existing handler should be defined in duplicate handler block');\n }\n \n this.log(`Handler duplicate ignored, returning existing unregister: ${String(action)}`, {\n handlerId,\n existingPriority: existing.config.priority,\n newPriority: config.priority,\n existingBlocking: existing.config.blocking,\n newBlocking: config.blocking,\n note: 'Use replaceExisting:true to replace'\n }, 'warn');\n \n if (existingUnregister) {\n return existingUnregister;\n } else {\n // Create new unregister function if somehow missing\n const newUnregister = this.createUnregisterFunction(action, handlerId, existing);\n this.unregisterFunctions.set(handlerId, newUnregister);\n return newUnregister;\n }\n }\n }\n \n // Add handler to pipeline\n pipeline.push(registration);\n pipeline.sort((a, b) => b.config.priority - a.config.priority);\n // Cache disabled\n\n // ๐Ÿ”ง Fix: Update last registered timestamp\n this.lastRegisteredTimestamps.set(action, new Date());\n\n // Create and store unregister function\n const unregister = this.createUnregisterFunction(action, handlerId, registration);\n this.unregisterFunctions.set(handlerId, unregister);\n\n this.log(`Handler registered: ${String(action)}`, {\n handlerId,\n priority: config.priority,\n totalHandlers: pipeline.length\n });\n\n return unregister;\n }\n\n\n /**\n * Dispatch an action with optional execution options\n * \n * @param action - The action type to dispatch\n * @param payload - The action payload data\n * @param options - Optional dispatch options (execution mode, filters, etc.)\n * \n * @returns Promise that resolves when all handlers complete\n * \n * @throws {Error} When action dispatching fails\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n // Overload for actions with payload (more specific)\n dispatch<K extends keyof T>(\n action: K,\n payload: T[K],\n options?: DispatchOptions\n ): Promise<void>;\n \n // Overload for actions without payload\n dispatch<K extends keyof T>(\n action: K,\n payload?: undefined,\n options?: DispatchOptions\n ): Promise<void>;\n \n // Implementation (least specific)\n dispatch<K extends keyof T>(\n action: K,\n payload?: T[K],\n options?: DispatchOptions\n ): Promise<void> {\n if (this.lifecycleState !== 'active') {\n return this.rejectedLifecyclePromise<void>();\n }\n\n const timeoutScope = this.createTimeoutScope(action, options);\n const dispatchHandlerPromises: DispatchHandlerPromises = new Set();\n const attemptState = { count: 0 };\n const operation = async () => {\n if (!timeoutScope.options?.signal?.aborted) {\n this.validatePayload(action, payload);\n }\n\n return this.executeWithRetry(async () => {\n const executedHandlers: HandlerRegistration<any, any>[] = [];\n try {\n return await this._performDispatch(\n action,\n payload,\n timeoutScope.options,\n attemptState.count > 1,\n executedHandlers,\n dispatchHandlerPromises\n );\n } finally {\n this.cleanupOneTimeHandlers(\n action,\n executedHandlers,\n dispatchHandlerPromises\n );\n }\n }, timeoutScope.options, attemptState, undefined, () => this.getHandlerCount(action) > 0);\n };\n\n const hasTimingGuard = (\n options?.debounce !== undefined ||\n options?.throttle !== undefined ||\n this.pipelines.get(action)?.some(handler => (\n handler.config.debounce !== undefined ||\n handler.config.throttle !== undefined\n )) === true\n );\n\n let dispatchPromise: Promise<void>;\n this.dispatchConstructionDepth += 1;\n try {\n // Timing guards must observe rapid calls when they are dispatched. If\n // they enter the serial queue first, each debounce window completes\n // before the next call starts and every call is executed.\n if (timeoutScope.options?.immediate || hasTimingGuard || !this.dispatchQueue) {\n dispatchPromise = operation();\n } else {\n const queued = this.dispatchQueue.enqueueWithHandle(\n operation,\n timeoutScope.options?.queuePriority ?? 0\n );\n timeoutScope.onTimeout(error => queued.cancel(error));\n dispatchPromise = queued.promise;\n }\n this.trackDispatchPromise(dispatchPromise);\n } finally {\n this.dispatchConstructionDepth -= 1;\n }\n const exposedPromise = this.raceWithTimeout(\n dispatchPromise,\n timeoutScope,\n dispatchHandlerPromises\n );\n const observedPromise = exposedPromise.catch(error => {\n this.invokeErrorHandler(error, action, payload, options, attemptState.count);\n throw error;\n });\n\n // Preserve rejection semantics for observers without leaking fire-and-forget\n // dispatches as process-level unhandled rejections.\n void observedPromise.catch(() => {});\n return observedPromise;\n }\n\n /** Execute a dispatch operation with an optional whole-action retry policy. */\n private async executeWithRetry<R>(\n operation: () => Promise<R>,\n options: DispatchOptions | undefined,\n attemptState: { count: number },\n shouldRetryResult?: (result: R) => boolean,\n canRetry: () => boolean = () => true\n ): Promise<R> {\n const configuredAttempts = options?.retryOnError?.maxAttempts ?? 1;\n const maxAttempts = Number.isFinite(configuredAttempts)\n ? Math.max(1, Math.floor(configuredAttempts))\n : 1;\n const retryDelay = Math.max(0, options?.retryOnError?.delay ?? 0);\n\n while (attemptState.count < maxAttempts) {\n attemptState.count += 1;\n\n try {\n const result = await operation();\n const shouldRetry = shouldRetryResult?.(result) ?? false;\n if (\n !shouldRetry ||\n attemptState.count >= maxAttempts ||\n options?.signal?.aborted ||\n !canRetry()\n ) {\n return result;\n }\n } catch (error) {\n if (\n error instanceof ActionValidationError ||\n attemptState.count >= maxAttempts ||\n options?.signal?.aborted ||\n !canRetry()\n ) {\n throw error;\n }\n }\n\n await this.waitForRetry(retryDelay, options?.signal);\n }\n\n // The loop always returns or throws. This protects the generic return type\n // if an invalid retry configuration somehow reaches this point.\n return operation();\n }\n\n private trackDispatchPromise<R>(promise: Promise<R>): Promise<R> {\n this.activeDispatches.add(promise);\n const remove = () => this.activeDispatches.delete(promise);\n void promise.then(remove, remove);\n return promise;\n }\n\n private trackHandlerPromise<R>(\n promise: Promise<R>,\n dispatchHandlerPromises: DispatchHandlerPromises\n ): Promise<R> {\n this.activeHandlerPromises.add(promise);\n dispatchHandlerPromises.add(promise);\n const remove = () => {\n this.activeHandlerPromises.delete(promise);\n dispatchHandlerPromises.delete(promise);\n };\n void promise.then(remove, remove);\n return promise;\n }\n\n private trackGlobalHandlerPromise<R>(promise: Promise<R>): Promise<R> {\n this.activeHandlerPromises.add(promise);\n const remove = () => this.activeHandlerPromises.delete(promise);\n void promise.then(remove, remove);\n return promise;\n }\n\n /** Abort-aware retry delay so cancellation does not wait for the full backoff. */\n private waitForRetry(delay: number, signal?: AbortSignal): Promise<void> {\n if (delay <= 0 || signal?.aborted) return Promise.resolve();\n\n return new Promise(resolve => {\n const timer = setTimeout(finish, delay);\n const abort = () => finish();\n\n function finish() {\n clearTimeout(timer);\n signal?.removeEventListener('abort', abort);\n resolve();\n }\n\n signal?.addEventListener('abort', abort, { once: true });\n });\n }\n\n /** Build a wall-clock timeout that also participates in pipeline cancellation. */\n private createTimeoutScope<K extends keyof T>(\n action: K,\n options?: DispatchOptions\n ): {\n options: DispatchOptions | undefined;\n timeoutPromise?: Promise<never>;\n onTimeout: (callback: (error: ActionTimeoutError) => void) => void;\n cleanup: () => void;\n cleanupSignals: () => void;\n } {\n const hasTimeout = options?.timeout !== undefined && Number.isFinite(options.timeout);\n const timeout = hasTimeout ? Math.max(0, options!.timeout!) : undefined;\n const timeoutController = hasTimeout ? new AbortController() : undefined;\n const signalCleanups: Array<() => void> = [];\n const timeoutCallbacks = new Set<(error: ActionTimeoutError) => void>();\n const signals = [\n this.lifecycleController.signal,\n options?.signal,\n timeoutController?.signal,\n ].filter((candidate): candidate is AbortSignal => Boolean(candidate));\n let signal = signals[0]!;\n\n if (signals.length > 1) {\n if (typeof (AbortSignal as typeof AbortSignal & {\n any?: (signals: AbortSignal[]) => AbortSignal;\n }).any === 'function') {\n signal = (AbortSignal as typeof AbortSignal & {\n any: (signals: AbortSignal[]) => AbortSignal;\n }).any(signals);\n } else {\n const mergedController = new AbortController();\n const forwardAbort = (source: AbortSignal) => {\n if (!mergedController.signal.aborted) mergedController.abort(source.reason);\n };\n\n for (const source of signals) {\n if (source.aborted) {\n forwardAbort(source);\n break;\n }\n const listener = () => forwardAbort(source);\n source.addEventListener('abort', listener, { once: true });\n signalCleanups.push(() => source.removeEventListener('abort', listener));\n }\n signal = mergedController.signal;\n }\n }\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = timeoutController && timeout !== undefined\n ? new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n const error = new ActionTimeoutError(String(action), timeout);\n timeoutController.abort(error);\n timeoutCallbacks.forEach(callback => callback(error));\n reject(error);\n }, timeout);\n })\n : undefined;\n\n return {\n options: { ...options, signal },\n timeoutPromise,\n onTimeout: callback => timeoutCallbacks.add(callback),\n cleanup: () => {\n if (timer !== undefined) clearTimeout(timer);\n timeoutCallbacks.clear();\n },\n cleanupSignals: () => signalCleanups.forEach(cleanup => cleanup()),\n };\n }\n\n /** Expose timeout failure while allowing the queued operation to drain safely. */\n private raceWithTimeout<R>(\n operation: Promise<R>,\n scope: {\n timeoutPromise?: Promise<never>;\n cleanup: () => void;\n cleanupSignals: () => void;\n },\n dispatchHandlerPromises: DispatchHandlerPromises\n ): Promise<R> {\n const exposed = scope.timeoutPromise\n ? Promise.race([operation, scope.timeoutPromise])\n : operation;\n const cleanupAfterStartedHandlers = () => {\n // Successful completion must cancel the ref'ed timeout timer immediately.\n // Only fallback signal-forwarding listeners need to outlive race losers.\n scope.cleanup();\n this.cleanupSignalsAfterStartedHandlers(\n scope.cleanupSignals,\n dispatchHandlerPromises\n );\n };\n void exposed.then(cleanupAfterStartedHandlers, cleanupAfterStartedHandlers);\n return exposed;\n }\n\n private cleanupSignalsAfterStartedHandlers(\n cleanup: () => void,\n dispatchHandlerPromises: DispatchHandlerPromises\n ): void {\n const handlersStillRunning = [...dispatchHandlerPromises];\n if (handlersStillRunning.length === 0) {\n cleanup();\n return;\n }\n\n // In AbortSignal.any() fallback environments, this dispatch's signal\n // forwarding listeners must outlive its race-mode losers even though the\n // exposed dispatch resolved. Unrelated dispatches must not delay cleanup.\n void Promise.allSettled(handlersStillRunning).then(cleanup);\n }\n\n /** Invoke the configured error handler without allowing it to replace the dispatch error. */\n private invokeErrorHandler<K extends keyof T>(\n error: unknown,\n action: K,\n payload: T[K] | undefined,\n options: DispatchOptions | undefined,\n attempts: number\n ): void {\n const errorHandler = this.registryConfig?.errorHandler;\n if (!errorHandler) return;\n\n const normalizedError = error instanceof Error ? error : new Error(String(error));\n try {\n const handlerResult = errorHandler(normalizedError, {\n action: String(action),\n payload,\n options,\n attempts,\n phase: normalizedError instanceof ActionTimeoutError\n ? 'timeout'\n : normalizedError instanceof ActionValidationError\n ? 'validation'\n : 'execution',\n });\n if (handlerResult && typeof (handlerResult as PromiseLike<void>).then === 'function') {\n void Promise.resolve(handlerResult).catch(handlerError => {\n this.log('Global async error handler failed', handlerError, 'warn');\n });\n }\n } catch (handlerError) {\n this.log('Global error handler failed', handlerError, 'warn');\n }\n }\n\n /**\n * Validate an action payload against the configured schema.\n * Shared by all dispatch paths so result collection cannot bypass validation.\n */\n private validatePayload<K extends keyof T>(\n action: K,\n payload?: T[K]\n ): ExecutionResult<never>['validation'] {\n if (\n !this.registryConfig?.schema ||\n this.registryConfig.validateOnDispatch === false\n ) {\n return undefined;\n }\n\n const actionName = String(action);\n const actionSchema = this.registryConfig.schema[actionName];\n if (!actionSchema) {\n return undefined;\n }\n\n let result: ReturnType<typeof actionSchema.safeParse>;\n try {\n result = actionSchema.safeParse(payload);\n } catch (error) {\n throw new ActionValidationError(actionName, error);\n }\n if (result.success) {\n return { passed: true, errors: [] };\n }\n\n const mode = this.registryConfig.validationMode ?? 'strict';\n if (mode === 'strict') {\n throw new ActionValidationError(actionName, result.error);\n }\n\n if (mode === 'warn') {\n console.warn(\n `Action \"${actionName}\" payload validation failed:`,\n result.error.message\n );\n this.log(`Validation warning for action '${actionName}'`, {\n issues: result.error.issues,\n }, 'warn');\n }\n\n return {\n passed: false,\n errors: result.error.issues.map(issue => issue.message),\n };\n }\n\n private createAbortedExecutionResult<R>(\n startTime: number,\n handlersSkipped: number = 0,\n validation?: ExecutionResult<R>['validation']\n ): ExecutionResult<R> {\n const endTime = Date.now();\n\n return {\n success: false,\n aborted: true,\n abortReason: 'Action dispatch aborted by signal',\n terminated: false,\n validation,\n result: undefined,\n successResults: [],\n results: [],\n failedResults: [],\n execution: {\n duration: endTime - startTime,\n handlersExecuted: 0,\n handlersSkipped,\n handlersFailed: 0,\n startTime,\n endTime,\n },\n handlers: [],\n errors: [],\n };\n }\n\n /**\n * ๐Ÿ†• ์‹ค์ œ ๋””์ŠคํŒจ์น˜ ์ž‘์—… ์ˆ˜ํ–‰ (ํ์—์„œ ํ˜ธ์ถœ๋จ)\n */\n private async _performDispatch<K extends keyof T>(\n action: K,\n payload: T[K] | undefined,\n options: DispatchOptions | undefined,\n skipGuards: boolean,\n executedHandlers: HandlerRegistration<any, any>[],\n dispatchHandlerPromises: DispatchHandlerPromises\n ): Promise<void> {\n // ๐Ÿ” ๋””์ŠคํŒจ์น˜ ์‹œ์ž‘ ๋””๋ฒ„๊ทธ\n this.log(`Starting dispatch for action '${String(action)}'`, {\n hasPayload: payload !== undefined,\n payloadType: payload?.constructor?.name || typeof payload,\n options: options ? Object.keys(options) : 'none',\n timestamp: new Date().toISOString()\n });\n \n // Simple Event object detection for development\n if (payload instanceof Event && process.env.NODE_ENV === 'development') {\n console.warn(`Event object passed to action \"${String(action)}\"`, payload.type);\n }\n\n // ๐Ÿ”ง Improved AbortSignal handling with cleaner merge logic\n const [effectiveSignal, autoAbortController, cleanup] = this.createAbortSignal(options);\n \n if (options?.autoAbort?.onControllerCreated && autoAbortController) {\n options.autoAbort.onControllerCreated(autoAbortController);\n }\n \n // Check if dispatch is aborted before starting\n if (effectiveSignal?.aborted) {\n this.log(`Dispatch aborted before execution for '${String(action)}'`);\n cleanup();\n return;\n }\n \n const pipeline = this.pipelines.get(action);\n \n // ๐Ÿ” ํŒŒ์ดํ”„๋ผ์ธ ์กด์žฌ ์—ฌ๋ถ€ ๋””๋ฒ„๊ทธ\n this.log(`Pipeline lookup for '${String(action)}'`, {\n pipelineExists: Boolean(pipeline),\n handlersCount: pipeline?.length || 0,\n allRegisteredActions: Array.from(this.pipelines.keys()),\n pipelineMap: Object.fromEntries(Array.from(this.pipelines.entries()).map(([k, v]) => [k, v.length]))\n });\n \n if (!pipeline || pipeline.length === 0) {\n // ๐Ÿšจ ๊ฒฝ๊ณ : ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ์•ก์…˜ ์‹คํ–‰\n const warningMessage = `โš ๏ธ Action '${String(action)}' has no registered handlers. This action will be ignored.`;\n \n if (process.env.NODE_ENV === 'development') {\n console.warn(warningMessage);\n console.warn('๐Ÿ’ก Tip: Register a handler using registry.register() before dispatching this action.');\n console.warn('๐Ÿ“‹ Available actions:', Array.from(this.pipelines.keys()));\n }\n \n this.log(`No handlers found for action '${String(action)}', dispatch cancelled`, {}, 'warn');\n cleanup();\n return;\n }\n\n // ๐Ÿ†• Optimize filtering - only copy array if filtering is needed\n const filteredHandlers = options?.filter \n ? this.filterHandlers(pipeline, options.filter)\n : pipeline;\n\n // Apply ActionGuard controls - check both dispatch options and handler configs\n const actionKey = String(action);\n \n // Get throttle/debounce settings from dispatch options or handler configs\n let throttleMs: number | undefined;\n let debounceMs: number | undefined;\n \n // Priority: dispatch options > handler config\n if (options?.throttle !== undefined) {\n throttleMs = options.throttle;\n } else if (filteredHandlers.length > 0) {\n // Use throttle from the first handler that has it (handlers are sorted by priority)\n for (const handler of filteredHandlers) {\n if (handler.config.throttle !== undefined) {\n throttleMs = handler.config.throttle;\n break;\n }\n }\n }\n \n if (options?.debounce !== undefined) {\n debounceMs = options.debounce;\n } else if (filteredHandlers.length > 0) {\n // Use debounce from the first handler that has it (handlers are sorted by priority)\n for (const handler of filteredHandlers) {\n if (handler.config.debounce !== undefined) {\n debounceMs = handler.config.debounce;\n break;\n }\n }\n }\n \n // Apply debounce if specified\n if (!skipGuards && debounceMs !== undefined) {\n const shouldProceed = await this.actionGuard.debounce(actionKey, debounceMs);\n if (!shouldProceed) {\n cleanup();\n return; // Debounced - don't execute\n }\n }\n \n // Apply throttle if specified\n if (!skipGuards && throttleMs !== undefined) {\n const shouldProceed = this.actionGuard.throttle(actionKey, throttleMs);\n if (!shouldProceed) {\n cleanup();\n return; // Throttled - don't execute\n }\n }\n\n // The signal may have been aborted while awaiting debounce.\n if (effectiveSignal?.aborted) {\n this.log(`Dispatch aborted during guard processing for '${String(action)}'`);\n cleanup();\n return;\n }\n\n // Determine execution mode for this action (with option override)\n const currentExecutionMode = options?.executionMode || \n this.actionExecutionModes.get(action) || \n this.executionMode;\n\n // Create pipeline execution context\n const context: PipelineContext<T[K], any> = {\n action: String(action),\n payload: payload as T[K],\n handlers: [...filteredHandlers],\n executedHandlers: [],\n deferOnceCleanup: true,\n signal: effectiveSignal ?? this.lifecycleController.signal,\n trackHandlerPromise: promise => this.trackHandlerPromise(\n promise,\n dispatchHandlerPromises\n ),\n aborted: false,\n abortReason: undefined as string | undefined,\n currentIndex: 0,\n jumpToPriority: undefined as number | undefined,\n jumpCount: 0,\n maxJumps: 10, // Default max jumps to prevent infinite loops\n executionMode: currentExecutionMode,\n \n // New result collection fields\n results: [],\n terminated: false,\n terminationResult: undefined as any,\n };\n\n \n // Add abort listener if signal provided (use effectiveSignal for auto-abort)\n const abortHandler = effectiveSignal ? () => {\n context.aborted = true;\n context.abortReason = typeof effectiveSignal.reason === 'string'\n ? effectiveSignal.reason\n : 'Action dispatch aborted by signal';\n } : undefined;\n \n if (effectiveSignal && abortHandler) {\n effectiveSignal.addEventListener('abort', abortHandler, { once: true });\n }\n \n \n try {\n await this.executePipeline(\n context,\n dispatchHandlerPromises,\n autoAbortController,\n options?.autoAbort\n );\n this.log(`Pipeline execution succeeded for ${String(action)}`);\n } catch (error) {\n this.log(`Pipeline execution failed for ${String(action)}`, error, 'error');\n throw error;\n } finally {\n executedHandlers?.push(...(context.executedHandlers ?? []));\n if (effectiveSignal && abortHandler) {\n effectiveSignal.removeEventListener('abort', abortHandler);\n }\n this.cleanupSignalsAfterStartedHandlers(cleanup, dispatchHandlerPromises);\n }\n }\n\n /**\n * Dispatch an action and return detailed execution results\n * \n * @param action - The action type to dispatch\n * @param payload - The action payload data\n * @param options - Optional dispatch options including result collection strategy\n * \n * @returns Promise resolving to comprehensive execution results\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n dispatchWithResult<K extends keyof T, R = void>(\n action: K,\n payload?: T[K],\n options?: DispatchOptions\n ): Promise<ExecutionResult<R>> {\n if (this.lifecycleState !== 'active') {\n return this.rejectedLifecyclePromise<ExecutionResult<R>>();\n }\n\n const timeoutScope = this.createTimeoutScope(action, options);\n const dispatchHandlerPromises: DispatchHandlerPromises = new Set();\n const attemptState = { count: 0 };\n let validation: ExecutionResult<R>['validation'];\n\n const operation = async () => {\n if (!timeoutScope.options?.signal?.aborted) {\n validation = this.validatePayload(action, payload);\n }\n\n return this.executeWithRetry(async () => {\n const executedHandlers: HandlerRegistration<any, any>[] = [];\n try {\n return await this._performDispatchWithResult<K, R>(\n action,\n payload,\n timeoutScope.options,\n validation,\n attemptState.count > 1,\n executedHandlers,\n dispatchHandlerPromises\n );\n } finally {\n this.cleanupOneTimeHandlers(\n action,\n executedHandlers,\n dispatchHandlerPromises\n );\n }\n }, timeoutScope.options, attemptState, result => (\n !result.success &&\n !result.aborted &&\n this.getHandlerCount(action) > 0\n ), () => this.getHandlerCount(action) > 0);\n };\n\n // Result dispatches historically executed immediately. Preserve that\n // behavior for nested dispatch and debounce compatibility; queuePriority is\n // the explicit opt-in to shared queue ordering.\n const shouldQueue = (\n !timeoutScope.options?.immediate &&\n Boolean(this.dispatchQueue) &&\n timeoutScope.options?.queuePriority !== undefined\n );\n let dispatchPromise: Promise<ExecutionResult<R>>;\n this.dispatchConstructionDepth += 1;\n try {\n if (shouldQueue) {\n const queued = this.dispatchQueue!.enqueueWithHandle(\n operation,\n timeoutScope.options!.queuePriority!\n );\n timeoutScope.onTimeout(error => queued.cancel(error));\n dispatchPromise = queued.promise;\n } else {\n dispatchPromise = operation();\n }\n this.trackDispatchPromise(dispatchPromise);\n } finally {\n this.dispatchConstructionDepth -= 1;\n }\n const exposedPromise = this.raceWithTimeout(\n dispatchPromise,\n timeoutScope,\n dispatchHandlerPromises\n );\n const observedPromise = exposedPromise.then(result => {\n if (!result.success && !result.aborted) {\n const terminalError = result.errors[result.errors.length - 1]?.error\n ?? new Error(`Action \"${String(action)}\" failed`);\n this.invokeErrorHandler(\n terminalError,\n action,\n payload,\n options,\n attemptState.count\n );\n }\n return result;\n }, error => {\n this.invokeErrorHandler(error, action, payload, options, attemptState.count);\n throw error;\n });\n\n void observedPromise.catch(() => {});\n return observedPromise;\n }\n\n private async _performDispatchWithResult<K extends keyof T, R = void>(\n action: K,\n payload: T[K] | undefined,\n options: DispatchOptions | undefined,\n validation: ExecutionResult<R>['validation'],\n skipGuards: boolean,\n executedHandlers: HandlerRegistration<any, any>[],\n dispatchHandlerPromises: DispatchHandlerPromises\n ): Promise<ExecutionResult<R>> {\n const _startTime = Date.now();\n \n // ๐Ÿ”ง Improved AbortSignal handling with cleaner merge logic (same as dispatch)\n const [effectiveSignal, autoAbortController, cleanup] = this.createAbortSignal(options);\n \n if (options?.autoAbort?.onControllerCreated && autoAbortController) {\n options.autoAbort.onControllerCreated(autoAbortController);\n }\n \n // Check if dispatch is aborted before starting\n if (effectiveSignal?.aborted) {\n cleanup();\n return this.createAbortedExecutionResult<R>(_startTime, 0, validation);\n }\n \n const pipeline = this.pipelines.get(action);\n \n if (!pipeline || pipeline.length === 0) {\n // ๐Ÿšจ ๊ฒฝ๊ณ : ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ์•ก์…˜ ์‹คํ–‰\n const warningMessage = `โš ๏ธ Action '${String(action)}' has no registered handlers. This action will be ignored.`;\n \n if (process.env.NODE_ENV === 'development') {\n console.warn(warningMessage);\n console.warn('๐Ÿ’ก Tip: Register a handler using registry.register() before dispatching this action.');\n console.warn('๐Ÿ“‹ Available actions:', Array.from(this.pipelines.keys()));\n }\n \n cleanup();\n return {\n success: true,\n aborted: false,\n abortReason: undefined as string | undefined,\n terminated: false,\n validation,\n result: undefined as any,\n successResults: [] as any,\n results: [],\n failedResults: [],\n execution: {\n duration: 0,\n handlersExecuted: 0,\n handlersSkipped: 0,\n handlersFailed: 0,\n startTime: _startTime,\n endTime: _startTime,\n },\n handlers: [],\n errors: [],\n };\n }\n\n // ๐Ÿ†• Optimize filtering - only copy array if filtering is needed\n const filteredHandlers = options?.filter \n ? this.filterHandlers(pipeline, options.filter)\n : pipeline;\n\n // ๐Ÿ”ง Apply ActionGuard controls using unified method with ExecutionResult return\n const actionKey = String(action);\n const guardResult = skipGuards\n ? null\n : await this.applyActionGuardControlsWithResult<R>(\n actionKey,\n filteredHandlers,\n options,\n _startTime,\n pipeline.length\n );\n\n // The signal may have been aborted while awaiting debounce.\n if (effectiveSignal?.aborted) {\n cleanup();\n return this.createAbortedExecutionResult<R>(_startTime, pipeline.length, validation);\n }\n\n if (guardResult) {\n cleanup();\n return { ...guardResult, validation }; // Throttled or debounced\n }\n\n // Determine execution mode for this action (with option override)\n const currentExecutionMode = options?.executionMode || \n this.actionExecutionModes.get(action) || \n this.executionMode;\n\n // Create pipeline execution context\n const context: PipelineContext<T[K], R> = {\n action: String(action),\n payload: payload as T[K],\n handlers: [...filteredHandlers],\n executedHandlers: [],\n deferOnceCleanup: true,\n signal: effectiveSignal ?? this.lifecycleController.signal,\n trackHandlerPromise: promise => this.trackHandlerPromise(\n promise,\n dispatchHandlerPromises\n ),\n aborted: false,\n abortReason: undefined as string | undefined,\n currentIndex: 0,\n jumpToPriority: undefined as number | undefined,\n jumpCount: 0,\n maxJumps: 10, // Default max jumps to prevent infinite loops\n executionMode: currentExecutionMode,\n \n // Result collection fields\n results: [],\n terminated: false,\n terminationResult: undefined as R | undefined,\n };\n\n let executionError: Error | undefined;\n const handlerResults: Array<{\n id: string;\n executed: boolean;\n duration: number | undefined;\n result: R | undefined;\n error: Error | undefined;\n metadata: Record<string, any> | undefined;\n }> = [];\n\n\n // Initialize handler tracking - all handlers start as not executed\n filteredHandlers.forEach(handler => {\n handlerResults.push({\n id: handler.config.id,\n executed: false,\n duration: undefined as number | undefined,\n result: undefined as R | undefined,\n error: undefined as Error | undefined,\n metadata: undefined as Record<string, any> | undefined,\n });\n });\n\n // Add abort listener if signal provided (use effectiveSignal for auto-abort)\n const abortHandler = effectiveSignal ? () => {\n context.aborted = true;\n context.abortReason = typeof effectiveSignal.reason === 'string'\n ? effectiveSignal.reason\n : 'Action dispatch aborted by signal';\n } : undefined;\n \n if (effectiveSignal && abortHandler) {\n effectiveSignal.addEventListener('abort', abortHandler, { once: true });\n }\n \n // ๐Ÿ”ง Initialize errors array (will be updated after pipeline execution)\n let errors: HandlerError[] = [];\n \n try {\n await this.executePipeline(\n context,\n dispatchHandlerPromises,\n autoAbortController,\n options?.autoAbort\n );\n \n // ๐Ÿ”ง Collect errors from execution context after pipeline execution\n const contextWithErrors = context as PipelineContext<any, any> & { collectedErrors?: HandlerError[] };\n errors = contextWithErrors.collectedErrors || [];\n \n // Mark executed handlers based on context.currentIndex\n // In sequential mode, handlers 0 to currentIndex were executed\n // In parallel/race mode, all handlers that didn't error were executed\n const executedCount = Math.min(context.currentIndex + (context.aborted ? 0 : 1), filteredHandlers.length);\n for (let i = 0; i < executedCount; i++) {\n const handler = filteredHandlers[i];\n if (!handler) continue;\n const handlerResult = handlerResults.find(hr => hr.id === handler.config.id);\n if (handlerResult) {\n handlerResult.executed = true;\n }\n }\n } catch (error) {\n // ๐Ÿ”ง Collect errors from execution context before adding pipeline error\n const contextWithErrors = context as PipelineContext<any, any> & { collectedErrors?: HandlerError[] };\n errors = contextWithErrors.collectedErrors || [];\n \n executionError = error instanceof Error ? error : new Error(String(error));\n errors.push({\n handlerId: 'pipeline',\n error: executionError,\n timestamp: Date.now(),\n severity: 'blocking'\n });\n \n // Mark executed handlers even when there's an error\n const executedCount = Math.min(context.currentIndex + 1, filteredHandlers.length);\n for (let i = 0; i < executedCount; i++) {\n const handler = filteredHandlers[i];\n if (!handler) continue;\n const handlerResult = handlerResults.find(hr => hr.id === handler.config.id);\n if (handlerResult) {\n handlerResult.executed = true;\n }\n }\n } finally {\n executedHandlers.push(...(context.executedHandlers ?? []));\n if (effectiveSignal && abortHandler) {\n effectiveSignal.removeEventListener('abort', abortHandler);\n }\n this.cleanupSignalsAfterStartedHandlers(cleanup, dispatchHandlerPromises);\n }\n\n const endTime = Date.now();\n \n // Process results based on options\n const processedResult = this.processResults(context, options?.result);\n\n // ๐Ÿ”ง Type safety: Separate successful results from failed ones\n const successResults = context.results.filter((result): result is R => result !== undefined);\n const failedResults = errors.map(err => ({\n handlerId: err.handlerId,\n error: err.error,\n expectedType: typeof processedResult\n }));\n\n // Build execution result with improved type safety\n const executionResult: ExecutionResult<R> = {\n success: !executionError && !context.aborted,\n aborted: context.aborted,\n abortReason: context.abortReason,\n terminated: context.terminated,\n validation,\n result: processedResult,\n successResults: successResults,\n results: context.results,\n failedResults,\n execution: {\n duration: endTime - _startTime,\n handlersExecuted: filteredHandlers.length === 0 ? 0 : context.currentIndex + (context.aborted ? 0 : 1),\n handlersSkipped: Math.max(0, filteredHandlers.length - (context.currentIndex + 1)),\n handlersFailed: errors.length,\n startTime: _startTime,\n endTime,\n },\n handlers: handlerResults,\n errors: errors.map(err => ({\n handlerId: err.handlerId,\n error: err.error,\n timestamp: err.timestamp,\n severity: 'non-blocking' as const\n })),\n };\n\n return executionResult;\n }\n\n /**\n * ๐Ÿ”ง Unified method for dispatchWithResult that returns ExecutionResult on guard rejection\n */\n private async applyActionGuardControlsWithResult<R>(\n actionKey: string,\n filteredHandlers: HandlerRegistration<any, any>[],\n options: DispatchOptions | undefined,\n startTime: number,\n pipelineLength: number\n ): Promise<ExecutionResult<R> | null> {\n // Get throttle/debounce settings (same logic as above)\n let throttleMs: number | undefined;\n let debounceMs: number | undefined;\n \n if (options?.throttle !== undefined) {\n throttleMs = options.throttle;\n } else if (filteredHandlers.length > 0) {\n for (const handler of filteredHandlers) {\n if (handler.config.throttle !== undefined) {\n throttleMs = handler.config.throttle;\n break;\n }\n }\n }\n \n if (options?.debounce !== undefined) {\n debounceMs = options.debounce;\n } else if (filteredHandlers.length > 0) {\n for (const handler of filteredHandlers) {\n if (handler.config.debounce !== undefined) {\n debounceMs = handler.config.debounce;\n break;\n }\n }\n }\n \n // Apply debounce if specified\n if (debounceMs !== undefined) {\n const shouldProceed = await this.actionGuard.debounce(actionKey, debounceMs);\n if (!shouldProceed) {\n return {\n success: false,\n aborted: true,\n abortReason: 'Debounced execution',\n terminated: false,\n result: undefined as any,\n successResults: [] as any,\n results: [],\n failedResults: [],\n execution: {\n duration: Date.now() - startTime,\n handlersExecuted: 0,\n handlersSkipped: pipelineLength,\n handlersFailed: 0,\n startTime: startTime,\n endTime: Date.now(),\n },\n handlers: [],\n errors: [],\n };\n }\n }\n \n // Apply throttle if specified\n if (throttleMs !== undefined) {\n const shouldProceed = this.actionGuard.throttle(actionKey, throttleMs);\n if (!shouldProceed) {\n return {\n success: false,\n aborted: true,\n abortReason: 'Throttled execution',\n terminated: false,\n result: undefined as any,\n successResults: [] as any,\n results: [],\n failedResults: [],\n execution: {\n duration: Date.now() - startTime,\n handlersExecuted: 0,\n handlersSkipped: pipelineLength,\n handlersFailed: 0,\n startTime: startTime,\n endTime: Date.now(),\n },\n handlers: [],\n errors: [],\n };\n }\n }\n\n return null; // No guard intervention, proceed with execution\n }\n\n // Cache invalidation removed for memory stability\n\n /**\n * ๐Ÿ”ง Create or reuse PipelineController from pool for better performance\n */\n private getControllerFromPool<K extends keyof T>(\n context: PipelineContext<T[K], any>, \n autoAbortController?: AbortController,\n autoAbortOptions?: { allowHandlerAbort?: boolean }\n ): PipelineController<T[K], any> {\n // Try to reuse from pool\n let controller = this.controllerPool.pop();\n \n if (!controller) {\n // Create new controller if pool is empty\n controller = {} as PipelineController<T[K], any>;\n }\n\n // Configure/reset the controller for current context\n (controller as { signal: AbortSignal }).signal =\n context.signal ?? this.lifecycleController.signal;\n\n controller.abort = (reason?: string) => {\n context.aborted = true;\n context.abortReason = reason;\n \n // Auto-abort: Handler can trigger pipeline abort if enabled\n if (autoAbortController && autoAbortOptions?.allowHandlerAbort) {\n autoAbortController.abort(reason);\n }\n };\n\n controller.modifyPayload = (modifier: (payload: T[K]) => T[K]) => {\n try {\n context.payload = modifier(context.payload);\n } catch (modificationError) {\n // ๐Ÿ”ง Fix: Don't let payload modification errors crash the pipeline\n this.log('Payload modification error', modificationError, 'warn');\n // Keep original payload on modification error\n }\n };\n\n controller.getPayload = () => context.payload;\n\n controller.jumpToPriority = (priority: number) => {\n context.jumpToPriority = priority;\n };\n\n controller.return = (result: any) => {\n context.terminated = true;\n context.terminationResult = result;\n };\n\n controller.setResult = (result: any) => {\n context.results.push(result);\n };\n\n controller.getResults = () => {\n return [...context.results];\n };\n\n controller.mergeResult = (merger: (previousResults: any[], currentResult: any) => any) => {\n const currentResult = context.results[context.results.length - 1];\n const previousResults = context.results.slice(0, -1);\n const mergedResult = merger(previousResults, currentResult);\n context.results[context.results.length - 1] = mergedResult;\n };\n\n return controller;\n }\n\n private filterHandlers(\n handlers: HandlerRegistration<any, any>[],\n filterOptions?: DispatchOptions['filter']\n ): HandlerRegistration<any, any>[] {\n if (!filterOptions) {\n return handlers;\n }\n\n // Cache disabled for memory stability\n\n // Cache disabled - using direct filtering for memory stability\n\n // Create Sets for fast lookup if arrays are provided\n const handlerIdSet = filterOptions.handlerIds ? new Set(filterOptions.handlerIds) : null;\n const excludeIdSet = filterOptions.excludeHandlerIds ? new Set(filterOptions.excludeHandlerIds) : null;\n\n // Filter handlers with optimized checks\n const filtered = handlers.filter(registration => {\n const config = registration.config;\n\n // Fast Set-based inclusion check\n if (handlerIdSet && !handlerIdSet.has(config.id)) {\n return false;\n }\n\n // Fast Set-based exclusion check\n if (excludeIdSet?.has(config.id)) {\n return false;\n }\n\n // Priority range check\n if (filterOptions.priority) {\n const priority = config.priority;\n if (filterOptions.priority.min !== undefined && priority < filterOptions.priority.min) {\n return false;\n }\n if (filterOptions.priority.max !== undefined && priority > filterOptions.priority.max) {\n return false;\n }\n }\n\n // Custom filter (not cached)\n if (filterOptions.custom && !filterOptions.custom(config)) {\n return false;\n }\n\n return true;\n });\n\n // Cache disabled for memory stability\n\n return filtered;\n }\n\n private processResults<R>(\n context: PipelineContext<any, R>,\n resultOptions?: DispatchOptions['result']\n ): R | R[] | undefined {\n const results = context.results;\n\n // ๐Ÿ”ง Fix: Always handle termination result regardless of collect option\n if (context.terminated && context.terminationResult !== undefined) {\n return context.terminationResult;\n }\n\n // ๐Ÿ”ง Fix: Return undefined only if no results options specified AND no results available\n if (!resultOptions) {\n // If no result options specified but we have results, return the last one\n return results.length > 0 ? results[results.length - 1] : undefined;\n }\n\n // ๐Ÿ”ง Fix: Process results even when collect is false if we have a strategy specified\n if (!resultOptions.collect && !resultOptions.strategy) {\n return undefined;\n }\n\n // Apply maxResults limit\n const limitedResults = resultOptions.maxResults\n ? results.slice(0, resultOptions.maxResults)\n : results;\n\n if (limitedResults.length === 0) {\n return undefined;\n }\n\n // Process results based on strategy with improved type handling\n switch (resultOptions.strategy) {\n case 'first':\n return limitedResults[0];\n case 'last':\n return limitedResults[limitedResults.length - 1];\n case 'all':\n return limitedResults;\n case 'merge':\n if (resultOptions.merger) {\n return resultOptions.merger(limitedResults);\n }\n // Default merge: return last result\n return limitedResults[limitedResults.length - 1];\n case 'custom':\n if (resultOptions.merger) {\n return resultOptions.merger(limitedResults);\n }\n throw new Error('Custom result strategy requires a merger function');\n default:\n // ๐Ÿ”ง Fix: If collect is true but no strategy specified, return all results\n if (resultOptions.collect) {\n return limitedResults;\n }\n // Default: return last result if no strategy specified\n return limitedResults[limitedResults.length - 1];\n }\n }\n\n private async executePipeline<K extends keyof T>(\n context: PipelineContext<T[K], any>,\n dispatchHandlerPromises: DispatchHandlerPromises,\n autoAbortController?: AbortController,\n autoAbortOptions?: { allowHandlerAbort?: boolean }\n ): Promise<void> {\n const createController = (_registration: HandlerRegistration<T[K], any>, _index: number): PipelineController<T[K], any> => {\n return this.getControllerFromPool(context, autoAbortController, autoAbortOptions);\n };\n\n switch (context.executionMode) {\n case 'sequential':\n await executeSequential<T[K], any>(context, createController);\n break;\n case 'parallel':\n await executeParallel<T[K], any>(context, createController);\n break;\n case 'race':\n await executeRace<T[K], any>(context, createController);\n break;\n default:\n throw new Error(`Unknown execution mode: ${context.executionMode}`);\n }\n\n if (!context.deferOnceCleanup) {\n this.cleanupOneTimeHandlers(\n context.action as K,\n context.executedHandlers ?? [],\n dispatchHandlerPromises\n );\n }\n }\n\n private cleanupOneTimeHandlers<K extends keyof T>(\n action: K,\n executedHandlers: HandlerRegistration<any, any>[],\n dispatchHandlerPromises: DispatchHandlerPromises\n ): void {\n const oneTimeHandlers = executedHandlers.filter(reg => reg.config.once);\n if (oneTimeHandlers.length === 0) return;\n\n // Race mode returns its winner while loser handlers can still be active.\n // Detach every invoked once-handler immediately so retries cannot invoke it\n // again, but defer resource cleanup until this dispatch's started handler\n // work drains. Unrelated dispatches must not delay cleanup.\n const handlersStillRunning = [...dispatchHandlerPromises];\n const shouldDeferCleanup = handlersStillRunning.length > 0;\n\n oneTimeHandlers.forEach(registration => {\n if (this.removeRegistration(action, registration, !shouldDeferCleanup)) {\n if (\n shouldDeferCleanup &&\n typeof registration.config.cleanup === 'function'\n ) {\n const cleanupPromise = Promise.allSettled(handlersStillRunning).then(() => {\n this.runRegistrationCleanup(action, registration);\n });\n void this.trackGlobalHandlerPromise(cleanupPromise).catch(() => {});\n }\n\n this.log(`One-time handler removed: ${String(action)}`, {\n handlerId: registration.id,\n remainingHandlers: this.getHandlerCount(action)\n });\n }\n });\n }\n\n\n /**\n * Get the number of registered handlers for an action\n * \n * @param action - The action type to count handlers for\n * \n * @returns Number of registered handlers\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n getHandlerCount<K extends keyof T>(action: K): number {\n const pipeline = this.pipelines.get(action);\n return pipeline ? pipeline.length : 0;\n }\n\n /**\n * Check if an action has any registered handlers\n * \n * @param action - The action type to check\n * \n * @returns True if action has handlers, false otherwise\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n hasHandlers<K extends keyof T>(action: K): boolean {\n return this.getHandlerCount(action) > 0;\n }\n\n /**\n * Get all registered action types\n * \n * @returns Array of all registered action types\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n getRegisteredActions(): (keyof T)[] {\n return Array.from(this.pipelines.keys());\n }\n\n /**\n * Remove all handlers for a specific action\n * \n * @param action - The action type to clear handlers for\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n clearAction<K extends keyof T>(action: K): void {\n const pipeline = this.pipelines.get(action);\n if (pipeline) {\n [...pipeline].forEach(registration => {\n this.removeRegistration(action, registration);\n });\n }\n\n this.pipelines.delete(action);\n this.lastRegisteredTimestamps.delete(action);\n this.actionGuard.clearGuards(String(action));\n }\n\n /**\n * Remove all handlers for all actions\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n clearAll(): void {\n [...this.pipelines.keys()].forEach(action => {\n this.clearAction(action);\n });\n\n this.pipelines.clear();\n this.lastRegisteredTimestamps.clear();\n this.unregisterFunctions.clear();\n this.actionGuard.clearAll();\n }\n\n /**\n * Get the name of this action register\n * \n * @returns The register name\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n getName(): string {\n return this.name;\n }\n\n /**\n * Get comprehensive registry information (similar to DeclarativeStoreRegistry pattern)\n * \n * @returns Registry information including actions, handlers, and execution modes\n */\n getRegistryInfo(): ActionRegistryInfo<T> {\n const totalHandlers = Array.from(this.pipelines.values()).reduce(\n (total, pipeline) => total + pipeline.length, \n 0\n );\n \n return {\n name: this.name,\n totalActions: this.pipelines.size,\n totalHandlers,\n registeredActions: Array.from(this.pipelines.keys()),\n actionExecutionModes: new Map(this.actionExecutionModes),\n defaultExecutionMode: this.executionMode,\n };\n }\n\n /**\n * Get detailed statistics for a specific action\n * \n * @param action Action name to get statistics for\n * @returns Detailed handler statistics\n */\n getActionStats<K extends keyof T>(action: K): ActionHandlerStats<T> | null {\n const pipeline = this.pipelines.get(action);\n if (!pipeline) {\n return null;\n }\n\n // Group handlers by priority\n const priorityMap = new Map<number, typeof pipeline>();\n pipeline.forEach(handler => {\n if (!priorityMap.has(handler.config.priority)) {\n priorityMap.set(handler.config.priority, []);\n }\n priorityMap.get(handler.config.priority)!.push(handler);\n });\n\n const handlersByPriority = Array.from(priorityMap.entries())\n .sort(([a], [b]) => b - a) // Sort by priority (highest first)\n .map(([priority, handlers]) => ({\n priority,\n handlers: handlers.map(h => ({\n id: h.config.id,\n }))\n }));\n\n // Execution statistics are no longer tracked\n const executionStats = undefined;\n\n return {\n action,\n handlerCount: pipeline.length,\n totalHandlers: pipeline.length,\n handlersByPriority,\n executionStats,\n lastRegistered: this.lastRegisteredTimestamps.get(action),\n };\n }\n\n /**\n * Get statistics for all registered actions\n * \n * @returns Array of statistics for all actions\n */\n getAllActionStats(): Array<ActionHandlerStats<T>> {\n return Array.from(this.pipelines.keys())\n .map(action => this.getActionStats(action))\n .filter((stats): stats is ActionHandlerStats<T> => stats !== null);\n }\n\n\n /**\n * Set global execution mode for all actions\n * \n * @param mode Execution mode to set\n */\n setExecutionMode(mode: ExecutionMode): void {\n this.executionMode = mode;\n \n if (this.registryConfig?.debug && process.env.NODE_ENV === 'development') {\n console.log(`๐ŸŽฏ Global execution mode set to: ${mode}`);\n }\n }\n\n /**\n * Set execution mode for a specific action\n * \n * @param action Action name\n * @param mode Execution mode to set\n */\n setActionExecutionMode<K extends keyof T>(action: K, mode: ExecutionMode): void {\n this.actionExecutionModes.set(action, mode);\n \n if (this.registryConfig?.debug && process.env.NODE_ENV === 'development') {\n console.log(`๐ŸŽฏ Execution mode set for action '${String(action)}': ${mode}`);\n }\n }\n\n /**\n * Get execution mode for a specific action\n * \n * @param action Action name\n * @returns Execution mode for the action, or default if not set\n */\n getActionExecutionMode<K extends keyof T>(action: K): ExecutionMode {\n return this.actionExecutionModes.get(action) || this.executionMode;\n }\n\n /**\n * Remove execution mode override for a specific action\n * \n * @param action Action name\n */\n removeActionExecutionMode<K extends keyof T>(action: K): void {\n this.actionExecutionModes.delete(action);\n \n if (this.registryConfig?.debug && process.env.NODE_ENV === 'development') {\n console.log(`๐ŸŽฏ Execution mode reset for action '${String(action)}' to default: ${this.executionMode}`);\n }\n }\n\n\n /**\n * Get registry configuration (for debugging and inspection)\n * \n * @returns Current registry configuration\n */\n getRegistryConfig(): ActionRegisterConfig['registry'] {\n return this.registryConfig;\n }\n\n /**\n * Check if registry has debug mode enabled\n * \n * @returns Whether debug mode is enabled\n */\n isDebugEnabled(): boolean {\n return this.isDebugMode;\n }\n\n /**\n * Creates a consistent unregister function for a handler\n * \n * @param action - Action key\n * @param handlerId - Handler identifier\n * @param registration - Handler registration object\n * @returns Unregister function\n * @private\n */\n private createUnregisterFunction<K extends keyof T>(\n action: K,\n handlerId: string,\n registration: HandlerRegistration<any, any>\n ): UnregisterFunction {\n return () => {\n if (this.removeRegistration(action, registration)) {\n this.log(`Handler unregistered: ${String(action)}`, {\n handlerId,\n remainingHandlers: this.getHandlerCount(action),\n actionRemoved: !this.pipelines.has(action)\n });\n }\n };\n }\n\n /** Remove a registration and release every resource owned by it exactly once. */\n private removeRegistration<K extends keyof T>(\n action: K,\n registration: HandlerRegistration<any, any>,\n runCleanup = true\n ): boolean {\n const pipeline = this.pipelines.get(action);\n if (!pipeline) return false;\n\n const index = pipeline.indexOf(registration);\n if (index === -1) return false;\n\n pipeline.splice(index, 1);\n this.unregisterFunctions.delete(registration.id);\n\n if (runCleanup) {\n this.runRegistrationCleanup(action, registration);\n }\n\n if (pipeline.length === 0) {\n this.pipelines.delete(action);\n this.lastRegisteredTimestamps.delete(action);\n }\n\n return true;\n }\n\n private runRegistrationCleanup<K extends keyof T>(\n action: K,\n registration: HandlerRegistration<any, any>\n ): void {\n if (!registration.config.cleanup) return;\n\n try {\n registration.config.cleanup();\n } catch (cleanupError) {\n this.log(`Cleanup error while removing handler: ${String(action)}`, cleanupError, 'warn');\n }\n }\n\n /**\n * Gets the total count of registered unregister functions\n * \n * @returns Number of unregister functions\n * @public\n */\n getUnregisterFunctionCount(): number {\n return this.unregisterFunctions.size;\n }\n \n /**\n * Checks if an unregister function exists for the given handler ID\n * \n * @param handlerId - Handler identifier to check\n * @returns True if unregister function exists\n * @public\n */\n hasUnregisterFunction(handlerId: string): boolean {\n return this.unregisterFunctions.has(handlerId);\n }\n\n /** Reject queued dispatches without releasing registered handlers. */\n cancelPendingDispatches(): void {\n this.dispatchQueue?.clear({ rejectPending: true });\n }\n\n private beginShutdown(): Promise<void> {\n if (this.destroyAsyncPromise) return this.destroyAsyncPromise;\n\n if (this.lifecycleState === 'destroyed') {\n this.destroyAsyncPromise = Promise.resolve();\n return this.destroyAsyncPromise;\n }\n\n this.lifecycleState = 'closing';\n const shutdownError = new ActionRegisterDestroyedError(this.name, 'closing');\n\n // Store the stable shutdown promise before aborting signals: abort listeners\n // run synchronously and may re-enter destroyAsync().\n let resolveShutdown!: () => void;\n let rejectShutdown!: (error: unknown) => void;\n this.destroyAsyncPromise = new Promise<void>((resolve, reject) => {\n resolveShutdown = resolve;\n rejectShutdown = reject;\n });\n\n if (!this.lifecycleController.signal.aborted) {\n this.lifecycleController.abort(shutdownError);\n }\n\n // Stop guard timers immediately and reject operations that have not begun.\n // Registered handler cleanup is deferred until every started handler settles.\n this.actionGuard.destroy();\n this.dispatchQueue?.clear({ rejectPending: true, reason: shutdownError });\n\n const canFinalizeSynchronously = (\n this.dispatchConstructionDepth === 0 &&\n this.activeDispatches.size === 0 &&\n this.activeHandlerPromises.size === 0\n );\n\n if (canFinalizeSynchronously) {\n this.finalizeDestroy();\n resolveShutdown();\n return this.destroyAsyncPromise;\n }\n\n const drainAndFinalize = async () => {\n // Handler promises can be created by a dispatch that was already starting\n // when shutdown began, so drain until both dynamic sets stay empty.\n while (this.activeDispatches.size > 0 || this.activeHandlerPromises.size > 0) {\n await Promise.allSettled([\n ...this.activeDispatches,\n ...this.activeHandlerPromises,\n ]);\n }\n\n this.finalizeDestroy();\n };\n // Dispatch and queue construction call handlers synchronously before their\n // promises can be inserted into the active sets. Start draining on the next\n // microtask so handler-initiated shutdown cannot finalize through that gap.\n void Promise.resolve()\n .then(drainAndFinalize)\n .then(resolveShutdown, rejectShutdown);\n\n // destroy() is intentionally fire-and-forget; keep its internal promise\n // observed while destroyAsync() remains available to callers that need proof.\n void this.destroyAsyncPromise.catch(error => {\n this.log('ActionRegister async destroy failed', error, 'warn');\n });\n return this.destroyAsyncPromise;\n }\n\n private finalizeDestroy(): void {\n if (this.lifecycleState === 'destroyed') return;\n\n this.clearAll();\n this.actionExecutionModes.clear();\n this.controllerPool.length = 0;\n this.lifecycleState = 'destroyed';\n this.log('ActionRegister destroyed');\n }\n\n /**\n * ๐Ÿ†• Destroy method for comprehensive cleanup\n *\n * Begins terminal cleanup of pipelines, guards, queues, and statistics. Cleanup\n * remains synchronous when no work has started; otherwise active handlers drain\n * in the background. Use destroyAsync() when completion must be observed.\n *\n * @public\n */\n destroy(): void {\n void this.beginShutdown();\n }\n\n /**\n * Begin terminal shutdown and resolve after all started handlers have settled\n * and their registered cleanup functions have run.\n *\n * Repeated calls return the same promise. New registrations and dispatches are\n * rejected as soon as shutdown begins.\n *\n * @public\n */\n destroyAsync(): Promise<void> {\n return this.beginShutdown();\n }\n}\n","/**\n * @fileoverview React integration helpers for ActionRegister\n * \n * Provides React-specific utilities and hooks for seamless integration\n * with React components and lifecycle management.\n * \n * Note: This file provides utilities for React integration but does not\n * have direct React dependencies. Import React types externally when used.\n */\n\n// ActionRegister is intentionally erased in the diagnostics helper because\n// it aggregates handlers from an arbitrary application action map.\n// biome-ignore-all lint/suspicious/noExplicitAny: heterogeneous action maps are erased only at this runtime inspection boundary.\n\nimport type { \n ActionPayloadMap, \n ActionHandler, \n HandlerConfig,\n UnregisterFunction\n} from './types.js';\nimport type { ActionRegister } from './ActionRegister.js';\n\n/**\n * ๐Ÿ”ง Create action handler registration configuration for React components\n * \n * Creates a configuration object that can be used with React's useEffect to properly\n * register and unregister action handlers with lifecycle management and cleanup.\n * This is NOT a hook - it's a factory function for React hook integration.\n * \n * @template T - ActionPayloadMap type\n * @template K - Action key type\n * \n * @param registry - ActionRegister instance\n * @param action - Action name to register handler for\n * @param handler - Handler function (should be memoized with useCallback)\n * @param config - Handler configuration\n * \n * @returns Configuration object with register/unregister functions\n * \n * @example Basic Usage with useEffect\n * ```tsx\n * import { useCallback, useEffect } from 'react';\n * import { createActionHandler } from '@context-action/core/react-helpers';\n * \n * function MyComponent() {\n * const registry = useActionRegister();\n * \n * const handleUserUpdate = useCallback(async (payload, controller) => {\n * // Handler logic here\n * }, []);\n * \n * useEffect(() => {\n * const { register, unregister } = createActionHandler(\n * registry,\n * 'updateUser',\n * handleUserUpdate,\n * { priority: 10 }\n * );\n * \n * const cleanup = register();\n * return () => {\n * cleanup();\n * unregister();\n * };\n * }, [registry, handleUserUpdate]);\n * }\n * ```\n * \n * @example With Automatic Cleanup\n * ```tsx\n * const [userId, setUserId] = useState('123');\n * \n * const handleUserUpdate = useCallback(async (payload, controller) => {\n * console.log('Updating user:', userId, payload);\n * }, [userId]);\n * \n * useEffect(() => {\n * const handlerManager = createActionHandler(\n * registry,\n * 'updateUser',\n * handleUserUpdate,\n * { priority: 10 }\n * );\n * \n * // Simplified registration with automatic cleanup\n * return handlerManager.registerWithCleanup();\n * }, [registry, handleUserUpdate, userId]);\n * ```\n * \n * @public\n */\nexport function createActionHandler<T extends ActionPayloadMap, K extends keyof T>(\n registry: ActionRegister<T>,\n action: K,\n handler: ActionHandler<T[K]>,\n config?: HandlerConfig<T[K]>\n): {\n register: () => UnregisterFunction;\n unregister: () => void;\n registerWithCleanup: () => () => void;\n config: Required<HandlerConfig<T[K]>>;\n} {\n // Inline React-optimized handler configuration\n const timestamp = Date.now();\n const random = Math.random().toString(36).substr(2, 5);\n \n const finalConfig: Required<HandlerConfig<T[K]>> = {\n priority: config?.priority ?? 0,\n id: config?.id || `react_${String(action)}_${timestamp}_${random}`,\n blocking: config?.blocking ?? false,\n once: config?.once ?? false,\n debounce: config?.debounce ?? undefined,\n throttle: config?.throttle ?? undefined,\n // React-optimized defaults\n replaceExisting: true, // Always replace in React (handles HMR/remounting)\n } as Required<HandlerConfig<T[K]>>;\n let currentUnregister: UnregisterFunction | undefined;\n let isRegistered = false;\n \n return {\n /**\n * Register the handler and return cleanup function\n */\n register(): UnregisterFunction {\n if (isRegistered && currentUnregister) {\n // Clean up previous registration\n currentUnregister();\n }\n \n currentUnregister = registry.register(action, handler, finalConfig);\n isRegistered = true;\n \n return currentUnregister;\n },\n \n /**\n * Unregister the handler if currently registered\n */\n unregister(): void {\n if (isRegistered && currentUnregister) {\n currentUnregister();\n currentUnregister = undefined;\n isRegistered = false;\n }\n },\n \n /**\n * Register and return cleanup function (React useEffect pattern)\n */\n registerWithCleanup(): () => void {\n const unregisterFn = this.register();\n \n return () => {\n unregisterFn();\n this.unregister();\n };\n },\n \n config: finalConfig\n };\n}\n\n\n/**\n * ๐Ÿ†• React development utilities\n * \n * Provides debugging and development helpers specifically for React environments.\n */\nexport const ReactDevUtils = {\n /**\n * Enable detailed React integration debugging\n */\n enableDebugMode(): void {\n if (typeof window !== 'undefined') {\n (window as any).__CONTEXT_ACTION_REACT_DEBUG__ = true;\n }\n },\n\n /**\n * Disable React integration debugging\n */\n disableDebugMode(): void {\n if (typeof window !== 'undefined') {\n (window as any).__CONTEXT_ACTION_REACT_DEBUG__ = false;\n }\n },\n\n /**\n * Check if React debug mode is enabled\n */\n isDebugMode(): boolean {\n return typeof window !== 'undefined' && \n Boolean((window as any).__CONTEXT_ACTION_REACT_DEBUG__);\n },\n\n /**\n * Log React-specific debugging information\n */\n log(component: string, action: string, message: string, data?: unknown): void {\n if (this.isDebugMode()) {\n console.log(`๐ŸŽฏ [React-ActionRegister] [${component}] ${action}: ${message}`, data || '');\n }\n },\n\n /**\n * Get React integration statistics\n */\n getStats(registry: ActionRegister<any>): {\n totalHandlers: number;\n reactHandlers: number;\n registryInfo: ReturnType<ActionRegister<any>['getRegistryInfo']>;\n } {\n const registryInfo = registry.getRegistryInfo();\n \n // Count React handlers (handlers with 'react' in their ID)\n let reactHandlers = 0;\n registry.getRegisteredActions().forEach((action: keyof any) => {\n const stats = registry.getActionStats(action);\n if (stats) {\n stats.handlersByPriority.forEach((priorityGroup: any) => {\n priorityGroup.handlers.forEach((handler: any) => {\n if (handler.id.includes('react')) {\n reactHandlers++;\n }\n });\n });\n }\n });\n\n return {\n totalHandlers: registryInfo.totalHandlers,\n reactHandlers,\n registryInfo\n };\n }\n};\n\n/**\n * ๐Ÿ†• React Error Boundary integration\n * \n * Utilities for integrating ActionRegister errors with React Error Boundaries.\n */\nexport class ReactActionError extends Error {\n public readonly action: string;\n public readonly payload?: unknown;\n public readonly handlerId: string | undefined;\n public readonly timestamp: number;\n\n constructor(\n message: string,\n action: string,\n payload?: unknown,\n handlerId: string | undefined = undefined,\n originalError?: Error\n ) {\n super(message);\n this.name = 'ReactActionError';\n this.action = action;\n this.payload = payload;\n this.handlerId = handlerId;\n this.timestamp = Date.now();\n\n // Maintain original error stack if available\n if (originalError?.stack) {\n this.stack = originalError.stack;\n }\n }\n\n /**\n * Create a React Error Boundary compatible error\n */\n static fromActionError(\n originalError: Error,\n action: string,\n payload?: unknown,\n handlerId?: string\n ): ReactActionError {\n return new ReactActionError(\n `Action '${action}' failed: ${originalError.message}`,\n action,\n payload,\n handlerId,\n originalError\n );\n }\n}\n\n/**\n * ๐Ÿ†• Type guard for React Action Errors\n * \n * @param error - Error to check\n * @returns True if error is a ReactActionError\n */\nexport function isReactActionError(error: unknown): error is ReactActionError {\n return error instanceof ReactActionError;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["contextWithErrors"],"sources":["../src/execution-modes.ts","../src/action-guard.ts","../src/concurrency/OperationQueue.ts","../src/errors.ts","../src/ActionRegister.ts"],"sourcesContent":["/**\n * @fileoverview Execution mode implementations for ActionRegister\n * \n * Provides three different execution strategies for action handler pipelines:\n * - Sequential: Execute handlers one after another in priority order\n * - Parallel: Execute all handlers simultaneously\n * - Race: First handler to complete wins, other started handlers keep running\n */\n\nimport type { \n HandlerRegistration, \n PipelineContext, \n PipelineController,\n HandlerError\n} from './types.js';\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n (typeof value === 'object' || typeof value === 'function') &&\n value !== null &&\n typeof (value as { then?: unknown }).then === 'function'\n );\n}\n\n/**\n * Create standardized error handling for handlers\n * \n * @param error - The error that occurred\n * @param registration - The handler registration that failed\n * @returns Standardized HandlerError object\n * \n * @internal\n */\nfunction handleExecutionError<T, R>(\n error: unknown,\n registration: HandlerRegistration<T, R>\n): HandlerError {\n const errorObj = error instanceof Error ? error : new Error(String(error));\n return {\n handlerId: registration.id,\n error: errorObj,\n timestamp: Date.now(),\n severity: registration.config.blocking ? 'blocking' : 'non-blocking'\n };\n}\n\n/**\n * Execute handlers in sequential mode (one after another)\n * \n * Executes action handlers one at a time in priority order (highest first).\n * Supports both blocking and non-blocking handlers, with proper abort and\n * termination handling. Handlers can modify payload for subsequent handlers\n * and jump to different priority levels.\n * \n * @template T - The payload type for the action\n * @template R - The result type for handlers\n * \n * @param context - Pipeline execution context containing handlers and state\n * @param createController - Factory function for creating pipeline controllers\n * \n * @throws {Error} When a blocking handler fails\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/dispatch-patterns\n * \n * @public\n */\nexport async function executeSequential<T, R = void>(\n context: PipelineContext<T, R>,\n createController: (registration: HandlerRegistration<T, R>, index: number) => PipelineController<T, R>\n): Promise<void> {\n\n let i = 0;\n const nonBlockingPromises: Array<Promise<unknown>> = [];\n const errors: HandlerError[] = [];\n \n while (i < context.handlers.length) {\n // Check for abort or termination\n if (context.aborted || context.terminated) {\n break;\n }\n\n const registration = context.handlers[i];\n if (!registration) {\n continue; // Skip if handler not found\n }\n context.currentIndex = i;\n const controller = createController(registration, i);\n\n try {\n // Check for abort before executing handler\n if (context.aborted) {\n break;\n }\n\n // ๐Ÿ”ง Fix: Check handler condition before execution\n if (registration.config.condition) {\n try {\n const shouldExecute = registration.config.condition(context.payload);\n if (!shouldExecute) {\n i++; // Skip this handler\n continue;\n }\n } catch {\n // If condition function throws, skip the handler\n i++;\n continue;\n }\n }\n\n (context.executedHandlers ??= []).push(registration);\n const result = registration.handler(context.payload, controller);\n const asyncResult = isPromiseLike(result) ? Promise.resolve(result) : undefined;\n const trackedResult = asyncResult && context.trackHandlerPromise\n ? context.trackHandlerPromise<unknown>(asyncResult)\n : asyncResult;\n\n if (registration.config.blocking) {\n // ๐Ÿ†• Blocking handlers: Wait for completion (sync or async)\n const handlerResult = trackedResult\n ? await trackedResult\n : result;\n if (handlerResult !== undefined && !context.terminated) {\n context.results.push(handlerResult as R);\n }\n } else {\n // ๐Ÿ†• Non-blocking handlers: Handle differently for sync vs async\n if (trackedResult) {\n // Non-blocking async: Track promise with error handling\n const promiseWithErrorHandling = trackedResult\n .then(asyncResult => {\n if (asyncResult !== undefined && !context.terminated) {\n context.results.push(asyncResult as R);\n }\n return asyncResult;\n })\n .catch(error => {\n // ๐Ÿ†• Non-blocking async handler error collection\n const handlerError = handleExecutionError(error, registration);\n errors.push({\n handlerId: handlerError.handlerId,\n error: handlerError.error,\n timestamp: handlerError.timestamp,\n severity: 'non-blocking'\n });\n return undefined; // Return undefined for failed non-blocking handlers\n });\n \n nonBlockingPromises.push(promiseWithErrorHandling);\n } else if (result !== undefined && !context.terminated) {\n // Non-blocking sync: Immediately collect result\n context.results.push(result as R);\n }\n }\n\n /** Check if pipeline was terminated by controller.return() */\n if (context.terminated) {\n break;\n }\n\n /** Handle jump to priority AFTER handler execution */\n if (context.jumpToPriority !== undefined) {\n // Check if we've exceeded maximum jumps to prevent infinite loops\n context.jumpCount = (context.jumpCount || 0) + 1;\n if (context.jumpCount > (context.maxJumps || 10)) {\n console.error(\n `[ActionRegister] ERROR: Maximum jump limit (${context.maxJumps || 10}) exceeded. ` +\n `Aborting to prevent infinite loop. Check your jumpToPriority logic and conditions.`\n );\n context.aborted = true;\n context.abortReason = `Maximum jump limit exceeded (${context.jumpCount} jumps)`;\n context.jumpToPriority = undefined;\n break;\n }\n\n // Find first handler with priority <= jumpToPriority\n const jumpIndex = context.handlers.findIndex(\n handler => (handler.config.priority || 0) <= context.jumpToPriority!\n );\n\n if (jumpIndex !== -1 && jumpIndex !== i) {\n if (jumpIndex < i) {\n // โš ๏ธ WARNING: Backward jump detected - risk of infinite loop!\n // Only allow backward jumps if handler has condition to prevent infinite loops\n const targetHandler = context.handlers[jumpIndex];\n if (targetHandler && !targetHandler.config.condition) {\n console.warn(\n `[ActionRegister] WARNING: Backward jumpToPriority to handler '${targetHandler.config.id || 'unnamed'}' without condition. ` +\n `This may cause infinite loops! Consider adding a condition to prevent re-execution. ` +\n `Jump count: ${context.jumpCount}/${context.maxJumps || 10}`\n );\n }\n }\n\n // Allow both forward and backward jumps\n i = jumpIndex;\n context.jumpToPriority = undefined;\n } else {\n // No valid jump target found, or jumping to same handler\n context.jumpToPriority = undefined;\n i++;\n }\n } else {\n i++;\n }\n\n } catch (error: unknown) {\n // ๐Ÿ”ง Fix: Handle errors gracefully and continue pipeline execution\n const handlerError = handleExecutionError(error, registration);\n errors.push(handlerError);\n\n // ๐Ÿ”ง Fix: Only fail pipeline for blocking handlers, let non-blocking continue\n if (registration.config.blocking) {\n throw handlerError.error;\n }\n\n // For non-blocking handlers, continue to next handler\n i++;\n }\n }\n \n // ๐Ÿ†• Wait for all non-blocking promises with error collection\n if (nonBlockingPromises.length > 0) {\n await Promise.allSettled(nonBlockingPromises);\n }\n\n // ๐Ÿ”ง Store collected errors in context for ExecutionResult with proper typing\n if (errors.length > 0) {\n // Convert to proper HandlerError format\n const handlerErrors: HandlerError[] = errors.map(err => ({\n handlerId: err.handlerId,\n error: err.error,\n timestamp: err.timestamp,\n severity: 'non-blocking' as const\n }));\n \n // Add to context with proper typing\n context.collectedErrors = handlerErrors;\n }\n}\n\n/**\n * Execute handlers in parallel mode (all at once)\n * \n * Executes all qualifying action handlers simultaneously using Promise.allSettled.\n * Supports both blocking and non-blocking handlers. Blocking handlers can still\n * fail the entire pipeline if they throw errors.\n * \n * @template T - The payload type for the action\n * @template R - The result type for handlers\n * \n * @param context - Pipeline execution context containing handlers and state\n * @param createController - Factory function for creating pipeline controllers\n * \n * @throws {Error} When any blocking handler fails\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/dispatch-patterns#parallel-execution\n * \n * @public\n */\nexport async function executeParallel<T, R = void>(\n context: PipelineContext<T, R>,\n createController: (registration: HandlerRegistration<T, R>, index: number) => PipelineController<T, R>\n): Promise<void> {\n\n /** All handlers are runnable */\n const runnableHandlers = context.handlers;\n\n /** Create promises for all handlers */\n const handlerPromises = runnableHandlers.map(async (registration, _index) => {\n const controller = createController(registration, _index);\n\n try {\n // ๐Ÿ”ง Fix: Check handler condition before execution\n if (registration.config.condition) {\n try {\n const shouldExecute = registration.config.condition(context.payload);\n if (!shouldExecute) {\n // Return a skipped result for conditions that don't pass\n return {\n success: true,\n handlerId: registration.id,\n result: undefined,\n terminated: false,\n skipped: true\n };\n }\n } catch {\n // If condition function throws, skip the handler\n return {\n success: true,\n handlerId: registration.id,\n result: undefined,\n terminated: false,\n skipped: true\n };\n }\n }\n\n (context.executedHandlers ??= []).push(registration);\n const result = registration.handler(context.payload, controller);\n \n const handlerResult = (\n isPromiseLike(result) ? await Promise.resolve(result) : result\n ) as R | undefined;\n \n /** Collect result if handler returned something and pipeline wasn't terminated */\n if (handlerResult !== undefined && !context.terminated) {\n context.results.push(handlerResult);\n }\n \n return { \n success: true, \n handlerId: registration.id, \n result: handlerResult,\n terminated: context.terminated \n };\n \n } catch (error: unknown) {\n // ๐Ÿ†• Consistent error object creation\n const handlerError = handleExecutionError(error, registration);\n \n if (handlerError.severity === 'blocking') {\n throw handlerError.error;\n }\n \n return { success: false, handlerId: registration.id, error: handlerError.error };\n }\n });\n\n const trackedHandlerPromises = context.trackHandlerPromise\n ? handlerPromises.map(promise => context.trackHandlerPromise!(promise))\n : handlerPromises;\n\n /** Wait for all handlers to complete */\n const results = await Promise.allSettled(trackedHandlerPromises);\n \n /** Check for any rejected blocking handlers */\n const failures = results.filter((result, index) => {\n if (result.status === 'rejected') {\n const registration = runnableHandlers[index];\n return registration?.config.blocking ?? false;\n }\n return false;\n });\n\n if (failures.length > 0) {\n const firstFailure = failures[0] as PromiseRejectedResult;\n throw firstFailure.reason;\n }\n\n /** Check if any handler terminated the pipeline */\n const terminatedResults = results.filter(result => \n result.status === 'fulfilled' && result.value.terminated\n );\n \n if (terminatedResults.length > 0) {\n context.terminated = true;\n // In parallel mode, we can't determine which handler's termination result to use,\n // so we use the first one that terminated\n const firstTerminated = terminatedResults[0] as PromiseFulfilledResult<{\n terminated: boolean;\n result: R | undefined;\n }>;\n context.terminationResult = firstTerminated.value.result;\n }\n}\n\n/**\n * Execute handlers in race mode (first to complete wins)\n * \n * Executes all qualifying handlers simultaneously using Promise.race, where\n * the first handler to complete determines the pipeline result. Other handlers\n * continue in the background and remain tracked for lifecycle cleanup; handlers\n * must observe the controller signal for cooperative external cancellation.\n * Useful for scenarios where you want the fastest response from multiple\n * equivalent handlers.\n * \n * @template T - The payload type for the action\n * @template R - The result type for handlers\n * \n * @param context - Pipeline execution context containing handlers and state\n * @param createController - Factory function for creating pipeline controllers\n * \n * @throws {Error} When the winning handler fails and is blocking\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/dispatch-patterns#race-execution\n * \n * @public\n */\nexport async function executeRace<T, R = void>(\n context: PipelineContext<T, R>,\n createController: (registration: HandlerRegistration<T, R>, index: number) => PipelineController<T, R>\n): Promise<void> {\n\n /** All handlers are runnable */\n const runnableHandlers = context.handlers;\n\n if (runnableHandlers.length === 0) {\n return;\n }\n\n /** Create promises for all handlers */\n const handlerPromises = runnableHandlers.map(async (registration, _index) => {\n const controller = createController(registration, _index);\n\n try {\n // ๐Ÿ”ง Fix: Check handler condition before execution\n if (registration.config.condition) {\n try {\n const shouldExecute = registration.config.condition(context.payload);\n if (!shouldExecute) {\n // Return a skipped result for conditions that don't pass\n return {\n success: true,\n handlerId: registration.id,\n registration,\n result: undefined,\n terminated: false,\n skipped: true\n };\n }\n } catch {\n // If condition function throws, skip the handler\n return {\n success: true,\n handlerId: registration.id,\n registration,\n result: undefined,\n terminated: false,\n skipped: true\n };\n }\n }\n\n (context.executedHandlers ??= []).push(registration);\n const result = registration.handler(context.payload, controller);\n \n const handlerResult = (\n isPromiseLike(result) ? await Promise.resolve(result) : result\n ) as R | undefined;\n \n return { \n success: true, \n handlerId: registration.id, \n registration,\n result: handlerResult,\n terminated: context.terminated\n };\n \n } catch (error: unknown) {\n // ๐Ÿ†• Consistent error object creation\n const handlerError = handleExecutionError(error, registration);\n return { success: false, handlerId: registration.id, error: handlerError.error, registration };\n }\n });\n\n const trackedHandlerPromises = context.trackHandlerPromise\n ? handlerPromises.map(promise => context.trackHandlerPromise!(promise))\n : handlerPromises;\n\n /** Race all handlers while retaining every loser for lifecycle draining. */\n const winner = await Promise.race(trackedHandlerPromises);\n\n /** If the winner failed and was blocking, throw the error */\n if (!winner.success && winner.registration?.config.blocking) {\n throw winner.error;\n }\n\n /** Collect result from the winning handler */\n if (winner.success && winner.result !== undefined) {\n context.results.push(winner.result);\n }\n\n /** Check if the winning handler terminated the pipeline */\n if (winner.success && winner.terminated) {\n context.terminated = true;\n context.terminationResult = winner.result;\n }\n}\n","/**\n * @fileoverview Action Guard system for debouncing, throttling and blocking\n * \n * Provides rate limiting and user experience optimization for actions through\n * debouncing (wait for pause) and throttling (limit frequency) mechanisms.\n * Used internally by ActionRegister to control action execution timing.\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/\n */\n\n\n/**\n * Action guard state tracking for debouncing and throttling\n * \n * Tracks timing and execution state for action execution control.\n * Maintains separate state for each action to enable independent\n * rate limiting per action type.\n * \n * @internal\n */\ninterface GuardState {\n /** Timestamp of last successful execution for throttling calculations */\n lastExecuted: number;\n \n /** Active debounce timer - cleared when new debounce requests arrive */\n debounceTimer: NodeJS.Timeout | undefined;\n \n /** Active throttle timer - tracks when throttle period will end */\n throttleTimer: NodeJS.Timeout | undefined;\n \n /** Flag indicating if action is currently in throttled state */\n isThrottled: boolean;\n \n /** Current debounce promise - reused for concurrent calls */\n debouncePromise: Promise<boolean> | undefined;\n \n /** Resolve function for current debounce promise */\n debounceResolve: ((value: boolean) => void) | undefined;\n}\n\n/**\n * Action Guard system for managing action execution timing\n * \n * Provides performance optimization and user experience enhancement through\n * debouncing and throttling mechanisms. Debouncing waits for a pause in calls\n * before executing, while throttling limits execution frequency.\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @example Manual Usage (Advanced)\n * ```typescript\n * const guard = new ActionGuard()\n * \n * // Manual debouncing\n * if (await guard.debounce('search', 300)) {\n * performSearch() // Only executes after 300ms pause\n * }\n * \n * // Manual throttling\n * if (guard.throttle('scroll', 100)) {\n * updateUI() // Max once per 100ms\n * }\n * ```\n * \n * @internal\n */\nexport class ActionGuard {\n private guards = new Map<string, GuardState>();\n private cleanupInterval: NodeJS.Timeout | undefined;\n private readonly autoCleanupEnabled: boolean;\n private readonly maxIdleTime: number = 60000; // 1 minute\n private readonly cleanupIntervalMs: number = 30000; // 30 seconds\n\n // ๐Ÿ”ง Performance optimization: Limit max guards to prevent unbounded growth\n private readonly maxGuards: number = 1000;\n // ๐Ÿ”ง Performance optimization: Track access order for LRU-style eviction\n private accessOrder: string[] = [];\n\n constructor(autoCleanup: boolean = true) {\n this.autoCleanupEnabled = autoCleanup;\n }\n\n /** Start cleanup only after the first guard is used. */\n private ensureAutoCleanup(): void {\n if (this.autoCleanupEnabled && !this.cleanupInterval) {\n this.startAutoCleanup();\n }\n }\n\n /**\n * Start automatic cleanup of idle guard states\n *\n * @internal\n */\n private startAutoCleanup(): void {\n if (this.cleanupInterval) return;\n\n this.cleanupInterval = setInterval(() => {\n this.performCleanup();\n }, this.cleanupIntervalMs);\n\n // A library-owned maintenance timer must not keep a Node.js process alive.\n this.cleanupInterval.unref?.();\n }\n\n private stopAutoCleanup(): void {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = undefined;\n }\n }\n\n /**\n * ๐Ÿ”ง Optimized cleanup with early exit and batched operations\n *\n * @internal\n */\n private performCleanup(): void {\n const guardCount = this.guards.size;\n\n // Early exit if no guards to clean\n if (guardCount === 0) {\n this.stopAutoCleanup();\n return;\n }\n\n const now = Date.now();\n const keysToDelete: string[] = [];\n\n // ๐Ÿ”ง Performance: Only iterate if cleanup is potentially needed\n // Skip cleanup if guard count is low and no guards are old enough\n if (guardCount <= 10) {\n // For small maps, check all entries\n this.guards.forEach((state, key) => {\n const isIdle = now - state.lastExecuted > this.maxIdleTime;\n const hasActiveTimers = state.debounceTimer || state.throttleTimer;\n\n if (isIdle && !hasActiveTimers) {\n keysToDelete.push(key);\n }\n });\n } else {\n // ๐Ÿ”ง Performance: For larger maps, use access order for LRU-style cleanup\n // Only check oldest entries first (more likely to be idle)\n const entriesToCheck = Math.min(this.accessOrder.length, Math.ceil(guardCount / 4));\n\n for (let i = 0; i < entriesToCheck; i++) {\n const key = this.accessOrder[i];\n if (!key) continue;\n\n const state = this.guards.get(key);\n if (!state) {\n // Key no longer exists, will be cleaned from accessOrder\n keysToDelete.push(key);\n continue;\n }\n\n const isIdle = now - state.lastExecuted > this.maxIdleTime;\n const hasActiveTimers = state.debounceTimer || state.throttleTimer;\n\n if (isIdle && !hasActiveTimers) {\n keysToDelete.push(key);\n }\n }\n }\n\n // Batch delete idle guards\n if (keysToDelete.length > 0) {\n keysToDelete.forEach(key => {\n this.guards.delete(key);\n // Remove from access order\n const accessIndex = this.accessOrder.indexOf(key);\n if (accessIndex !== -1) {\n this.accessOrder.splice(accessIndex, 1);\n }\n });\n\n // Optional debug logging for cleanup\n if (typeof process !== 'undefined' && process.env?.DEBUG_CONTEXT_ACTION) {\n console.debug(`[ActionGuard] Cleaned up ${keysToDelete.length} idle guards`);\n }\n\n if (this.guards.size === 0) {\n this.stopAutoCleanup();\n }\n }\n }\n\n /**\n * ๐Ÿ”ง Update access order for LRU tracking\n *\n * @internal\n */\n private updateAccessOrder(key: string): void {\n // Remove existing entry if present\n const existingIndex = this.accessOrder.indexOf(key);\n if (existingIndex !== -1) {\n this.accessOrder.splice(existingIndex, 1);\n }\n // Add to end (most recently accessed)\n this.accessOrder.push(key);\n }\n\n /**\n * ๐Ÿ”ง Evict oldest guards if max limit exceeded\n *\n * @internal\n */\n private evictIfNeeded(): void {\n if (this.guards.size >= this.maxGuards) {\n // Evict oldest 10% of guards\n const evictCount = Math.ceil(this.maxGuards * 0.1);\n const keysToEvict = this.accessOrder.slice(0, evictCount);\n\n keysToEvict.forEach(key => {\n const state = this.guards.get(key);\n // Clean up timers before eviction\n if (state) {\n if (state.debounceTimer) {\n clearTimeout(state.debounceTimer);\n if (state.debounceResolve) {\n state.debounceResolve(false);\n }\n }\n if (state.throttleTimer) {\n clearTimeout(state.throttleTimer);\n }\n }\n this.guards.delete(key);\n });\n\n // Remove from access order\n this.accessOrder = this.accessOrder.slice(evictCount);\n\n if (typeof process !== 'undefined' && process.env?.DEBUG_CONTEXT_ACTION) {\n console.debug(`[ActionGuard] Evicted ${evictCount} oldest guards due to limit`);\n }\n }\n }\n\n /**\n * Apply debouncing to an action\n * \n * Debouncing waits for a specified delay after the last call before allowing\n * execution. Each new call resets the timer. Useful for search inputs, resize\n * handlers, and other high-frequency user interactions.\n * \n * @param actionKey - Unique identifier for the action being debounced\n * @param debounceMs - Delay in milliseconds to wait after the last call\n * \n * @returns Promise resolving to true if execution should proceed, false if cancelled\n * \n * @example Search Input Debouncing\n * ```typescript\n * // Only search after user stops typing for 300ms\n * if (await guard.debounce('userSearch', 300)) {\n * performSearch(query)\n * }\n * ```\n * \n * @internal\n */\n async debounce(actionKey: string, debounceMs: number): Promise<boolean> {\n this.ensureAutoCleanup();\n\n // ๐Ÿ”ง Performance: Check for eviction before adding new guards\n this.evictIfNeeded();\n\n /** Get or create guard state for this action */\n let state = this.guards.get(actionKey);\n if (!state) {\n /** Initialize new guard state with default values */\n state = {\n lastExecuted: 0,\n isThrottled: false,\n debounceTimer: undefined as NodeJS.Timeout | undefined,\n throttleTimer: undefined as NodeJS.Timeout | undefined,\n debouncePromise: undefined as Promise<boolean> | undefined,\n debounceResolve: undefined as ((value: boolean) => void) | undefined,\n };\n this.guards.set(actionKey, state);\n }\n\n // ๐Ÿ”ง Performance: Update LRU access order\n this.updateAccessOrder(actionKey);\n\n /** Clear any existing debounce timer to restart the delay period */\n if (state.debounceTimer) {\n clearTimeout(state.debounceTimer);\n // Resolve previous debounce with false if exists\n if (state.debounceResolve) {\n state.debounceResolve(false);\n state.debounceResolve = undefined as ((value: boolean) => void) | undefined;\n }\n }\n\n /** Create new debounce promise */\n return new Promise<boolean>((resolve) => {\n // Store new resolve function\n state!.debounceResolve = resolve;\n \n // Set new timer\n state!.debounceTimer = setTimeout(() => {\n /** Clean up timer and resolver references */\n state!.debounceTimer = undefined as NodeJS.Timeout | undefined;\n state!.debounceResolve = undefined as ((value: boolean) => void) | undefined;\n /** Update last execution timestamp */\n state!.lastExecuted = Date.now();\n resolve(true);\n }, debounceMs);\n });\n }\n\n /**\n * Apply throttling to an action\n * \n * Throttling limits execution frequency by ensuring a minimum interval between\n * calls. Unlike debouncing, throttling executes immediately on the first call\n * and then blocks subsequent calls until the interval expires.\n * \n * @param actionKey - Unique identifier for the action being throttled\n * @param throttleMs - Minimum interval in milliseconds between executions\n * \n * @returns True if execution should proceed, false if currently throttled\n * \n * @example Scroll Handler Throttling\n * ```typescript\n * // Update scroll position max once per 100ms\n * if (guard.throttle('scrollUpdate', 100)) {\n * updateScrollPosition()\n * }\n * ```\n * \n * @internal\n */\n throttle(actionKey: string, throttleMs: number): boolean {\n this.ensureAutoCleanup();\n\n // ๐Ÿ”ง Performance: Check for eviction before adding new guards\n this.evictIfNeeded();\n\n /** Get or create guard state for this action */\n let state = this.guards.get(actionKey);\n if (!state) {\n /** Initialize new guard state with default values */\n state = {\n lastExecuted: 0,\n isThrottled: false,\n debounceTimer: undefined as NodeJS.Timeout | undefined,\n throttleTimer: undefined as NodeJS.Timeout | undefined,\n debouncePromise: undefined as Promise<boolean> | undefined,\n debounceResolve: undefined as ((value: boolean) => void) | undefined,\n };\n this.guards.set(actionKey, state);\n }\n\n // ๐Ÿ”ง Performance: Update LRU access order\n this.updateAccessOrder(actionKey);\n\n const now = Date.now();\n const timeSinceLastExecution = now - state.lastExecuted;\n\n /** Check if enough time has passed since last execution */\n /** If throttle period has elapsed, allow immediate execution */\n if (timeSinceLastExecution >= throttleMs) {\n /** Update execution timestamp and clear throttled state */\n state.lastExecuted = now;\n state.isThrottled = false;\n \n \n return true;\n }\n\n /** If already in throttled state, don't create duplicate timers */\n /** This prevents timer accumulation and unnecessary processing */\n if (state.isThrottled) {\n return false;\n }\n\n /** Set throttle timer to automatically clear the throttled state */\n /** Calculate remaining time until throttle period expires */\n state.isThrottled = true;\n const remainingTime = throttleMs - timeSinceLastExecution;\n \n /** Create timer to reset throttled state when period expires */\n state.throttleTimer = setTimeout(() => {\n /** Clear throttled state and timer reference */\n state!.isThrottled = false;\n state!.throttleTimer = undefined as NodeJS.Timeout | undefined;\n }, remainingTime);\n\n\n return false;\n }\n\n /**\n * Clear all guard state for a specific action\n * \n * Removes debounce and throttle timers for the specified action,\n * preventing memory leaks and allowing immediate re-execution.\n * \n * @param actionKey - Action identifier to clear guards for\n * \n * @internal\n */\n clearGuards(actionKey: string): void {\n const state = this.guards.get(actionKey);\n if (state) {\n // Clear debounce timer and cancel pending promises to prevent memory leaks\n if (state.debounceTimer) {\n clearTimeout(state.debounceTimer);\n if (state.debounceResolve) {\n state.debounceResolve(false);\n state.debounceResolve = undefined;\n }\n state.debounceTimer = undefined;\n }\n \n // Clear throttle timer to prevent memory leaks\n if (state.throttleTimer) {\n clearTimeout(state.throttleTimer);\n state.throttleTimer = undefined;\n }\n \n \n // Remove guard state from memory\n this.guards.delete(actionKey);\n const accessIndex = this.accessOrder.indexOf(actionKey);\n if (accessIndex !== -1) {\n this.accessOrder.splice(accessIndex, 1);\n }\n\n if (this.guards.size === 0) {\n this.stopAutoCleanup();\n }\n }\n }\n\n /**\n * Clear all guard states for all actions\n * \n * Removes all active debounce and throttle timers, useful for cleanup\n * when shutting down the action system or resetting state.\n * \n * @internal\n */\n clearAll(): void {\n \n /** Iterate through all guard states and clear their timers */\n /** This prevents memory leaks when clearing the entire guard system */\n this.guards.forEach((state) => {\n /** Clear any active debounce timers */\n if (state.debounceTimer) {\n clearTimeout(state.debounceTimer);\n // Cancel waiting debounce calls\n if (state.debounceResolve) {\n state.debounceResolve(false);\n }\n }\n /** Clear any active throttle timers */\n if (state.throttleTimer) {\n clearTimeout(state.throttleTimer);\n }\n });\n \n /** Remove all guard states from memory */\n this.guards.clear();\n this.accessOrder = [];\n this.stopAutoCleanup();\n }\n\n /**\n * Get current guard state for debugging purposes\n * \n * Returns the internal state for a specific action, including timer\n * information and execution timestamps.\n * \n * @param actionKey - Action identifier to inspect\n * @returns Guard state or undefined if no state exists\n * \n * @internal\n */\n getGuardState(actionKey: string): GuardState | undefined {\n return this.guards.get(actionKey);\n }\n\n /**\n * Get all active guard states for debugging purposes\n * \n * Returns a copy of all current guard states, useful for monitoring\n * and debugging rate limiting behavior across all actions.\n * \n * @returns Map of action keys to their guard states\n * \n * @internal\n */\n getAllGuardStates(): Map<string, GuardState> {\n return new Map(this.guards);\n }\n\n /**\n * ๐Ÿ†• Explicit destroy method for comprehensive cleanup\n * \n * Cleans up all timers, promises, and intervals to prevent memory leaks.\n * Should be called when ActionGuard is no longer needed.\n * \n * @internal\n */\n destroy(): void {\n // Clear all existing guards\n this.clearAll();\n }\n\n /**\n * ๐Ÿ†• Get statistics about active guards\n * \n * @returns Statistics about guard usage\n * \n * @internal\n */\n getStats(): { activeGuards: number; withTimers: number } {\n let withTimers = 0;\n this.guards.forEach(state => {\n if (state.debounceTimer || state.throttleTimer) {\n withTimers++;\n }\n });\n \n return {\n activeGuards: this.guards.size,\n withTimers\n };\n }\n}\n","/**\n * ๋™์‹œ์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์œ„ํ•œ ์ž‘์—… ํ ์‹œ์Šคํ…œ\n * \n * ๋ชจ๋“  ์ƒํƒœ ๋ณ€๊ฒฝ ์ž‘์—…์„ ์ง๋ ฌํ™”ํ•˜์—ฌ race condition์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.\n */\n\nexport interface QueuedOperation<T = unknown> {\n id: string;\n operation: () => T | Promise<T>;\n resolve: (value: T) => void;\n reject: (error: unknown) => void;\n priority?: number;\n timestamp: number;\n}\n\nexport interface QueuedOperationHandle<T> {\n promise: Promise<T>;\n /** Cancels only while the operation is still waiting in the queue. */\n cancel(reason?: unknown): boolean;\n}\n\n/**\n * ์ž‘์—… ํ ๊ด€๋ฆฌ์ž\n *\n * ํ•ต์‹ฌ ๊ธฐ๋Šฅ:\n * 1. ์ž‘์—… ์ง๋ ฌํ™” - ๋ชจ๋“  ์ž‘์—…์„ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰\n * 2. ์šฐ์„ ์ˆœ์œ„ ์ง€์› - ์ค‘์š”ํ•œ ์ž‘์—… ์šฐ์„  ์ฒ˜๋ฆฌ\n * 3. ์—๋Ÿฌ ์ฒ˜๋ฆฌ - ๊ฐœ๋ณ„ ์ž‘์—… ์‹คํŒจ๊ฐ€ ์ „์ฒด์— ์˜ํ–ฅ ์ฃผ์ง€ ์•Š์Œ\n * 4. ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ - ์™„๋ฃŒ๋œ ์ž‘์—… ์ž๋™ ์ •๋ฆฌ\n * 5. ๐Ÿ†• ๋™์‹œ์„ฑ ์ œ์–ด - maxConcurrency๋กœ ๋™์‹œ ์‹คํ–‰ ์ œํ•œ\n * 6. ๐Ÿ†• ๋น„๋™๊ธฐ ์ง€์› - Promise.all() ์™„๋ฒฝ ์ง€์›\n * 7. ๐Ÿ†• ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์ฒ˜๋ฆฌ - ํšจ์œจ์ ์ธ ํ ์ฒ˜๋ฆฌ ์‹œ์Šคํ…œ\n */\nexport class OperationQueue {\n private queue: Array<QueuedOperation<unknown>> = [];\n private processingPromise: Promise<void> | null = null;\n private operationCounter = 0;\n \n // ๐Ÿ†• Concurrency control\n private activeOperations = 0;\n private readonly maxConcurrency: number;\n \n constructor(\n private name: string = 'OperationQueue', \n maxConcurrency: number = 1\n ) {\n this.maxConcurrency = Math.max(1, maxConcurrency);\n }\n\n /**\n * ์ž‘์—…์„ ํ์— ์ถ”๊ฐ€ํ•˜๊ณ  ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜\n * \n * @param operation ์‹คํ–‰ํ•  ์ž‘์—…\n * @param priority ์šฐ์„ ์ˆœ์œ„ (๋†’์„์ˆ˜๋ก ๋จผ์ € ์‹คํ–‰)\n * @returns Promise๋กœ ๋ž˜ํ•‘๋œ ์ž‘์—… ๊ฒฐ๊ณผ\n */\n enqueue<T>(operation: () => T | Promise<T>, priority: number = 0): Promise<T> {\n return this.enqueueWithHandle(operation, priority).promise;\n }\n\n /** Enqueue an operation and retain a handle for pre-start cancellation. */\n enqueueWithHandle<T>(\n operation: () => T | Promise<T>,\n priority: number = 0\n ): QueuedOperationHandle<T> {\n let queuedOperation!: QueuedOperation<T>;\n const promise = new Promise<T>((resolve, reject) => {\n queuedOperation = {\n id: `${this.name}-${++this.operationCounter}`,\n operation,\n resolve,\n reject,\n priority,\n timestamp: Date.now()\n };\n\n\n // ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ์‚ฝ์ž… ์œ„์น˜ ๊ฒฐ์ • (๋†’์€ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ์•ž์ชฝ)\n let insertIndex = this.queue.length;\n for (let i = 0; i < this.queue.length; i++) {\n const item = this.queue[i];\n // ํ˜„์žฌ ์•„์ดํ…œ์˜ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ์ƒˆ ์•„์ดํ…œ๋ณด๋‹ค ๋‚ฎ์œผ๋ฉด, ์ƒˆ ์•„์ดํ…œ์„ ์•ž์— ์‚ฝ์ž…\n if (item && (item.priority || 0) < priority) {\n insertIndex = i;\n break;\n }\n }\n\n this.queue.splice(insertIndex, 0, queuedOperation as unknown as QueuedOperation<unknown>);\n\n // ํ ์ฒ˜๋ฆฌ ์‹œ์ž‘ (์ด๋ฏธ ์ฒ˜๋ฆฌ ์ค‘์ด๋ฉด ๋ฌด์‹œ๋จ)\n if (this.processingPromise) {\n // ์ด๋ฏธ ์ฒ˜๋ฆฌ ์ค‘์ด๋ผ๋ฉด, ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค์—๊ฒŒ ์ƒˆ๋กœ์šด ์ž‘์—…์ด ์ถ”๊ฐ€๋˜์—ˆ์Œ์„ ์•Œ๋ฆผ\n this.notifyNewOperation();\n }\n this.processQueue();\n });\n\n return {\n promise,\n cancel: (reason = new Error('Queue operation cancelled')) => {\n const index = this.queue.indexOf(queuedOperation as unknown as QueuedOperation<unknown>);\n if (index === -1) return false;\n\n this.queue.splice(index, 1);\n queuedOperation.reject(reason);\n this.notifyNewOperation();\n return true;\n },\n };\n }\n\n /**\n * ๐Ÿ†• ํ ์ฒ˜๋ฆฌ ๋ฉ”์ธ ๋กœ์ง - ๋™์‹œ์„ฑ ์ œ์–ด ๋ฐ ๋น„๋™๊ธฐ ์ง€์›\n *\n * ์ฃผ์š” ํŠน์ง•:\n * - maxConcurrency์— ๋”ฐ๋ผ ๋™์‹œ ์‹คํ–‰ ์ž‘์—… ์ˆ˜๋ฅผ ์ œํ•œํ•˜์—ฌ ๋™์‹œ์„ฑ ๋ฌธ์ œ ๋ฐฉ์ง€\n * - Promise.all() ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ์™„๋ฒฝํ•œ ์ˆœ์ฐจ์  ์‹คํ–‰ ๋ณด์žฅ\n * - ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์•Œ๋ฆผ ์‹œ์Šคํ…œ์œผ๋กœ ํšจ์œจ์ ์ธ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ\n * - ์ž‘์—… ์™„๋ฃŒ ์‹œ ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค์—๊ฒŒ ์ž๋™ ์•Œ๋ฆผ\n */\n private async processQueue(): Promise<void> {\n if (this.processingPromise) {\n // Wait for current processing to complete, then check if we need to process more\n await this.processingPromise;\n // After waiting, check if there are new items to process\n if (this.queue.length > 0 && !this.processingPromise) {\n return this.processQueue();\n }\n return;\n }\n\n this.processingPromise = this._doProcess();\n try {\n await this.processingPromise;\n } finally {\n this.processingPromise = null;\n }\n }\n \n private async _doProcess(): Promise<void> {\n while (this.queue.length > 0 || this.activeOperations > 0) {\n // ๐Ÿ†• ๋™์‹œ์„ฑ ์ œ์–ด: maxConcurrency ๋งŒํผ๋งŒ ๋™์‹œ ์‹คํ–‰\n while (this.queue.length > 0 && this.activeOperations < this.maxConcurrency) {\n const operation = this.queue.shift()!;\n\n // ๐Ÿ†• ๋น„๋™๊ธฐ ์ž‘์—… ์‹คํ–‰ (await๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ - ๋ณ‘๋ ฌ ์‹คํ–‰์„ ์œ„ํ•ด)\n this.startOperation(operation);\n }\n\n // ๐Ÿ†• ์‹คํ–‰ ์ค‘์ธ ์ž‘์—…์ด ์žˆ์œผ๋ฉด ํ•˜๋‚˜๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ\n if (this.activeOperations > 0) {\n await this.waitForAnyOperation();\n }\n }\n }\n\n /**\n * ๐Ÿ†• ๊ฐœ๋ณ„ ์ž‘์—…์„ ์‹œ์ž‘ํ•˜๊ณ  ์™„๋ฃŒ๋ฅผ ์ถ”์ \n */\n private startOperation(operation: QueuedOperation<unknown>): void {\n this.activeOperations++;\n\n // ๋น„๋™๊ธฐ๋กœ ์ž‘์—… ์‹คํ–‰\n this.executeOperation(operation)\n .finally(() => {\n this.activeOperations--;\n\n // ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค์—๊ฒŒ ์‹ ํ˜ธ ๋ณด๋‚ด๊ธฐ\n this.notifyOperationComplete();\n });\n }\n\n private pendingResolvers: Array<() => void> = [];\n\n /**\n * ๐Ÿ†• ํ•˜๋‚˜์˜ ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•˜๊ฑฐ๋‚˜ ์ƒˆ๋กœ์šด ์ž‘์—…์ด ์ถ”๊ฐ€๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ\n */\n private waitForAnyOperation(): Promise<void> {\n return new Promise<void>((resolve) => {\n this.pendingResolvers.push(resolve);\n });\n }\n\n /**\n * ๐Ÿ†• ์ž‘์—… ์™„๋ฃŒ ์‹ ํ˜ธ - ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋“ค์—๊ฒŒ ์•Œ๋ฆผ\n */\n private notifyOperationComplete(): void {\n // ๋Œ€๊ธฐ ์ค‘์ธ ๋ชจ๋“  ๋ฆฌ์กธ๋ฒ„๋ฅผ ๊นจ์šฐ๊ธฐ\n const resolvers = this.pendingResolvers.splice(0);\n resolvers.forEach(resolve => resolve());\n }\n\n /**\n * ๐Ÿ†• ์ƒˆ๋กœ์šด ์ž‘์—… ์ถ”๊ฐ€ ์‹ ํ˜ธ - processQueue์—์„œ ํ˜ธ์ถœ\n */\n private notifyNewOperation(): void {\n // ์ƒˆ๋กœ์šด ์ž‘์—…์ด ์ถ”๊ฐ€๋˜์—ˆ์œผ๋ฏ€๋กœ ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊นจ์›Œ์„œ ๋‹ค์‹œ ํ™•์ธํ•˜๋„๋ก ํ•จ\n this.notifyOperationComplete();\n }\n \n /**\n * ๐Ÿ†• ๊ฐœ๋ณ„ ์ž‘์—… ์‹คํ–‰ ๋กœ์ง\n */\n private async executeOperation(operation: QueuedOperation<unknown>): Promise<void> {\n try {\n // ์ž‘์—… ์‹คํ–‰ (๋™๊ธฐ/๋น„๋™๊ธฐ ๋ชจ๋‘ ์ง€์›)\n const result = await Promise.resolve(operation.operation());\n operation.resolve(result);\n } catch (error) {\n // ๊ฐœ๋ณ„ ์ž‘์—… ์‹คํŒจ๋Š” ์ „์ฒด ํ์— ์˜ํ–ฅ ์ฃผ์ง€ ์•Š์Œ\n operation.reject(error);\n }\n }\n\n /**\n * ๐Ÿ†• ํ˜„์žฌ ํ ์ƒํƒœ ์กฐํšŒ (๋””๋ฒ„๊น…์šฉ) - ๋™์‹œ์„ฑ ์ •๋ณด ํฌํ•จ\n */\n getQueueInfo() {\n return {\n name: this.name,\n queueLength: this.queue.length,\n isProcessing: Boolean(this.processingPromise),\n activeOperations: this.activeOperations,\n maxConcurrency: this.maxConcurrency,\n operations: this.queue.map(op => ({\n id: op.id,\n priority: op.priority,\n timestamp: op.timestamp\n }))\n };\n }\n \n /**\n * ๐Ÿ†• ๋™์‹œ์„ฑ ์„ค์ • ์กฐํšŒ\n */\n getConcurrencyInfo() {\n return {\n maxConcurrency: this.maxConcurrency,\n activeOperations: this.activeOperations,\n availableSlots: this.maxConcurrency - this.activeOperations,\n queuedOperations: this.queue.length,\n efficiency: this.activeOperations / this.maxConcurrency\n };\n }\n\n /**\n * ํ ๋น„์šฐ๊ธฐ (ํ…Œ์ŠคํŠธ์šฉ)\n */\n clear(options: { rejectPending?: boolean; reason?: unknown } = {}): void {\n const rejectPending = options.rejectPending ?? true;\n const reason = options.reason ?? new Error('Queue cleared');\n\n // Settle queued operations so callers are never left with pending promises.\n this.queue.forEach(operation => {\n if (rejectPending) {\n operation.reject(reason);\n } else {\n operation.resolve(undefined as never);\n }\n });\n\n this.queue = [];\n\n // ๋Œ€๊ธฐ ์ค‘์ธ ๋ฆฌ์กธ๋ฒ„๋“ค๋„ ์ •๋ฆฌ\n const resolvers = this.pendingResolvers.splice(0);\n resolvers.forEach(resolve => resolve());\n }\n\n /**\n * ํ ํฌ๊ธฐ ์กฐํšŒ\n */\n get size(): number {\n return this.queue.length;\n }\n\n /**\n * ์ฒ˜๋ฆฌ ์ค‘ ์—ฌ๋ถ€ ์กฐํšŒ \n */\n get processing(): boolean {\n return Boolean(this.processingPromise);\n }\n}\n","/**\n * Action Validation Errors\n *\n * Zod ์Šคํ‚ค๋งˆ ๊ธฐ๋ฐ˜ ๊ฒ€์ฆ ์‹คํŒจ ์‹œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ ํด๋ž˜์Šค๋“ค\n */\n\n// ============================================\n// Zod Error Compatible Types\n// ============================================\n\n/**\n * Zod Issue interface (loose typing for Zod 4 compatibility)\n */\nexport interface ZodIssueLike {\n message: string;\n path: readonly (string | number | symbol)[];\n code: string;\n}\n\n/**\n * Zod Error interface (loose typing for Zod 4 compatibility)\n * Accepts any object with these minimum required properties\n */\nexport interface ZodErrorLike {\n message: string;\n issues: readonly ZodIssueLike[];\n format?: () => unknown;\n flatten?: () => unknown;\n}\n\n// ============================================\n// Action Validation Error\n// ============================================\n\n/**\n * Action payload ๊ฒ€์ฆ ์‹คํŒจ ์—๋Ÿฌ\n *\n * dispatch ์‹œ Zod ์Šคํ‚ค๋งˆ ๊ฒ€์ฆ์ด ์‹คํŒจํ•˜๋ฉด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.\n * (validationMode๊ฐ€ 'strict'์ผ ๋•Œ๋งŒ throw)\n *\n * @example\n * ```typescript\n * try {\n * dispatch('updateUser', { id: '', name: 'John' });\n * } catch (error) {\n * if (error instanceof ActionValidationError) {\n * console.log('Action:', error.action);\n * console.log('Issues:', error.issues);\n * console.log('Formatted:', error.formattedErrors);\n * }\n * }\n * ```\n */\nexport class ActionValidationError extends Error {\n /** ์—๋Ÿฌ ์ด๋ฆ„ */\n override name = 'ActionValidationError';\n\n /** ์›๋ณธ Zod ์—๋Ÿฌ ๊ฐ์ฒด */\n public readonly zodError: unknown;\n\n /**\n * @param action - ๊ฒ€์ฆ ์‹คํŒจํ•œ action ์ด๋ฆ„\n * @param zodError - Zod ๊ฒ€์ฆ ์—๋Ÿฌ ๊ฐ์ฒด (ZodError compatible)\n */\n constructor(action: string, zodError: unknown) {\n const errorMessage =\n zodError && typeof zodError === 'object' && 'message' in zodError\n ? String((zodError as { message: unknown }).message)\n : 'Validation failed';\n\n const message = `Action \"${action}\" payload validation failed: ${errorMessage}`;\n super(message);\n\n this.action = action;\n this.zodError = zodError;\n\n // Error ์ƒ์† ์‹œ prototype chain ๋ณต์› (ES5 ํ˜ธํ™˜)\n Object.setPrototypeOf(this, ActionValidationError.prototype);\n }\n\n /** ๊ฒ€์ฆ ์‹คํŒจํ•œ action ์ด๋ฆ„ */\n public readonly action: string;\n\n /**\n * Zod ๊ฒ€์ฆ ์ด์Šˆ ๋ชฉ๋ก\n */\n get issues(): readonly ZodIssueLike[] {\n if (\n this.zodError &&\n typeof this.zodError === 'object' &&\n 'issues' in this.zodError &&\n Array.isArray((this.zodError as { issues: unknown }).issues)\n ) {\n return (this.zodError as { issues: readonly ZodIssueLike[] }).issues;\n }\n return [];\n }\n\n /**\n * ํฌ๋งท๋œ ์—๋Ÿฌ ๊ฐ์ฒด (ํ•„๋“œ๋ณ„ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€)\n */\n get formattedErrors(): unknown {\n if (\n this.zodError &&\n typeof this.zodError === 'object' &&\n 'format' in this.zodError &&\n typeof (this.zodError as { format: unknown }).format === 'function'\n ) {\n return (this.zodError as { format: () => unknown }).format();\n }\n return {};\n }\n\n /**\n * ํ”Œ๋žซ ์—๋Ÿฌ ๋งต (ํ•„๋“œ๋ช… โ†’ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋ฐฐ์—ด)\n */\n get flattenedErrors(): unknown {\n if (\n this.zodError &&\n typeof this.zodError === 'object' &&\n 'flatten' in this.zodError &&\n typeof (this.zodError as { flatten: unknown }).flatten === 'function'\n ) {\n return (this.zodError as { flatten: () => unknown }).flatten();\n }\n return { fieldErrors: {}, formErrors: [] };\n }\n\n /**\n * ์ฒซ ๋ฒˆ์งธ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€\n */\n get firstError(): string | undefined {\n return this.issues[0]?.message;\n }\n\n /**\n * ์—๋Ÿฌ ๋ฐœ์ƒ ํ•„๋“œ ๊ฒฝ๋กœ ๋ชฉ๋ก\n */\n get errorPaths(): string[] {\n return this.issues.map((issue) =>\n issue.path.map((p) => String(p)).join('.')\n );\n }\n\n /**\n * JSON ์ง๋ ฌํ™”\n */\n toJSON() {\n return {\n name: this.name,\n action: this.action,\n message: this.message,\n issues: this.issues,\n };\n }\n}\n\n/**\n * Raised when a dispatch exceeds its configured wall-clock timeout.\n * The underlying handler receives an aborted controller signal and the internal\n * queue keeps draining it safely, while the caller is released immediately with\n * this error.\n */\nexport class ActionTimeoutError extends Error {\n override name = 'ActionTimeoutError';\n\n constructor(\n public readonly action: string,\n public readonly timeout: number\n ) {\n super(`Action \"${action}\" timed out after ${timeout}ms`);\n Object.setPrototypeOf(this, ActionTimeoutError.prototype);\n }\n}\n\n/** Raised when work is submitted after an ActionRegister begins shutdown. */\nexport class ActionRegisterDestroyedError extends Error {\n override name = 'ActionRegisterDestroyedError';\n\n constructor(\n public readonly registerName: string,\n public readonly state: 'closing' | 'destroyed'\n ) {\n super(`ActionRegister \"${registerName}\" is ${state} and cannot accept new work`);\n Object.setPrototypeOf(this, ActionRegisterDestroyedError.prototype);\n }\n}\n\n// ============================================\n// Type Guard\n// ============================================\n\n/**\n * ActionValidationError ํƒ€์ž… ๊ฐ€๋“œ\n */\nexport function isActionValidationError(\n error: unknown\n): error is ActionValidationError {\n return error instanceof ActionValidationError;\n}\n\n/** ActionTimeoutError type guard. */\nexport function isActionTimeoutError(\n error: unknown\n): error is ActionTimeoutError {\n return error instanceof ActionTimeoutError;\n}\n\n/** ActionRegisterDestroyedError type guard. */\nexport function isActionRegisterDestroyedError(\n error: unknown\n): error is ActionRegisterDestroyedError {\n return error instanceof ActionRegisterDestroyedError;\n}\n","// biome-ignore-all lint/suspicious/noExplicitAny: heterogeneous runtime pipeline storage.\n\nimport {\n ActionPayloadMap,\n ActionHandler,\n HandlerConfig,\n HandlerRegistration,\n PipelineContext,\n PipelineController,\n ActionRegisterConfig,\n UnregisterFunction,\n ExecutionMode,\n ExecutionResult,\n ActionRegistryInfo,\n ActionHandlerStats,\n DispatchOptions,\n HandlerError,\n} from './types.js';\nimport { executeSequential, executeParallel, executeRace } from './execution-modes.js';\nimport { ActionGuard } from './action-guard.js';\nimport { OperationQueue } from './concurrency/OperationQueue.js';\nimport {\n ActionRegisterDestroyedError,\n ActionTimeoutError,\n ActionValidationError,\n} from './errors.js';\n\ntype DispatchHandlerPromises = Set<Promise<unknown>>;\n\n/**\n * Action Register for managing action handlers with priority-based execution\n * \n * Central action registration and dispatch system providing type-safe action pipeline management.\n * Supports sequential, parallel, and race execution modes with advanced handler filtering,\n * throttling, debouncing, and comprehensive result collection.\n * \n * @template TActionMap - Action payload mapping interface extending ActionPayloadMap\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/\n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/register-delegation\n * \n * @public\n */\n\nexport class ActionRegister<\n T extends ActionPayloadMap = Record<string, unknown>\n> {\n private pipelines = new Map<keyof T, Array<HandlerRegistration<any, any>>>();\n private readonly actionGuard: ActionGuard;\n private executionMode: ExecutionMode = 'sequential';\n private actionExecutionModes = new Map<keyof T, ExecutionMode>();\n \n // ๐Ÿ†• Advanced unregister function management system\n private unregisterFunctions = new Map<string, UnregisterFunction>();\n\n // ๐Ÿ”ง Fix: Track last registration timestamps for getActionStats\n private lastRegisteredTimestamps = new Map<keyof T, Date>();\n \n public readonly name: string;\n private readonly registryConfig: ActionRegisterConfig['registry'];\n\n // ๐Ÿ†• Performance optimizations\n private readonly isDebugMode: boolean;\n private readonly maxHandlersPerAction: number;\n\n // ๐Ÿ†• ๋™์‹œ์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์œ„ํ•œ ํ ์‹œ์Šคํ…œ (conditional)\n private dispatchQueue?: OperationQueue;\n\n // ๐Ÿ”ง Performance optimization: Fast handler ID generation counter\n private handlerIdCounter = 0;\n\n // ๐Ÿ”ง Performance optimization: PipelineController pool for object reuse\n private controllerPool: PipelineController<any, any>[] = [];\n\n private lifecycleState: 'active' | 'closing' | 'destroyed' = 'active';\n private readonly lifecycleController = new AbortController();\n private readonly activeDispatches = new Set<Promise<unknown>>();\n private readonly activeHandlerPromises = new Set<Promise<unknown>>();\n private destroyAsyncPromise: Promise<void> | undefined;\n private dispatchConstructionDepth = 0;\n\n // ๐Ÿ”ง Performance optimization: Cached Proxy instances for actions getters\n private _actionsProxy?: {\n [K in keyof T]: T[K] extends void\n ? (\n payload?: undefined,\n options?: DispatchOptions\n ) => Promise<void>\n : (payload: T[K], options?: DispatchOptions) => Promise<void>\n };\n private _actionsWithResultProxy?: {\n [K in keyof T]: T[K] extends void\n ? (\n payload?: undefined,\n options?: DispatchOptions\n ) => Promise<ExecutionResult<any>>\n : (payload: T[K], options?: DispatchOptions) => Promise<ExecutionResult<any>>\n };\n\n constructor(config: ActionRegisterConfig = {}) {\n this.name = config.name || 'ActionRegister';\n this.registryConfig = config.registry;\n this.maxHandlersPerAction = config.registry?.maxHandlersPerAction ?? 1000;\n \n // ๐Ÿ†• Environment variable check cached (performance optimization)\n this.isDebugMode = Boolean(\n this.registryConfig?.debug && \n process.env.NODE_ENV === 'development'\n );\n \n // Guard creation with improved cleanup handling\n this.actionGuard = new ActionGuard(this.registryConfig?.autoCleanup !== false);\n \n // ๐Ÿ†• Conditional queue system initialization\n if (config.registry?.useConcurrencyQueue !== false) {\n this.dispatchQueue = new OperationQueue(`${this.name}-Dispatch`);\n }\n \n if (this.registryConfig?.defaultExecutionMode) {\n this.executionMode = this.registryConfig.defaultExecutionMode;\n }\n \n this.log('ActionRegister initialized', {\n defaultExecutionMode: this.executionMode,\n autoCleanup: this.registryConfig?.autoCleanup !== false,\n concurrencyQueue: Boolean(this.dispatchQueue),\n debugMode: this.isDebugMode\n });\n }\n\n /**\n * ๐Ÿ†• Action-based dispatcher\n *\n * Provides function-based access to actions for more convenient dispatching.\n * Each action becomes a callable function that can be invoked directly.\n *\n * @example\n * ```typescript\n * interface MyActions extends ActionPayloadMap {\n * userLogin: { userId: string; email: string };\n * resetApp: void;\n * }\n * \n * const registry = new ActionRegister<MyActions>();\n * \n * // Function-based dispatching\n * await registry.actions.userLogin({ userId: '123', email: 'test@example.com' });\n * await registry.actions.resetApp();\n * await registry.actions.resetApp(undefined, { debounce: 100 });\n * ```\n * \n * @public\n */\n get actions(): {\n [K in keyof T]: T[K] extends void\n ? (\n payload?: undefined,\n options?: DispatchOptions\n ) => Promise<void>\n : (payload: T[K], options?: DispatchOptions) => Promise<void>\n } {\n // ๐Ÿ”ง Performance: Return cached Proxy instance\n if (!this._actionsProxy) {\n this._actionsProxy = new Proxy({} as any, {\n get: (_target, prop: string | symbol) => {\n // Type guard to ensure prop is a valid action key\n const actionKey = prop as keyof T;\n if (typeof prop === 'string' && this.pipelines.has(actionKey)) {\n return (\n payload?: T[typeof actionKey],\n options?: DispatchOptions\n ) => {\n return this.dispatch(\n actionKey,\n payload as T[typeof actionKey],\n options\n );\n };\n }\n return undefined;\n }\n });\n }\n return this._actionsProxy!;\n }\n\n /**\n * Actions-based dispatching with result collection\n * \n * Provides a function-based interface for dispatching actions with detailed execution results.\n * Each registered action becomes a callable function that returns ExecutionResult.\n * \n * @example\n * ```typescript\n * // Actions with payload\n * const result = await registry.actionsWithResult.userLogin({ userId: '123', email: 'user@example.com' });\n * \n * // Actions without payload\n * const result = await registry.actionsWithResult.userLogout();\n * const debouncedResult = await registry.actionsWithResult.userLogout(\n * undefined,\n * { debounce: 100 }\n * );\n * \n * // With options\n * const result = await registry.actionsWithResult.processData(\n * { data: { name: 'test' }, type: 'json' },\n * { executionMode: 'parallel' }\n * );\n * ```\n * \n * @returns Proxy object with action functions that return ExecutionResult\n */\n get actionsWithResult(): {\n [K in keyof T]: T[K] extends void\n ? (\n payload?: undefined,\n options?: DispatchOptions\n ) => Promise<ExecutionResult<any>>\n : (payload: T[K], options?: DispatchOptions) => Promise<ExecutionResult<any>>\n } {\n // ๐Ÿ”ง Performance: Return cached Proxy instance\n if (!this._actionsWithResultProxy) {\n this._actionsWithResultProxy = new Proxy({} as any, {\n get: (_target, prop: string | symbol) => {\n // Type guard to ensure prop is a valid action key\n const actionKey = prop as keyof T;\n if (typeof prop === 'string' && this.pipelines.has(actionKey)) {\n return (\n payload?: T[typeof actionKey],\n options?: DispatchOptions\n ) => {\n return this.dispatchWithResult(actionKey, payload, options);\n };\n }\n return undefined;\n }\n });\n }\n return this._actionsWithResultProxy!;\n }\n\n /**\n * Register an action handler with optional configuration\n * \n * @param action - The action type to register handler for\n * @param handler - The handler function to execute\n * @param config - Optional handler configuration including priority, tags, etc.\n * \n * @returns Unregister function to remove this handler\n * \n * @throws {Error} When maximum handlers limit is reached\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n register<K extends keyof T, R = void>(\n action: K,\n handler: ActionHandler<T[K], R>,\n config: HandlerConfig<T[K]> = {}\n ): UnregisterFunction {\n this.assertAcceptingWork();\n // ๐Ÿ”„ ์ž„์‹œ๋กœ ๊ธฐ์กด ๊ตฌํ˜„ ์œ ์ง€ํ•˜๋˜ ๊ฐœ์„ ๋œ ๋ฐฉ์‹ ์ ์šฉ\n // ๋™๊ธฐ์  API๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ๋‚ด๋ถ€์ ์œผ๋กœ๋งŒ ๋™์‹œ์„ฑ ๋ณดํ˜ธ\n \n // ๐Ÿ†• Optimized handler ID generation\n const handlerId = config.id || this.generateHandlerId(action);\n \n // ๐Ÿ†• Direct synchronous registration\n const unregisterFn = this._performRegistrationSync(action, handler, config, handlerId);\n \n return unregisterFn;\n }\n\n /**\n * ๐Ÿ†• Unified logging method with cached debug mode check\n */\n private log(message: string, data?: unknown, level: 'log' | 'warn' | 'error' = 'log') {\n if (this.isDebugMode) {\n const timestamp = new Date().toISOString();\n console[level](`๐ŸŽฏ [${timestamp}] [${this.name}] ${message}`, data || '');\n }\n }\n\n private assertAcceptingWork(): void {\n if (this.lifecycleState !== 'active') {\n throw new ActionRegisterDestroyedError(this.name, this.lifecycleState);\n }\n }\n\n private rejectedLifecyclePromise<R>(): Promise<R> {\n const error = new ActionRegisterDestroyedError(\n this.name,\n this.lifecycleState === 'active' ? 'destroyed' : this.lifecycleState\n );\n const rejected = Promise.reject<R>(error);\n void rejected.catch(() => {});\n return rejected;\n }\n\n /**\n * ๐Ÿ”ง Generate unique handler ID using optimized counter-based approach\n */\n private generateHandlerId<K extends keyof T>(action: K): string {\n // ๐Ÿ”ง Performance: Use simple counter instead of crypto.randomUUID()\n // This is safe for single-process apps and ~70% faster\n return `${String(action)}_${this.name}_${++this.handlerIdCounter}`;\n }\n\n /**\n * ๐Ÿ”ง Create and merge AbortSignal instances with proper cleanup\n * \n * @param options Dispatch options containing signal and autoAbort configuration\n * @returns [effectiveSignal, autoAbortController, cleanupFunction]\n */\n private createAbortSignal(options?: DispatchOptions): [\n AbortSignal | undefined, \n AbortController | undefined, \n () => void\n ] {\n const signals: AbortSignal[] = [];\n const cleanups: (() => void)[] = [];\n let autoAbortController: AbortController | undefined;\n\n // Add existing signal if provided\n if (options?.signal) {\n signals.push(options.signal);\n }\n\n // Create auto-abort controller if enabled\n if (options?.autoAbort?.enabled) {\n autoAbortController = new AbortController();\n signals.push(autoAbortController.signal);\n }\n\n // No signals to merge\n if (signals.length === 0) {\n return [undefined, autoAbortController, () => {}];\n }\n\n // Single signal - no merge needed\n if (signals.length === 1) {\n return [signals[0], autoAbortController, () => cleanups.forEach(c => c())];\n }\n\n // Multiple signals - use AbortSignal.any() if available, fallback to manual merge\n let effectiveSignal: AbortSignal;\n \n if (typeof (AbortSignal as any).any === 'function') {\n // Modern browsers with AbortSignal.any()\n effectiveSignal = (AbortSignal as any).any(signals);\n } else {\n // Fallback: Create controller and link all signals\n const mergedController = new AbortController();\n effectiveSignal = mergedController.signal;\n \n signals.forEach(signal => {\n if (signal.aborted) {\n mergedController.abort();\n } else {\n const abortHandler = () => mergedController.abort();\n signal.addEventListener('abort', abortHandler, { once: true });\n cleanups.push(() => signal.removeEventListener('abort', abortHandler));\n }\n });\n }\n\n const cleanup = () => {\n cleanups.forEach(c => {\n try {\n c();\n } catch (error) {\n this.log('Cleanup error during AbortSignal cleanup', error, 'warn');\n }\n });\n };\n\n return [effectiveSignal, autoAbortController, cleanup];\n }\n\n /**\n * ๐Ÿ†• Perform synchronous handler registration\n */\n private _performRegistrationSync<K extends keyof T, R = void>(\n action: K,\n handler: ActionHandler<T[K], R>,\n config: HandlerConfig<T[K]>,\n handlerId: string\n ): UnregisterFunction {\n // Create handler registration with defaults\n const registration: HandlerRegistration<T[K], R> = {\n handler,\n config: {\n priority: config.priority ?? 0,\n id: handlerId,\n blocking: config.blocking ?? false,\n once: config.once ?? false,\n debounce: config.debounce ?? undefined,\n throttle: config.throttle ?? undefined,\n replaceExisting: config.replaceExisting ?? true, // ๐Ÿ”ง Fix: Default to true for backward compatibility\n cleanup: config.cleanup, // ๐Ÿ”ง Preserve cleanup function from config\n condition: config.condition, // ๐Ÿ”ง Fix: Preserve condition function from config\n } as Required<HandlerConfig<T[K]>>,\n id: handlerId,\n };\n \n // Initialize pipeline if it doesn't exist\n if (!this.pipelines.has(action)) {\n this.pipelines.set(action, []);\n }\n\n const pipeline = this.pipelines.get(action)!;\n \n // Check handler limit\n if (pipeline.length >= this.maxHandlersPerAction) {\n console.warn(`Handler limit (${this.maxHandlersPerAction}) reached for action \"${String(action)}\". Registration ignored.`);\n return () => {}; // No-op unregister\n }\n const existingIndex = pipeline.findIndex(reg => reg.id === handlerId);\n\n // ๐Ÿ†• Enhanced duplicate ID handling with replaceExisting support and cleanup\n if (existingIndex !== -1) {\n const existing = pipeline[existingIndex];\n const existingUnregister = this.unregisterFunctions.get(handlerId);\n \n if (registration.config.replaceExisting) {\n // ๐Ÿ”ง Fix: Clean up existing handler properly without removing from pipeline\n\n // Call cleanup if available on the old handler\n if (existing?.config.cleanup && typeof existing.config.cleanup === 'function') {\n try {\n existing.config.cleanup();\n } catch (cleanupError) {\n this.log(`Cleanup error for replaced handler: ${String(action)}`, cleanupError, 'warn');\n }\n }\n\n // Clean up existing unregister function\n if (existingUnregister) {\n this.unregisterFunctions.delete(handlerId);\n }\n\n // Replace existing handler directly in pipeline\n pipeline[existingIndex] = registration;\n pipeline.sort((a, b) => b.config.priority - a.config.priority);\n // Cache disabled\n\n // ๐Ÿ”ง Fix: Update last registered timestamp when replacing\n this.lastRegisteredTimestamps.set(action, new Date());\n\n // Create new unregister function and store it\n const newUnregister = this.createUnregisterFunction(action, handlerId, registration);\n this.unregisterFunctions.set(handlerId, newUnregister);\n \n this.log(`Handler replaced: ${String(action)}`, {\n handlerId,\n priority: config.priority,\n totalHandlers: pipeline.length,\n hadExistingUnregister: Boolean(existingUnregister)\n });\n \n return newUnregister;\n } else {\n // Return existing unregister function or create a new one\n // At this point, existing is guaranteed to be defined because we're in the duplicate handler block\n if (!existing) {\n throw new Error('Internal error: existing handler should be defined in duplicate handler block');\n }\n \n this.log(`Handler duplicate ignored, returning existing unregister: ${String(action)}`, {\n handlerId,\n existingPriority: existing.config.priority,\n newPriority: config.priority,\n existingBlocking: existing.config.blocking,\n newBlocking: config.blocking,\n note: 'Use replaceExisting:true to replace'\n }, 'warn');\n \n if (existingUnregister) {\n return existingUnregister;\n } else {\n // Create new unregister function if somehow missing\n const newUnregister = this.createUnregisterFunction(action, handlerId, existing);\n this.unregisterFunctions.set(handlerId, newUnregister);\n return newUnregister;\n }\n }\n }\n \n // Add handler to pipeline\n pipeline.push(registration);\n pipeline.sort((a, b) => b.config.priority - a.config.priority);\n // Cache disabled\n\n // ๐Ÿ”ง Fix: Update last registered timestamp\n this.lastRegisteredTimestamps.set(action, new Date());\n\n // Create and store unregister function\n const unregister = this.createUnregisterFunction(action, handlerId, registration);\n this.unregisterFunctions.set(handlerId, unregister);\n\n this.log(`Handler registered: ${String(action)}`, {\n handlerId,\n priority: config.priority,\n totalHandlers: pipeline.length\n });\n\n return unregister;\n }\n\n\n /**\n * Dispatch an action with optional execution options\n * \n * @param action - The action type to dispatch\n * @param payload - The action payload data\n * @param options - Optional dispatch options (execution mode, filters, etc.)\n * \n * @returns Promise that resolves when all handlers complete\n * \n * @throws {Error} When action dispatching fails\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n // Overload for actions with payload (more specific)\n dispatch<K extends keyof T>(\n action: K,\n payload: T[K],\n options?: DispatchOptions\n ): Promise<void>;\n \n // Overload for actions without payload\n dispatch<K extends keyof T>(\n action: K,\n payload?: undefined,\n options?: DispatchOptions\n ): Promise<void>;\n \n // Implementation (least specific)\n dispatch<K extends keyof T>(\n action: K,\n payload?: T[K],\n options?: DispatchOptions\n ): Promise<void> {\n if (this.lifecycleState !== 'active') {\n return this.rejectedLifecyclePromise<void>();\n }\n\n const timeoutScope = this.createTimeoutScope(action, options);\n const dispatchHandlerPromises: DispatchHandlerPromises = new Set();\n const attemptState = { count: 0 };\n const operation = async () => {\n if (!timeoutScope.options?.signal?.aborted) {\n this.validatePayload(action, payload);\n }\n\n return this.executeWithRetry(async () => {\n const executedHandlers: HandlerRegistration<any, any>[] = [];\n try {\n return await this._performDispatch(\n action,\n payload,\n timeoutScope.options,\n attemptState.count > 1,\n executedHandlers,\n dispatchHandlerPromises\n );\n } finally {\n this.cleanupOneTimeHandlers(\n action,\n executedHandlers,\n dispatchHandlerPromises\n );\n }\n }, timeoutScope.options, attemptState, undefined, () => this.getHandlerCount(action) > 0);\n };\n\n const hasTimingGuard = (\n options?.debounce !== undefined ||\n options?.throttle !== undefined ||\n this.pipelines.get(action)?.some(handler => (\n handler.config.debounce !== undefined ||\n handler.config.throttle !== undefined\n )) === true\n );\n\n let dispatchPromise: Promise<void>;\n this.dispatchConstructionDepth += 1;\n try {\n // Timing guards must observe rapid calls when they are dispatched. If\n // they enter the serial queue first, each debounce window completes\n // before the next call starts and every call is executed.\n if (timeoutScope.options?.immediate || hasTimingGuard || !this.dispatchQueue) {\n dispatchPromise = operation();\n } else {\n const queued = this.dispatchQueue.enqueueWithHandle(\n operation,\n timeoutScope.options?.queuePriority ?? 0\n );\n timeoutScope.onTimeout(error => queued.cancel(error));\n dispatchPromise = queued.promise;\n }\n this.trackDispatchPromise(dispatchPromise);\n } finally {\n this.dispatchConstructionDepth -= 1;\n }\n const exposedPromise = this.raceWithTimeout(\n dispatchPromise,\n timeoutScope,\n dispatchHandlerPromises\n );\n const observedPromise = exposedPromise.catch(error => {\n this.invokeErrorHandler(error, action, payload, options, attemptState.count);\n throw error;\n });\n\n // Preserve rejection semantics for observers without leaking fire-and-forget\n // dispatches as process-level unhandled rejections.\n void observedPromise.catch(() => {});\n return observedPromise;\n }\n\n /** Execute a dispatch operation with an optional whole-action retry policy. */\n private async executeWithRetry<R>(\n operation: () => Promise<R>,\n options: DispatchOptions | undefined,\n attemptState: { count: number },\n shouldRetryResult?: (result: R) => boolean,\n canRetry: () => boolean = () => true\n ): Promise<R> {\n const configuredAttempts = options?.retryOnError?.maxAttempts ?? 1;\n const maxAttempts = Number.isFinite(configuredAttempts)\n ? Math.max(1, Math.floor(configuredAttempts))\n : 1;\n const retryDelay = Math.max(0, options?.retryOnError?.delay ?? 0);\n\n while (attemptState.count < maxAttempts) {\n attemptState.count += 1;\n\n try {\n const result = await operation();\n const shouldRetry = shouldRetryResult?.(result) ?? false;\n if (\n !shouldRetry ||\n attemptState.count >= maxAttempts ||\n options?.signal?.aborted ||\n !canRetry()\n ) {\n return result;\n }\n } catch (error) {\n if (\n error instanceof ActionValidationError ||\n attemptState.count >= maxAttempts ||\n options?.signal?.aborted ||\n !canRetry()\n ) {\n throw error;\n }\n }\n\n await this.waitForRetry(retryDelay, options?.signal);\n }\n\n // The loop always returns or throws. This protects the generic return type\n // if an invalid retry configuration somehow reaches this point.\n return operation();\n }\n\n private trackDispatchPromise<R>(promise: Promise<R>): Promise<R> {\n this.activeDispatches.add(promise);\n const remove = () => this.activeDispatches.delete(promise);\n void promise.then(remove, remove);\n return promise;\n }\n\n private trackHandlerPromise<R>(\n promise: Promise<R>,\n dispatchHandlerPromises: DispatchHandlerPromises\n ): Promise<R> {\n this.activeHandlerPromises.add(promise);\n dispatchHandlerPromises.add(promise);\n const remove = () => {\n this.activeHandlerPromises.delete(promise);\n dispatchHandlerPromises.delete(promise);\n };\n void promise.then(remove, remove);\n return promise;\n }\n\n private trackGlobalHandlerPromise<R>(promise: Promise<R>): Promise<R> {\n this.activeHandlerPromises.add(promise);\n const remove = () => this.activeHandlerPromises.delete(promise);\n void promise.then(remove, remove);\n return promise;\n }\n\n /** Abort-aware retry delay so cancellation does not wait for the full backoff. */\n private waitForRetry(delay: number, signal?: AbortSignal): Promise<void> {\n if (delay <= 0 || signal?.aborted) return Promise.resolve();\n\n return new Promise(resolve => {\n const timer = setTimeout(finish, delay);\n const abort = () => finish();\n\n function finish() {\n clearTimeout(timer);\n signal?.removeEventListener('abort', abort);\n resolve();\n }\n\n signal?.addEventListener('abort', abort, { once: true });\n });\n }\n\n /** Build a wall-clock timeout that also participates in pipeline cancellation. */\n private createTimeoutScope<K extends keyof T>(\n action: K,\n options?: DispatchOptions\n ): {\n options: DispatchOptions | undefined;\n timeoutPromise?: Promise<never>;\n onTimeout: (callback: (error: ActionTimeoutError) => void) => void;\n cleanup: () => void;\n cleanupSignals: () => void;\n } {\n const hasTimeout = options?.timeout !== undefined && Number.isFinite(options.timeout);\n const timeout = hasTimeout ? Math.max(0, options!.timeout!) : undefined;\n const timeoutController = hasTimeout ? new AbortController() : undefined;\n const signalCleanups: Array<() => void> = [];\n const timeoutCallbacks = new Set<(error: ActionTimeoutError) => void>();\n const signals = [\n this.lifecycleController.signal,\n options?.signal,\n timeoutController?.signal,\n ].filter((candidate): candidate is AbortSignal => Boolean(candidate));\n let signal = signals[0]!;\n\n if (signals.length > 1) {\n if (typeof (AbortSignal as typeof AbortSignal & {\n any?: (signals: AbortSignal[]) => AbortSignal;\n }).any === 'function') {\n signal = (AbortSignal as typeof AbortSignal & {\n any: (signals: AbortSignal[]) => AbortSignal;\n }).any(signals);\n } else {\n const mergedController = new AbortController();\n const forwardAbort = (source: AbortSignal) => {\n if (!mergedController.signal.aborted) mergedController.abort(source.reason);\n };\n\n for (const source of signals) {\n if (source.aborted) {\n forwardAbort(source);\n break;\n }\n const listener = () => forwardAbort(source);\n source.addEventListener('abort', listener, { once: true });\n signalCleanups.push(() => source.removeEventListener('abort', listener));\n }\n signal = mergedController.signal;\n }\n }\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = timeoutController && timeout !== undefined\n ? new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n const error = new ActionTimeoutError(String(action), timeout);\n timeoutController.abort(error);\n timeoutCallbacks.forEach(callback => callback(error));\n reject(error);\n }, timeout);\n })\n : undefined;\n\n return {\n options: { ...options, signal },\n timeoutPromise,\n onTimeout: callback => timeoutCallbacks.add(callback),\n cleanup: () => {\n if (timer !== undefined) clearTimeout(timer);\n timeoutCallbacks.clear();\n },\n cleanupSignals: () => signalCleanups.forEach(cleanup => cleanup()),\n };\n }\n\n /** Expose timeout failure while allowing the queued operation to drain safely. */\n private raceWithTimeout<R>(\n operation: Promise<R>,\n scope: {\n timeoutPromise?: Promise<never>;\n cleanup: () => void;\n cleanupSignals: () => void;\n },\n dispatchHandlerPromises: DispatchHandlerPromises\n ): Promise<R> {\n const exposed = scope.timeoutPromise\n ? Promise.race([operation, scope.timeoutPromise])\n : operation;\n const cleanupAfterStartedHandlers = () => {\n // Successful completion must cancel the ref'ed timeout timer immediately.\n // Only fallback signal-forwarding listeners need to outlive race losers.\n scope.cleanup();\n this.cleanupSignalsAfterStartedHandlers(\n scope.cleanupSignals,\n dispatchHandlerPromises\n );\n };\n void exposed.then(cleanupAfterStartedHandlers, cleanupAfterStartedHandlers);\n return exposed;\n }\n\n private cleanupSignalsAfterStartedHandlers(\n cleanup: () => void,\n dispatchHandlerPromises: DispatchHandlerPromises\n ): void {\n const handlersStillRunning = [...dispatchHandlerPromises];\n if (handlersStillRunning.length === 0) {\n cleanup();\n return;\n }\n\n // In AbortSignal.any() fallback environments, this dispatch's signal\n // forwarding listeners must outlive its race-mode losers even though the\n // exposed dispatch resolved. Unrelated dispatches must not delay cleanup.\n void Promise.allSettled(handlersStillRunning).then(cleanup);\n }\n\n /** Invoke the configured error handler without allowing it to replace the dispatch error. */\n private invokeErrorHandler<K extends keyof T>(\n error: unknown,\n action: K,\n payload: T[K] | undefined,\n options: DispatchOptions | undefined,\n attempts: number\n ): void {\n const errorHandler = this.registryConfig?.errorHandler;\n if (!errorHandler) return;\n\n const normalizedError = error instanceof Error ? error : new Error(String(error));\n try {\n const handlerResult = errorHandler(normalizedError, {\n action: String(action),\n payload,\n options,\n attempts,\n phase: normalizedError instanceof ActionTimeoutError\n ? 'timeout'\n : normalizedError instanceof ActionValidationError\n ? 'validation'\n : 'execution',\n });\n if (handlerResult && typeof (handlerResult as PromiseLike<void>).then === 'function') {\n void Promise.resolve(handlerResult).catch(handlerError => {\n this.log('Global async error handler failed', handlerError, 'warn');\n });\n }\n } catch (handlerError) {\n this.log('Global error handler failed', handlerError, 'warn');\n }\n }\n\n /**\n * Validate an action payload against the configured schema.\n * Shared by all dispatch paths so result collection cannot bypass validation.\n */\n private validatePayload<K extends keyof T>(\n action: K,\n payload?: T[K]\n ): ExecutionResult<never>['validation'] {\n if (\n !this.registryConfig?.schema ||\n this.registryConfig.validateOnDispatch === false\n ) {\n return undefined;\n }\n\n const actionName = String(action);\n const actionSchema = this.registryConfig.schema[actionName];\n if (!actionSchema) {\n return undefined;\n }\n\n let result: ReturnType<typeof actionSchema.safeParse>;\n try {\n result = actionSchema.safeParse(payload);\n } catch (error) {\n throw new ActionValidationError(actionName, error);\n }\n if (result.success) {\n return { passed: true, errors: [] };\n }\n\n const mode = this.registryConfig.validationMode ?? 'strict';\n if (mode === 'strict') {\n throw new ActionValidationError(actionName, result.error);\n }\n\n if (mode === 'warn') {\n console.warn(\n `Action \"${actionName}\" payload validation failed:`,\n result.error.message\n );\n this.log(`Validation warning for action '${actionName}'`, {\n issues: result.error.issues,\n }, 'warn');\n }\n\n return {\n passed: false,\n errors: result.error.issues.map(issue => issue.message),\n };\n }\n\n private createAbortedExecutionResult<R>(\n startTime: number,\n handlersSkipped: number = 0,\n validation?: ExecutionResult<R>['validation']\n ): ExecutionResult<R> {\n const endTime = Date.now();\n\n return {\n success: false,\n aborted: true,\n abortReason: 'Action dispatch aborted by signal',\n terminated: false,\n validation,\n result: undefined,\n successResults: [],\n results: [],\n failedResults: [],\n execution: {\n duration: endTime - startTime,\n handlersExecuted: 0,\n handlersSkipped,\n handlersFailed: 0,\n startTime,\n endTime,\n },\n handlers: [],\n errors: [],\n };\n }\n\n /**\n * ๐Ÿ†• ์‹ค์ œ ๋””์ŠคํŒจ์น˜ ์ž‘์—… ์ˆ˜ํ–‰ (ํ์—์„œ ํ˜ธ์ถœ๋จ)\n */\n private async _performDispatch<K extends keyof T>(\n action: K,\n payload: T[K] | undefined,\n options: DispatchOptions | undefined,\n skipGuards: boolean,\n executedHandlers: HandlerRegistration<any, any>[],\n dispatchHandlerPromises: DispatchHandlerPromises\n ): Promise<void> {\n // ๐Ÿ” ๋””์ŠคํŒจ์น˜ ์‹œ์ž‘ ๋””๋ฒ„๊ทธ\n this.log(`Starting dispatch for action '${String(action)}'`, {\n hasPayload: payload !== undefined,\n payloadType: payload?.constructor?.name || typeof payload,\n options: options ? Object.keys(options) : 'none',\n timestamp: new Date().toISOString()\n });\n \n // Simple Event object detection for development\n if (payload instanceof Event && process.env.NODE_ENV === 'development') {\n console.warn(`Event object passed to action \"${String(action)}\"`, payload.type);\n }\n\n // ๐Ÿ”ง Improved AbortSignal handling with cleaner merge logic\n const [effectiveSignal, autoAbortController, cleanup] = this.createAbortSignal(options);\n \n if (options?.autoAbort?.onControllerCreated && autoAbortController) {\n options.autoAbort.onControllerCreated(autoAbortController);\n }\n \n // Check if dispatch is aborted before starting\n if (effectiveSignal?.aborted) {\n this.log(`Dispatch aborted before execution for '${String(action)}'`);\n cleanup();\n return;\n }\n \n const pipeline = this.pipelines.get(action);\n \n // ๐Ÿ” ํŒŒ์ดํ”„๋ผ์ธ ์กด์žฌ ์—ฌ๋ถ€ ๋””๋ฒ„๊ทธ\n this.log(`Pipeline lookup for '${String(action)}'`, {\n pipelineExists: Boolean(pipeline),\n handlersCount: pipeline?.length || 0,\n allRegisteredActions: Array.from(this.pipelines.keys()),\n pipelineMap: Object.fromEntries(Array.from(this.pipelines.entries()).map(([k, v]) => [k, v.length]))\n });\n \n if (!pipeline || pipeline.length === 0) {\n // ๐Ÿšจ ๊ฒฝ๊ณ : ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ์•ก์…˜ ์‹คํ–‰\n const warningMessage = `โš ๏ธ Action '${String(action)}' has no registered handlers. This action will be ignored.`;\n \n if (process.env.NODE_ENV === 'development') {\n console.warn(warningMessage);\n console.warn('๐Ÿ’ก Tip: Register a handler using registry.register() before dispatching this action.');\n console.warn('๐Ÿ“‹ Available actions:', Array.from(this.pipelines.keys()));\n }\n \n this.log(`No handlers found for action '${String(action)}', dispatch cancelled`, {}, 'warn');\n cleanup();\n return;\n }\n\n // ๐Ÿ†• Optimize filtering - only copy array if filtering is needed\n const filteredHandlers = options?.filter \n ? this.filterHandlers(pipeline, options.filter)\n : pipeline;\n\n // Apply ActionGuard controls - check both dispatch options and handler configs\n const actionKey = String(action);\n \n // Get throttle/debounce settings from dispatch options or handler configs\n let throttleMs: number | undefined;\n let debounceMs: number | undefined;\n \n // Priority: dispatch options > handler config\n if (options?.throttle !== undefined) {\n throttleMs = options.throttle;\n } else if (filteredHandlers.length > 0) {\n // Use throttle from the first handler that has it (handlers are sorted by priority)\n for (const handler of filteredHandlers) {\n if (handler.config.throttle !== undefined) {\n throttleMs = handler.config.throttle;\n break;\n }\n }\n }\n \n if (options?.debounce !== undefined) {\n debounceMs = options.debounce;\n } else if (filteredHandlers.length > 0) {\n // Use debounce from the first handler that has it (handlers are sorted by priority)\n for (const handler of filteredHandlers) {\n if (handler.config.debounce !== undefined) {\n debounceMs = handler.config.debounce;\n break;\n }\n }\n }\n \n // Apply debounce if specified\n if (!skipGuards && debounceMs !== undefined) {\n const shouldProceed = await this.actionGuard.debounce(actionKey, debounceMs);\n if (!shouldProceed) {\n cleanup();\n return; // Debounced - don't execute\n }\n }\n \n // Apply throttle if specified\n if (!skipGuards && throttleMs !== undefined) {\n const shouldProceed = this.actionGuard.throttle(actionKey, throttleMs);\n if (!shouldProceed) {\n cleanup();\n return; // Throttled - don't execute\n }\n }\n\n // The signal may have been aborted while awaiting debounce.\n if (effectiveSignal?.aborted) {\n this.log(`Dispatch aborted during guard processing for '${String(action)}'`);\n cleanup();\n return;\n }\n\n // Determine execution mode for this action (with option override)\n const currentExecutionMode = options?.executionMode || \n this.actionExecutionModes.get(action) || \n this.executionMode;\n\n // Create pipeline execution context\n const context: PipelineContext<T[K], any> = {\n action: String(action),\n payload: payload as T[K],\n handlers: [...filteredHandlers],\n executedHandlers: [],\n deferOnceCleanup: true,\n signal: effectiveSignal ?? this.lifecycleController.signal,\n trackHandlerPromise: promise => this.trackHandlerPromise(\n promise,\n dispatchHandlerPromises\n ),\n aborted: false,\n abortReason: undefined as string | undefined,\n currentIndex: 0,\n jumpToPriority: undefined as number | undefined,\n jumpCount: 0,\n maxJumps: 10, // Default max jumps to prevent infinite loops\n executionMode: currentExecutionMode,\n \n // New result collection fields\n results: [],\n terminated: false,\n terminationResult: undefined as any,\n };\n\n \n // Add abort listener if signal provided (use effectiveSignal for auto-abort)\n const abortHandler = effectiveSignal ? () => {\n context.aborted = true;\n context.abortReason = typeof effectiveSignal.reason === 'string'\n ? effectiveSignal.reason\n : 'Action dispatch aborted by signal';\n } : undefined;\n \n if (effectiveSignal && abortHandler) {\n effectiveSignal.addEventListener('abort', abortHandler, { once: true });\n }\n \n \n try {\n await this.executePipeline(\n context,\n dispatchHandlerPromises,\n autoAbortController,\n options?.autoAbort\n );\n this.log(`Pipeline execution succeeded for ${String(action)}`);\n } catch (error) {\n this.log(`Pipeline execution failed for ${String(action)}`, error, 'error');\n throw error;\n } finally {\n executedHandlers?.push(...(context.executedHandlers ?? []));\n if (effectiveSignal && abortHandler) {\n effectiveSignal.removeEventListener('abort', abortHandler);\n }\n this.cleanupSignalsAfterStartedHandlers(cleanup, dispatchHandlerPromises);\n }\n }\n\n /**\n * Dispatch an action and return detailed execution results\n * \n * @param action - The action type to dispatch\n * @param payload - The action payload data\n * @param options - Optional dispatch options including result collection strategy\n * \n * @returns Promise resolving to comprehensive execution results\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n dispatchWithResult<K extends keyof T, R = void>(\n action: K,\n payload?: T[K],\n options?: DispatchOptions\n ): Promise<ExecutionResult<R>> {\n if (this.lifecycleState !== 'active') {\n return this.rejectedLifecyclePromise<ExecutionResult<R>>();\n }\n\n const timeoutScope = this.createTimeoutScope(action, options);\n const dispatchHandlerPromises: DispatchHandlerPromises = new Set();\n const attemptState = { count: 0 };\n let validation: ExecutionResult<R>['validation'];\n\n const operation = async () => {\n if (!timeoutScope.options?.signal?.aborted) {\n validation = this.validatePayload(action, payload);\n }\n\n return this.executeWithRetry(async () => {\n const executedHandlers: HandlerRegistration<any, any>[] = [];\n try {\n return await this._performDispatchWithResult<K, R>(\n action,\n payload,\n timeoutScope.options,\n validation,\n attemptState.count > 1,\n executedHandlers,\n dispatchHandlerPromises\n );\n } finally {\n this.cleanupOneTimeHandlers(\n action,\n executedHandlers,\n dispatchHandlerPromises\n );\n }\n }, timeoutScope.options, attemptState, result => (\n !result.success &&\n !result.aborted &&\n this.getHandlerCount(action) > 0\n ), () => this.getHandlerCount(action) > 0);\n };\n\n // Result dispatches historically executed immediately. Preserve that\n // behavior for nested dispatch and debounce compatibility; queuePriority is\n // the explicit opt-in to shared queue ordering.\n const shouldQueue = (\n !timeoutScope.options?.immediate &&\n Boolean(this.dispatchQueue) &&\n timeoutScope.options?.queuePriority !== undefined\n );\n let dispatchPromise: Promise<ExecutionResult<R>>;\n this.dispatchConstructionDepth += 1;\n try {\n if (shouldQueue) {\n const queued = this.dispatchQueue!.enqueueWithHandle(\n operation,\n timeoutScope.options!.queuePriority!\n );\n timeoutScope.onTimeout(error => queued.cancel(error));\n dispatchPromise = queued.promise;\n } else {\n dispatchPromise = operation();\n }\n this.trackDispatchPromise(dispatchPromise);\n } finally {\n this.dispatchConstructionDepth -= 1;\n }\n const exposedPromise = this.raceWithTimeout(\n dispatchPromise,\n timeoutScope,\n dispatchHandlerPromises\n );\n const observedPromise = exposedPromise.then(result => {\n if (!result.success && !result.aborted) {\n const terminalError = result.errors[result.errors.length - 1]?.error\n ?? new Error(`Action \"${String(action)}\" failed`);\n this.invokeErrorHandler(\n terminalError,\n action,\n payload,\n options,\n attemptState.count\n );\n }\n return result;\n }, error => {\n this.invokeErrorHandler(error, action, payload, options, attemptState.count);\n throw error;\n });\n\n void observedPromise.catch(() => {});\n return observedPromise;\n }\n\n private async _performDispatchWithResult<K extends keyof T, R = void>(\n action: K,\n payload: T[K] | undefined,\n options: DispatchOptions | undefined,\n validation: ExecutionResult<R>['validation'],\n skipGuards: boolean,\n executedHandlers: HandlerRegistration<any, any>[],\n dispatchHandlerPromises: DispatchHandlerPromises\n ): Promise<ExecutionResult<R>> {\n const _startTime = Date.now();\n \n // ๐Ÿ”ง Improved AbortSignal handling with cleaner merge logic (same as dispatch)\n const [effectiveSignal, autoAbortController, cleanup] = this.createAbortSignal(options);\n \n if (options?.autoAbort?.onControllerCreated && autoAbortController) {\n options.autoAbort.onControllerCreated(autoAbortController);\n }\n \n // Check if dispatch is aborted before starting\n if (effectiveSignal?.aborted) {\n cleanup();\n return this.createAbortedExecutionResult<R>(_startTime, 0, validation);\n }\n \n const pipeline = this.pipelines.get(action);\n \n if (!pipeline || pipeline.length === 0) {\n // ๐Ÿšจ ๊ฒฝ๊ณ : ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ์•ก์…˜ ์‹คํ–‰\n const warningMessage = `โš ๏ธ Action '${String(action)}' has no registered handlers. This action will be ignored.`;\n \n if (process.env.NODE_ENV === 'development') {\n console.warn(warningMessage);\n console.warn('๐Ÿ’ก Tip: Register a handler using registry.register() before dispatching this action.');\n console.warn('๐Ÿ“‹ Available actions:', Array.from(this.pipelines.keys()));\n }\n \n cleanup();\n return {\n success: true,\n aborted: false,\n abortReason: undefined as string | undefined,\n terminated: false,\n validation,\n result: undefined as any,\n successResults: [] as any,\n results: [],\n failedResults: [],\n execution: {\n duration: 0,\n handlersExecuted: 0,\n handlersSkipped: 0,\n handlersFailed: 0,\n startTime: _startTime,\n endTime: _startTime,\n },\n handlers: [],\n errors: [],\n };\n }\n\n // ๐Ÿ†• Optimize filtering - only copy array if filtering is needed\n const filteredHandlers = options?.filter \n ? this.filterHandlers(pipeline, options.filter)\n : pipeline;\n\n // ๐Ÿ”ง Apply ActionGuard controls using unified method with ExecutionResult return\n const actionKey = String(action);\n const guardResult = skipGuards\n ? null\n : await this.applyActionGuardControlsWithResult<R>(\n actionKey,\n filteredHandlers,\n options,\n _startTime,\n pipeline.length\n );\n\n // The signal may have been aborted while awaiting debounce.\n if (effectiveSignal?.aborted) {\n cleanup();\n return this.createAbortedExecutionResult<R>(_startTime, pipeline.length, validation);\n }\n\n if (guardResult) {\n cleanup();\n return { ...guardResult, validation }; // Throttled or debounced\n }\n\n // Determine execution mode for this action (with option override)\n const currentExecutionMode = options?.executionMode || \n this.actionExecutionModes.get(action) || \n this.executionMode;\n\n // Create pipeline execution context\n const context: PipelineContext<T[K], R> = {\n action: String(action),\n payload: payload as T[K],\n handlers: [...filteredHandlers],\n executedHandlers: [],\n deferOnceCleanup: true,\n signal: effectiveSignal ?? this.lifecycleController.signal,\n trackHandlerPromise: promise => this.trackHandlerPromise(\n promise,\n dispatchHandlerPromises\n ),\n aborted: false,\n abortReason: undefined as string | undefined,\n currentIndex: 0,\n jumpToPriority: undefined as number | undefined,\n jumpCount: 0,\n maxJumps: 10, // Default max jumps to prevent infinite loops\n executionMode: currentExecutionMode,\n \n // Result collection fields\n results: [],\n terminated: false,\n terminationResult: undefined as R | undefined,\n };\n\n let executionError: Error | undefined;\n const handlerResults: Array<{\n id: string;\n executed: boolean;\n duration: number | undefined;\n result: R | undefined;\n error: Error | undefined;\n metadata: Record<string, any> | undefined;\n }> = [];\n\n\n // Initialize handler tracking - all handlers start as not executed\n filteredHandlers.forEach(handler => {\n handlerResults.push({\n id: handler.config.id,\n executed: false,\n duration: undefined as number | undefined,\n result: undefined as R | undefined,\n error: undefined as Error | undefined,\n metadata: undefined as Record<string, any> | undefined,\n });\n });\n\n // Add abort listener if signal provided (use effectiveSignal for auto-abort)\n const abortHandler = effectiveSignal ? () => {\n context.aborted = true;\n context.abortReason = typeof effectiveSignal.reason === 'string'\n ? effectiveSignal.reason\n : 'Action dispatch aborted by signal';\n } : undefined;\n \n if (effectiveSignal && abortHandler) {\n effectiveSignal.addEventListener('abort', abortHandler, { once: true });\n }\n \n // ๐Ÿ”ง Initialize errors array (will be updated after pipeline execution)\n let errors: HandlerError[] = [];\n \n try {\n await this.executePipeline(\n context,\n dispatchHandlerPromises,\n autoAbortController,\n options?.autoAbort\n );\n \n // ๐Ÿ”ง Collect errors from execution context after pipeline execution\n const contextWithErrors = context as PipelineContext<any, any> & { collectedErrors?: HandlerError[] };\n errors = contextWithErrors.collectedErrors || [];\n \n // Mark executed handlers based on context.currentIndex\n // In sequential mode, handlers 0 to currentIndex were executed\n // In parallel/race mode, all handlers that didn't error were executed\n const executedCount = Math.min(context.currentIndex + (context.aborted ? 0 : 1), filteredHandlers.length);\n for (let i = 0; i < executedCount; i++) {\n const handler = filteredHandlers[i];\n if (!handler) continue;\n const handlerResult = handlerResults.find(hr => hr.id === handler.config.id);\n if (handlerResult) {\n handlerResult.executed = true;\n }\n }\n } catch (error) {\n // ๐Ÿ”ง Collect errors from execution context before adding pipeline error\n const contextWithErrors = context as PipelineContext<any, any> & { collectedErrors?: HandlerError[] };\n errors = contextWithErrors.collectedErrors || [];\n \n executionError = error instanceof Error ? error : new Error(String(error));\n errors.push({\n handlerId: 'pipeline',\n error: executionError,\n timestamp: Date.now(),\n severity: 'blocking'\n });\n \n // Mark executed handlers even when there's an error\n const executedCount = Math.min(context.currentIndex + 1, filteredHandlers.length);\n for (let i = 0; i < executedCount; i++) {\n const handler = filteredHandlers[i];\n if (!handler) continue;\n const handlerResult = handlerResults.find(hr => hr.id === handler.config.id);\n if (handlerResult) {\n handlerResult.executed = true;\n }\n }\n } finally {\n executedHandlers.push(...(context.executedHandlers ?? []));\n if (effectiveSignal && abortHandler) {\n effectiveSignal.removeEventListener('abort', abortHandler);\n }\n this.cleanupSignalsAfterStartedHandlers(cleanup, dispatchHandlerPromises);\n }\n\n const endTime = Date.now();\n \n // Process results based on options\n const processedResult = this.processResults(context, options?.result);\n\n // ๐Ÿ”ง Type safety: Separate successful results from failed ones\n const successResults = context.results.filter((result): result is R => result !== undefined);\n const failedResults = errors.map(err => ({\n handlerId: err.handlerId,\n error: err.error,\n expectedType: typeof processedResult\n }));\n\n // Build execution result with improved type safety\n const executionResult: ExecutionResult<R> = {\n success: !executionError && !context.aborted,\n aborted: context.aborted,\n abortReason: context.abortReason,\n terminated: context.terminated,\n validation,\n result: processedResult,\n successResults: successResults,\n results: context.results,\n failedResults,\n execution: {\n duration: endTime - _startTime,\n handlersExecuted: filteredHandlers.length === 0 ? 0 : context.currentIndex + (context.aborted ? 0 : 1),\n handlersSkipped: Math.max(0, filteredHandlers.length - (context.currentIndex + 1)),\n handlersFailed: errors.length,\n startTime: _startTime,\n endTime,\n },\n handlers: handlerResults,\n errors: errors.map(err => ({\n handlerId: err.handlerId,\n error: err.error,\n timestamp: err.timestamp,\n severity: 'non-blocking' as const\n })),\n };\n\n return executionResult;\n }\n\n /**\n * ๐Ÿ”ง Unified method for dispatchWithResult that returns ExecutionResult on guard rejection\n */\n private async applyActionGuardControlsWithResult<R>(\n actionKey: string,\n filteredHandlers: HandlerRegistration<any, any>[],\n options: DispatchOptions | undefined,\n startTime: number,\n pipelineLength: number\n ): Promise<ExecutionResult<R> | null> {\n // Get throttle/debounce settings (same logic as above)\n let throttleMs: number | undefined;\n let debounceMs: number | undefined;\n \n if (options?.throttle !== undefined) {\n throttleMs = options.throttle;\n } else if (filteredHandlers.length > 0) {\n for (const handler of filteredHandlers) {\n if (handler.config.throttle !== undefined) {\n throttleMs = handler.config.throttle;\n break;\n }\n }\n }\n \n if (options?.debounce !== undefined) {\n debounceMs = options.debounce;\n } else if (filteredHandlers.length > 0) {\n for (const handler of filteredHandlers) {\n if (handler.config.debounce !== undefined) {\n debounceMs = handler.config.debounce;\n break;\n }\n }\n }\n \n // Apply debounce if specified\n if (debounceMs !== undefined) {\n const shouldProceed = await this.actionGuard.debounce(actionKey, debounceMs);\n if (!shouldProceed) {\n return {\n success: false,\n aborted: true,\n abortReason: 'Debounced execution',\n terminated: false,\n result: undefined as any,\n successResults: [] as any,\n results: [],\n failedResults: [],\n execution: {\n duration: Date.now() - startTime,\n handlersExecuted: 0,\n handlersSkipped: pipelineLength,\n handlersFailed: 0,\n startTime: startTime,\n endTime: Date.now(),\n },\n handlers: [],\n errors: [],\n };\n }\n }\n \n // Apply throttle if specified\n if (throttleMs !== undefined) {\n const shouldProceed = this.actionGuard.throttle(actionKey, throttleMs);\n if (!shouldProceed) {\n return {\n success: false,\n aborted: true,\n abortReason: 'Throttled execution',\n terminated: false,\n result: undefined as any,\n successResults: [] as any,\n results: [],\n failedResults: [],\n execution: {\n duration: Date.now() - startTime,\n handlersExecuted: 0,\n handlersSkipped: pipelineLength,\n handlersFailed: 0,\n startTime: startTime,\n endTime: Date.now(),\n },\n handlers: [],\n errors: [],\n };\n }\n }\n\n return null; // No guard intervention, proceed with execution\n }\n\n // Cache invalidation removed for memory stability\n\n /**\n * ๐Ÿ”ง Create or reuse PipelineController from pool for better performance\n */\n private getControllerFromPool<K extends keyof T>(\n context: PipelineContext<T[K], any>, \n autoAbortController?: AbortController,\n autoAbortOptions?: { allowHandlerAbort?: boolean }\n ): PipelineController<T[K], any> {\n // Try to reuse from pool\n let controller = this.controllerPool.pop();\n \n if (!controller) {\n // Create new controller if pool is empty\n controller = {} as PipelineController<T[K], any>;\n }\n\n // Configure/reset the controller for current context\n (controller as { signal: AbortSignal }).signal =\n context.signal ?? this.lifecycleController.signal;\n\n controller.abort = (reason?: string) => {\n context.aborted = true;\n context.abortReason = reason;\n \n // Auto-abort: Handler can trigger pipeline abort if enabled\n if (autoAbortController && autoAbortOptions?.allowHandlerAbort) {\n autoAbortController.abort(reason);\n }\n };\n\n controller.modifyPayload = (modifier: (payload: T[K]) => T[K]) => {\n try {\n context.payload = modifier(context.payload);\n } catch (modificationError) {\n // ๐Ÿ”ง Fix: Don't let payload modification errors crash the pipeline\n this.log('Payload modification error', modificationError, 'warn');\n // Keep original payload on modification error\n }\n };\n\n controller.getPayload = () => context.payload;\n\n controller.jumpToPriority = (priority: number) => {\n context.jumpToPriority = priority;\n };\n\n controller.return = (result: any) => {\n context.terminated = true;\n context.terminationResult = result;\n };\n\n controller.setResult = (result: any) => {\n context.results.push(result);\n };\n\n controller.getResults = () => {\n return [...context.results];\n };\n\n controller.mergeResult = (merger: (previousResults: any[], currentResult: any) => any) => {\n const currentResult = context.results[context.results.length - 1];\n const previousResults = context.results.slice(0, -1);\n const mergedResult = merger(previousResults, currentResult);\n context.results[context.results.length - 1] = mergedResult;\n };\n\n return controller;\n }\n\n private filterHandlers(\n handlers: HandlerRegistration<any, any>[],\n filterOptions?: DispatchOptions['filter']\n ): HandlerRegistration<any, any>[] {\n if (!filterOptions) {\n return handlers;\n }\n\n // Cache disabled for memory stability\n\n // Cache disabled - using direct filtering for memory stability\n\n // Create Sets for fast lookup if arrays are provided\n const handlerIdSet = filterOptions.handlerIds ? new Set(filterOptions.handlerIds) : null;\n const excludeIdSet = filterOptions.excludeHandlerIds ? new Set(filterOptions.excludeHandlerIds) : null;\n\n // Filter handlers with optimized checks\n const filtered = handlers.filter(registration => {\n const config = registration.config;\n\n // Fast Set-based inclusion check\n if (handlerIdSet && !handlerIdSet.has(config.id)) {\n return false;\n }\n\n // Fast Set-based exclusion check\n if (excludeIdSet?.has(config.id)) {\n return false;\n }\n\n // Priority range check\n if (filterOptions.priority) {\n const priority = config.priority;\n if (filterOptions.priority.min !== undefined && priority < filterOptions.priority.min) {\n return false;\n }\n if (filterOptions.priority.max !== undefined && priority > filterOptions.priority.max) {\n return false;\n }\n }\n\n // Custom filter (not cached)\n if (filterOptions.custom && !filterOptions.custom(config)) {\n return false;\n }\n\n return true;\n });\n\n // Cache disabled for memory stability\n\n return filtered;\n }\n\n private processResults<R>(\n context: PipelineContext<any, R>,\n resultOptions?: DispatchOptions['result']\n ): R | R[] | undefined {\n const results = context.results;\n\n // ๐Ÿ”ง Fix: Always handle termination result regardless of collect option\n if (context.terminated && context.terminationResult !== undefined) {\n return context.terminationResult;\n }\n\n // ๐Ÿ”ง Fix: Return undefined only if no results options specified AND no results available\n if (!resultOptions) {\n // If no result options specified but we have results, return the last one\n return results.length > 0 ? results[results.length - 1] : undefined;\n }\n\n // ๐Ÿ”ง Fix: Process results even when collect is false if we have a strategy specified\n if (!resultOptions.collect && !resultOptions.strategy) {\n return undefined;\n }\n\n // Apply maxResults limit\n const limitedResults = resultOptions.maxResults\n ? results.slice(0, resultOptions.maxResults)\n : results;\n\n if (limitedResults.length === 0) {\n return undefined;\n }\n\n // Process results based on strategy with improved type handling\n switch (resultOptions.strategy) {\n case 'first':\n return limitedResults[0];\n case 'last':\n return limitedResults[limitedResults.length - 1];\n case 'all':\n return limitedResults;\n case 'merge':\n if (resultOptions.merger) {\n return resultOptions.merger(limitedResults);\n }\n // Default merge: return last result\n return limitedResults[limitedResults.length - 1];\n case 'custom':\n if (resultOptions.merger) {\n return resultOptions.merger(limitedResults);\n }\n throw new Error('Custom result strategy requires a merger function');\n default:\n // ๐Ÿ”ง Fix: If collect is true but no strategy specified, return all results\n if (resultOptions.collect) {\n return limitedResults;\n }\n // Default: return last result if no strategy specified\n return limitedResults[limitedResults.length - 1];\n }\n }\n\n private async executePipeline<K extends keyof T>(\n context: PipelineContext<T[K], any>,\n dispatchHandlerPromises: DispatchHandlerPromises,\n autoAbortController?: AbortController,\n autoAbortOptions?: { allowHandlerAbort?: boolean }\n ): Promise<void> {\n const createController = (_registration: HandlerRegistration<T[K], any>, _index: number): PipelineController<T[K], any> => {\n return this.getControllerFromPool(context, autoAbortController, autoAbortOptions);\n };\n\n switch (context.executionMode) {\n case 'sequential':\n await executeSequential<T[K], any>(context, createController);\n break;\n case 'parallel':\n await executeParallel<T[K], any>(context, createController);\n break;\n case 'race':\n await executeRace<T[K], any>(context, createController);\n break;\n default:\n throw new Error(`Unknown execution mode: ${context.executionMode}`);\n }\n\n if (!context.deferOnceCleanup) {\n this.cleanupOneTimeHandlers(\n context.action as K,\n context.executedHandlers ?? [],\n dispatchHandlerPromises\n );\n }\n }\n\n private cleanupOneTimeHandlers<K extends keyof T>(\n action: K,\n executedHandlers: HandlerRegistration<any, any>[],\n dispatchHandlerPromises: DispatchHandlerPromises\n ): void {\n const oneTimeHandlers = executedHandlers.filter(reg => reg.config.once);\n if (oneTimeHandlers.length === 0) return;\n\n // Race mode returns its winner while loser handlers can still be active.\n // Detach every invoked once-handler immediately so retries cannot invoke it\n // again, but defer resource cleanup until this dispatch's started handler\n // work drains. Unrelated dispatches must not delay cleanup.\n const handlersStillRunning = [...dispatchHandlerPromises];\n const shouldDeferCleanup = handlersStillRunning.length > 0;\n\n oneTimeHandlers.forEach(registration => {\n if (this.removeRegistration(action, registration, !shouldDeferCleanup)) {\n if (\n shouldDeferCleanup &&\n typeof registration.config.cleanup === 'function'\n ) {\n const cleanupPromise = Promise.allSettled(handlersStillRunning).then(() => {\n this.runRegistrationCleanup(action, registration);\n });\n void this.trackGlobalHandlerPromise(cleanupPromise).catch(() => {});\n }\n\n this.log(`One-time handler removed: ${String(action)}`, {\n handlerId: registration.id,\n remainingHandlers: this.getHandlerCount(action)\n });\n }\n });\n }\n\n\n /**\n * Get the number of registered handlers for an action\n * \n * @param action - The action type to count handlers for\n * \n * @returns Number of registered handlers\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n getHandlerCount<K extends keyof T>(action: K): number {\n const pipeline = this.pipelines.get(action);\n return pipeline ? pipeline.length : 0;\n }\n\n /**\n * Check if an action has any registered handlers\n * \n * @param action - The action type to check\n * \n * @returns True if action has handlers, false otherwise\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n hasHandlers<K extends keyof T>(action: K): boolean {\n return this.getHandlerCount(action) > 0;\n }\n\n /**\n * Get all registered action types\n * \n * @returns Array of all registered action types\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n getRegisteredActions(): (keyof T)[] {\n return Array.from(this.pipelines.keys());\n }\n\n /**\n * Remove all handlers for a specific action\n * \n * @param action - The action type to clear handlers for\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n clearAction<K extends keyof T>(action: K): void {\n const pipeline = this.pipelines.get(action);\n if (pipeline) {\n [...pipeline].forEach(registration => {\n this.removeRegistration(action, registration);\n });\n }\n\n this.pipelines.delete(action);\n this.lastRegisteredTimestamps.delete(action);\n this.actionGuard.clearGuards(String(action));\n }\n\n /**\n * Remove all handlers for all actions\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n clearAll(): void {\n [...this.pipelines.keys()].forEach(action => {\n this.clearAction(action);\n });\n\n this.pipelines.clear();\n this.lastRegisteredTimestamps.clear();\n this.unregisterFunctions.clear();\n this.actionGuard.clearAll();\n }\n\n /**\n * Get the name of this action register\n * \n * @returns The register name\n * \n * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage\n * \n * @public\n */\n getName(): string {\n return this.name;\n }\n\n /**\n * Get comprehensive registry information (similar to DeclarativeStoreRegistry pattern)\n * \n * @returns Registry information including actions, handlers, and execution modes\n */\n getRegistryInfo(): ActionRegistryInfo<T> {\n const totalHandlers = Array.from(this.pipelines.values()).reduce(\n (total, pipeline) => total + pipeline.length, \n 0\n );\n \n return {\n name: this.name,\n totalActions: this.pipelines.size,\n totalHandlers,\n registeredActions: Array.from(this.pipelines.keys()),\n actionExecutionModes: new Map(this.actionExecutionModes),\n defaultExecutionMode: this.executionMode,\n };\n }\n\n /**\n * Get detailed statistics for a specific action\n * \n * @param action Action name to get statistics for\n * @returns Detailed handler statistics\n */\n getActionStats<K extends keyof T>(action: K): ActionHandlerStats<T> | null {\n const pipeline = this.pipelines.get(action);\n if (!pipeline) {\n return null;\n }\n\n // Group handlers by priority\n const priorityMap = new Map<number, typeof pipeline>();\n pipeline.forEach(handler => {\n if (!priorityMap.has(handler.config.priority)) {\n priorityMap.set(handler.config.priority, []);\n }\n priorityMap.get(handler.config.priority)!.push(handler);\n });\n\n const handlersByPriority = Array.from(priorityMap.entries())\n .sort(([a], [b]) => b - a) // Sort by priority (highest first)\n .map(([priority, handlers]) => ({\n priority,\n handlers: handlers.map(h => ({\n id: h.config.id,\n }))\n }));\n\n // Execution statistics are no longer tracked\n const executionStats = undefined;\n\n return {\n action,\n handlerCount: pipeline.length,\n totalHandlers: pipeline.length,\n handlersByPriority,\n executionStats,\n lastRegistered: this.lastRegisteredTimestamps.get(action),\n };\n }\n\n /**\n * Get statistics for all registered actions\n * \n * @returns Array of statistics for all actions\n */\n getAllActionStats(): Array<ActionHandlerStats<T>> {\n return Array.from(this.pipelines.keys())\n .map(action => this.getActionStats(action))\n .filter((stats): stats is ActionHandlerStats<T> => stats !== null);\n }\n\n\n /**\n * Set global execution mode for all actions\n * \n * @param mode Execution mode to set\n */\n setExecutionMode(mode: ExecutionMode): void {\n this.executionMode = mode;\n \n if (this.registryConfig?.debug && process.env.NODE_ENV === 'development') {\n console.log(`๐ŸŽฏ Global execution mode set to: ${mode}`);\n }\n }\n\n /**\n * Set execution mode for a specific action\n * \n * @param action Action name\n * @param mode Execution mode to set\n */\n setActionExecutionMode<K extends keyof T>(action: K, mode: ExecutionMode): void {\n this.actionExecutionModes.set(action, mode);\n \n if (this.registryConfig?.debug && process.env.NODE_ENV === 'development') {\n console.log(`๐ŸŽฏ Execution mode set for action '${String(action)}': ${mode}`);\n }\n }\n\n /**\n * Get execution mode for a specific action\n * \n * @param action Action name\n * @returns Execution mode for the action, or default if not set\n */\n getActionExecutionMode<K extends keyof T>(action: K): ExecutionMode {\n return this.actionExecutionModes.get(action) || this.executionMode;\n }\n\n /**\n * Remove execution mode override for a specific action\n * \n * @param action Action name\n */\n removeActionExecutionMode<K extends keyof T>(action: K): void {\n this.actionExecutionModes.delete(action);\n \n if (this.registryConfig?.debug && process.env.NODE_ENV === 'development') {\n console.log(`๐ŸŽฏ Execution mode reset for action '${String(action)}' to default: ${this.executionMode}`);\n }\n }\n\n\n /**\n * Get registry configuration (for debugging and inspection)\n * \n * @returns Current registry configuration\n */\n getRegistryConfig(): ActionRegisterConfig['registry'] {\n return this.registryConfig;\n }\n\n /**\n * Check if registry has debug mode enabled\n * \n * @returns Whether debug mode is enabled\n */\n isDebugEnabled(): boolean {\n return this.isDebugMode;\n }\n\n /**\n * Creates a consistent unregister function for a handler\n * \n * @param action - Action key\n * @param handlerId - Handler identifier\n * @param registration - Handler registration object\n * @returns Unregister function\n * @private\n */\n private createUnregisterFunction<K extends keyof T>(\n action: K,\n handlerId: string,\n registration: HandlerRegistration<any, any>\n ): UnregisterFunction {\n return () => {\n if (this.removeRegistration(action, registration)) {\n this.log(`Handler unregistered: ${String(action)}`, {\n handlerId,\n remainingHandlers: this.getHandlerCount(action),\n actionRemoved: !this.pipelines.has(action)\n });\n }\n };\n }\n\n /** Remove a registration and release every resource owned by it exactly once. */\n private removeRegistration<K extends keyof T>(\n action: K,\n registration: HandlerRegistration<any, any>,\n runCleanup = true\n ): boolean {\n const pipeline = this.pipelines.get(action);\n if (!pipeline) return false;\n\n const index = pipeline.indexOf(registration);\n if (index === -1) return false;\n\n pipeline.splice(index, 1);\n this.unregisterFunctions.delete(registration.id);\n\n if (runCleanup) {\n this.runRegistrationCleanup(action, registration);\n }\n\n if (pipeline.length === 0) {\n this.pipelines.delete(action);\n this.lastRegisteredTimestamps.delete(action);\n }\n\n return true;\n }\n\n private runRegistrationCleanup<K extends keyof T>(\n action: K,\n registration: HandlerRegistration<any, any>\n ): void {\n if (!registration.config.cleanup) return;\n\n try {\n registration.config.cleanup();\n } catch (cleanupError) {\n this.log(`Cleanup error while removing handler: ${String(action)}`, cleanupError, 'warn');\n }\n }\n\n /**\n * Gets the total count of registered unregister functions\n * \n * @returns Number of unregister functions\n * @public\n */\n getUnregisterFunctionCount(): number {\n return this.unregisterFunctions.size;\n }\n \n /**\n * Checks if an unregister function exists for the given handler ID\n * \n * @param handlerId - Handler identifier to check\n * @returns True if unregister function exists\n * @public\n */\n hasUnregisterFunction(handlerId: string): boolean {\n return this.unregisterFunctions.has(handlerId);\n }\n\n /** Reject queued dispatches without releasing registered handlers. */\n cancelPendingDispatches(): void {\n this.dispatchQueue?.clear({ rejectPending: true });\n }\n\n private beginShutdown(): Promise<void> {\n if (this.destroyAsyncPromise) return this.destroyAsyncPromise;\n\n if (this.lifecycleState === 'destroyed') {\n this.destroyAsyncPromise = Promise.resolve();\n return this.destroyAsyncPromise;\n }\n\n this.lifecycleState = 'closing';\n const shutdownError = new ActionRegisterDestroyedError(this.name, 'closing');\n\n // Store the stable shutdown promise before aborting signals: abort listeners\n // run synchronously and may re-enter destroyAsync().\n let resolveShutdown!: () => void;\n let rejectShutdown!: (error: unknown) => void;\n this.destroyAsyncPromise = new Promise<void>((resolve, reject) => {\n resolveShutdown = resolve;\n rejectShutdown = reject;\n });\n\n if (!this.lifecycleController.signal.aborted) {\n this.lifecycleController.abort(shutdownError);\n }\n\n // Stop guard timers immediately and reject operations that have not begun.\n // Registered handler cleanup is deferred until every started handler settles.\n this.actionGuard.destroy();\n this.dispatchQueue?.clear({ rejectPending: true, reason: shutdownError });\n\n const canFinalizeSynchronously = (\n this.dispatchConstructionDepth === 0 &&\n this.activeDispatches.size === 0 &&\n this.activeHandlerPromises.size === 0\n );\n\n if (canFinalizeSynchronously) {\n this.finalizeDestroy();\n resolveShutdown();\n return this.destroyAsyncPromise;\n }\n\n const drainAndFinalize = async () => {\n // Handler promises can be created by a dispatch that was already starting\n // when shutdown began, so drain until both dynamic sets stay empty.\n while (this.activeDispatches.size > 0 || this.activeHandlerPromises.size > 0) {\n await Promise.allSettled([\n ...this.activeDispatches,\n ...this.activeHandlerPromises,\n ]);\n }\n\n this.finalizeDestroy();\n };\n // Dispatch and queue construction call handlers synchronously before their\n // promises can be inserted into the active sets. Start draining on the next\n // microtask so handler-initiated shutdown cannot finalize through that gap.\n void Promise.resolve()\n .then(drainAndFinalize)\n .then(resolveShutdown, rejectShutdown);\n\n // destroy() is intentionally fire-and-forget; keep its internal promise\n // observed while destroyAsync() remains available to callers that need proof.\n void this.destroyAsyncPromise.catch(error => {\n this.log('ActionRegister async destroy failed', error, 'warn');\n });\n return this.destroyAsyncPromise;\n }\n\n private finalizeDestroy(): void {\n if (this.lifecycleState === 'destroyed') return;\n\n this.clearAll();\n this.actionExecutionModes.clear();\n this.controllerPool.length = 0;\n this.lifecycleState = 'destroyed';\n this.log('ActionRegister destroyed');\n }\n\n /**\n * ๐Ÿ†• Destroy method for comprehensive cleanup\n *\n * Begins terminal cleanup of pipelines, guards, queues, and statistics. Cleanup\n * remains synchronous when no work has started; otherwise active handlers drain\n * in the background. Use destroyAsync() when completion must be observed.\n *\n * @public\n */\n destroy(): void {\n void this.beginShutdown();\n }\n\n /**\n * Begin terminal shutdown and resolve after all started handlers have settled\n * and their registered cleanup functions have run.\n *\n * Repeated calls return the same promise. New registrations and dispatches are\n * rejected as soon as shutdown begins.\n *\n * @public\n */\n destroyAsync(): Promise<void> {\n return this.beginShutdown();\n }\n}\n"],"mappings":"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"}