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