@graphrefly/ts 0.0.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/LICENSE +21 -0
- package/dist/adapters/index.cjs +9015 -0
- package/dist/adapters/index.cjs.map +1 -0
- package/dist/adapters/index.d.cts +678 -0
- package/dist/adapters/index.d.ts +678 -0
- package/dist/adapters/index.js +2894 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/observe-storage.cjs +260 -0
- package/dist/adapters/observe-storage.cjs.map +1 -0
- package/dist/adapters/observe-storage.d.cts +77 -0
- package/dist/adapters/observe-storage.d.ts +77 -0
- package/dist/adapters/observe-storage.js +161 -0
- package/dist/adapters/observe-storage.js.map +1 -0
- package/dist/append-log-DisvEReb.d.cts +189 -0
- package/dist/append-log-DzKMmjxx.d.ts +189 -0
- package/dist/chunk-2ILL7HQI.js +1189 -0
- package/dist/chunk-2ILL7HQI.js.map +1 -0
- package/dist/chunk-4VLAQHZI.js +330 -0
- package/dist/chunk-4VLAQHZI.js.map +1 -0
- package/dist/chunk-6PHB5CJS.js +229 -0
- package/dist/chunk-6PHB5CJS.js.map +1 -0
- package/dist/chunk-COHO25CZ.js +2449 -0
- package/dist/chunk-COHO25CZ.js.map +1 -0
- package/dist/chunk-D6BG7U6A.js +161 -0
- package/dist/chunk-D6BG7U6A.js.map +1 -0
- package/dist/chunk-DJC4CHLQ.js +818 -0
- package/dist/chunk-DJC4CHLQ.js.map +1 -0
- package/dist/chunk-DK554R7P.js +67 -0
- package/dist/chunk-DK554R7P.js.map +1 -0
- package/dist/chunk-DKP56CSW.js +322 -0
- package/dist/chunk-DKP56CSW.js.map +1 -0
- package/dist/chunk-G4M3NHRJ.js +688 -0
- package/dist/chunk-G4M3NHRJ.js.map +1 -0
- package/dist/chunk-GAJW5I5P.js +1 -0
- package/dist/chunk-GAJW5I5P.js.map +1 -0
- package/dist/chunk-GDL26N2T.js +282 -0
- package/dist/chunk-GDL26N2T.js.map +1 -0
- package/dist/chunk-GTPCOEOZ.js +741 -0
- package/dist/chunk-GTPCOEOZ.js.map +1 -0
- package/dist/chunk-H2HTHFVN.js +1 -0
- package/dist/chunk-H2HTHFVN.js.map +1 -0
- package/dist/chunk-HDRL4VQQ.js +218 -0
- package/dist/chunk-HDRL4VQQ.js.map +1 -0
- package/dist/chunk-I3IHOHCJ.js +2267 -0
- package/dist/chunk-I3IHOHCJ.js.map +1 -0
- package/dist/chunk-JIMUDQN3.js +965 -0
- package/dist/chunk-JIMUDQN3.js.map +1 -0
- package/dist/chunk-JR4IKCR2.js +462 -0
- package/dist/chunk-JR4IKCR2.js.map +1 -0
- package/dist/chunk-K3FXTC3I.js +165 -0
- package/dist/chunk-K3FXTC3I.js.map +1 -0
- package/dist/chunk-OOEN33FB.js +65 -0
- package/dist/chunk-OOEN33FB.js.map +1 -0
- package/dist/chunk-PKVBHGBM.js +554 -0
- package/dist/chunk-PKVBHGBM.js.map +1 -0
- package/dist/chunk-RIIOUTGM.js +1857 -0
- package/dist/chunk-RIIOUTGM.js.map +1 -0
- package/dist/chunk-SCRFRCGR.js +33 -0
- package/dist/chunk-SCRFRCGR.js.map +1 -0
- package/dist/chunk-SWTLEQL6.js +53 -0
- package/dist/chunk-SWTLEQL6.js.map +1 -0
- package/dist/chunk-SZAETNNA.js +1 -0
- package/dist/chunk-SZAETNNA.js.map +1 -0
- package/dist/chunk-TEW47IVR.js +49 -0
- package/dist/chunk-TEW47IVR.js.map +1 -0
- package/dist/chunk-Y3ZLRGHC.js +1482 -0
- package/dist/chunk-Y3ZLRGHC.js.map +1 -0
- package/dist/chunk-Z2ANQ6JW.js +149 -0
- package/dist/chunk-Z2ANQ6JW.js.map +1 -0
- package/dist/codec-BB7p8fJc.d.cts +38 -0
- package/dist/codec-BB7p8fJc.d.ts +38 -0
- package/dist/composition/index.cjs +2505 -0
- package/dist/composition/index.cjs.map +1 -0
- package/dist/composition/index.d.cts +95 -0
- package/dist/composition/index.d.ts +95 -0
- package/dist/composition/index.js +19 -0
- package/dist/composition/index.js.map +1 -0
- package/dist/core/index.cjs +2475 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +25 -0
- package/dist/core/index.d.ts +25 -0
- package/dist/core/index.js +74 -0
- package/dist/core/index.js.map +1 -0
- package/dist/cqrs/index.cjs +595 -0
- package/dist/cqrs/index.cjs.map +1 -0
- package/dist/cqrs/index.d.cts +200 -0
- package/dist/cqrs/index.d.ts +200 -0
- package/dist/cqrs/index.js +557 -0
- package/dist/cqrs/index.js.map +1 -0
- package/dist/data-structures/index.cjs +4277 -0
- package/dist/data-structures/index.cjs.map +1 -0
- package/dist/data-structures/index.d.cts +22 -0
- package/dist/data-structures/index.d.ts +22 -0
- package/dist/data-structures/index.js +31 -0
- package/dist/data-structures/index.js.map +1 -0
- package/dist/describe-BZb7AS2y.d.ts +57 -0
- package/dist/describe-Ciu8SUnN.d.cts +57 -0
- package/dist/graph/index.cjs +7832 -0
- package/dist/graph/index.cjs.map +1 -0
- package/dist/graph/index.d.cts +251 -0
- package/dist/graph/index.d.ts +251 -0
- package/dist/graph/index.js +131 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph-DfdF9zy4.d.ts +666 -0
- package/dist/graph-s23RbbFO.d.cts +666 -0
- package/dist/index-CAEmLCYF.d.cts +166 -0
- package/dist/index-SnzZu3x7.d.ts +166 -0
- package/dist/index.cjs +15409 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +23 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +582 -0
- package/dist/index.js.map +1 -0
- package/dist/messages-BZqrGGm1.d.cts +55 -0
- package/dist/messages-BZqrGGm1.d.ts +55 -0
- package/dist/messaging/index.cjs +818 -0
- package/dist/messaging/index.cjs.map +1 -0
- package/dist/messaging/index.d.cts +235 -0
- package/dist/messaging/index.d.ts +235 -0
- package/dist/messaging/index.js +767 -0
- package/dist/messaging/index.js.map +1 -0
- package/dist/observe-event-log-0SVsx7JG.d.cts +88 -0
- package/dist/observe-event-log-Dnm76owp.d.ts +88 -0
- package/dist/operators/index.cjs +3774 -0
- package/dist/operators/index.cjs.map +1 -0
- package/dist/operators/index.d.cts +308 -0
- package/dist/operators/index.d.ts +308 -0
- package/dist/operators/index.js +112 -0
- package/dist/operators/index.js.map +1 -0
- package/dist/orchestration/index.cjs +3541 -0
- package/dist/orchestration/index.cjs.map +1 -0
- package/dist/orchestration/index.d.cts +302 -0
- package/dist/orchestration/index.d.ts +302 -0
- package/dist/orchestration/index.js +1004 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/patterns/index.cjs +1045 -0
- package/dist/patterns/index.cjs.map +1 -0
- package/dist/patterns/index.d.cts +39 -0
- package/dist/patterns/index.d.ts +39 -0
- package/dist/patterns/index.js +33 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/reactive-collection-BxBqtIOE.d.cts +344 -0
- package/dist/reactive-collection-Cb1II1Fi.d.ts +344 -0
- package/dist/reactive-collection-storage-BNiEc-Gd.d.ts +217 -0
- package/dist/reactive-collection-storage-D-KmjE0J.d.cts +217 -0
- package/dist/reactive-map-BcB4KsQR.d.ts +256 -0
- package/dist/reactive-map-D-g3dv8I.d.cts +256 -0
- package/dist/read-through-B1CYPfq_.d.cts +82 -0
- package/dist/read-through-DwyJhGs1.d.ts +82 -0
- package/dist/render/index.cjs +250 -0
- package/dist/render/index.cjs.map +1 -0
- package/dist/render/index.d.cts +58 -0
- package/dist/render/index.d.ts +58 -0
- package/dist/render/index.js +20 -0
- package/dist/render/index.js.map +1 -0
- package/dist/resilience-Dig3Q7n0.d.cts +45 -0
- package/dist/resilience-Dig3Q7n0.d.ts +45 -0
- package/dist/semantic-memory-graph-BYoIlP35.d.cts +356 -0
- package/dist/semantic-memory-graph-CxyXLms3.d.ts +356 -0
- package/dist/solutions/index.cjs +3249 -0
- package/dist/solutions/index.cjs.map +1 -0
- package/dist/solutions/index.d.cts +520 -0
- package/dist/solutions/index.d.ts +520 -0
- package/dist/solutions/index.js +31 -0
- package/dist/solutions/index.js.map +1 -0
- package/dist/sources/browser.cjs +3095 -0
- package/dist/sources/browser.cjs.map +1 -0
- package/dist/sources/browser.d.cts +39 -0
- package/dist/sources/browser.d.ts +39 -0
- package/dist/sources/browser.js +137 -0
- package/dist/sources/browser.js.map +1 -0
- package/dist/sources/index.cjs +3021 -0
- package/dist/sources/index.cjs.map +1 -0
- package/dist/sources/index.d.cts +7 -0
- package/dist/sources/index.d.ts +7 -0
- package/dist/sources/index.js +63 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/node.cjs +675 -0
- package/dist/sources/node.cjs.map +1 -0
- package/dist/sources/node.d.cts +109 -0
- package/dist/sources/node.d.ts +109 -0
- package/dist/sources/node.js +639 -0
- package/dist/sources/node.js.map +1 -0
- package/dist/storage/browser.cjs +777 -0
- package/dist/storage/browser.cjs.map +1 -0
- package/dist/storage/browser.d.cts +40 -0
- package/dist/storage/browser.d.ts +40 -0
- package/dist/storage/browser.js +275 -0
- package/dist/storage/browser.js.map +1 -0
- package/dist/storage/index.cjs +1989 -0
- package/dist/storage/index.cjs.map +1 -0
- package/dist/storage/index.d.cts +92 -0
- package/dist/storage/index.d.ts +92 -0
- package/dist/storage/index.js +161 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/node.cjs +898 -0
- package/dist/storage/node.cjs.map +1 -0
- package/dist/storage/node.d.cts +66 -0
- package/dist/storage/node.d.ts +66 -0
- package/dist/storage/node.js +402 -0
- package/dist/storage/node.js.map +1 -0
- package/dist/testing/index.cjs +95 -0
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.cts +20 -0
- package/dist/testing/index.d.ts +20 -0
- package/dist/testing/index.js +8 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types-bNMSWKqF.d.cts +732 -0
- package/dist/types-h12mNYbq.d.ts +732 -0
- package/package.json +250 -0
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
import {
|
|
2
|
+
depBatch
|
|
3
|
+
} from "../chunk-SWTLEQL6.js";
|
|
4
|
+
import "../chunk-DK554R7P.js";
|
|
5
|
+
|
|
6
|
+
// src/cqrs/index.ts
|
|
7
|
+
function cqrsCommandHandler(type, handle) {
|
|
8
|
+
if (type.length === 0) throw new Error("cqrsCommandHandler: type must be non-empty");
|
|
9
|
+
return { type, handle };
|
|
10
|
+
}
|
|
11
|
+
function cqrs(graph, opts = {}) {
|
|
12
|
+
const name = opts.name ?? "cqrs";
|
|
13
|
+
const handlers = normalizeHandlers(opts.handlers ?? []);
|
|
14
|
+
const knownEvents = opts.events === void 0 ? void 0 : new Set(uniqueNames(opts.events, "cqrs.events"));
|
|
15
|
+
const now = opts.now ?? Date.now;
|
|
16
|
+
const dedupe = normalizeDedupePolicy(opts.dedupe);
|
|
17
|
+
const command = graph.node([], null, {
|
|
18
|
+
name: `${name}/command`,
|
|
19
|
+
factory: "cqrsCommand",
|
|
20
|
+
completeWhenDepsComplete: false,
|
|
21
|
+
errorWhenDepsError: false
|
|
22
|
+
});
|
|
23
|
+
const runtime = graph.node(
|
|
24
|
+
[command],
|
|
25
|
+
(ctx) => {
|
|
26
|
+
const state = ctx.state.get() ?? {
|
|
27
|
+
eventSeq: 0,
|
|
28
|
+
commandCount: 0,
|
|
29
|
+
errorCount: 0,
|
|
30
|
+
auditSeq: 0,
|
|
31
|
+
seenCommandIds: [],
|
|
32
|
+
seenEventIds: []
|
|
33
|
+
};
|
|
34
|
+
ctx.state.persist(true);
|
|
35
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
36
|
+
reduceCommandFact(
|
|
37
|
+
raw,
|
|
38
|
+
state,
|
|
39
|
+
handlers,
|
|
40
|
+
knownEvents,
|
|
41
|
+
now,
|
|
42
|
+
dedupe,
|
|
43
|
+
(fact) => ctx.down([["DATA", fact]])
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
ctx.state.set(state);
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: `${name}/runtime`,
|
|
50
|
+
factory: "cqrsRuntime",
|
|
51
|
+
meta: {
|
|
52
|
+
commandTypes: [...handlers.keys()],
|
|
53
|
+
eventTypes: knownEvents ? [...knownEvents] : "open",
|
|
54
|
+
dedupe: dedupeMeta(dedupe)
|
|
55
|
+
},
|
|
56
|
+
completeWhenDepsComplete: false,
|
|
57
|
+
errorWhenDepsError: false
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
const events = runtimeProjection(
|
|
61
|
+
graph,
|
|
62
|
+
runtime,
|
|
63
|
+
"event",
|
|
64
|
+
`${name}/events`,
|
|
65
|
+
"cqrsEvents",
|
|
66
|
+
(fact) => fact.kind === "event" ? fact.event : void 0
|
|
67
|
+
);
|
|
68
|
+
const status = runtimeProjection(
|
|
69
|
+
graph,
|
|
70
|
+
runtime,
|
|
71
|
+
"status",
|
|
72
|
+
`${name}/status`,
|
|
73
|
+
"cqrsStatus",
|
|
74
|
+
(fact) => fact.kind === "status" ? fact.status : void 0
|
|
75
|
+
);
|
|
76
|
+
const errors = runtimeProjection(
|
|
77
|
+
graph,
|
|
78
|
+
runtime,
|
|
79
|
+
"error",
|
|
80
|
+
`${name}/errors`,
|
|
81
|
+
"cqrsErrors",
|
|
82
|
+
(fact) => fact.kind === "error" ? fact.error : void 0
|
|
83
|
+
);
|
|
84
|
+
const audit = runtimeProjection(
|
|
85
|
+
graph,
|
|
86
|
+
runtime,
|
|
87
|
+
"audit",
|
|
88
|
+
`${name}/audit`,
|
|
89
|
+
"cqrsAudit",
|
|
90
|
+
(fact) => fact.kind === "audit" ? fact.audit : void 0
|
|
91
|
+
);
|
|
92
|
+
const cursor = runtimeProjection(
|
|
93
|
+
graph,
|
|
94
|
+
runtime,
|
|
95
|
+
"cursor",
|
|
96
|
+
`${name}/cursor`,
|
|
97
|
+
"cqrsCursor",
|
|
98
|
+
(fact) => fact.kind === "cursor" ? fact.cursor : void 0
|
|
99
|
+
);
|
|
100
|
+
graph.retain(runtime, { reason: `${name}.cqrs.runtime` });
|
|
101
|
+
graph.retain(events, { reason: `${name}.cqrs.events` });
|
|
102
|
+
graph.retain(status, { reason: `${name}.cqrs.status` });
|
|
103
|
+
graph.retain(errors, { reason: `${name}.cqrs.errors` });
|
|
104
|
+
graph.retain(audit, { reason: `${name}.cqrs.audit` });
|
|
105
|
+
graph.retain(cursor, { reason: `${name}.cqrs.cursor` });
|
|
106
|
+
return {
|
|
107
|
+
command,
|
|
108
|
+
runtime,
|
|
109
|
+
events,
|
|
110
|
+
status,
|
|
111
|
+
errors,
|
|
112
|
+
audit,
|
|
113
|
+
cursor,
|
|
114
|
+
dispatch(commandFact) {
|
|
115
|
+
command.down([["DATA", commandFact]]);
|
|
116
|
+
return commandFact;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function cqrsProjection(graph, source, opts) {
|
|
121
|
+
const name = opts.name ?? "cqrsProjection";
|
|
122
|
+
const eventFilter = opts.events === void 0 ? void 0 : new Set(uniqueNames(opts.events, "cqrsProjection.events"));
|
|
123
|
+
const frames = graph.node(
|
|
124
|
+
[source.events],
|
|
125
|
+
(ctx) => {
|
|
126
|
+
const state = ctx.state.get() ?? { value: opts.initial };
|
|
127
|
+
ctx.state.persist(true);
|
|
128
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
129
|
+
const event = raw;
|
|
130
|
+
if (eventFilter !== void 0 && !eventFilter.has(event.type)) continue;
|
|
131
|
+
try {
|
|
132
|
+
state.value = opts.reducer(state.value, event);
|
|
133
|
+
ctx.state.set(state);
|
|
134
|
+
ctx.down([
|
|
135
|
+
[
|
|
136
|
+
"DATA",
|
|
137
|
+
{
|
|
138
|
+
kind: "value",
|
|
139
|
+
state: state.value,
|
|
140
|
+
eventId: event.id,
|
|
141
|
+
cursor: event.runtimeCursor
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
]);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
rethrowGraphRuntimeInvariant(error);
|
|
147
|
+
ctx.down([
|
|
148
|
+
[
|
|
149
|
+
"DATA",
|
|
150
|
+
{
|
|
151
|
+
kind: "error",
|
|
152
|
+
error: {
|
|
153
|
+
code: "projection-threw",
|
|
154
|
+
message: errorMessage(error),
|
|
155
|
+
eventId: event.id,
|
|
156
|
+
eventType: event.type,
|
|
157
|
+
cursor: event.runtimeCursor
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
]);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
name,
|
|
168
|
+
factory: "cqrsProjection",
|
|
169
|
+
meta: { eventTypes: eventFilter ? [...eventFilter] : "open" },
|
|
170
|
+
completeWhenDepsComplete: false,
|
|
171
|
+
errorWhenDepsError: false
|
|
172
|
+
}
|
|
173
|
+
);
|
|
174
|
+
const value = graph.node(
|
|
175
|
+
[frames],
|
|
176
|
+
(ctx) => {
|
|
177
|
+
for (const frame of depBatch(ctx, 0) ?? []) {
|
|
178
|
+
const typed = frame;
|
|
179
|
+
if (typed.kind === "value") ctx.down([["DATA", typed.state]]);
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: `${name}/value`,
|
|
184
|
+
factory: "cqrsProjectionValue",
|
|
185
|
+
completeWhenDepsComplete: false,
|
|
186
|
+
errorWhenDepsError: false
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
const errors = graph.node(
|
|
190
|
+
[frames],
|
|
191
|
+
(ctx) => {
|
|
192
|
+
for (const frame of depBatch(ctx, 0) ?? []) {
|
|
193
|
+
const typed = frame;
|
|
194
|
+
if (typed.kind === "error") ctx.down([["DATA", typed.error]]);
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
name: `${name}/errors`,
|
|
199
|
+
factory: "cqrsProjectionErrors",
|
|
200
|
+
completeWhenDepsComplete: false,
|
|
201
|
+
errorWhenDepsError: false
|
|
202
|
+
}
|
|
203
|
+
);
|
|
204
|
+
const status = graph.node(
|
|
205
|
+
[frames],
|
|
206
|
+
(ctx) => {
|
|
207
|
+
for (const frame of depBatch(ctx, 0) ?? []) {
|
|
208
|
+
const typed = frame;
|
|
209
|
+
if (typed.kind === "value") {
|
|
210
|
+
ctx.down([
|
|
211
|
+
[
|
|
212
|
+
"DATA",
|
|
213
|
+
{
|
|
214
|
+
state: "updated",
|
|
215
|
+
eventId: typed.eventId,
|
|
216
|
+
cursor: typed.cursor
|
|
217
|
+
}
|
|
218
|
+
]
|
|
219
|
+
]);
|
|
220
|
+
} else {
|
|
221
|
+
ctx.down([
|
|
222
|
+
[
|
|
223
|
+
"DATA",
|
|
224
|
+
{
|
|
225
|
+
state: "errored",
|
|
226
|
+
eventId: typed.error.eventId,
|
|
227
|
+
eventType: typed.error.eventType,
|
|
228
|
+
cursor: typed.error.cursor
|
|
229
|
+
}
|
|
230
|
+
]
|
|
231
|
+
]);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
name: `${name}/status`,
|
|
237
|
+
factory: "cqrsProjectionStatus",
|
|
238
|
+
completeWhenDepsComplete: false,
|
|
239
|
+
errorWhenDepsError: false
|
|
240
|
+
}
|
|
241
|
+
);
|
|
242
|
+
graph.retain(frames, { reason: `${name}.cqrsProjection.frames` });
|
|
243
|
+
graph.retain(value, { reason: `${name}.cqrsProjection.value` });
|
|
244
|
+
graph.retain(status, { reason: `${name}.cqrsProjection.status` });
|
|
245
|
+
graph.retain(errors, { reason: `${name}.cqrsProjection.errors` });
|
|
246
|
+
return { frames, value, status, errors };
|
|
247
|
+
}
|
|
248
|
+
function normalizeHandlers(definitions) {
|
|
249
|
+
const handlers = /* @__PURE__ */ new Map();
|
|
250
|
+
for (const definition of definitions) {
|
|
251
|
+
if (definition.type.length === 0) throw new Error("cqrs: handler type must be non-empty");
|
|
252
|
+
if (handlers.has(definition.type))
|
|
253
|
+
throw new Error(`cqrs: duplicate handler '${definition.type}'`);
|
|
254
|
+
handlers.set(definition.type, {
|
|
255
|
+
type: definition.type,
|
|
256
|
+
handle: definition.handle
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
return handlers;
|
|
260
|
+
}
|
|
261
|
+
function reduceCommandFact(raw, state, handlers, knownEvents, now, dedupe, emit) {
|
|
262
|
+
state.commandCount += 1;
|
|
263
|
+
const parsed = parseCommand(raw);
|
|
264
|
+
if (typeof parsed === "string") {
|
|
265
|
+
emitFailure(state, emit, raw, void 0, "malformed-command", parsed, dedupe);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const command = parsed;
|
|
269
|
+
if (state.seenCommandIds.includes(command.id)) {
|
|
270
|
+
emitFailure(
|
|
271
|
+
state,
|
|
272
|
+
emit,
|
|
273
|
+
command,
|
|
274
|
+
command,
|
|
275
|
+
"duplicate-command",
|
|
276
|
+
`cqrs: duplicate command '${command.id}'`,
|
|
277
|
+
dedupe
|
|
278
|
+
);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
state.seenCommandIds.push(command.id);
|
|
282
|
+
trimDedupeWindow(state.seenCommandIds, dedupe.commandMaxEntries, (evicted) => {
|
|
283
|
+
state.commandDedupeEvicted = (state.commandDedupeEvicted ?? 0) + evicted;
|
|
284
|
+
});
|
|
285
|
+
const handler = handlers.get(command.type);
|
|
286
|
+
if (handler === void 0) {
|
|
287
|
+
emitFailure(
|
|
288
|
+
state,
|
|
289
|
+
emit,
|
|
290
|
+
command,
|
|
291
|
+
command,
|
|
292
|
+
"unknown-command",
|
|
293
|
+
`cqrs: unknown command '${command.type}'`,
|
|
294
|
+
dedupe
|
|
295
|
+
);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
let drafts;
|
|
299
|
+
try {
|
|
300
|
+
drafts = handler.handle(command);
|
|
301
|
+
} catch (error) {
|
|
302
|
+
rethrowGraphRuntimeInvariant(error);
|
|
303
|
+
emitFailure(state, emit, command, command, "handler-threw", errorMessage(error), dedupe);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (!Array.isArray(drafts)) {
|
|
307
|
+
emitFailure(
|
|
308
|
+
state,
|
|
309
|
+
emit,
|
|
310
|
+
command,
|
|
311
|
+
command,
|
|
312
|
+
"malformed-event",
|
|
313
|
+
"cqrs: command handler must return an event draft array",
|
|
314
|
+
dedupe
|
|
315
|
+
);
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const prepared = prepareEvents(command, drafts, state, knownEvents);
|
|
319
|
+
if (typeof prepared === "string") {
|
|
320
|
+
emitFailure(state, emit, command, command, preparedCode(prepared), prepared, dedupe);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const timestampMs = readTimestampMs(now);
|
|
324
|
+
if (typeof timestampMs === "string") {
|
|
325
|
+
emitFailure(state, emit, command, command, "clock-threw", timestampMs, dedupe);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const events = [];
|
|
329
|
+
for (const draft of prepared) {
|
|
330
|
+
state.eventSeq += 1;
|
|
331
|
+
state.seenEventIds.push(draft.id);
|
|
332
|
+
trimDedupeWindow(state.seenEventIds, dedupe.eventMaxEntries, (evicted) => {
|
|
333
|
+
state.eventDedupeEvicted = (state.eventDedupeEvicted ?? 0) + evicted;
|
|
334
|
+
});
|
|
335
|
+
const runtimeCursor = cursorOf(state, dedupe);
|
|
336
|
+
events.push({
|
|
337
|
+
id: draft.id,
|
|
338
|
+
type: draft.type,
|
|
339
|
+
seq: state.eventSeq,
|
|
340
|
+
cursor: state.eventSeq,
|
|
341
|
+
runtimeCursor,
|
|
342
|
+
commandId: command.id,
|
|
343
|
+
commandType: command.type,
|
|
344
|
+
payload: draft.payload,
|
|
345
|
+
timestampMs,
|
|
346
|
+
...draft.aggregateId === void 0 ? {} : { aggregateId: draft.aggregateId },
|
|
347
|
+
...draft.correlationId === void 0 ? {} : { correlationId: draft.correlationId },
|
|
348
|
+
...draft.causationId === void 0 ? {} : { causationId: draft.causationId },
|
|
349
|
+
...draft.metadata === void 0 ? {} : { metadata: draft.metadata }
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
for (const event of events) emit({ kind: "event", event });
|
|
353
|
+
emitStatus(state, emit, command, "accepted", events.length, dedupe);
|
|
354
|
+
emitAudit(state, emit, command, "success", events, void 0, void 0, dedupe);
|
|
355
|
+
emit({ kind: "cursor", cursor: cursorOf(state, dedupe) });
|
|
356
|
+
}
|
|
357
|
+
function parseCommand(value) {
|
|
358
|
+
if (!isObjectRecord(value)) return "cqrs: command fact must be an object";
|
|
359
|
+
if (typeof value.id !== "string" || value.id.length === 0) {
|
|
360
|
+
return "cqrs: command id must be a non-empty string";
|
|
361
|
+
}
|
|
362
|
+
if (typeof value.type !== "string" || value.type.length === 0) {
|
|
363
|
+
return "cqrs: command type must be a non-empty string";
|
|
364
|
+
}
|
|
365
|
+
return {
|
|
366
|
+
id: value.id,
|
|
367
|
+
type: value.type,
|
|
368
|
+
payload: value.payload,
|
|
369
|
+
...typeof value.aggregateId === "string" ? { aggregateId: value.aggregateId } : {},
|
|
370
|
+
...typeof value.correlationId === "string" ? { correlationId: value.correlationId } : {},
|
|
371
|
+
...typeof value.causationId === "string" ? { causationId: value.causationId } : {},
|
|
372
|
+
...isObjectRecord(value.metadata) ? { metadata: value.metadata } : {}
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
function prepareEvents(command, drafts, state, knownEvents) {
|
|
376
|
+
const seenInCommand = /* @__PURE__ */ new Set();
|
|
377
|
+
const prepared = [];
|
|
378
|
+
for (let i = 0; i < drafts.length; i += 1) {
|
|
379
|
+
const draft = drafts[i];
|
|
380
|
+
if (!isObjectRecord(draft) || typeof draft.type !== "string" || draft.type.length === 0) {
|
|
381
|
+
return "cqrs: event draft must have a non-empty type";
|
|
382
|
+
}
|
|
383
|
+
if (knownEvents !== void 0 && !knownEvents.has(draft.type)) {
|
|
384
|
+
return `cqrs: unknown event '${draft.type}'`;
|
|
385
|
+
}
|
|
386
|
+
const id = typeof draft.id === "string" && draft.id.length > 0 ? draft.id : `${command.id}:${i + 1}`;
|
|
387
|
+
if (state.seenEventIds.includes(id) || seenInCommand.has(id)) {
|
|
388
|
+
return `cqrs: duplicate event '${id}'`;
|
|
389
|
+
}
|
|
390
|
+
seenInCommand.add(id);
|
|
391
|
+
prepared.push({
|
|
392
|
+
id,
|
|
393
|
+
type: draft.type,
|
|
394
|
+
payload: draft.payload,
|
|
395
|
+
...typeof draft.aggregateId === "string" ? { aggregateId: draft.aggregateId } : {},
|
|
396
|
+
...typeof draft.correlationId === "string" ? { correlationId: draft.correlationId } : {},
|
|
397
|
+
...typeof draft.causationId === "string" ? { causationId: draft.causationId } : {},
|
|
398
|
+
...isObjectRecord(draft.metadata) ? { metadata: draft.metadata } : {}
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
return prepared;
|
|
402
|
+
}
|
|
403
|
+
function preparedCode(message) {
|
|
404
|
+
if (message.includes("unknown event")) return "unknown-event";
|
|
405
|
+
if (message.includes("duplicate event")) return "duplicate-event";
|
|
406
|
+
return "malformed-event";
|
|
407
|
+
}
|
|
408
|
+
function rethrowGraphRuntimeInvariant(error) {
|
|
409
|
+
const message = errorMessage(error);
|
|
410
|
+
if (message.includes("R-reentrancy") || message.includes("R-rewire") || message.includes("R-graph-domain") || message.includes("D37") || message.includes("D22") || message.includes("different graph") || message.includes("cross-graph") || message.includes("wire bridge") || message.includes("mid-fn topology mutation") || message.includes("reentrant dep mutation") || message.includes("feedback cycle")) {
|
|
411
|
+
throw error;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
function emitFailure(state, emit, raw, command, code, message, dedupe) {
|
|
415
|
+
state.errorCount += 1;
|
|
416
|
+
const cursor = cursorOf(state, dedupe);
|
|
417
|
+
const error = {
|
|
418
|
+
code,
|
|
419
|
+
message,
|
|
420
|
+
command: raw,
|
|
421
|
+
...command === void 0 ? {} : { commandId: command.id, commandType: command.type },
|
|
422
|
+
cursor
|
|
423
|
+
};
|
|
424
|
+
emit({ kind: "error", error });
|
|
425
|
+
emit({
|
|
426
|
+
kind: "status",
|
|
427
|
+
status: {
|
|
428
|
+
state: "rejected",
|
|
429
|
+
...command === void 0 ? {} : { commandId: command.id, commandType: command.type },
|
|
430
|
+
eventCount: 0,
|
|
431
|
+
errorCode: code,
|
|
432
|
+
cursor
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
emitAudit(state, emit, command, "failure", [], code, message, dedupe);
|
|
436
|
+
emit({ kind: "cursor", cursor: cursorOf(state, dedupe) });
|
|
437
|
+
}
|
|
438
|
+
function emitStatus(state, emit, command, statusState, eventCount, dedupe) {
|
|
439
|
+
emit({
|
|
440
|
+
kind: "status",
|
|
441
|
+
status: {
|
|
442
|
+
state: statusState,
|
|
443
|
+
commandId: command.id,
|
|
444
|
+
commandType: command.type,
|
|
445
|
+
eventCount,
|
|
446
|
+
cursor: cursorOf(state, dedupe)
|
|
447
|
+
}
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
function emitAudit(state, emit, command, outcome, events, errorCode, errorMessageValue, dedupe) {
|
|
451
|
+
state.auditSeq += 1;
|
|
452
|
+
emit({
|
|
453
|
+
kind: "audit",
|
|
454
|
+
audit: {
|
|
455
|
+
seq: state.auditSeq,
|
|
456
|
+
...command === void 0 ? {} : { commandId: command.id, commandType: command.type },
|
|
457
|
+
outcome,
|
|
458
|
+
eventIds: Object.freeze(events.map((event) => event.id)),
|
|
459
|
+
eventTypes: Object.freeze(events.map((event) => event.type)),
|
|
460
|
+
...errorCode === void 0 ? {} : { errorCode },
|
|
461
|
+
...errorMessageValue === void 0 ? {} : { errorMessage: errorMessageValue },
|
|
462
|
+
cursor: cursorOf(state, dedupe)
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
function runtimeProjection(graph, runtime, kind, name, factory, select) {
|
|
467
|
+
return graph.node(
|
|
468
|
+
[runtime],
|
|
469
|
+
(ctx) => {
|
|
470
|
+
for (const fact of depBatch(ctx, 0) ?? []) {
|
|
471
|
+
const typed = fact;
|
|
472
|
+
if (typed.kind !== kind) continue;
|
|
473
|
+
const selected = select(typed);
|
|
474
|
+
if (selected !== void 0) ctx.down([["DATA", selected]]);
|
|
475
|
+
}
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
name,
|
|
479
|
+
factory,
|
|
480
|
+
completeWhenDepsComplete: false,
|
|
481
|
+
errorWhenDepsError: false
|
|
482
|
+
}
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
function cursorOf(state, dedupe) {
|
|
486
|
+
return {
|
|
487
|
+
eventSeq: state.eventSeq,
|
|
488
|
+
commandCount: state.commandCount,
|
|
489
|
+
errorCount: state.errorCount,
|
|
490
|
+
auditSeq: state.auditSeq,
|
|
491
|
+
...dedupe.bounded ? {
|
|
492
|
+
dedupe: {
|
|
493
|
+
commandIdsRetained: state.seenCommandIds.length,
|
|
494
|
+
eventIdsRetained: state.seenEventIds.length,
|
|
495
|
+
commandIdsEvicted: state.commandDedupeEvicted ?? 0,
|
|
496
|
+
eventIdsEvicted: state.eventDedupeEvicted ?? 0
|
|
497
|
+
}
|
|
498
|
+
} : {}
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
function normalizeDedupePolicy(policy) {
|
|
502
|
+
const commandMaxEntries = normalizeDedupeWindow(policy?.commands, "cqrs.dedupe.commands");
|
|
503
|
+
const eventMaxEntries = normalizeDedupeWindow(policy?.events, "cqrs.dedupe.events");
|
|
504
|
+
return {
|
|
505
|
+
...commandMaxEntries === void 0 ? {} : { commandMaxEntries },
|
|
506
|
+
...eventMaxEntries === void 0 ? {} : { eventMaxEntries },
|
|
507
|
+
bounded: commandMaxEntries !== void 0 || eventMaxEntries !== void 0
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
function normalizeDedupeWindow(window, owner) {
|
|
511
|
+
if (window === void 0 || window === "unbounded") return void 0;
|
|
512
|
+
if (!Number.isInteger(window.maxEntries) || window.maxEntries < 0) {
|
|
513
|
+
throw new RangeError(`${owner}: maxEntries must be a non-negative integer`);
|
|
514
|
+
}
|
|
515
|
+
return window.maxEntries;
|
|
516
|
+
}
|
|
517
|
+
function dedupeMeta(dedupe) {
|
|
518
|
+
if (!dedupe.bounded) return "unbounded";
|
|
519
|
+
return {
|
|
520
|
+
commands: dedupe.commandMaxEntries === void 0 ? "unbounded" : { maxEntries: dedupe.commandMaxEntries },
|
|
521
|
+
events: dedupe.eventMaxEntries === void 0 ? "unbounded" : { maxEntries: dedupe.eventMaxEntries }
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
function trimDedupeWindow(ids, maxEntries, onEvicted) {
|
|
525
|
+
if (maxEntries === void 0 || ids.length <= maxEntries) return;
|
|
526
|
+
const evicted = ids.length - maxEntries;
|
|
527
|
+
ids.splice(0, evicted);
|
|
528
|
+
onEvicted(evicted);
|
|
529
|
+
}
|
|
530
|
+
function readTimestampMs(now) {
|
|
531
|
+
try {
|
|
532
|
+
const timestampMs = now();
|
|
533
|
+
return Number.isFinite(timestampMs) ? timestampMs : "cqrs: now() must return a finite number";
|
|
534
|
+
} catch (error) {
|
|
535
|
+
return `cqrs: now() threw: ${errorMessage(error)}`;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
function uniqueNames(values, owner) {
|
|
539
|
+
const unique = [...new Set(values)];
|
|
540
|
+
if (unique.length !== values.length) throw new Error(`${owner}: duplicate value`);
|
|
541
|
+
for (const value of unique) {
|
|
542
|
+
if (value.length === 0) throw new Error(`${owner}: values must be non-empty`);
|
|
543
|
+
}
|
|
544
|
+
return Object.freeze(unique);
|
|
545
|
+
}
|
|
546
|
+
function errorMessage(error) {
|
|
547
|
+
return error instanceof Error ? error.message : String(error);
|
|
548
|
+
}
|
|
549
|
+
function isObjectRecord(value) {
|
|
550
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
551
|
+
}
|
|
552
|
+
export {
|
|
553
|
+
cqrs,
|
|
554
|
+
cqrsCommandHandler,
|
|
555
|
+
cqrsProjection
|
|
556
|
+
};
|
|
557
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cqrs/index.ts"],"sourcesContent":["/**\n * Reusable application-infrastructure CQRS helpers (B63 / D125 / D129).\n *\n * The bundle is graph-visible facts over ordinary nodes: command DATA facts\n * enter through a graph-owned command node, command handlers run inside the\n * dispatched runtime node, and events/status/errors/audit/cursor are derived\n * facts. It is not a Graph subclass, hidden EventEmitter, saga runtime, or\n * storage-owned restore surface.\n */\n\nimport { depBatch } from \"../ctx/types.js\";\nimport type { Graph } from \"../graph/graph.js\";\nimport type { Node } from \"../node/node.js\";\n\n/** Command fact accepted by a CQRS bundle. */\nexport interface CqrsCommand<T = unknown> {\n\treadonly id: string;\n\treadonly type: string;\n\treadonly payload: T;\n\treadonly aggregateId?: string;\n\treadonly correlationId?: string;\n\treadonly causationId?: string;\n\treadonly metadata?: Record<string, unknown>;\n}\n\n/** Event draft returned by a command handler before the runtime orders it. */\nexport interface CqrsEventDraft<T = unknown> {\n\treadonly id?: string;\n\treadonly type: string;\n\treadonly payload: T;\n\treadonly aggregateId?: string;\n\treadonly correlationId?: string;\n\treadonly causationId?: string;\n\treadonly metadata?: Record<string, unknown>;\n}\n\n/** Ordered event fact emitted by the CQRS runtime node. */\nexport interface CqrsEvent<T = unknown> {\n\treadonly id: string;\n\treadonly type: string;\n\treadonly seq: number;\n\treadonly cursor: number;\n\treadonly runtimeCursor: CqrsCursor;\n\treadonly commandId: string;\n\treadonly commandType: string;\n\treadonly payload: T;\n\treadonly timestampMs: number;\n\treadonly aggregateId?: string;\n\treadonly correlationId?: string;\n\treadonly causationId?: string;\n\treadonly metadata?: Record<string, unknown>;\n}\n\nexport type CqrsErrorCode =\n\t| \"malformed-command\"\n\t| \"duplicate-command\"\n\t| \"unknown-command\"\n\t| \"handler-threw\"\n\t| \"clock-threw\"\n\t| \"malformed-event\"\n\t| \"unknown-event\"\n\t| \"duplicate-event\";\n\n/** Graph-visible CQRS error fact. These are DATA facts, not protocol ERROR. */\nexport interface CqrsError {\n\treadonly code: CqrsErrorCode;\n\treadonly message: string;\n\treadonly command?: unknown;\n\treadonly commandId?: string;\n\treadonly commandType?: string;\n\treadonly event?: unknown;\n\treadonly eventType?: string;\n\treadonly cursor: CqrsCursor;\n}\n\nexport interface CqrsStatus {\n\treadonly state: \"accepted\" | \"rejected\";\n\treadonly commandId?: string;\n\treadonly commandType?: string;\n\treadonly eventCount: number;\n\treadonly errorCode?: CqrsErrorCode;\n\treadonly cursor: CqrsCursor;\n}\n\nexport interface CqrsAuditRecord {\n\treadonly seq: number;\n\treadonly commandId?: string;\n\treadonly commandType?: string;\n\treadonly outcome: \"success\" | \"failure\";\n\treadonly eventIds: readonly string[];\n\treadonly eventTypes: readonly string[];\n\treadonly errorCode?: CqrsErrorCode;\n\treadonly errorMessage?: string;\n\treadonly cursor: CqrsCursor;\n}\n\nexport interface CqrsDedupeSnapshot {\n\treadonly commandIdsRetained: number;\n\treadonly eventIdsRetained: number;\n\treadonly commandIdsEvicted: number;\n\treadonly eventIdsEvicted: number;\n}\n\nexport interface CqrsCursor {\n\treadonly eventSeq: number;\n\treadonly commandCount: number;\n\treadonly errorCount: number;\n\treadonly auditSeq: number;\n\treadonly dedupe?: CqrsDedupeSnapshot;\n}\n\nexport type CqrsRuntimeFact<T = unknown> =\n\t| { readonly kind: \"event\"; readonly event: CqrsEvent<T> }\n\t| { readonly kind: \"status\"; readonly status: CqrsStatus }\n\t| { readonly kind: \"error\"; readonly error: CqrsError }\n\t| { readonly kind: \"audit\"; readonly audit: CqrsAuditRecord }\n\t| { readonly kind: \"cursor\"; readonly cursor: CqrsCursor };\n\nexport type CqrsCommandHandler<TCommand = unknown, TEvent = unknown> = (\n\tcommand: CqrsCommand<TCommand>,\n) => readonly CqrsEventDraft<TEvent>[];\n\nexport interface CqrsCommandHandlerDefinition<TCommand = unknown, TEvent = unknown> {\n\treadonly type: string;\n\treadonly handle: CqrsCommandHandler<TCommand, TEvent>;\n}\n\nexport interface CqrsOptions<TCommand = unknown, TEvent = unknown> {\n\treadonly name?: string;\n\treadonly handlers?: readonly CqrsCommandHandlerDefinition<TCommand, TEvent>[];\n\treadonly events?: readonly string[];\n\treadonly now?: () => number;\n\t/**\n\t * D142: static command/event duplicate-recognition windows. Omitted means\n\t * exact unbounded dedupe; bounded windows evict oldest ids by insertion order.\n\t */\n\treadonly dedupe?: CqrsDedupePolicy;\n}\n\n/**\n * D151 membership-based duplicate-recognition window for CQRS ids.\n *\n * This is passive CQRS vocabulary, not a shared idempotency reducer engine:\n * commands and events each own their own id membership window.\n */\nexport type CqrsDedupeWindow = \"unbounded\" | { readonly maxEntries: number };\n\nexport interface CqrsDedupePolicy {\n\treadonly commands?: CqrsDedupeWindow;\n\treadonly events?: CqrsDedupeWindow;\n}\n\nexport interface CqrsBundle<TCommand = unknown, TEvent = unknown> {\n\treadonly command: Node<CqrsCommand<TCommand>>;\n\treadonly runtime: Node<CqrsRuntimeFact<TEvent>>;\n\treadonly events: Node<CqrsEvent<TEvent>>;\n\treadonly status: Node<CqrsStatus>;\n\treadonly errors: Node<CqrsError>;\n\treadonly audit: Node<CqrsAuditRecord>;\n\treadonly cursor: Node<CqrsCursor>;\n\tdispatch(command: CqrsCommand<TCommand>): CqrsCommand<TCommand>;\n}\n\ninterface CqrsRuntimeState {\n\teventSeq: number;\n\tcommandCount: number;\n\terrorCount: number;\n\tauditSeq: number;\n\tseenCommandIds: string[];\n\tseenEventIds: string[];\n\tcommandDedupeEvicted?: number;\n\teventDedupeEvicted?: number;\n}\n\ninterface HandlerRecord {\n\treadonly type: string;\n\treadonly handle: CqrsCommandHandler<unknown, unknown>;\n}\n\ninterface NormalizedCqrsDedupePolicy {\n\treadonly commandMaxEntries?: number;\n\treadonly eventMaxEntries?: number;\n\treadonly bounded: boolean;\n}\n\n/** Convenience helper for declaring typed command handlers in a CQRS bundle. */\nexport function cqrsCommandHandler<TCommand = unknown, TEvent = unknown>(\n\ttype: string,\n\thandle: CqrsCommandHandler<TCommand, TEvent>,\n): CqrsCommandHandlerDefinition<TCommand, TEvent> {\n\tif (type.length === 0) throw new Error(\"cqrsCommandHandler: type must be non-empty\");\n\treturn { type, handle };\n}\n\n/**\n * Create a graph-visible CQRS bundle. Command dispatch is only DATA on the\n * returned `command` node; all derived facts flow through declared graph deps.\n */\nexport function cqrs<TCommand = unknown, TEvent = unknown>(\n\tgraph: Graph,\n\topts: CqrsOptions<TCommand, TEvent> = {},\n): CqrsBundle<TCommand, TEvent> {\n\tconst name = opts.name ?? \"cqrs\";\n\tconst handlers = normalizeHandlers(opts.handlers ?? []);\n\tconst knownEvents =\n\t\topts.events === undefined ? undefined : new Set(uniqueNames(opts.events, \"cqrs.events\"));\n\tconst now = opts.now ?? Date.now;\n\tconst dedupe = normalizeDedupePolicy(opts.dedupe);\n\tconst command = graph.node<CqrsCommand<TCommand>>([], null, {\n\t\tname: `${name}/command`,\n\t\tfactory: \"cqrsCommand\",\n\t\tcompleteWhenDepsComplete: false,\n\t\terrorWhenDepsError: false,\n\t});\n\tconst runtime = graph.node<CqrsRuntimeFact<TEvent>>(\n\t\t[command],\n\t\t(ctx) => {\n\t\t\tconst state =\n\t\t\t\tctx.state.get<CqrsRuntimeState>() ??\n\t\t\t\t({\n\t\t\t\t\teventSeq: 0,\n\t\t\t\t\tcommandCount: 0,\n\t\t\t\t\terrorCount: 0,\n\t\t\t\t\tauditSeq: 0,\n\t\t\t\t\tseenCommandIds: [],\n\t\t\t\t\tseenEventIds: [],\n\t\t\t\t} satisfies CqrsRuntimeState);\n\t\t\tctx.state.persist(true);\n\t\t\tfor (const raw of depBatch(ctx, 0) ?? []) {\n\t\t\t\treduceCommandFact(raw, state, handlers, knownEvents, now, dedupe, (fact) =>\n\t\t\t\t\tctx.down([[\"DATA\", fact as CqrsRuntimeFact<TEvent>]]),\n\t\t\t\t);\n\t\t\t}\n\t\t\tctx.state.set(state);\n\t\t},\n\t\t{\n\t\t\tname: `${name}/runtime`,\n\t\t\tfactory: \"cqrsRuntime\",\n\t\t\tmeta: {\n\t\t\t\tcommandTypes: [...handlers.keys()],\n\t\t\t\teventTypes: knownEvents ? [...knownEvents] : \"open\",\n\t\t\t\tdedupe: dedupeMeta(dedupe),\n\t\t\t},\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\terrorWhenDepsError: false,\n\t\t},\n\t);\n\tconst events = runtimeProjection<CqrsEvent<TEvent>, TEvent>(\n\t\tgraph,\n\t\truntime,\n\t\t\"event\",\n\t\t`${name}/events`,\n\t\t\"cqrsEvents\",\n\t\t(fact) => (fact.kind === \"event\" ? fact.event : undefined),\n\t);\n\tconst status = runtimeProjection<CqrsStatus, TEvent>(\n\t\tgraph,\n\t\truntime,\n\t\t\"status\",\n\t\t`${name}/status`,\n\t\t\"cqrsStatus\",\n\t\t(fact) => (fact.kind === \"status\" ? fact.status : undefined),\n\t);\n\tconst errors = runtimeProjection<CqrsError, TEvent>(\n\t\tgraph,\n\t\truntime,\n\t\t\"error\",\n\t\t`${name}/errors`,\n\t\t\"cqrsErrors\",\n\t\t(fact) => (fact.kind === \"error\" ? fact.error : undefined),\n\t);\n\tconst audit = runtimeProjection<CqrsAuditRecord, TEvent>(\n\t\tgraph,\n\t\truntime,\n\t\t\"audit\",\n\t\t`${name}/audit`,\n\t\t\"cqrsAudit\",\n\t\t(fact) => (fact.kind === \"audit\" ? fact.audit : undefined),\n\t);\n\tconst cursor = runtimeProjection<CqrsCursor, TEvent>(\n\t\tgraph,\n\t\truntime,\n\t\t\"cursor\",\n\t\t`${name}/cursor`,\n\t\t\"cqrsCursor\",\n\t\t(fact) => (fact.kind === \"cursor\" ? fact.cursor : undefined),\n\t);\n\tgraph.retain(runtime, { reason: `${name}.cqrs.runtime` });\n\tgraph.retain(events, { reason: `${name}.cqrs.events` });\n\tgraph.retain(status, { reason: `${name}.cqrs.status` });\n\tgraph.retain(errors, { reason: `${name}.cqrs.errors` });\n\tgraph.retain(audit, { reason: `${name}.cqrs.audit` });\n\tgraph.retain(cursor, { reason: `${name}.cqrs.cursor` });\n\treturn {\n\t\tcommand,\n\t\truntime,\n\t\tevents,\n\t\tstatus,\n\t\terrors,\n\t\taudit,\n\t\tcursor,\n\t\tdispatch(commandFact) {\n\t\t\tcommand.down([[\"DATA\", commandFact]]);\n\t\t\treturn commandFact;\n\t\t},\n\t};\n}\n\nexport interface CqrsProjectionOptions<TState, TEvent = unknown> {\n\treadonly name?: string;\n\treadonly events?: readonly string[];\n\treadonly initial: TState;\n\treadonly reducer: (state: TState, event: CqrsEvent<TEvent>) => TState;\n}\n\nexport type CqrsProjectionFrame<TState> =\n\t| {\n\t\t\treadonly kind: \"value\";\n\t\t\treadonly state: TState;\n\t\t\treadonly eventId: string;\n\t\t\treadonly cursor: CqrsCursor;\n\t }\n\t| { readonly kind: \"error\"; readonly error: CqrsProjectionError };\n\nexport interface CqrsProjectionError {\n\treadonly code: \"projection-threw\";\n\treadonly message: string;\n\treadonly eventId: string;\n\treadonly eventType: string;\n\treadonly cursor: CqrsCursor;\n}\n\nexport interface CqrsProjectionStatus {\n\treadonly state: \"updated\" | \"errored\";\n\treadonly eventId: string;\n\treadonly eventType?: string;\n\treadonly cursor: CqrsCursor;\n}\n\nexport interface CqrsProjection<TState> {\n\treadonly frames: Node<CqrsProjectionFrame<TState>>;\n\treadonly value: Node<TState>;\n\treadonly status: Node<CqrsProjectionStatus>;\n\treadonly errors: Node<CqrsProjectionError>;\n}\n\n/**\n * Derive a projection from declared CQRS event deps. Reducer failures become\n * graph-visible error DATA facts on the returned `errors` node.\n */\nexport function cqrsProjection<TState, TEvent = unknown>(\n\tgraph: Graph,\n\tsource: Pick<CqrsBundle<unknown, TEvent>, \"events\">,\n\topts: CqrsProjectionOptions<TState, TEvent>,\n): CqrsProjection<TState> {\n\tconst name = opts.name ?? \"cqrsProjection\";\n\tconst eventFilter =\n\t\topts.events === undefined\n\t\t\t? undefined\n\t\t\t: new Set(uniqueNames(opts.events, \"cqrsProjection.events\"));\n\tconst frames = graph.node<CqrsProjectionFrame<TState>>(\n\t\t[source.events],\n\t\t(ctx) => {\n\t\t\tconst state = ctx.state.get<{ value: TState }>() ?? { value: opts.initial };\n\t\t\tctx.state.persist(true);\n\t\t\tfor (const raw of depBatch(ctx, 0) ?? []) {\n\t\t\t\tconst event = raw as CqrsEvent<TEvent>;\n\t\t\t\tif (eventFilter !== undefined && !eventFilter.has(event.type)) continue;\n\t\t\t\ttry {\n\t\t\t\t\tstate.value = opts.reducer(state.value, event);\n\t\t\t\t\tctx.state.set(state);\n\t\t\t\t\tctx.down([\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"DATA\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkind: \"value\",\n\t\t\t\t\t\t\t\tstate: state.value,\n\t\t\t\t\t\t\t\teventId: event.id,\n\t\t\t\t\t\t\t\tcursor: event.runtimeCursor,\n\t\t\t\t\t\t\t} satisfies CqrsProjectionFrame<TState>,\n\t\t\t\t\t\t],\n\t\t\t\t\t]);\n\t\t\t\t} catch (error) {\n\t\t\t\t\trethrowGraphRuntimeInvariant(error);\n\t\t\t\t\tctx.down([\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"DATA\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkind: \"error\",\n\t\t\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\t\t\tcode: \"projection-threw\",\n\t\t\t\t\t\t\t\t\tmessage: errorMessage(error),\n\t\t\t\t\t\t\t\t\teventId: event.id,\n\t\t\t\t\t\t\t\t\teventType: event.type,\n\t\t\t\t\t\t\t\t\tcursor: event.runtimeCursor,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t} satisfies CqrsProjectionFrame<TState>,\n\t\t\t\t\t\t],\n\t\t\t\t\t]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tname,\n\t\t\tfactory: \"cqrsProjection\",\n\t\t\tmeta: { eventTypes: eventFilter ? [...eventFilter] : \"open\" },\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\terrorWhenDepsError: false,\n\t\t},\n\t);\n\tconst value = graph.node<TState>(\n\t\t[frames],\n\t\t(ctx) => {\n\t\t\tfor (const frame of depBatch(ctx, 0) ?? []) {\n\t\t\t\tconst typed = frame as CqrsProjectionFrame<TState>;\n\t\t\t\tif (typed.kind === \"value\") ctx.down([[\"DATA\", typed.state]]);\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tname: `${name}/value`,\n\t\t\tfactory: \"cqrsProjectionValue\",\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\terrorWhenDepsError: false,\n\t\t},\n\t);\n\tconst errors = graph.node<CqrsProjectionError>(\n\t\t[frames],\n\t\t(ctx) => {\n\t\t\tfor (const frame of depBatch(ctx, 0) ?? []) {\n\t\t\t\tconst typed = frame as CqrsProjectionFrame<TState>;\n\t\t\t\tif (typed.kind === \"error\") ctx.down([[\"DATA\", typed.error]]);\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tname: `${name}/errors`,\n\t\t\tfactory: \"cqrsProjectionErrors\",\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\terrorWhenDepsError: false,\n\t\t},\n\t);\n\tconst status = graph.node<CqrsProjectionStatus>(\n\t\t[frames],\n\t\t(ctx) => {\n\t\t\tfor (const frame of depBatch(ctx, 0) ?? []) {\n\t\t\t\tconst typed = frame as CqrsProjectionFrame<TState>;\n\t\t\t\tif (typed.kind === \"value\") {\n\t\t\t\t\tctx.down([\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"DATA\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstate: \"updated\",\n\t\t\t\t\t\t\t\teventId: typed.eventId,\n\t\t\t\t\t\t\t\tcursor: typed.cursor,\n\t\t\t\t\t\t\t} satisfies CqrsProjectionStatus,\n\t\t\t\t\t\t],\n\t\t\t\t\t]);\n\t\t\t\t} else {\n\t\t\t\t\tctx.down([\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"DATA\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstate: \"errored\",\n\t\t\t\t\t\t\t\teventId: typed.error.eventId,\n\t\t\t\t\t\t\t\teventType: typed.error.eventType,\n\t\t\t\t\t\t\t\tcursor: typed.error.cursor,\n\t\t\t\t\t\t\t} satisfies CqrsProjectionStatus,\n\t\t\t\t\t\t],\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tname: `${name}/status`,\n\t\t\tfactory: \"cqrsProjectionStatus\",\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\terrorWhenDepsError: false,\n\t\t},\n\t);\n\tgraph.retain(frames, { reason: `${name}.cqrsProjection.frames` });\n\tgraph.retain(value, { reason: `${name}.cqrsProjection.value` });\n\tgraph.retain(status, { reason: `${name}.cqrsProjection.status` });\n\tgraph.retain(errors, { reason: `${name}.cqrsProjection.errors` });\n\treturn { frames, value, status, errors };\n}\n\nfunction normalizeHandlers<TCommand, TEvent>(\n\tdefinitions: readonly CqrsCommandHandlerDefinition<TCommand, TEvent>[],\n): ReadonlyMap<string, HandlerRecord> {\n\tconst handlers = new Map<string, HandlerRecord>();\n\tfor (const definition of definitions) {\n\t\tif (definition.type.length === 0) throw new Error(\"cqrs: handler type must be non-empty\");\n\t\tif (handlers.has(definition.type))\n\t\t\tthrow new Error(`cqrs: duplicate handler '${definition.type}'`);\n\t\thandlers.set(definition.type, {\n\t\t\ttype: definition.type,\n\t\t\thandle: definition.handle as CqrsCommandHandler<unknown, unknown>,\n\t\t});\n\t}\n\treturn handlers;\n}\n\nfunction reduceCommandFact<TEvent>(\n\traw: unknown,\n\tstate: CqrsRuntimeState,\n\thandlers: ReadonlyMap<string, HandlerRecord>,\n\tknownEvents: ReadonlySet<string> | undefined,\n\tnow: () => number,\n\tdedupe: NormalizedCqrsDedupePolicy,\n\temit: (fact: CqrsRuntimeFact<TEvent>) => void,\n): void {\n\tstate.commandCount += 1;\n\tconst parsed = parseCommand(raw);\n\tif (typeof parsed === \"string\") {\n\t\temitFailure(state, emit, raw, undefined, \"malformed-command\", parsed, dedupe);\n\t\treturn;\n\t}\n\tconst command = parsed as CqrsCommand<unknown>;\n\tif (state.seenCommandIds.includes(command.id)) {\n\t\temitFailure(\n\t\t\tstate,\n\t\t\temit,\n\t\t\tcommand,\n\t\t\tcommand,\n\t\t\t\"duplicate-command\",\n\t\t\t`cqrs: duplicate command '${command.id}'`,\n\t\t\tdedupe,\n\t\t);\n\t\treturn;\n\t}\n\tstate.seenCommandIds.push(command.id);\n\ttrimDedupeWindow(state.seenCommandIds, dedupe.commandMaxEntries, (evicted) => {\n\t\tstate.commandDedupeEvicted = (state.commandDedupeEvicted ?? 0) + evicted;\n\t});\n\tconst handler = handlers.get(command.type);\n\tif (handler === undefined) {\n\t\temitFailure(\n\t\t\tstate,\n\t\t\temit,\n\t\t\tcommand,\n\t\t\tcommand,\n\t\t\t\"unknown-command\",\n\t\t\t`cqrs: unknown command '${command.type}'`,\n\t\t\tdedupe,\n\t\t);\n\t\treturn;\n\t}\n\tlet drafts: readonly CqrsEventDraft<unknown>[];\n\ttry {\n\t\tdrafts = handler.handle(command);\n\t} catch (error) {\n\t\trethrowGraphRuntimeInvariant(error);\n\t\temitFailure(state, emit, command, command, \"handler-threw\", errorMessage(error), dedupe);\n\t\treturn;\n\t}\n\tif (!Array.isArray(drafts)) {\n\t\temitFailure(\n\t\t\tstate,\n\t\t\temit,\n\t\t\tcommand,\n\t\t\tcommand,\n\t\t\t\"malformed-event\",\n\t\t\t\"cqrs: command handler must return an event draft array\",\n\t\t\tdedupe,\n\t\t);\n\t\treturn;\n\t}\n\tconst prepared = prepareEvents(command, drafts, state, knownEvents);\n\tif (typeof prepared === \"string\") {\n\t\temitFailure(state, emit, command, command, preparedCode(prepared), prepared, dedupe);\n\t\treturn;\n\t}\n\tconst timestampMs = readTimestampMs(now);\n\tif (typeof timestampMs === \"string\") {\n\t\temitFailure(state, emit, command, command, \"clock-threw\", timestampMs, dedupe);\n\t\treturn;\n\t}\n\tconst events: CqrsEvent<unknown>[] = [];\n\tfor (const draft of prepared) {\n\t\tstate.eventSeq += 1;\n\t\tstate.seenEventIds.push(draft.id);\n\t\ttrimDedupeWindow(state.seenEventIds, dedupe.eventMaxEntries, (evicted) => {\n\t\t\tstate.eventDedupeEvicted = (state.eventDedupeEvicted ?? 0) + evicted;\n\t\t});\n\t\tconst runtimeCursor = cursorOf(state, dedupe);\n\t\tevents.push({\n\t\t\tid: draft.id,\n\t\t\ttype: draft.type,\n\t\t\tseq: state.eventSeq,\n\t\t\tcursor: state.eventSeq,\n\t\t\truntimeCursor,\n\t\t\tcommandId: command.id,\n\t\t\tcommandType: command.type,\n\t\t\tpayload: draft.payload,\n\t\t\ttimestampMs,\n\t\t\t...(draft.aggregateId === undefined ? {} : { aggregateId: draft.aggregateId }),\n\t\t\t...(draft.correlationId === undefined ? {} : { correlationId: draft.correlationId }),\n\t\t\t...(draft.causationId === undefined ? {} : { causationId: draft.causationId }),\n\t\t\t...(draft.metadata === undefined ? {} : { metadata: draft.metadata }),\n\t\t});\n\t}\n\tfor (const event of events) emit({ kind: \"event\", event: event as CqrsEvent<TEvent> });\n\temitStatus(state, emit, command, \"accepted\", events.length, dedupe);\n\temitAudit(state, emit, command, \"success\", events, undefined, undefined, dedupe);\n\temit({ kind: \"cursor\", cursor: cursorOf(state, dedupe) });\n}\n\nfunction parseCommand(value: unknown): CqrsCommand<unknown> | string {\n\tif (!isObjectRecord(value)) return \"cqrs: command fact must be an object\";\n\tif (typeof value.id !== \"string\" || value.id.length === 0) {\n\t\treturn \"cqrs: command id must be a non-empty string\";\n\t}\n\tif (typeof value.type !== \"string\" || value.type.length === 0) {\n\t\treturn \"cqrs: command type must be a non-empty string\";\n\t}\n\treturn {\n\t\tid: value.id,\n\t\ttype: value.type,\n\t\tpayload: value.payload,\n\t\t...(typeof value.aggregateId === \"string\" ? { aggregateId: value.aggregateId } : {}),\n\t\t...(typeof value.correlationId === \"string\" ? { correlationId: value.correlationId } : {}),\n\t\t...(typeof value.causationId === \"string\" ? { causationId: value.causationId } : {}),\n\t\t...(isObjectRecord(value.metadata) ? { metadata: value.metadata } : {}),\n\t};\n}\n\nfunction prepareEvents(\n\tcommand: CqrsCommand<unknown>,\n\tdrafts: readonly CqrsEventDraft<unknown>[],\n\tstate: CqrsRuntimeState,\n\tknownEvents: ReadonlySet<string> | undefined,\n): Array<CqrsEventDraft<unknown> & { readonly id: string }> | string {\n\tconst seenInCommand = new Set<string>();\n\tconst prepared: Array<CqrsEventDraft<unknown> & { readonly id: string }> = [];\n\tfor (let i = 0; i < drafts.length; i += 1) {\n\t\tconst draft = drafts[i];\n\t\tif (!isObjectRecord(draft) || typeof draft.type !== \"string\" || draft.type.length === 0) {\n\t\t\treturn \"cqrs: event draft must have a non-empty type\";\n\t\t}\n\t\tif (knownEvents !== undefined && !knownEvents.has(draft.type)) {\n\t\t\treturn `cqrs: unknown event '${draft.type}'`;\n\t\t}\n\t\tconst id =\n\t\t\ttypeof draft.id === \"string\" && draft.id.length > 0 ? draft.id : `${command.id}:${i + 1}`;\n\t\tif (state.seenEventIds.includes(id) || seenInCommand.has(id)) {\n\t\t\treturn `cqrs: duplicate event '${id}'`;\n\t\t}\n\t\tseenInCommand.add(id);\n\t\tprepared.push({\n\t\t\tid,\n\t\t\ttype: draft.type,\n\t\t\tpayload: draft.payload,\n\t\t\t...(typeof draft.aggregateId === \"string\" ? { aggregateId: draft.aggregateId } : {}),\n\t\t\t...(typeof draft.correlationId === \"string\" ? { correlationId: draft.correlationId } : {}),\n\t\t\t...(typeof draft.causationId === \"string\" ? { causationId: draft.causationId } : {}),\n\t\t\t...(isObjectRecord(draft.metadata) ? { metadata: draft.metadata } : {}),\n\t\t});\n\t}\n\treturn prepared;\n}\n\nfunction preparedCode(message: string): CqrsErrorCode {\n\tif (message.includes(\"unknown event\")) return \"unknown-event\";\n\tif (message.includes(\"duplicate event\")) return \"duplicate-event\";\n\treturn \"malformed-event\";\n}\n\nfunction rethrowGraphRuntimeInvariant(error: unknown): void {\n\tconst message = errorMessage(error);\n\tif (\n\t\tmessage.includes(\"R-reentrancy\") ||\n\t\tmessage.includes(\"R-rewire\") ||\n\t\tmessage.includes(\"R-graph-domain\") ||\n\t\tmessage.includes(\"D37\") ||\n\t\tmessage.includes(\"D22\") ||\n\t\tmessage.includes(\"different graph\") ||\n\t\tmessage.includes(\"cross-graph\") ||\n\t\tmessage.includes(\"wire bridge\") ||\n\t\tmessage.includes(\"mid-fn topology mutation\") ||\n\t\tmessage.includes(\"reentrant dep mutation\") ||\n\t\tmessage.includes(\"feedback cycle\")\n\t) {\n\t\tthrow error;\n\t}\n}\n\nfunction emitFailure<TEvent>(\n\tstate: CqrsRuntimeState,\n\temit: (fact: CqrsRuntimeFact<TEvent>) => void,\n\traw: unknown,\n\tcommand: CqrsCommand<unknown> | undefined,\n\tcode: CqrsErrorCode,\n\tmessage: string,\n\tdedupe: NormalizedCqrsDedupePolicy,\n): void {\n\tstate.errorCount += 1;\n\tconst cursor = cursorOf(state, dedupe);\n\tconst error: CqrsError = {\n\t\tcode,\n\t\tmessage,\n\t\tcommand: raw,\n\t\t...(command === undefined ? {} : { commandId: command.id, commandType: command.type }),\n\t\tcursor,\n\t};\n\temit({ kind: \"error\", error });\n\temit({\n\t\tkind: \"status\",\n\t\tstatus: {\n\t\t\tstate: \"rejected\",\n\t\t\t...(command === undefined ? {} : { commandId: command.id, commandType: command.type }),\n\t\t\teventCount: 0,\n\t\t\terrorCode: code,\n\t\t\tcursor,\n\t\t},\n\t});\n\temitAudit(state, emit, command, \"failure\", [], code, message, dedupe);\n\temit({ kind: \"cursor\", cursor: cursorOf(state, dedupe) });\n}\n\nfunction emitStatus<TEvent>(\n\tstate: CqrsRuntimeState,\n\temit: (fact: CqrsRuntimeFact<TEvent>) => void,\n\tcommand: CqrsCommand<unknown>,\n\tstatusState: \"accepted\" | \"rejected\",\n\teventCount: number,\n\tdedupe: NormalizedCqrsDedupePolicy,\n): void {\n\temit({\n\t\tkind: \"status\",\n\t\tstatus: {\n\t\t\tstate: statusState,\n\t\t\tcommandId: command.id,\n\t\t\tcommandType: command.type,\n\t\t\teventCount,\n\t\t\tcursor: cursorOf(state, dedupe),\n\t\t},\n\t});\n}\n\nfunction emitAudit<TEvent>(\n\tstate: CqrsRuntimeState,\n\temit: (fact: CqrsRuntimeFact<TEvent>) => void,\n\tcommand: CqrsCommand<unknown> | undefined,\n\toutcome: \"success\" | \"failure\",\n\tevents: readonly CqrsEvent<unknown>[],\n\terrorCode: CqrsErrorCode | undefined,\n\terrorMessageValue: string | undefined,\n\tdedupe: NormalizedCqrsDedupePolicy,\n): void {\n\tstate.auditSeq += 1;\n\temit({\n\t\tkind: \"audit\",\n\t\taudit: {\n\t\t\tseq: state.auditSeq,\n\t\t\t...(command === undefined ? {} : { commandId: command.id, commandType: command.type }),\n\t\t\toutcome,\n\t\t\teventIds: Object.freeze(events.map((event) => event.id)),\n\t\t\teventTypes: Object.freeze(events.map((event) => event.type)),\n\t\t\t...(errorCode === undefined ? {} : { errorCode }),\n\t\t\t...(errorMessageValue === undefined ? {} : { errorMessage: errorMessageValue }),\n\t\t\tcursor: cursorOf(state, dedupe),\n\t\t},\n\t});\n}\n\nfunction runtimeProjection<TOut, TEvent>(\n\tgraph: Graph,\n\truntime: Node<CqrsRuntimeFact<TEvent>>,\n\tkind: CqrsRuntimeFact<TEvent>[\"kind\"],\n\tname: string,\n\tfactory: string,\n\tselect: (fact: CqrsRuntimeFact<TEvent>) => TOut | undefined,\n): Node<TOut> {\n\treturn graph.node<TOut>(\n\t\t[runtime],\n\t\t(ctx) => {\n\t\t\tfor (const fact of depBatch(ctx, 0) ?? []) {\n\t\t\t\tconst typed = fact as CqrsRuntimeFact<TEvent>;\n\t\t\t\tif (typed.kind !== kind) continue;\n\t\t\t\tconst selected = select(typed);\n\t\t\t\tif (selected !== undefined) ctx.down([[\"DATA\", selected]]);\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tname,\n\t\t\tfactory,\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\terrorWhenDepsError: false,\n\t\t},\n\t);\n}\n\nfunction cursorOf(state: CqrsRuntimeState, dedupe: NormalizedCqrsDedupePolicy): CqrsCursor {\n\treturn {\n\t\teventSeq: state.eventSeq,\n\t\tcommandCount: state.commandCount,\n\t\terrorCount: state.errorCount,\n\t\tauditSeq: state.auditSeq,\n\t\t...(dedupe.bounded\n\t\t\t? {\n\t\t\t\t\tdedupe: {\n\t\t\t\t\t\tcommandIdsRetained: state.seenCommandIds.length,\n\t\t\t\t\t\teventIdsRetained: state.seenEventIds.length,\n\t\t\t\t\t\tcommandIdsEvicted: state.commandDedupeEvicted ?? 0,\n\t\t\t\t\t\teventIdsEvicted: state.eventDedupeEvicted ?? 0,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {}),\n\t};\n}\n\nfunction normalizeDedupePolicy(policy: CqrsDedupePolicy | undefined): NormalizedCqrsDedupePolicy {\n\tconst commandMaxEntries = normalizeDedupeWindow(policy?.commands, \"cqrs.dedupe.commands\");\n\tconst eventMaxEntries = normalizeDedupeWindow(policy?.events, \"cqrs.dedupe.events\");\n\treturn {\n\t\t...(commandMaxEntries === undefined ? {} : { commandMaxEntries }),\n\t\t...(eventMaxEntries === undefined ? {} : { eventMaxEntries }),\n\t\tbounded: commandMaxEntries !== undefined || eventMaxEntries !== undefined,\n\t};\n}\n\nfunction normalizeDedupeWindow(\n\twindow: CqrsDedupeWindow | undefined,\n\towner: string,\n): number | undefined {\n\tif (window === undefined || window === \"unbounded\") return undefined;\n\tif (!Number.isInteger(window.maxEntries) || window.maxEntries < 0) {\n\t\tthrow new RangeError(`${owner}: maxEntries must be a non-negative integer`);\n\t}\n\treturn window.maxEntries;\n}\n\nfunction dedupeMeta(dedupe: NormalizedCqrsDedupePolicy): unknown {\n\tif (!dedupe.bounded) return \"unbounded\";\n\treturn {\n\t\tcommands:\n\t\t\tdedupe.commandMaxEntries === undefined\n\t\t\t\t? \"unbounded\"\n\t\t\t\t: { maxEntries: dedupe.commandMaxEntries },\n\t\tevents:\n\t\t\tdedupe.eventMaxEntries === undefined ? \"unbounded\" : { maxEntries: dedupe.eventMaxEntries },\n\t};\n}\n\nfunction trimDedupeWindow(\n\tids: string[],\n\tmaxEntries: number | undefined,\n\tonEvicted: (evicted: number) => void,\n): void {\n\tif (maxEntries === undefined || ids.length <= maxEntries) return;\n\tconst evicted = ids.length - maxEntries;\n\tids.splice(0, evicted);\n\tonEvicted(evicted);\n}\n\nfunction readTimestampMs(now: () => number): number | string {\n\ttry {\n\t\tconst timestampMs = now();\n\t\treturn Number.isFinite(timestampMs) ? timestampMs : \"cqrs: now() must return a finite number\";\n\t} catch (error) {\n\t\treturn `cqrs: now() threw: ${errorMessage(error)}`;\n\t}\n}\n\nfunction uniqueNames(values: readonly string[], owner: string): readonly string[] {\n\tconst unique = [...new Set(values)];\n\tif (unique.length !== values.length) throw new Error(`${owner}: duplicate value`);\n\tfor (const value of unique) {\n\t\tif (value.length === 0) throw new Error(`${owner}: values must be non-empty`);\n\t}\n\treturn Object.freeze(unique);\n}\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":"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","names":[]}
|