@context-action/core 0.2.2 → 0.2.3

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.cjs CHANGED
@@ -28,9 +28,42 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  //#region src/execution-modes.ts
29
29
  /**
30
30
  * Execute handlers in sequential mode (one after another)
31
+ *
32
+ * Executes action handlers one at a time in priority order (highest first).
33
+ * Supports both blocking and non-blocking handlers, with proper abort and
34
+ * termination handling. Handlers can modify payload for subsequent handlers
35
+ * and jump to different priority levels.
36
+ *
37
+ * @template T - The payload type for the action
38
+ * @template R - The result type for handlers
39
+ *
40
+ * @param context - Pipeline execution context containing handlers and state
41
+ * @param createController - Factory function for creating pipeline controllers
42
+ *
43
+ * @throws {Error} When a blocking handler fails or validation errors occur
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * // This is called internally by ActionRegister.dispatch()
48
+ * // when executionMode is 'sequential'
49
+ *
50
+ * // Handlers execute in this order (by priority):
51
+ * // 1. Priority 100: Validation handler
52
+ * // 2. Priority 50: Business logic handler
53
+ * // 3. Priority 10: Logging handler
54
+ *
55
+ * await executeSequential(context, (registration, index) => ({
56
+ * abort: (reason) => { context.aborted = true; context.abortReason = reason },
57
+ * modifyPayload: (modifier) => { context.payload = modifier(context.payload) },
58
+ * // ... other controller methods
59
+ * }))
60
+ * ```
61
+ *
62
+ * @public
31
63
  */
32
64
  async function executeSequential(context, createController) {
33
65
  let i = 0;
66
+ const nonBlockingPromises = [];
34
67
  while (i < context.handlers.length) {
35
68
  if (context.aborted || context.terminated) break;
36
69
  const registration = context.handlers[i];
@@ -56,10 +89,15 @@ async function executeSequential(context, createController) {
56
89
  if (handlerResult !== void 0 && !context.terminated) context.results.push(handlerResult);
57
90
  } else if (result !== void 0 && !context.terminated)
58
91
  /** Collect synchronous result */
59
- if (result instanceof Promise) result.then((asyncResult) => {
60
- if (asyncResult !== void 0 && !context.terminated) context.results.push(asyncResult);
61
- }).catch(() => {});
62
- else context.results.push(result);
92
+ if (result instanceof Promise) {
93
+ const promiseWithHandling = result.then((asyncResult) => {
94
+ if (asyncResult !== void 0 && !context.terminated) context.results.push(asyncResult);
95
+ return asyncResult;
96
+ }).catch((error) => {
97
+ throw error;
98
+ });
99
+ nonBlockingPromises.push(promiseWithHandling);
100
+ } else context.results.push(result);
63
101
  /** Check if pipeline was terminated by controller.return() */
64
102
  if (context.terminated) break;
65
103
  /** Handle jump to priority AFTER handler execution */
@@ -76,12 +114,56 @@ async function executeSequential(context, createController) {
76
114
  } else i++;
77
115
  } catch (error) {
78
116
  if (registration.config.blocking) throw error;
79
- i++;
117
+ throw error;
80
118
  }
81
119
  }
120
+ if (nonBlockingPromises.length > 0) await Promise.all(nonBlockingPromises);
82
121
  }
