@context-action/core 0.8.8 โ†’ 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 CHANGED
@@ -103,7 +103,6 @@ async function executeSequential(context, createController) {
103
103
  }
104
104
  i = jumpIndex;
105
105
  context.jumpToPriority = void 0;
106
- continue;
107
106
  } else {
108
107
  context.jumpToPriority = void 0;
109
108
  i++;
@@ -984,55 +983,6 @@ function isActionRegisterDestroyedError(error) {
984
983
 
985
984
  //#endregion
986
985
  //#region src/ActionRegister.ts
987
- const dispatchOptionKeys = /* @__PURE__ */ new Set([
988
- "autoAbort",
989
- "debounce",
990
- "executionMode",
991
- "filter",
992
- "immediate",
993
- "queuePriority",
994
- "result",
995
- "retryOnError",
996
- "signal",
997
- "throttle",
998
- "timeout"
999
- ]);
1000
- function isRecord(value) {
1001
- return value !== null && typeof value === "object" && !Array.isArray(value);
1002
- }
1003
- function isOptionalNumber(value) {
1004
- return value === void 0 || typeof value === "number";
1005
- }
1006
- function isOptionalBoolean(value) {
1007
- return value === void 0 || typeof value === "boolean";
1008
- }
1009
- /**
1010
- * Recognize the deprecated options-first void-action proxy call.
1011
- *
1012
- * Every supplied field is validated so ordinary payloads that merely overlap
1013
- * one option name are not silently reinterpreted as dispatch options.
1014
- */
1015
- function isDispatchOptions(value) {
1016
- if (!isRecord(value)) return false;
1017
- const keys = Object.keys(value);
1018
- if (keys.length === 0 || keys.some((key) => !dispatchOptionKeys.has(key))) return false;
1019
- return keys.every((key) => {
1020
- const optionValue = value[key];
1021
- switch (key) {
1022
- case "debounce":
1023
- case "queuePriority":
1024
- case "throttle":
1025
- case "timeout": return isOptionalNumber(optionValue);
1026
- case "immediate": return isOptionalBoolean(optionValue);
1027
- case "executionMode": return optionValue === void 0 || optionValue === "sequential" || optionValue === "parallel" || optionValue === "race";
1028
- case "signal": return optionValue === void 0 || isRecord(optionValue) && typeof optionValue.aborted === "boolean" && typeof optionValue.addEventListener === "function";
1029
- case "retryOnError": return optionValue === void 0 || isRecord(optionValue) && typeof optionValue.maxAttempts === "number" && typeof optionValue.delay === "number";
1030
- case "autoAbort": return optionValue === void 0 || isRecord(optionValue) && typeof optionValue.enabled === "boolean" && isOptionalBoolean(optionValue.allowHandlerAbort) && (optionValue.onControllerCreated === void 0 || typeof optionValue.onControllerCreated === "function");
1031
- case "filter": return optionValue === void 0 || isRecord(optionValue) && (optionValue.handlerIds === void 0 || Array.isArray(optionValue.handlerIds) && optionValue.handlerIds.every((item) => typeof item === "string")) && (optionValue.excludeHandlerIds === void 0 || Array.isArray(optionValue.excludeHandlerIds) && optionValue.excludeHandlerIds.every((item) => typeof item === "string")) && (optionValue.priority === void 0 || isRecord(optionValue.priority)) && (optionValue.custom === void 0 || typeof optionValue.custom === "function");
1032
- case "result": return optionValue === void 0 || isRecord(optionValue) && (optionValue.strategy === void 0 || optionValue.strategy === "first" || optionValue.strategy === "last" || optionValue.strategy === "all" || optionValue.strategy === "merge" || optionValue.strategy === "custom") && (optionValue.merger === void 0 || typeof optionValue.merger === "function") && isOptionalBoolean(optionValue.collect) && isOptionalNumber(optionValue.maxResults) && isOptionalBoolean(optionValue.includeErrors);
1033
- }
1034
- });
1035
- }
1036
986
  /**
1037
987
  * Action Register for managing action handlers with priority-based execution
1038
988
  *
@@ -1055,10 +1005,8 @@ var ActionRegister = class {
1055
1005
  this.actionExecutionModes = /* @__PURE__ */ new Map();
1056
1006
  this.unregisterFunctions = /* @__PURE__ */ new Map();
1057
1007
  this.lastRegisteredTimestamps = /* @__PURE__ */ new Map();
1058
- this.filterCacheDisabled = true;
1059
1008
  this.handlerIdCounter = 0;
1060
1009
  this.controllerPool = [];
1061
- this.maxControllerPoolSize = 10;
1062
1010
  this.lifecycleState = "active";
1063
1011
  this.lifecycleController = new AbortController();
1064
1012
  this.activeDispatches = /* @__PURE__ */ new Set();
@@ -1096,7 +1044,6 @@ var ActionRegister = class {
1096
1044
  * // Function-based dispatching
1097
1045
  * await registry.actions.userLogin({ userId: '123', email: 'test@example.com' });
1098
1046
  * await registry.actions.resetApp();
1099
- * await registry.actions.resetApp({ debounce: 100 }); // Legacy options-first form
1100
1047
  * await registry.actions.resetApp(undefined, { debounce: 100 });
1101
1048
  * ```
1102
1049
  *
@@ -1105,9 +1052,8 @@ var ActionRegister = class {
1105
1052
  get actions() {
1106
1053
  if (!this._actionsProxy) this._actionsProxy = new Proxy({}, { get: (_target, prop) => {
1107
1054
  const actionKey = prop;
1108
- if (typeof prop === "string" && this.pipelines.has(actionKey)) return (payloadOrOptions, options) => {
1109
- if (isDispatchOptions(payloadOrOptions)) return this.dispatch(actionKey, void 0, payloadOrOptions);
1110
- return this.dispatch(actionKey, payloadOrOptions, options);
1055
+ if (typeof prop === "string" && this.pipelines.has(actionKey)) return (payload, options) => {
1056
+ return this.dispatch(actionKey, payload, options);
1111
1057
  };
1112
1058
  } });
1113
1059
  return this._actionsProxy;
@@ -1142,9 +1088,8 @@ var ActionRegister = class {
1142
1088
  get actionsWithResult() {
1143
1089
  if (!this._actionsWithResultProxy) this._actionsWithResultProxy = new Proxy({}, { get: (_target, prop) => {
1144
1090
  const actionKey = prop;
1145
- if (typeof prop === "string" && this.pipelines.has(actionKey)) return (payloadOrOptions, options) => {
1146
- if (isDispatchOptions(payloadOrOptions)) return this.dispatchWithResult(actionKey, void 0, payloadOrOptions);
1147
- return this.dispatchWithResult(actionKey, payloadOrOptions, options);
1091
+ if (typeof prop === "string" && this.pipelines.has(actionKey)) return (payload, options) => {
1092
+ return this.dispatchWithResult(actionKey, payload, options);
1148
1093
  };
1149
1094
  } });
1150
1095
  return this._actionsWithResultProxy;
@@ -1277,7 +1222,7 @@ var ActionRegister = class {
1277
1222
  const existing = pipeline[existingIndex];
1278
1223
  const existingUnregister = this.unregisterFunctions.get(handlerId);
1279
1224
  if (registration.config.replaceExisting) {
1280
- if (existing && existing.config.cleanup && typeof existing.config.cleanup === "function") try {
1225
+ if (existing?.config.cleanup && typeof existing.config.cleanup === "function") try {
1281
1226
  existing.config.cleanup();
1282
1227
  } catch (cleanupError) {
1283
1228
  this.log(`Cleanup error for replaced handler: ${String(action)}`, cleanupError, "warn");
@@ -1944,21 +1889,6 @@ var ActionRegister = class {
1944
1889
  return null;
1945
1890
  }
1946
1891
  /**
1947
- * ๐Ÿ”ง Generate optimized cache key for filter options
1948
- */
1949
- generateFilterCacheKey(filterOptions) {
1950
- if (!filterOptions) return "no-filter";
1951
- const parts = [];
1952
- if (filterOptions.handlerIds?.length) parts.push(`h:${filterOptions.handlerIds.slice().sort().join(",")}`);
1953
- if (filterOptions.excludeHandlerIds?.length) parts.push(`e:${filterOptions.excludeHandlerIds.slice().sort().join(",")}`);
1954
- if (filterOptions.priority) {
1955
- const { min, max } = filterOptions.priority;
1956
- if (min !== void 0 || max !== void 0) parts.push(`p:${min ?? "*"}-${max ?? "*"}`);
1957
- }
1958
- if (filterOptions.custom) return "custom-" + Date.now() + Math.random();
1959
- return parts.length > 0 ? parts.join("|") : "no-filter";
1960
- }
1961
- /**
1962
1892
  * ๐Ÿ”ง Create or reuse PipelineController from pool for better performance
1963
1893
  */
1964
1894
  getControllerFromPool(context, autoAbortController, autoAbortOptions) {
@@ -1998,12 +1928,6 @@ var ActionRegister = class {
1998
1928
  };
1999
1929
  return controller;
2000
1930
  }
2001
- /**
2002
- * ๐Ÿ”ง Return controller to pool for reuse
2003
- */
2004
- returnControllerToPool(controller) {
2005
- if (this.controllerPool.length < this.maxControllerPoolSize) this.controllerPool.push(controller);
2006
- }
2007
1931
  filterHandlers(handlers, filterOptions) {
2008
1932
  if (!filterOptions) return handlers;
2009
1933
  const handlerIdSet = filterOptions.handlerIds ? new Set(filterOptions.handlerIds) : null;
@@ -2011,7 +1935,7 @@ var ActionRegister = class {
2011
1935
  return handlers.filter((registration) => {
2012
1936
  const config = registration.config;
2013
1937
  if (handlerIdSet && !handlerIdSet.has(config.id)) return false;
2014
- if (excludeIdSet && excludeIdSet.has(config.id)) return false;
1938
+ if (excludeIdSet?.has(config.id)) return false;
2015
1939
  if (filterOptions.priority) {
2016
1940
  const priority = config.priority;
2017
1941
  if (filterOptions.priority.min !== void 0 && priority < filterOptions.priority.min) return false;
@@ -2294,7 +2218,7 @@ var ActionRegister = class {
2294
2218
  removeRegistration(action, registration, runCleanup = true) {
2295
2219
  const pipeline = this.pipelines.get(action);
2296
2220
  if (!pipeline) return false;
2297
- const index = pipeline.findIndex((candidate) => candidate === registration);
2221
+ const index = pipeline.indexOf(registration);
2298
2222
  if (index === -1) return false;
2299
2223
  pipeline.splice(index, 1);
2300
2224
  this.unregisterFunctions.delete(registration.id);
@@ -2406,341 +2330,5 @@ var ActionRegister = class {
2406
2330
  };
2407
2331
 
2408
2332
  //#endregion
2409
- //#region src/react-helpers.ts
2410
- /**
2411
- * ๐Ÿ”ง Create action handler registration configuration for React components
2412
- *
2413
- * Creates a configuration object that can be used with React's useEffect to properly
2414
- * register and unregister action handlers with lifecycle management and cleanup.
2415
- * This is NOT a hook - it's a factory function for React hook integration.
2416
- *
2417
- * @template T - ActionPayloadMap type
2418
- * @template K - Action key type
2419
- *
2420
- * @param registry - ActionRegister instance
2421
- * @param action - Action name to register handler for
2422
- * @param handler - Handler function (should be memoized with useCallback)
2423
- * @param config - Handler configuration
2424
- *
2425
- * @returns Configuration object with register/unregister functions
2426
- *
2427
- * @example Basic Usage with useEffect
2428
- * ```tsx
2429
- * import { useCallback, useEffect } from 'react';
2430
- * import { createActionHandler } from '@context-action/core/react-helpers';
2431
- *
2432
- * function MyComponent() {
2433
- * const registry = useActionRegister();
2434
- *
2435
- * const handleUserUpdate = useCallback(async (payload, controller) => {
2436
- * // Handler logic here
2437
- * }, []);
2438
- *
2439
- * useEffect(() => {
2440
- * const { register, unregister } = createActionHandler(
2441
- * registry,
2442
- * 'updateUser',
2443
- * handleUserUpdate,
2444
- * { priority: 10 }
2445
- * );
2446
- *
2447
- * const cleanup = register();
2448
- * return () => {
2449
- * cleanup();
2450
- * unregister();
2451
- * };
2452
- * }, [registry, handleUserUpdate]);
2453
- * }
2454
- * ```
2455
- *
2456
- * @example With Automatic Cleanup
2457
- * ```tsx
2458
- * const [userId, setUserId] = useState('123');
2459
- *
2460
- * const handleUserUpdate = useCallback(async (payload, controller) => {
2461
- * console.log('Updating user:', userId, payload);
2462
- * }, [userId]);
2463
- *
2464
- * useEffect(() => {
2465
- * const handlerManager = createActionHandler(
2466
- * registry,
2467
- * 'updateUser',
2468
- * handleUserUpdate,
2469
- * { priority: 10 }
2470
- * );
2471
- *
2472
- * // Simplified registration with automatic cleanup
2473
- * return handlerManager.registerWithCleanup();
2474
- * }, [registry, handleUserUpdate, userId]);
2475
- * ```
2476
- *
2477
- * @public
2478
- */
2479
- function createActionHandler(registry, action, handler, config) {
2480
- const timestamp = Date.now();
2481
- const random = Math.random().toString(36).substr(2, 5);
2482
- const finalConfig = {
2483
- priority: config?.priority ?? 0,
2484
- id: config?.id || `react_${String(action)}_${timestamp}_${random}`,
2485
- blocking: config?.blocking ?? false,
2486
- once: config?.once ?? false,
2487
- debounce: config?.debounce ?? void 0,
2488
- throttle: config?.throttle ?? void 0,
2489
- replaceExisting: true
2490
- };
2491
- let currentUnregister;
2492
- let isRegistered = false;
2493
- return {
2494
- /**
2495
- * Register the handler and return cleanup function
2496
- */
2497
- register() {
2498
- if (isRegistered && currentUnregister) currentUnregister();
2499
- currentUnregister = registry.register(action, handler, finalConfig);
2500
- isRegistered = true;
2501
- return currentUnregister;
2502
- },
2503
- /**
2504
- * Unregister the handler if currently registered
2505
- */
2506
- unregister() {
2507
- if (isRegistered && currentUnregister) {
2508
- currentUnregister();
2509
- currentUnregister = void 0;
2510
- isRegistered = false;
2511
- }
2512
- },
2513
- /**
2514
- * Register and return cleanup function (React useEffect pattern)
2515
- */
2516
- registerWithCleanup() {
2517
- const unregisterFn = this.register();
2518
- return () => {
2519
- unregisterFn();
2520
- this.unregister();
2521
- };
2522
- },
2523
- config: finalConfig
2524
- };
2525
- }
2526
- /**
2527
- * ๐Ÿ†• React development utilities
2528
- *
2529
- * Provides debugging and development helpers specifically for React environments.
2530
- */
2531
- const ReactDevUtils = {
2532
- /**
2533
- * Enable detailed React integration debugging
2534
- */
2535
- enableDebugMode() {
2536
- if (typeof window !== "undefined") window.__CONTEXT_ACTION_REACT_DEBUG__ = true;
2537
- },
2538
- /**
2539
- * Disable React integration debugging
2540
- */
2541
- disableDebugMode() {
2542
- if (typeof window !== "undefined") window.__CONTEXT_ACTION_REACT_DEBUG__ = false;
2543
- },
2544
- /**
2545
- * Check if React debug mode is enabled
2546
- */
2547
- isDebugMode() {
2548
- return typeof window !== "undefined" && Boolean(window.__CONTEXT_ACTION_REACT_DEBUG__);
2549
- },
2550
- /**
2551
- * Log React-specific debugging information
2552
- */
2553
- log(component, action, message, data) {
2554
- if (this.isDebugMode()) console.log(`๐ŸŽฏ [React-ActionRegister] [${component}] ${action}: ${message}`, data || "");
2555
- },
2556
- /**
2557
- * Get React integration statistics
2558
- */
2559
- getStats(registry) {
2560
- const registryInfo = registry.getRegistryInfo();
2561
- let reactHandlers = 0;
2562
- registry.getRegisteredActions().forEach((action) => {
2563
- const stats = registry.getActionStats(action);
2564
- if (stats) stats.handlersByPriority.forEach((priorityGroup) => {
2565
- priorityGroup.handlers.forEach((handler) => {
2566
- if (handler.id.includes("react")) reactHandlers++;
2567
- });
2568
- });
2569
- });
2570
- return {
2571
- totalHandlers: registryInfo.totalHandlers,
2572
- reactHandlers,
2573
- registryInfo
2574
- };
2575
- }
2576
- };
2577
- /**
2578
- * ๐Ÿ†• React Error Boundary integration
2579
- *
2580
- * Utilities for integrating ActionRegister errors with React Error Boundaries.
2581
- */
2582
- var ReactActionError = class ReactActionError extends Error {
2583
- constructor(message, action, payload, handlerId = void 0, originalError) {
2584
- super(message);
2585
- this.name = "ReactActionError";
2586
- this.action = action;
2587
- this.payload = payload;
2588
- this.handlerId = handlerId;
2589
- this.timestamp = Date.now();
2590
- if (originalError && originalError.stack) this.stack = originalError.stack;
2591
- }
2592
- /**
2593
- * Create a React Error Boundary compatible error
2594
- */
2595
- static fromActionError(originalError, action, payload, handlerId) {
2596
- return new ReactActionError(`Action '${action}' failed: ${originalError.message}`, action, payload, handlerId, originalError);
2597
- }
2598
- };
2599
- /**
2600
- * ๐Ÿ†• Type guard for React Action Errors
2601
- *
2602
- * @param error - Error to check
2603
- * @returns True if error is a ReactActionError
2604
- */
2605
- function isReactActionError(error) {
2606
- return error instanceof ReactActionError;
2607
- }
2608
-
2609
- //#endregion
2610
- //#region src/action-schema.ts
2611
- /**
2612
- * Zod ์Šคํ‚ค๋งˆ๋ฅผ JSON Schema๋กœ ๋ณ€ํ™˜ (Zod 4 ๋„ค์ดํ‹ฐ๋ธŒ API)
2613
- *
2614
- * @param schema - Zod ์Šคํ‚ค๋งˆ
2615
- * @returns JSON Schema (draft-7)
2616
- */
2617
- function zodToJsonSchema(schema, zodModule) {
2618
- return zodModule.toJSONSchema(schema, {
2619
- target: "draft-7",
2620
- metadata: zodModule.globalRegistry
2621
- });
2622
- }
2623
- /**
2624
- * Zod ์Šคํ‚ค๋งˆ ๊ธฐ๋ฐ˜ Action ์ •์˜
2625
- *
2626
- * defineTool ํŒจํ„ด์„ ๊ธฐ๋ฐ˜์œผ๋กœ context-action์— ๋งž๊ฒŒ ๊ตฌํ˜„:
2627
- * - Single Source of Truth: Zod ์Šคํ‚ค๋งˆ๋กœ ํƒ€์ž… + ๊ฒ€์ฆ + ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํ†ตํ•ฉ
2628
- * - ๋Ÿฐํƒ€์ž„ ๊ฒ€์ฆ: validate(), safeParse()
2629
- * - Tool Chain ํ˜ธํ™˜: toMCP(), toOpenAI(), toAnthropic()
2630
- *
2631
- * @param options - Action ์ •์˜ ์˜ต์…˜
2632
- * @param zodModule - Zod ๋ชจ๋“ˆ (peerDependency๋กœ ์ฃผ์ž…)
2633
- * @returns UnifiedAction ์ธ์Šคํ„ด์Šค
2634
- *
2635
- * @example
2636
- * ```typescript
2637
- * import { z } from 'zod';
2638
- * import { defineAction } from '@context-action/core';
2639
- *
2640
- * const updateUserAction = defineAction({
2641
- * name: 'updateUser',
2642
- * description: 'Update user profile',
2643
- * parameters: z.object({
2644
- * id: z.string().min(1).meta({ description: 'User ID' }),
2645
- * name: z.string().min(2).max(50).meta({ description: 'User name' }),
2646
- * email: z.string().email().optional(),
2647
- * }),
2648
- * }, z);
2649
- *
2650
- * // ๊ฒ€์ฆ
2651
- * const validated = updateUserAction.validate({ id: '123', name: 'John' });
2652
- *
2653
- * // Tool chain ๋ณ€ํ™˜
2654
- * const mcpTool = updateUserAction.toMCP();
2655
- * ```
2656
- */
2657
- function defineAction(options, zodModule) {
2658
- const { name, description, parameters } = options;
2659
- const jsonSchema = zodToJsonSchema(parameters, zodModule);
2660
- return {
2661
- name,
2662
- description,
2663
- zodSchema: parameters,
2664
- jsonSchema,
2665
- validate: (payload) => {
2666
- return parameters.parse(payload);
2667
- },
2668
- safeParse: (payload) => {
2669
- return parameters.safeParse(payload);
2670
- },
2671
- toJSONSchema: () => jsonSchema,
2672
- toMCP: () => ({
2673
- name,
2674
- description,
2675
- inputSchema: jsonSchema
2676
- }),
2677
- toOpenAI: () => ({
2678
- type: "function",
2679
- function: {
2680
- name,
2681
- description,
2682
- parameters: {
2683
- type: "object",
2684
- properties: jsonSchema.properties ?? {},
2685
- required: jsonSchema.required
2686
- }
2687
- }
2688
- }),
2689
- toAnthropic: () => ({
2690
- name,
2691
- description,
2692
- input_schema: jsonSchema
2693
- })
2694
- };
2695
- }
2696
- /**
2697
- * ๋‹ค์ค‘ Action ์Šคํ‚ค๋งˆ ์ƒ์„ฑ
2698
- *
2699
- * ์—ฌ๋Ÿฌ defineAction์„ ๋ฌถ์–ด์„œ ActionSchemaMap ์ƒ์„ฑ
2700
- *
2701
- * @param actions - UnifiedAction ๋งต
2702
- * @returns ActionSchemaMap
2703
- *
2704
- * @example
2705
- * ```typescript
2706
- * const userActionSchema = createActionSchema({
2707
- * updateUser: defineAction({ ... }, z),
2708
- * deleteUser: defineAction({ ... }, z),
2709
- * });
2710
- *
2711
- * type UserActions = InferActionPayloadMap<typeof userActionSchema>;
2712
- * ```
2713
- */
2714
- function createActionSchema(actions) {
2715
- return actions;
2716
- }
2717
- /**
2718
- * Zod ๋ชจ๋“ˆ์„ ๋ฐ”์ธ๋”ฉํ•œ defineAction ํŒฉํ† ๋ฆฌ ์ƒ์„ฑ
2719
- *
2720
- * ๋งค๋ฒˆ z ๋ชจ๋“ˆ์„ ์ „๋‹ฌํ•˜์ง€ ์•Š์•„๋„ ๋˜๋„๋ก ํŒฉํ† ๋ฆฌ ํŒจํ„ด ์ œ๊ณต
2721
- *
2722
- * @param zodModule - Zod ๋ชจ๋“ˆ
2723
- * @returns defineAction ํ•จ์ˆ˜ (z ๋ฐ”์ธ๋”ฉ๋จ)
2724
- *
2725
- * @example
2726
- * ```typescript
2727
- * import { z } from 'zod';
2728
- * import { createActionFactory } from '@context-action/core';
2729
- *
2730
- * const defineAction = createActionFactory(z);
2731
- *
2732
- * const updateUser = defineAction({
2733
- * name: 'updateUser',
2734
- * parameters: z.object({ id: z.string() }),
2735
- * });
2736
- * ```
2737
- */
2738
- function createActionFactory(zodModule) {
2739
- return (options) => {
2740
- return defineAction(options, zodModule);
2741
- };
2742
- }
2743
-
2744
- //#endregion
2745
- export { ActionGuard, ActionRegister, ActionRegisterDestroyedError, ActionTimeoutError, ActionValidationError, ReactActionError, ReactDevUtils, createActionFactory, createActionHandler, createActionSchema, defineAction, executeParallel, executeRace, executeSequential, isActionRegisterDestroyedError, isActionTimeoutError, isActionValidationError, isReactActionError, zodToJsonSchema };
2333
+ export { ActionGuard, ActionRegister, ActionRegisterDestroyedError, ActionTimeoutError, ActionValidationError, executeParallel, executeRace, executeSequential, isActionRegisterDestroyedError, isActionTimeoutError, isActionValidationError };
2746
2334
  //# sourceMappingURL=index.js.map