@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/LICENSE +201 -0
- package/dist/index.cjs +108 -37
- package/dist/index.d.cts +6 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +104 -37
- package/dist/index.js.map +1 -1
- package/package.json +18 -19
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)
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
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
|
|
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;
|