83
122
  /**
84
123
  * Execute handlers in parallel mode (all at once)
124
+ *
125
+ * Executes all qualifying action handlers simultaneously using Promise.allSettled.
126
+ * Supports both blocking and non-blocking handlers. Blocking handlers can still
127
+ * fail the entire pipeline if they throw errors.
128
+ *
129
+ * @template T - The payload type for the action
130
+ * @template R - The result type for handlers
131
+ *
132
+ * @param context - Pipeline execution context containing handlers and state
133
+ * @param createController - Factory function for creating pipeline controllers
134
+ *
135
+ * @throws {Error} When any blocking handler fails
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * // This is called internally by ActionRegister.dispatch()
140
+ * // when executionMode is 'parallel'
141
+ *
142
+ * // All handlers execute simultaneously:
143
+ * // - Analytics handler (non-blocking)
144
+ * // - Validation handler (blocking)
145
+ * // - Update handler (blocking)
146
+ * // - Notification handler (non-blocking)
147
+ *
148
+ * await executeParallel(context, (registration, index) => ({
149
+ * abort: (reason) => { context.aborted = true },
150
+ * setResult: (result) => { context.results.push(result) },
151
+ * // ... other controller methods
152
+ * }))
153
+ * ```
154
+ *
155
+ * @example Use Case
156
+ * ```typescript
157
+ * // Perfect for independent operations
158
+ * register.setActionExecutionMode('logEvent', 'parallel')
159
+ *
160
+ * // These can all run simultaneously:
161
+ * register.register('logEvent', analyticsHandler, { blocking: false })
162
+ * register.register('logEvent', metricsHandler, { blocking: false })
163
+ * register.register('logEvent', auditHandler, { blocking: true })
164
+ * ```
165
+ *
166
+ * @public
85
167
  */
86
168
  async function executeParallel(context, createController) {
87
169
  /** Filter handlers that should run */
@@ -141,6 +223,56 @@ async function executeParallel(context, createController) {
141
223
  }
142
224
  /**
143
225
  * Execute handlers in race mode (first to complete wins)
226
+ *
227
+ * Executes all qualifying handlers simultaneously using Promise.race, where
228
+ * the first handler to complete determines the pipeline result. Other handlers
229
+ * are effectively cancelled. Useful for scenarios where you want the fastest
230
+ * response from multiple equivalent handlers.
231
+ *
232
+ * @template T - The payload type for the action
233
+ * @template R - The result type for handlers
234
+ *
235
+ * @param context - Pipeline execution context containing handlers and state
236
+ * @param createController - Factory function for creating pipeline controllers
237
+ *
238
+ * @throws {Error} When the winning handler fails and is blocking
239
+ *
240
+ * @example
241
+ * ```typescript
242
+ * // This is called internally by ActionRegister.dispatch()
243
+ * // when executionMode is 'race'
244
+ *
245
+ * // Multiple data sources racing for fastest response:
246
+ * // - Database handler (might be slow)
247
+ * // - Cache handler (usually fast)
248
+ * // - API handler (variable speed)
249
+ * //
250
+ * // Whichever completes first wins
251
+ *
252
+ * await executeRace(context, (registration, index) => ({
253
+ * return: (result) => {
254
+ * context.terminated = true
255
+ * context.terminationResult = result
256
+ * },
257
+ * // ... other controller methods
258
+ * }))
259
+ * ```
260
+ *
261
+ * @example Use Case
262
+ * ```typescript
263
+ * // Race between multiple data sources
264
+ * register.setActionExecutionMode('fetchUserData', 'race')
265
+ *
266
+ * // These handlers race for fastest response:
267
+ * register.register('fetchUserData', cacheHandler) // Usually fastest
268
+ * register.register('fetchUserData', databaseHandler) // Reliable fallback
269
+ * register.register('fetchUserData', apiHandler) // External source
270
+ *
271
+ * // First to complete wins, others are ignored
272
+ * const result = await register.dispatchWithResult('fetchUserData', { id: '123' })
273
+ * ```
274
+ *
275
+ * @public
144
276
  */
145
277
  async function executeRace(context, createController) {
146
278
  /** Filter handlers that should run */
@@ -190,8 +322,8 @@ async function executeRace(context, createController) {
190
322
  }
191
323
 
192
324
  //#endregion
193
- //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.81.0/node_modules/@oxc-project/runtime/src/helpers/typeof.js
194
- var require_typeof = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.81.0/node_modules/@oxc-project/runtime/src/helpers/typeof.js": ((exports, module) => {
325
+ //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.82.2/node_modules/@oxc-project/runtime/src/helpers/typeof.js
326
+ var require_typeof = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.82.2/node_modules/@oxc-project/runtime/src/helpers/typeof.js": ((exports, module) => {
195
327
  function _typeof$2(o) {
196
328
  "@babel/helpers - typeof";
197
329
  return module.exports = _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
@@ -204,8 +336,8 @@ var require_typeof = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@oxc
204
336
  }) });
