@context-action/core 0.7.8 → 0.8.1

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
@@ -787,6 +787,79 @@ var ActionRegister = class {
787
787
  });
788
788
  }
789
789
  /**
790
+ * 🆕 Action-based dispatcher
791
+ *
792
+ * Provides function-based access to actions for more convenient dispatching.
793
+ * Each action becomes a callable function that can be invoked directly.
794
+ *
795
+ * @example
796
+ * ```typescript
797
+ * interface MyActions extends ActionPayloadMap {
798
+ * userLogin: { userId: string; email: string };
799
+ * resetApp: void;
800
+ * }
801
+ *
802
+ * const registry = new ActionRegister<MyActions>();
803
+ *
804
+ * // Function-based dispatching
805
+ * await registry.actions.userLogin({ userId: '123', email: 'test@example.com' });
806
+ * await registry.actions.resetApp();
807
+ * ```
808
+ *
809
+ * @public
810
+ */
811
+ get actions() {
812
+ return new Proxy({}, { get: (target, prop) => {
813
+ if (typeof prop === "string" && this.pipelines.has(prop)) {
814
+ const actionKey = prop;
815
+ return (payloadOrOptions, options) => {
816
+ const isDispatchOptions = (obj) => {
817
+ return obj && typeof obj === "object" && ("debounce" in obj || "throttle" in obj || "executionMode" in obj || "signal" in obj || "immediate" in obj || "filter" in obj || "result" in obj);
818
+ };
819
+ if (payloadOrOptions && isDispatchOptions(payloadOrOptions)) return this.dispatch(actionKey, void 0, payloadOrOptions);
820
+ else return this.dispatch(actionKey, payloadOrOptions, options);
821
+ };
822
+ }
823
+ } });
824
+ }
825
+ /**
826
+ * Actions-based dispatching with result collection
827
+ *
828
+ * Provides a function-based interface for dispatching actions with detailed execution results.
829
+ * Each registered action becomes a callable function that returns ExecutionResult.
830
+ *
831
+ * @example
832
+ * ```typescript
833
+ * // Actions with payload
834
+ * const result = await registry.actionsWithResult.userLogin({ userId: '123', email: 'user@example.com' });
835
+ *
836
+ * // Actions without payload
837
+ * const result = await registry.actionsWithResult.userLogout();
838
+ *
839
+ * // With options
840
+ * const result = await registry.actionsWithResult.processData(
841
+ * { data: { name: 'test' }, type: 'json' },
842
+ * { executionMode: 'parallel' }
843
+ * );
844
+ * ```
845
+ *
846
+ * @returns Proxy object with action functions that return ExecutionResult
847
+ */
848
+ get actionsWithResult() {
849
+ return new Proxy({}, { get: (target, prop) => {
850
+ if (typeof prop === "string" && this.pipelines.has(prop)) {
851
+ const actionKey = prop;
852
+ return (payloadOrOptions, options) => {
853
+ const isDispatchOptions = (obj) => {
854
+ return obj && typeof obj === "object" && ("debounce" in obj || "throttle" in obj || "executionMode" in obj || "signal" in obj || "immediate" in obj || "filter" in obj || "result" in obj);
855
+ };
856
+ if (payloadOrOptions && isDispatchOptions(payloadOrOptions)) return this.dispatchWithResult(actionKey, void 0, payloadOrOptions);
857
+ else return this.dispatchWithResult(actionKey, payloadOrOptions, options);
858
+ };
859
+ }
860
+ } });
861
+ }
862
+ /**
790
863
  * Register an action handler with optional configuration
791
864
  *
792
865
  * @param action - The action type to register handler for
@@ -952,21 +1025,6 @@ var ActionRegister = class {
952
1025
  });
953
1026
  return unregister;
954
1027
  }
955
- /**
956
- * Dispatch an action with optional execution options
957
- *
958
- * @param action - The action type to dispatch
959
- * @param payload - The action payload data
960
- * @param options - Optional dispatch options (execution mode, filters, etc.)
961
- *
962
- * @returns Promise that resolves when all handlers complete
963
- *
964
- * @throws {Error} When action dispatching fails
965
- *
966
- * @see https://mineclover.github.io/context-action/en/guide/patterns/action/basic-usage
967
- *
968
- * @public
969
- */
970
1028
  async dispatch(action, payload, options) {
971
1029
  if (options?.immediate || !this.dispatchQueue) return this._performDispatch(action, payload, options);
972
1030
  else return this.dispatchQueue.enqueue(async () => {
@@ -998,6 +1056,10 @@ var ActionRegister = class {
998
1056
  pipelineMap: Object.fromEntries(Array.from(this.pipelines.entries()).map(([k, v]) => [k, v.length]))
999
1057
  });
1000
1058
  if (!pipeline || pipeline.length === 0) {
1059
+ const warningMessage = `⚠️ Action '${String(action)}' has no registered handlers. This action will be ignored.`;
1060
+ console.warn(warningMessage);
1061
+ console.warn("💡 Tip: Register a handler using registry.register() before dispatching this action.");
1062
+ console.warn("📋 Available actions:", Array.from(this.pipelines.keys()));
1001
1063
  this.log(`No handlers found for action '${String(action)}', dispatch cancelled`, {}, "warn");
1002
1064
  return;
1003
1065
  }
@@ -1094,26 +1156,32 @@ var ActionRegister = class {
1094
1156
  errors: []
1095
1157
  };
1096
1158
  const pipeline = this.pipelines.get(action);
1097
- if (!pipeline || pipeline.length === 0) return {
1098
- success: true,
1099
- aborted: false,
1100
- abortReason: void 0,
1101
- terminated: false,
1102
- result: void 0,
1103
- successResults: [],
1104
- results: [],
1105
- failedResults: [],
1106
- execution: {
1107
- duration: 0,
1108
- handlersExecuted: 0,
1109
- handlersSkipped: 0,
1110
- handlersFailed: 0,
1111
- startTime: _startTime,
1112
- endTime: _startTime
1113
- },
1114
- handlers: [],
1115
- errors: []
1116
- };
1159
+ if (!pipeline || pipeline.length === 0) {
1160
+ const warningMessage = `⚠️ Action '${String(action)}' has no registered handlers. This action will be ignored.`;
1161
+ console.warn(warningMessage);
1162
+ console.warn("💡 Tip: Register a handler using registry.register() before dispatching this action.");
1163
+ console.warn("📋 Available actions:", Array.from(this.pipelines.keys()));
1164
+ return {
1165
+ success: true,
1166
+ aborted: false,
1167
+ abortReason: void 0,
1168
+ terminated: false,
1169
+ result: void 0,
1170
+ successResults: [],
1171
+ results: [],
1172
+ failedResults: [],
1173
+ execution: {
1174
+ duration: 0,
1175
+ handlersExecuted: 0,
1176
+ handlersSkipped: 0,
1177
+ handlersFailed: 0,
1178
+ startTime: _startTime,
1179
+ endTime: _startTime
1180
+ },
1181
+ handlers: [],
1182
+ errors: []
1183
+ };
1184
+ }
1117
1185
  const filteredHandlers = options?.filter ? this.filterHandlers(pipeline, options.filter) : pipeline;
1118
1186
  const actionKey = String(action);
1119
1187
  const guardResult = await this.applyActionGuardControlsWithResult(actionKey, filteredHandlers, options, _startTime, pipeline.length);
@@ -1333,8 +1401,7 @@ var ActionRegister = class {
1333
1401
  };
1334
1402
  controller.mergeResult = (merger) => {
1335
1403
  const currentResult = context.results[context.results.length - 1];
1336
- const previousResults = context.results.slice(0, -1);
1337
- const mergedResult = merger(previousResults, currentResult);
1404
+ const mergedResult = merger(context.results.slice(0, -1), currentResult);
1338
1405
  context.results[context.results.length - 1] = mergedResult;
1339
1406
  };
1340
1407
  return controller;