@rotorsoft/act 0.37.0 → 0.38.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/README.md +33 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/@types/act.d.ts +14 -0
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/builders/act-builder.d.ts.map +1 -1
- package/dist/@types/ports.d.ts +10 -51
- package/dist/@types/ports.d.ts.map +1 -1
- package/dist/index.cjs +150 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +149 -114
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15,6 +15,9 @@ import {
|
|
|
15
15
|
ZodEmpty
|
|
16
16
|
} from "./chunk-AGWZY6YT.js";
|
|
17
17
|
|
|
18
|
+
// src/ports.ts
|
|
19
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
20
|
+
|
|
18
21
|
// src/adapters/console-logger.ts
|
|
19
22
|
var LEVEL_VALUES = {
|
|
20
23
|
fatal: 60,
|
|
@@ -803,6 +806,7 @@ var InMemoryStore = class {
|
|
|
803
806
|
};
|
|
804
807
|
|
|
805
808
|
// src/ports.ts
|
|
809
|
+
var scoped = new AsyncLocalStorage();
|
|
806
810
|
var ExitCodes = ["ERROR", "EXIT"];
|
|
807
811
|
var adapters = /* @__PURE__ */ new Map();
|
|
808
812
|
function port(injector) {
|
|
@@ -822,11 +826,17 @@ var log = port(function log2(adapter) {
|
|
|
822
826
|
pretty: cfg.env !== "production"
|
|
823
827
|
});
|
|
824
828
|
});
|
|
825
|
-
var
|
|
826
|
-
return adapter
|
|
829
|
+
var _store = port(function store(adapter) {
|
|
830
|
+
return adapter ?? new InMemoryStore();
|
|
831
|
+
});
|
|
832
|
+
var store2 = ((adapter) => {
|
|
833
|
+
return scoped.getStore()?.store ?? _store(adapter);
|
|
827
834
|
});
|
|
828
|
-
var
|
|
829
|
-
return adapter
|
|
835
|
+
var _cache = port(function cache(adapter) {
|
|
836
|
+
return adapter ?? new InMemoryCache();
|
|
837
|
+
});
|
|
838
|
+
var cache2 = ((adapter) => {
|
|
839
|
+
return scoped.getStore()?.cache ?? _cache(adapter);
|
|
830
840
|
});
|
|
831
841
|
var disposers = [];
|
|
832
842
|
async function disposeAndExit(code = "EXIT") {
|
|
@@ -956,7 +966,7 @@ async function scanStreamHeads(streams) {
|
|
|
956
966
|
let maxId = -1;
|
|
957
967
|
let version = -1;
|
|
958
968
|
let lastEventName = "";
|
|
959
|
-
await
|
|
969
|
+
await store2().query(
|
|
960
970
|
(e) => {
|
|
961
971
|
if (e.name === TOMBSTONE_EVENT || maxId !== -1) return;
|
|
962
972
|
maxId = e.id;
|
|
@@ -973,7 +983,7 @@ async function scanStreamHeads(streams) {
|
|
|
973
983
|
async function partitionBySafety(streamInfo, reactiveEventsSize, skipped) {
|
|
974
984
|
if (reactiveEventsSize === 0) return [...streamInfo.keys()];
|
|
975
985
|
const pendingSet = /* @__PURE__ */ new Set();
|
|
976
|
-
await
|
|
986
|
+
await store2().query_streams((position) => {
|
|
977
987
|
const sourceRe = position.source ? RegExp(position.source) : void 0;
|
|
978
988
|
for (const [stream, info] of streamInfo) {
|
|
979
989
|
if ((!sourceRe || sourceRe.test(stream)) && position.at < info.maxId) {
|
|
@@ -1044,13 +1054,13 @@ async function truncateAndWarmCache(guarded, seedStates, guardEvents, correlatio
|
|
|
1044
1054
|
}
|
|
1045
1055
|
};
|
|
1046
1056
|
});
|
|
1047
|
-
const truncated = await
|
|
1057
|
+
const truncated = await store2().truncate(truncTargets);
|
|
1048
1058
|
await Promise.all(
|
|
1049
1059
|
guarded.map(async (stream) => {
|
|
1050
1060
|
const entry = truncated.get(stream);
|
|
1051
1061
|
const state2 = seedStates.get(stream);
|
|
1052
1062
|
if (state2 && entry) {
|
|
1053
|
-
await
|
|
1063
|
+
await cache2().set(stream, {
|
|
1054
1064
|
state: state2,
|
|
1055
1065
|
version: entry.committed.version,
|
|
1056
1066
|
event_id: entry.committed.id,
|
|
@@ -1058,7 +1068,7 @@ async function truncateAndWarmCache(guarded, seedStates, guardEvents, correlatio
|
|
|
1058
1068
|
snaps: 1
|
|
1059
1069
|
});
|
|
1060
1070
|
} else {
|
|
1061
|
-
await
|
|
1071
|
+
await cache2().invalidate(stream);
|
|
1062
1072
|
}
|
|
1063
1073
|
})
|
|
1064
1074
|
);
|
|
@@ -1093,7 +1103,7 @@ var CorrelateCycle = class {
|
|
|
1093
1103
|
async init() {
|
|
1094
1104
|
if (this._initialized) return;
|
|
1095
1105
|
this._initialized = true;
|
|
1096
|
-
const { watermark } = await
|
|
1106
|
+
const { watermark } = await store2().subscribe([...this.staticTargets]);
|
|
1097
1107
|
this._checkpoint = watermark;
|
|
1098
1108
|
this.onInit?.();
|
|
1099
1109
|
for (const { stream } of this.staticTargets) {
|
|
@@ -1112,7 +1122,7 @@ var CorrelateCycle = class {
|
|
|
1112
1122
|
const after = Math.max(this._checkpoint, query.after || -1);
|
|
1113
1123
|
const correlated = /* @__PURE__ */ new Map();
|
|
1114
1124
|
let last_id = after;
|
|
1115
|
-
await
|
|
1125
|
+
await store2().query(
|
|
1116
1126
|
(event) => {
|
|
1117
1127
|
last_id = event.id;
|
|
1118
1128
|
const register = this.registry.events[event.name];
|
|
@@ -1632,12 +1642,12 @@ var SettleLoop = class {
|
|
|
1632
1642
|
};
|
|
1633
1643
|
|
|
1634
1644
|
// src/internal/drain.ts
|
|
1635
|
-
var claim = (lagging, leading, by, millis) =>
|
|
1645
|
+
var claim = (lagging, leading, by, millis) => store2().claim(lagging, leading, by, millis);
|
|
1636
1646
|
async function fetch(leased, eventLimit) {
|
|
1637
1647
|
return Promise.all(
|
|
1638
1648
|
leased.map(async ({ stream, source, at, lagging }) => {
|
|
1639
1649
|
const events = [];
|
|
1640
|
-
await
|
|
1650
|
+
await store2().query((e) => events.push(e), {
|
|
1641
1651
|
stream: source,
|
|
1642
1652
|
after: at,
|
|
1643
1653
|
limit: eventLimit
|
|
@@ -1646,9 +1656,9 @@ async function fetch(leased, eventLimit) {
|
|
|
1646
1656
|
})
|
|
1647
1657
|
);
|
|
1648
1658
|
}
|
|
1649
|
-
var ack = (leases) =>
|
|
1650
|
-
var block = (leases) =>
|
|
1651
|
-
var subscribe = (streams) =>
|
|
1659
|
+
var ack = (leases) => store2().ack(leases);
|
|
1660
|
+
var block = (leases) => store2().block(leases);
|
|
1661
|
+
var subscribe = (streams) => store2().subscribe(streams);
|
|
1652
1662
|
|
|
1653
1663
|
// src/internal/event-sourcing.ts
|
|
1654
1664
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
@@ -1656,7 +1666,7 @@ import { patch } from "@rotorsoft/act-patch";
|
|
|
1656
1666
|
async function snap(snapshot) {
|
|
1657
1667
|
try {
|
|
1658
1668
|
const { id, stream, name, meta, version } = snapshot.event;
|
|
1659
|
-
await
|
|
1669
|
+
await store2().commit(
|
|
1660
1670
|
stream,
|
|
1661
1671
|
[{ name: SNAP_EVENT, data: snapshot.state }],
|
|
1662
1672
|
{
|
|
@@ -1672,7 +1682,7 @@ async function snap(snapshot) {
|
|
|
1672
1682
|
}
|
|
1673
1683
|
async function tombstone(stream, expectedVersion, correlation) {
|
|
1674
1684
|
try {
|
|
1675
|
-
const [committed] = await
|
|
1685
|
+
const [committed] = await store2().commit(
|
|
1676
1686
|
stream,
|
|
1677
1687
|
[{ name: TOMBSTONE_EVENT, data: {} }],
|
|
1678
1688
|
{ correlation, causation: {} },
|
|
@@ -1686,7 +1696,7 @@ async function tombstone(stream, expectedVersion, correlation) {
|
|
|
1686
1696
|
}
|
|
1687
1697
|
async function load(me, stream, callback, asOf) {
|
|
1688
1698
|
const timeTravel = !!asOf && Object.values(asOf).some((v) => v !== void 0);
|
|
1689
|
-
const cached = timeTravel ? void 0 : await
|
|
1699
|
+
const cached = timeTravel ? void 0 : await cache2().get(stream);
|
|
1690
1700
|
const cache_hit = !!cached;
|
|
1691
1701
|
let state2 = cached?.state ?? (me.init ? me.init() : {});
|
|
1692
1702
|
let patches = cached?.patches ?? 0;
|
|
@@ -1694,7 +1704,7 @@ async function load(me, stream, callback, asOf) {
|
|
|
1694
1704
|
let version = cached?.version ?? -1;
|
|
1695
1705
|
let replayed = 0;
|
|
1696
1706
|
let event;
|
|
1697
|
-
await
|
|
1707
|
+
await store2().query(
|
|
1698
1708
|
(e) => {
|
|
1699
1709
|
event = e;
|
|
1700
1710
|
version = e.version;
|
|
@@ -1729,7 +1739,7 @@ async function load(me, stream, callback, asOf) {
|
|
|
1729
1739
|
}
|
|
1730
1740
|
);
|
|
1731
1741
|
if (replayed > 0 && !timeTravel && event) {
|
|
1732
|
-
await
|
|
1742
|
+
await cache2().set(stream, {
|
|
1733
1743
|
state: state2,
|
|
1734
1744
|
version,
|
|
1735
1745
|
event_id: event.id,
|
|
@@ -1802,7 +1812,7 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
1802
1812
|
};
|
|
1803
1813
|
let committed;
|
|
1804
1814
|
try {
|
|
1805
|
-
committed = await
|
|
1815
|
+
committed = await store2().commit(
|
|
1806
1816
|
stream,
|
|
1807
1817
|
emitted,
|
|
1808
1818
|
meta,
|
|
@@ -1814,7 +1824,7 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
1814
1824
|
);
|
|
1815
1825
|
} catch (error) {
|
|
1816
1826
|
if (error instanceof ConcurrencyError) {
|
|
1817
|
-
await
|
|
1827
|
+
await cache2().invalidate(stream);
|
|
1818
1828
|
}
|
|
1819
1829
|
throw error;
|
|
1820
1830
|
}
|
|
@@ -1836,7 +1846,7 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
1836
1846
|
});
|
|
1837
1847
|
const last = snapshots.at(-1);
|
|
1838
1848
|
const snapped = me.snap?.(last);
|
|
1839
|
-
|
|
1849
|
+
cache2().set(stream, {
|
|
1840
1850
|
state: last.state,
|
|
1841
1851
|
version: last.event.version,
|
|
1842
1852
|
event_id: last.event.id,
|
|
@@ -2031,6 +2041,7 @@ var Act = class {
|
|
|
2031
2041
|
this.registry = registry;
|
|
2032
2042
|
this._states = _states;
|
|
2033
2043
|
this._batch_handlers = batchHandlers;
|
|
2044
|
+
this._scoped = options.scoped ? (fn) => scoped.run(options.scoped, fn) : (fn) => fn();
|
|
2034
2045
|
this._es = buildEs(this._logger);
|
|
2035
2046
|
this._cd = buildDrain(this._logger);
|
|
2036
2047
|
this._handle = buildHandle({
|
|
@@ -2076,7 +2087,7 @@ var Act = class {
|
|
|
2076
2087
|
},
|
|
2077
2088
|
options.settleDebounceMs ?? DEFAULT_SETTLE_DEBOUNCE_MS
|
|
2078
2089
|
);
|
|
2079
|
-
this._notify_disposer = this._wireNotify();
|
|
2090
|
+
this._notify_disposer = this._wireNotify(options.scoped?.store ?? store2());
|
|
2080
2091
|
dispose(async () => {
|
|
2081
2092
|
this._emitter.removeAllListeners();
|
|
2082
2093
|
this.stop_correlations();
|
|
@@ -2145,6 +2156,11 @@ var Act = class {
|
|
|
2145
2156
|
_event_to_state;
|
|
2146
2157
|
/** Logger resolved at construction time (after user port configuration) */
|
|
2147
2158
|
_logger = log();
|
|
2159
|
+
/** Wraps a public-method body so internal `store()`/`cache()` resolve to the
|
|
2160
|
+
* per-Act ports (ACT-501). No-op when the Act is unscoped — so the singleton
|
|
2161
|
+
* path keeps reading fresh `store()`/`cache()` per call, which matters for
|
|
2162
|
+
* tests that dispose and re-seed mid-suite. */
|
|
2163
|
+
_scoped;
|
|
2148
2164
|
/** Pre-bound IAct methods reused across drain cycles. Only `do` varies per
|
|
2149
2165
|
* payload (it captures the triggering event for reactingTo auto-inject). */
|
|
2150
2166
|
_bound_do = this.do.bind(this);
|
|
@@ -2160,9 +2176,8 @@ var Act = class {
|
|
|
2160
2176
|
* subscription was made). Errors during subscription are logged but
|
|
2161
2177
|
* never thrown — `notify` is a hint, not a contract.
|
|
2162
2178
|
*/
|
|
2163
|
-
async _wireNotify() {
|
|
2179
|
+
async _wireNotify(s) {
|
|
2164
2180
|
if (this._reactive_events.size === 0) return void 0;
|
|
2165
|
-
const s = store();
|
|
2166
2181
|
if (!s.notify) return void 0;
|
|
2167
2182
|
try {
|
|
2168
2183
|
return await s.notify((notification) => {
|
|
@@ -2266,35 +2281,39 @@ var Act = class {
|
|
|
2266
2281
|
* @see {@link ValidationError}, {@link InvariantError}, {@link ConcurrencyError}
|
|
2267
2282
|
*/
|
|
2268
2283
|
async do(action2, target, payload, reactingTo, skipValidation = false) {
|
|
2269
|
-
|
|
2270
|
-
this.
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
this.
|
|
2281
|
-
|
|
2284
|
+
return this._scoped(async () => {
|
|
2285
|
+
const snapshots = await this._es.action(
|
|
2286
|
+
this.registry.actions[action2],
|
|
2287
|
+
action2,
|
|
2288
|
+
target,
|
|
2289
|
+
payload,
|
|
2290
|
+
reactingTo,
|
|
2291
|
+
skipValidation
|
|
2292
|
+
);
|
|
2293
|
+
if (this._reactive_events.size > 0) {
|
|
2294
|
+
for (const snap2 of snapshots) {
|
|
2295
|
+
if (snap2.event?.name && this._reactive_events.has(snap2.event.name)) {
|
|
2296
|
+
this._drain.arm();
|
|
2297
|
+
break;
|
|
2298
|
+
}
|
|
2282
2299
|
}
|
|
2283
2300
|
}
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2301
|
+
this.emit("committed", snapshots);
|
|
2302
|
+
return snapshots;
|
|
2303
|
+
});
|
|
2287
2304
|
}
|
|
2288
2305
|
async load(stateOrName, stream, callback, asOf) {
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2306
|
+
return this._scoped(async () => {
|
|
2307
|
+
let merged;
|
|
2308
|
+
if (typeof stateOrName === "string") {
|
|
2309
|
+
const found = this._states.get(stateOrName);
|
|
2310
|
+
if (!found) throw new Error(`State "${stateOrName}" not found`);
|
|
2311
|
+
merged = found;
|
|
2312
|
+
} else {
|
|
2313
|
+
merged = this._states.get(stateOrName.name) || stateOrName;
|
|
2314
|
+
}
|
|
2315
|
+
return await this._es.load(merged, stream, callback, asOf);
|
|
2316
|
+
});
|
|
2298
2317
|
}
|
|
2299
2318
|
/**
|
|
2300
2319
|
* Queries the event store for events matching a filter.
|
|
@@ -2343,14 +2362,16 @@ var Act = class {
|
|
|
2343
2362
|
* @see {@link query_array} for loading events into memory
|
|
2344
2363
|
*/
|
|
2345
2364
|
async query(query, callback) {
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2365
|
+
return this._scoped(async () => {
|
|
2366
|
+
let first;
|
|
2367
|
+
let last;
|
|
2368
|
+
const count = await store2().query((e) => {
|
|
2369
|
+
if (!first) first = e;
|
|
2370
|
+
last = e;
|
|
2371
|
+
callback?.(e);
|
|
2372
|
+
}, query);
|
|
2373
|
+
return { first, last, count };
|
|
2374
|
+
});
|
|
2354
2375
|
}
|
|
2355
2376
|
/**
|
|
2356
2377
|
* Queries the event store and returns all matching events in memory.
|
|
@@ -2379,9 +2400,11 @@ var Act = class {
|
|
|
2379
2400
|
* @see {@link query} for large result sets
|
|
2380
2401
|
*/
|
|
2381
2402
|
async query_array(query) {
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2403
|
+
return this._scoped(async () => {
|
|
2404
|
+
const events = [];
|
|
2405
|
+
await store2().query((e) => events.push(e), query);
|
|
2406
|
+
return events;
|
|
2407
|
+
});
|
|
2385
2408
|
}
|
|
2386
2409
|
/**
|
|
2387
2410
|
* Processes pending reactions by draining uncommitted events from the event store.
|
|
@@ -2421,7 +2444,7 @@ var Act = class {
|
|
|
2421
2444
|
* @see {@link start_correlations} for automatic correlation
|
|
2422
2445
|
*/
|
|
2423
2446
|
async drain(options = {}) {
|
|
2424
|
-
return this._drain.drain(options);
|
|
2447
|
+
return this._scoped(() => this._drain.drain(options));
|
|
2425
2448
|
}
|
|
2426
2449
|
/**
|
|
2427
2450
|
* Discovers and registers new streams dynamically based on reaction resolvers.
|
|
@@ -2469,7 +2492,7 @@ var Act = class {
|
|
|
2469
2492
|
* @see {@link stop_correlations} to stop automatic correlation
|
|
2470
2493
|
*/
|
|
2471
2494
|
async correlate(query = { after: -1, limit: 10 }) {
|
|
2472
|
-
return this._correlate.correlate(query);
|
|
2495
|
+
return this._scoped(() => this._correlate.correlate(query));
|
|
2473
2496
|
}
|
|
2474
2497
|
/**
|
|
2475
2498
|
* Starts automatic periodic correlation worker for discovering new streams.
|
|
@@ -2590,9 +2613,11 @@ var Act = class {
|
|
|
2590
2613
|
* @see {@link settle} for the debounced full-catch-up loop
|
|
2591
2614
|
*/
|
|
2592
2615
|
async reset(streams) {
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2616
|
+
return this._scoped(async () => {
|
|
2617
|
+
const count = await store2().reset(streams);
|
|
2618
|
+
if (count > 0 && this._reactive_events.size > 0) this._drain.arm();
|
|
2619
|
+
return count;
|
|
2620
|
+
});
|
|
2596
2621
|
}
|
|
2597
2622
|
/**
|
|
2598
2623
|
* Bulk-update scheduling priority for streams matching `filter`.
|
|
@@ -2633,7 +2658,7 @@ var Act = class {
|
|
|
2633
2658
|
* @see {@link claim} for how priority biases scheduling
|
|
2634
2659
|
*/
|
|
2635
2660
|
async prioritize(filter, priority) {
|
|
2636
|
-
return
|
|
2661
|
+
return this._scoped(() => store2().prioritize(filter, priority));
|
|
2637
2662
|
}
|
|
2638
2663
|
/**
|
|
2639
2664
|
* Close the books — guard, archive, truncate, and optionally restart streams.
|
|
@@ -2670,16 +2695,18 @@ var Act = class {
|
|
|
2670
2695
|
*/
|
|
2671
2696
|
async close(targets) {
|
|
2672
2697
|
if (!targets.length) return { truncated: /* @__PURE__ */ new Map(), skipped: [] };
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2698
|
+
return this._scoped(async () => {
|
|
2699
|
+
await this.correlate({ limit: 1e3 });
|
|
2700
|
+
const result = await runCloseCycle(targets, {
|
|
2701
|
+
reactiveEventsSize: this._reactive_events.size,
|
|
2702
|
+
eventToState: this._event_to_state,
|
|
2703
|
+
load: this._es.load,
|
|
2704
|
+
tombstone: this._es.tombstone,
|
|
2705
|
+
logger: this._logger
|
|
2706
|
+
});
|
|
2707
|
+
this.emit("closed", result);
|
|
2708
|
+
return result;
|
|
2680
2709
|
});
|
|
2681
|
-
this.emit("closed", result);
|
|
2682
|
-
return result;
|
|
2683
2710
|
}
|
|
2684
2711
|
/**
|
|
2685
2712
|
* Debounced, non-blocking correlate→drain cycle.
|
|
@@ -2733,6 +2760,41 @@ function act() {
|
|
|
2733
2760
|
};
|
|
2734
2761
|
const pendingProjections = [];
|
|
2735
2762
|
const batchHandlers = /* @__PURE__ */ new Map();
|
|
2763
|
+
let _built = false;
|
|
2764
|
+
const finalizeDeprecations = () => {
|
|
2765
|
+
const deprecationSummary = [];
|
|
2766
|
+
for (const state2 of states.values()) {
|
|
2767
|
+
const eventNames = Object.keys(state2.events);
|
|
2768
|
+
const deprecated = deprecatedEventNames(eventNames);
|
|
2769
|
+
if (deprecated.size === 0) continue;
|
|
2770
|
+
state2._deprecated = deprecated;
|
|
2771
|
+
for (const name of deprecated) {
|
|
2772
|
+
const current = currentVersionOf(name, eventNames);
|
|
2773
|
+
deprecationSummary.push({
|
|
2774
|
+
stateName: state2.name,
|
|
2775
|
+
deprecated: name,
|
|
2776
|
+
current
|
|
2777
|
+
});
|
|
2778
|
+
}
|
|
2779
|
+
for (const [actionName, handler] of Object.entries(state2.on)) {
|
|
2780
|
+
const staticTarget = handler?._staticEmit;
|
|
2781
|
+
if (staticTarget && deprecated.has(staticTarget)) {
|
|
2782
|
+
const current = currentVersionOf(staticTarget, eventNames);
|
|
2783
|
+
throw new Error(
|
|
2784
|
+
`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.`
|
|
2785
|
+
);
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2788
|
+
}
|
|
2789
|
+
if (deprecationSummary.length > 0) {
|
|
2790
|
+
const list = deprecationSummary.map(
|
|
2791
|
+
(d) => `"${d.deprecated}" (current: "${d.current}", state: "${d.stateName}")`
|
|
2792
|
+
).join(", ");
|
|
2793
|
+
log().info(
|
|
2794
|
+
`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.`
|
|
2795
|
+
);
|
|
2796
|
+
}
|
|
2797
|
+
};
|
|
2736
2798
|
const builder = {
|
|
2737
2799
|
withState: (state2) => {
|
|
2738
2800
|
registerState(state2, states, registry.actions, registry.events);
|
|
@@ -2776,41 +2838,13 @@ function act() {
|
|
|
2776
2838
|
}
|
|
2777
2839
|
}),
|
|
2778
2840
|
build: (options) => {
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
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
|
-
}
|
|
2841
|
+
if (!_built) {
|
|
2842
|
+
for (const proj of pendingProjections) {
|
|
2843
|
+
mergeProjection(proj, registry.events);
|
|
2844
|
+
registerBatchHandler(proj, batchHandlers);
|
|
2805
2845
|
}
|
|
2806
|
-
|
|
2807
|
-
|
|
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
|
-
);
|
|
2846
|
+
finalizeDeprecations();
|
|
2847
|
+
_built = true;
|
|
2814
2848
|
}
|
|
2815
2849
|
return new Act(
|
|
2816
2850
|
registry,
|
|
@@ -3045,7 +3079,7 @@ export {
|
|
|
3045
3079
|
ValidationError,
|
|
3046
3080
|
ZodEmpty,
|
|
3047
3081
|
act,
|
|
3048
|
-
cache,
|
|
3082
|
+
cache2 as cache,
|
|
3049
3083
|
config,
|
|
3050
3084
|
dispose,
|
|
3051
3085
|
disposeAndExit,
|
|
@@ -3053,10 +3087,11 @@ export {
|
|
|
3053
3087
|
log,
|
|
3054
3088
|
port,
|
|
3055
3089
|
projection,
|
|
3090
|
+
scoped,
|
|
3056
3091
|
sleep,
|
|
3057
3092
|
slice,
|
|
3058
3093
|
state,
|
|
3059
|
-
store,
|
|
3094
|
+
store2 as store,
|
|
3060
3095
|
validate
|
|
3061
3096
|
};
|
|
3062
3097
|
//# sourceMappingURL=index.js.map
|