205
337
 
206
338
  //#endregion
207
- //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.81.0/node_modules/@oxc-project/runtime/src/helpers/toPrimitive.js
208
- var require_toPrimitive = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.81.0/node_modules/@oxc-project/runtime/src/helpers/toPrimitive.js": ((exports, module) => {
339
+ //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.82.2/node_modules/@oxc-project/runtime/src/helpers/toPrimitive.js
340
+ var require_toPrimitive = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.82.2/node_modules/@oxc-project/runtime/src/helpers/toPrimitive.js": ((exports, module) => {
209
341
  var _typeof$1 = require_typeof()["default"];
210
342
  function toPrimitive$1(t, r) {
211
343
  if ("object" != _typeof$1(t) || !t) return t;
@@ -221,8 +353,8 @@ var require_toPrimitive = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm
221
353
  }) });
222
354
 
223
355
  //#endregion
224
- //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.81.0/node_modules/@oxc-project/runtime/src/helpers/toPropertyKey.js
225
- var require_toPropertyKey = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.81.0/node_modules/@oxc-project/runtime/src/helpers/toPropertyKey.js": ((exports, module) => {
356
+ //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.82.2/node_modules/@oxc-project/runtime/src/helpers/toPropertyKey.js
357
+ var require_toPropertyKey = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.82.2/node_modules/@oxc-project/runtime/src/helpers/toPropertyKey.js": ((exports, module) => {
226
358
  var _typeof = require_typeof()["default"];
227
359
  var toPrimitive = require_toPrimitive();
228
360
  function toPropertyKey$1(t) {
@@ -233,8 +365,8 @@ var require_toPropertyKey = /* @__PURE__ */ __commonJS({ "../../node_modules/.pn
233
365
  }) });
234
366
 
235
367
  //#endregion
236
- //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.81.0/node_modules/@oxc-project/runtime/src/helpers/defineProperty.js
237
- var require_defineProperty = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.81.0/node_modules/@oxc-project/runtime/src/helpers/defineProperty.js": ((exports, module) => {
368
+ //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.82.2/node_modules/@oxc-project/runtime/src/helpers/defineProperty.js
369
+ var require_defineProperty = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.82.2/node_modules/@oxc-project/runtime/src/helpers/defineProperty.js": ((exports, module) => {
238
370
  var toPropertyKey = require_toPropertyKey();
