@rotorsoft/act 0.36.0 → 0.37.0
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/.tsbuildinfo +1 -1
- package/dist/@types/builders/act-builder.d.ts.map +1 -1
- package/dist/@types/internal/event-sourcing.d.ts.map +1 -1
- package/dist/@types/internal/event-versions.d.ts +44 -0
- package/dist/@types/internal/event-versions.d.ts.map +1 -0
- package/dist/@types/internal/index.d.ts +1 -0
- package/dist/@types/internal/index.d.ts.map +1 -1
- package/dist/index.cjs +87 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +87 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1317,6 +1317,43 @@ var DrainController = class {
|
|
|
1317
1317
|
}
|
|
1318
1318
|
};
|
|
1319
1319
|
|
|
1320
|
+
// src/internal/event-versions.ts
|
|
1321
|
+
var VERSION_SUFFIX = /^(.+?)_v(\d+)$/;
|
|
1322
|
+
function parse(name) {
|
|
1323
|
+
const m = name.match(VERSION_SUFFIX);
|
|
1324
|
+
if (m) {
|
|
1325
|
+
const v = Number.parseInt(m[2], 10);
|
|
1326
|
+
if (v >= 2) return { base: m[1], version: v };
|
|
1327
|
+
}
|
|
1328
|
+
return { base: name, version: 1 };
|
|
1329
|
+
}
|
|
1330
|
+
function deprecatedEventNames(names) {
|
|
1331
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1332
|
+
for (const name of names) {
|
|
1333
|
+
const { base, version } = parse(name);
|
|
1334
|
+
const list = groups.get(base);
|
|
1335
|
+
if (list) list.push({ version, name });
|
|
1336
|
+
else groups.set(base, [{ version, name }]);
|
|
1337
|
+
}
|
|
1338
|
+
const deprecated = /* @__PURE__ */ new Set();
|
|
1339
|
+
for (const list of groups.values()) {
|
|
1340
|
+
if (list.length < 2) continue;
|
|
1341
|
+
list.sort((a, b) => b.version - a.version);
|
|
1342
|
+
for (let i = 1; i < list.length; i++) deprecated.add(list[i].name);
|
|
1343
|
+
}
|
|
1344
|
+
return deprecated;
|
|
1345
|
+
}
|
|
1346
|
+
function currentVersionOf(deprecatedName, allNames) {
|
|
1347
|
+
const target = parse(deprecatedName);
|
|
1348
|
+
let highest;
|
|
1349
|
+
for (const name of allNames) {
|
|
1350
|
+
const { base, version } = parse(name);
|
|
1351
|
+
if (base !== target.base) continue;
|
|
1352
|
+
if (!highest || version > highest.version) highest = { version, name };
|
|
1353
|
+
}
|
|
1354
|
+
return highest && highest.version > target.version ? highest.name : void 0;
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1320
1357
|
// src/internal/merge.ts
|
|
1321
1358
|
import { ZodObject } from "zod";
|
|
1322
1359
|
function baseTypeName(zodType) {
|
|
@@ -1729,6 +1766,20 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
1729
1766
|
return [snapshot];
|
|
1730
1767
|
}
|
|
1731
1768
|
const tuples = Array.isArray(result[0]) ? result : [result];
|
|
1769
|
+
const deprecated = me._deprecated;
|
|
1770
|
+
if (deprecated && deprecated.size > 0) {
|
|
1771
|
+
const me_ = me;
|
|
1772
|
+
const warned = me_._warned ?? (me_._warned = /* @__PURE__ */ new Set());
|
|
1773
|
+
for (const [name] of tuples) {
|
|
1774
|
+
const evt = name;
|
|
1775
|
+
if (deprecated.has(evt) && !warned.has(evt)) {
|
|
1776
|
+
warned.add(evt);
|
|
1777
|
+
log().warn(
|
|
1778
|
+
`Action "${String(action2)}" emitted deprecated event "${evt}". A newer version exists in the registry \u2014 update the action's .emit() to target the current version. (warned once per process)`
|
|
1779
|
+
);
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1732
1783
|
const emitted = tuples.map(([name, data]) => ({
|
|
1733
1784
|
name,
|
|
1734
1785
|
data: skipValidation ? data : validate(name, data, me.events[name])
|
|
@@ -2729,6 +2780,38 @@ function act() {
|
|
|
2729
2780
|
mergeProjection(proj, registry.events);
|
|
2730
2781
|
registerBatchHandler(proj, batchHandlers);
|
|
2731
2782
|
}
|
|
2783
|
+
const deprecationSummary = [];
|
|
2784
|
+
for (const state2 of states.values()) {
|
|
2785
|
+
const eventNames = Object.keys(state2.events);
|
|
2786
|
+
const deprecated = deprecatedEventNames(eventNames);
|
|
2787
|
+
if (deprecated.size === 0) continue;
|
|
2788
|
+
state2._deprecated = deprecated;
|
|
2789
|
+
for (const name of deprecated) {
|
|
2790
|
+
const current = currentVersionOf(name, eventNames);
|
|
2791
|
+
deprecationSummary.push({
|
|
2792
|
+
stateName: state2.name,
|
|
2793
|
+
deprecated: name,
|
|
2794
|
+
current
|
|
2795
|
+
});
|
|
2796
|
+
}
|
|
2797
|
+
for (const [actionName, handler] of Object.entries(state2.on)) {
|
|
2798
|
+
const staticTarget = handler?._staticEmit;
|
|
2799
|
+
if (staticTarget && deprecated.has(staticTarget)) {
|
|
2800
|
+
const current = currentVersionOf(staticTarget, eventNames);
|
|
2801
|
+
throw new Error(
|
|
2802
|
+
`Action "${actionName}" in state "${state2.name}" emits deprecated event "${staticTarget}". A newer version exists: "${current}". Update the .emit() call to target the current version. The reducer (.patch) for "${staticTarget}" stays as-is \u2014 historical events still need it.`
|
|
2803
|
+
);
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2807
|
+
if (deprecationSummary.length > 0) {
|
|
2808
|
+
const list = deprecationSummary.map(
|
|
2809
|
+
(d) => `"${d.deprecated}" (current: "${d.current}", state: "${d.stateName}")`
|
|
2810
|
+
).join(", ");
|
|
2811
|
+
log().info(
|
|
2812
|
+
`Act registered ${deprecationSummary.length} deprecated event(s): ${list}. These are legacy versions kept for the read path. Consider truncating closed streams via app.close() when feasible to reduce historical event load. See docs/docs/architecture/event-schema-evolution.md.`
|
|
2813
|
+
);
|
|
2814
|
+
}
|
|
2732
2815
|
return new Act(
|
|
2733
2816
|
registry,
|
|
2734
2817
|
states,
|
|
@@ -2915,10 +2998,10 @@ function action_builder(state2) {
|
|
|
2915
2998
|
function emit(handler) {
|
|
2916
2999
|
if (typeof handler === "string") {
|
|
2917
3000
|
const eventName = handler;
|
|
2918
|
-
|
|
2919
|
-
eventName
|
|
2920
|
-
|
|
2921
|
-
];
|
|
3001
|
+
const emitFn = Object.assign((payload) => [eventName, payload], {
|
|
3002
|
+
_staticEmit: eventName
|
|
3003
|
+
});
|
|
3004
|
+
internal.on[action2] = emitFn;
|
|
2922
3005
|
} else {
|
|
2923
3006
|
internal.on[action2] = handler;
|
|
2924
3007
|
}
|