239
371
  function _defineProperty$3(e, r, t) {
240
372
  return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
@@ -252,41 +384,81 @@ var require_defineProperty = /* @__PURE__ */ __commonJS({ "../../node_modules/.p
252
384
  var import_defineProperty$2 = /* @__PURE__ */ __toESM(require_defineProperty(), 1);
253
385
  /**
254
386
  * Action Guard system for managing action execution timing
255
- * @implements action-guard
256
- * @implements performance-optimization
257
- * @implements user-experience-optimization
258
- * @implements class-naming
259
- * @memberof core-concepts
260
- * @internal
261
- * @since 1.0.0
262
387
  *
263
- * Manages action execution timing through debouncing and throttling
264
- * @implements performance-optimization
388
+ * Provides performance optimization and user experience enhancement through
389
+ * debouncing and throttling mechanisms. Debouncing waits for a pause in calls
390
+ * before executing, while throttling limits execution frequency.
265
391
  *
266
- * @example
392
+ * @example Debouncing Search Input
267
393
  * ```typescript
268
- * const guard = new ActionGuard(logger);
394
+ * const guard = new ActionGuard()
269
395
  *
270
- * // Debounce search input (wait 300ms after typing stops)
396
+ * // Wait 300ms after user stops typing before searching
397
+ * register.register('searchUsers', async (payload, controller) => {
398
+ * const query = payload.query
399
+ * if (query.length < 2) return
400
+ *
401
+ * const results = await userService.search(query)
402
+ * controller.setResult(results)
403
+ * }, {
404
+ * debounce: 300, // Built into ActionRegister via ActionGuard
405
+ * tags: ['search', 'user-input']
406
+ * })
407
+ * ```
408
+ *
409
+ * @example Throttling High-Frequency Events
410
+ * ```typescript
411
+ * // Limit scroll position updates to once per 100ms
412
+ * register.register('updateScrollPosition', (payload, controller) => {
413
+ * scrollState.setValue(payload.position)
414
+ * }, {
415
+ * throttle: 100, // Built into ActionRegister via ActionGuard
416
+ * tags: ['scroll', 'performance']
417
+ * })
418
+ * ```
419
+ *
420
+ * @example Manual Usage (Advanced)
421
+ * ```typescript
422
+ * const guard = new ActionGuard()
423
+ *
424
+ * // Manual debouncing
271
425
  * if (await guard.debounce('search', 300)) {
272
- * executeSearch();
426
+ * performSearch() // Only executes after 300ms pause
273
427
  * }
274
428
  *
275
- * // Throttle scroll handler (max once per 100ms)
429
+ * // Manual throttling
276
430
  * if (guard.throttle('scroll', 100)) {
277
- * updateScrollPosition();
431
+ * updateUI() // Max once per 100ms
278
432
  * }
279
433
  * ```
434
+ *
435
+ * @internal
280
436
  */
281
437
  var ActionGuard = class {
282
438
  constructor() {
283
439
  (0, import_defineProperty$2.default)(this, "guards", /* @__PURE__ */ new Map());
284
440
  }
285
441
  /**
286
- * Check if action should be debounced
287
- * @param actionKey - Unique key for the action
288
- * @param debounceMs - Debounce delay in milliseconds
289
- * @returns Promise that resolves when debounce period is complete
442
+ * Apply debouncing to an action
443
+ *
444
+ * Debouncing waits for a specified delay after the last call before allowing
445
+ * execution. Each new call resets the timer. Useful for search inputs, resize
446
+ * handlers, and other high-frequency user interactions.
447
+ *
448
+ * @param actionKey - Unique identifier for the action being debounced
449
+ * @param debounceMs - Delay in milliseconds to wait after the last call
450
+ *
451
+ * @returns Promise resolving to true if execution should proceed, false if cancelled
452
+ *
453
+ * @example Search Input Debouncing
454
+ * ```typescript
455
+ * // Only search after user stops typing for 300ms
456
+ * if (await guard.debounce('userSearch', 300)) {
457
+ * performSearch(query)
458
+ * }
459
+ * ```
460
+ *
461
+ * @internal
290
462
  */
291
463
  async debounce(actionKey, debounceMs) {
292
464
  /** Get or create guard state for this action */
@@ -321,10 +493,26 @@ var ActionGuard = class {
321
493
  });
322
494
  }
323
495
  /**
324
- * Check if action should be throttled
325
- * @param actionKey - Unique key for the action
326
- * @param throttleMs - Throttle delay in milliseconds
327
- * @returns True if action should proceed, false if throttled
496
+ * Apply throttling to an action
497
+ *
498
+ * Throttling limits execution frequency by ensuring a minimum interval between
499
+ * calls. Unlike debouncing, throttling executes immediately on the first call
500
+ * and then blocks subsequent calls until the interval expires.
501
+ *
502
+ * @param actionKey - Unique identifier for the action being throttled
503
+ * @param throttleMs - Minimum interval in milliseconds between executions
504
+ *
505
+ * @returns True if execution should proceed, false if currently throttled
506
+ *
507
+ * @example Scroll Handler Throttling
508
+ * ```typescript
509
+ * // Update scroll position max once per 100ms
510
+ * if (guard.throttle('scrollUpdate', 100)) {
511
+ * updateScrollPosition()
512
+ * }
513
+ * ```
514
+ *
515
+ * @internal
328
516
  */
329
517
  throttle(actionKey, throttleMs) {
330
518
  /** Get or create guard state for this action */
@@ -363,8 +551,14 @@ var ActionGuard = class {
363
551
  return false;
364
552
  }
365
553
  /**
366
- * Clear all guards for an action
367
- * @param actionKey - Action key to clear
554
+ * Clear all guard state for a specific action
555
+ *
556
+ * Removes debounce and throttle timers for the specified action,
557
+ * preventing memory leaks and allowing immediate re-execution.
558
+ *
559
+ * @param actionKey - Action identifier to clear guards for
560
+ *
561
+ * @internal
368
562
  */
369
563
  clearGuards(actionKey) {
370
564
  const state = this.guards.get(actionKey);
@@ -381,7 +575,12 @@ var ActionGuard = class {
381
575
  }
382
576
  }
383
577
  /**
384
- * Clear all guards
578
+ * Clear all guard states for all actions
579
+ *
580
+ * Removes all active debounce and throttle timers, useful for cleanup
581
+ * when shutting down the action system or resetting state.
582
+ *
583
+ * @internal
385
584
  */
386
585
  clearAll() {
387
586
  /** Iterate through all guard states and clear their timers */
@@ -399,14 +598,28 @@ var ActionGuard = class {
399
598
  this.guards.clear();
400
599
  }
401
600
  /**
402
- * Get current guard state for debugging
403
- * @param actionKey - Action key to inspect
601
+ * Get current guard state for debugging purposes
602
+ *
603
+ * Returns the internal state for a specific action, including timer
604
+ * information and execution timestamps.
605
+ *
606
+ * @param actionKey - Action identifier to inspect
607
+ * @returns Guard state or undefined if no state exists
608
+ *
609
+ * @internal
404
610
  */
405
611
  getGuardState(actionKey) {
406
612
  return this.guards.get(actionKey);
407
613
  }
408
614
  /**
409
- * Get all active guards for debugging
615
+ * Get all active guard states for debugging purposes
616
+ *
617
+ * Returns a copy of all current guard states, useful for monitoring
618
+ * and debugging rate limiting behavior across all actions.
619
+ *
620
+ * @returns Map of action keys to their guard states
621
+ *
622
+ * @internal
410
623
  */
411
624
  getAllGuardStates() {
412
625
  return new Map(this.guards);
@@ -523,33 +736,84 @@ var OperationQueue = class {
523
736
  //#region src/ActionRegister.ts
524
737
  var import_defineProperty = /* @__PURE__ */ __toESM(require_defineProperty(), 1);
525
738
  /**
526
- * 중앙화된 액션 등록 디스패치 시스템으로, 타입 안전한 액션 파이프라인 관리를 제공하는 핵심 클래스입니다.
739
+ * Action Register for managing action handlers with priority-based execution
527
740
  *
528
- * @implements {ActionRegister}
529
- * @implements {Action Pipeline System}
530
- * @memberof core-concepts
741
+ * Central action registration and dispatch system providing type-safe action pipeline management.
742
+ * Supports sequential, parallel, and race execution modes with advanced handler filtering,
743
+ * throttling, debouncing, and comprehensive result collection.
531
744
  *
532
- * @example
745
+ * @template TActionMap - Action payload mapping interface extending ActionPayloadMap
746
+ *
747
+ * @example Basic Usage
533
748
  * ```typescript
534
749
  * interface AppActions extends ActionPayloadMap {
535
- * updateUser: { id: string; name: string };
536
- * calculateTotal: void;
750
+ * updateUser: { id: string; name: string; email: string }
751
+ * deleteUser: { id: string }
752
+ * resetUser: void
537
753
  * }
538
754
  *
539
755
  * const register = new ActionRegister<AppActions>({
540
756
  * name: 'AppRegister',
541
- * logLevel: LogLevel.DEBUG
542
- * });
757
+ * registry: { debug: true, maxHandlers: 10 }
758
+ * })
543
759
  *
544
- * // 핸들러 등록
545
- * register.register('updateUser', ({ id, name }, controller) => {
546
- * userStore.setValue({ id, name });
547
- * // 핸들러가 자동으로 다음 핸들러로 진행
548
- * }, { priority: 10 });
760
+ * // Register handler with priority
761
+ * register.register('updateUser', async (payload, controller) => {
762
+ * await userService.update(payload.id, payload)
763
+ * controller.setResult({ success: true, userId: payload.id })
764
+ * }, { priority: 10, tags: ['user', 'crud'] })
549
765
  *
550
- * // 액션 디스패치
551
- * await register.dispatch('updateUser', { id: '1', name: 'John' });
766
+ * // Dispatch action
767
+ * await register.dispatch('updateUser', {
768
+ * id: '123',
769
+ * name: 'John Doe',
770
+ * email: 'john@example.com'
771
+ * })
552
772
  * ```
773
+ *
774
+ * @example With Multiple Handlers
775
+ * ```typescript
776
+ * // High priority validation handler
777
+ * register.register('updateUser', async (payload, controller) => {
778
+ * if (!payload.email.includes('@')) {
779
+ * controller.abort('Invalid email format')
780
+ * return
781
+ * }
782
+ * }, { priority: 100, category: 'validation' })
783
+ *
784
+ * // Lower priority update handler
785
+ * register.register('updateUser', async (payload, controller) => {
786
+ * const user = await userService.update(payload.id, payload)
787
+ * controller.setResult(user)
788
+ * }, { priority: 50, category: 'business-logic' })
789
+ * ```
790
+ *
791
+ * @example Advanced Configuration
792
+ * ```typescript
793
+ * const register = new ActionRegister<AppActions>({
794
+ * name: 'AdvancedRegister',
795
+ * registry: {
796
+ * debug: true,
797
+ * maxHandlers: 20,
798
+ * defaultExecutionMode: 'parallel',
799
+ * autoCleanup: true
800
+ * }
801
+ * })
802
+ *
803
+ * // Handler with debouncing and tags
804
+ * register.register('searchUsers', async (payload, controller) => {
805
+ * const results = await userService.search(payload.query)
806
+ * controller.setResult(results)
807
+ * }, {
808
+ * priority: 10,
809
+ * debounce: 300,
810
+ * tags: ['search', 'user'],
811
+ * category: 'query',
812
+ * once: false
813
+ * })
814
+ * ```
815
+ *
816
+ * @public
553
817
  */
554
818
  var ActionRegister = class {
555
819
  constructor(config = {}) {
@@ -576,6 +840,43 @@ var ActionRegister = class {
576
840
  concurrencyProtection: true
577
841
  });
578
842
  }
843
+ /**
844
+ * Register an action handler with optional configuration
845
+ *
846
+ * @param action - The action type to register handler for
847
+ * @param handler - The handler function to execute
848
+ * @param config - Optional handler configuration including priority, tags, etc.
849
+ *
850
+ * @returns Unregister function to remove this handler
851
+ *
852
+ * @throws {Error} When maximum handlers limit is reached
853
+ *
854
+ * @example Basic Registration
855
+ * ```typescript
856
+ * const unregister = register.register('updateUser', async (payload, controller) => {
857
+ * await userService.update(payload.id, payload)
858
+ * })
859
+ *
860
+ * // Later remove the handler
861
+ * unregister()
862
+ * ```
863
+ *
864
+ * @example With Priority and Configuration
865
+ * ```typescript
866
+ * register.register('validateUser', async (payload, controller) => {
867
+ * if (!payload.email) {
868
+ * controller.abort('Email is required')
869
+ * }
870
+ * }, {
871
+ * priority: 100,
872
+ * tags: ['validation'],
873
+ * category: 'security',
874
+ * once: false
875
+ * })
876
+ * ```
877
+ *
878
+ * @public
879
+ */
579
880
  register(action, handler, config = {}) {
580
881
  const handlerId = config.id || `handler_${++this.handlerCounter}_${Math.random().toString(36).substr(2, 5)}`;
581
882
  const unregisterFn = this._performRegistrationSync(action, handler, config, handlerId);
@@ -708,6 +1009,48 @@ var ActionRegister = class {
708
1009
  }
709
1010
  };
710
1011
  }
1012
+ /**
1013
+ * Dispatch an action with optional execution options
1014
+ *
1015
+ * @param action - The action type to dispatch
1016
+ * @param payload - The action payload data
1017
+ * @param options - Optional dispatch options (execution mode, filters, etc.)
1018
+ *
1019
+ * @returns Promise that resolves when all handlers complete
1020
+ *
1021
+ * @throws {Error} When action dispatching fails
1022
+ *
1023
+ * @example Basic Dispatch
1024
+ * ```typescript
1025
+ * await register.dispatch('updateUser', {
1026
+ * id: '123',
1027
+ * name: 'John Doe',
1028
+ * email: 'john@example.com'
1029
+ * })
1030
+ * ```
1031
+ *
1032
+ * @example With Options
1033
+ * ```typescript
1034
+ * await register.dispatch('updateUser', payload, {
1035
+ * executionMode: 'parallel',
1036
+ * timeout: 5000,
1037
+ * filter: {
1038
+ * tags: ['validation', 'business-logic'],
1039
+ * excludeCategory: 'analytics'
1040
+ * }
1041
+ * })
1042
+ * ```
1043
+ *
1044
+ * @example With Throttling
1045
+ * ```typescript
1046
+ * await register.dispatch('searchUsers', { query: 'john' }, {
1047
+ * throttle: 300,
1048
+ * debounce: 100
1049
+ * })
1050
+ * ```
1051
+ *
1052
+ * @public
1053
+ */
711
1054
  async dispatch(action, payload, options) {
712
1055
  return this.dispatchQueue.enqueue(async () => {
713
1056
  return this._performDispatch(action, payload, options);
@@ -784,7 +1127,9 @@ var ActionRegister = class {
784
1127
  if (effectiveSignal && abortHandler) effectiveSignal.addEventListener("abort", abortHandler);
785
1128
  try {
786
1129
  await this.executePipeline(context, autoAbortController, options?.autoAbort);
1130
+ console.log(`[ActionRegister] Pipeline execution succeeded for ${String(action)}`);
787
1131
  } catch (error) {
1132
+ console.log(`[ActionRegister] Pipeline execution failed for ${String(action)}:`, error);
788
1133
  executionSuccess = false;
789
1134
  throw error;
790
1135
  } finally {
@@ -793,6 +1138,43 @@ var ActionRegister = class {
793
1138
  this.updateExecutionStats(action, executionSuccess, duration);
794
1139
  }
795
1140
  }
1141
+ /**
1142
+ * Dispatch an action and return detailed execution results
1143
+ *
1144
+ * @param action - The action type to dispatch
1145
+ * @param payload - The action payload data
1146
+ * @param options - Optional dispatch options including result collection strategy
1147
+ *
1148
+ * @returns Promise resolving to comprehensive execution results
1149
+ *
1150
+ * @example Basic Result Collection
1151
+ * ```typescript
1152
+ * const result = await register.dispatchWithResult('updateUser', payload)
1153
+ *
1154
+ * if (result.success) {
1155
+ * console.log(`Executed ${result.execution.handlersExecuted} handlers`)
1156
+ * console.log(`Duration: ${result.execution.duration}ms`)
1157
+ * }
1158
+ * ```
1159
+ *
1160
+ * @example Advanced Result Processing
1161
+ * ```typescript
1162
+ * const result = await register.dispatchWithResult('processOrder', order, {
1163
+ * result: {
1164
+ * collect: true,
1165
+ * strategy: 'merge',
1166
+ * maxResults: 5,
1167
+ * merger: (results) => results.reduce((acc, curr) => ({ ...acc, ...curr }), {})
1168
+ * }
1169
+ * })
1170
+ *
1171
+ * if (result.terminated) {
1172
+ * console.log('Handler returned early:', result.result)
1173
+ * }
1174
+ * ```
1175
+ *
1176
+ * @public
1177
+ */
796
1178
  async dispatchWithResult(action, payload, options) {
797
1179
  const startTime = Date.now();
798
1180
  let autoAbortController;
@@ -1095,22 +1477,105 @@ var ActionRegister = class {
1095
1477
  if (success) stats.successCount++;
1096
1478
  else stats.errorCount++;
1097
1479
  }
1480
+ /**
1481
+ * Get the number of registered handlers for an action
1482
+ *
1483
+ * @param action - The action type to count handlers for
1484
+ *
1485
+ * @returns Number of registered handlers
1486
+ *
1487
+ * @example
1488
+ * ```typescript
1489
+ * register.register('updateUser', handler1)
1490
+ * register.register('updateUser', handler2)
1491
+ *
1492
+ * console.log(register.getHandlerCount('updateUser')) // 2
1493
+ * ```
1494
+ *
1495
+ * @public
1496
+ */
1098
1497
  getHandlerCount(action) {
1099
1498
  const pipeline = this.pipelines.get(action);
1100
1499
  return pipeline ? pipeline.length : 0;
1101
1500
  }
1501
+ /**
1502
+ * Check if an action has any registered handlers
1503
+ *
1504
+ * @param action - The action type to check
1505
+ *
1506
+ * @returns True if action has handlers, false otherwise
1507
+ *
1508
+ * @example
1509
+ * ```typescript
1510
+ * if (register.hasHandlers('updateUser')) {
1511
+ * await register.dispatch('updateUser', userData)
1512
+ * }
1513
+ * ```
1514
+ *
1515
+ * @public
1516
+ */
1102
1517
  hasHandlers(action) {
1103
1518
  return this.getHandlerCount(action) > 0;
1104
1519
  }
1520
+ /**
1521
+ * Get all registered action types
1522
+ *
1523
+ * @returns Array of all registered action types
1524
+ *
1525
+ * @example
1526
+ * ```typescript
1527
+ * const actions = register.getRegisteredActions()
1528
+ * console.log('Registered actions:', actions) // ['updateUser', 'deleteUser', 'resetUser']
1529
+ * ```
1530
+ *
1531
+ * @public
1532
+ */
1105
1533
  getRegisteredActions() {
1106
1534
  return Array.from(this.pipelines.keys());
1107
1535
  }
1536
+ /**
1537
+ * Remove all handlers for a specific action
1538
+ *
1539
+ * @param action - The action type to clear handlers for
1540
+ *
1541
+ * @example
1542
+ * ```typescript
1543
+ * register.clearAction('updateUser')
1544
+ * console.log(register.hasHandlers('updateUser')) // false
1545
+ * ```
1546
+ *
1547
+ * @public
1548
+ */
1108
1549
  clearAction(action) {
1109
1550
  this.pipelines.delete(action);
1110
1551
  }
1552
+ /**
1553
+ * Remove all handlers for all actions
1554
+ *
1555
+ * @example
1556
+ * ```typescript
1557
+ * register.clearAll()
1558
+ * console.log(register.getRegisteredActions().length) // 0
1559
+ * ```
1560
+ *
1561
+ * @public
1562
+ */
1111
1563
  clearAll() {
1112
1564
  this.pipelines.clear();
1113
1565
  }
1566
+ /**
1567
+ * Get the name of this action register
1568
+ *
1569
+ * @returns The register name
1570
+ *
1571
+ * @example
1572
+ * ```typescript
1573
+ * const register = new ActionRegister({ name: 'UserRegister' })
1574
+ * console.log(register.getName()) // 'UserRegister'
1575
+ * ```
1576
+ *
1577
+ * @public
1578
+ */
1114
1579
  getName() {
1115
1580
  return this.name;
1116
1581
  }