@graphrefly/ts 0.0.0 → 0.0.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/README.md +135 -0
- package/dist/adapters/index.cjs +105 -66
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +11 -136
- package/dist/adapters/index.d.ts +11 -136
- package/dist/adapters/index.js +27 -225
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/observe-storage.d.cts +4 -4
- package/dist/adapters/observe-storage.d.ts +4 -4
- package/dist/adapters/observe-storage.js +1 -0
- package/dist/adapters/observe-storage.js.map +1 -1
- package/dist/adapters/react.cjs +166 -0
- package/dist/adapters/react.cjs.map +1 -0
- package/dist/adapters/react.d.cts +31 -0
- package/dist/adapters/react.d.ts +31 -0
- package/dist/adapters/react.js +51 -0
- package/dist/adapters/react.js.map +1 -0
- package/dist/adapters/solid.cjs +157 -0
- package/dist/adapters/solid.cjs.map +1 -0
- package/dist/adapters/solid.d.cts +26 -0
- package/dist/adapters/solid.d.ts +26 -0
- package/dist/adapters/solid.js +48 -0
- package/dist/adapters/solid.js.map +1 -0
- package/dist/adapters/svelte.cjs +148 -0
- package/dist/adapters/svelte.cjs.map +1 -0
- package/dist/adapters/svelte.d.cts +31 -0
- package/dist/adapters/svelte.d.ts +31 -0
- package/dist/adapters/svelte.js +46 -0
- package/dist/adapters/svelte.js.map +1 -0
- package/dist/adapters/vue.cjs +155 -0
- package/dist/adapters/vue.cjs.map +1 -0
- package/dist/adapters/vue.d.cts +26 -0
- package/dist/adapters/vue.d.ts +26 -0
- package/dist/adapters/vue.js +46 -0
- package/dist/adapters/vue.js.map +1 -0
- package/dist/agent-runtime-BesGDZcB.d.ts +555 -0
- package/dist/agent-runtime-DZTJ3C-p.d.cts +555 -0
- package/dist/agentic-memory-BmRCvh0d.d.ts +517 -0
- package/dist/agentic-memory-DfuVZ-lY.d.cts +517 -0
- package/dist/capability-admission-B0BzqAm5.d.cts +102 -0
- package/dist/capability-admission-g0mn9hpq.d.ts +102 -0
- package/dist/{chunk-JR4IKCR2.js → chunk-2747WN4Y.js} +5 -5
- package/dist/{chunk-2ILL7HQI.js → chunk-3JR3EDB2.js} +17 -17
- package/dist/{chunk-2ILL7HQI.js.map → chunk-3JR3EDB2.js.map} +1 -1
- package/dist/{chunk-GDL26N2T.js → chunk-3KN7NJDR.js} +2 -2
- package/dist/{chunk-DJC4CHLQ.js → chunk-43BKLFZU.js} +9 -9
- package/dist/chunk-6XAIOL3X.js +2407 -0
- package/dist/chunk-6XAIOL3X.js.map +1 -0
- package/dist/{chunk-SCRFRCGR.js → chunk-BSQGE5PS.js} +1 -1
- package/dist/{chunk-Y3ZLRGHC.js → chunk-CZNV3VXM.js} +16 -16
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/{chunk-JIMUDQN3.js → chunk-FBUU43PM.js} +2 -2
- package/dist/chunk-H75VXTGT.js +219 -0
- package/dist/chunk-H75VXTGT.js.map +1 -0
- package/dist/{chunk-RIIOUTGM.js → chunk-HKK2JD7Z.js} +12 -9
- package/dist/chunk-HKK2JD7Z.js.map +1 -0
- package/dist/{chunk-D6BG7U6A.js → chunk-IXZBUWSP.js} +3 -3
- package/dist/chunk-PC3BTTBE.js +3217 -0
- package/dist/chunk-PC3BTTBE.js.map +1 -0
- package/dist/chunk-QFY4AFY4.js +879 -0
- package/dist/chunk-QFY4AFY4.js.map +1 -0
- package/dist/{chunk-DK554R7P.js → chunk-S6HXABGL.js} +2 -1
- package/dist/chunk-S6HXABGL.js.map +1 -0
- package/dist/{chunk-PKVBHGBM.js → chunk-SS2A464I.js} +7 -7
- package/dist/chunk-UT3MHJCW.js +49 -0
- package/dist/chunk-UT3MHJCW.js.map +1 -0
- package/dist/{chunk-G4M3NHRJ.js → chunk-V7CIJE4B.js} +3 -3
- package/dist/{chunk-TEW47IVR.js → chunk-VPEFSDME.js} +2 -2
- package/dist/chunk-VTHLCFN4.js +368 -0
- package/dist/chunk-VTHLCFN4.js.map +1 -0
- package/dist/{chunk-SWTLEQL6.js → chunk-WQIA3GFB.js} +2 -2
- package/dist/chunk-WQIA3GFB.js.map +1 -0
- package/dist/{chunk-I3IHOHCJ.js → chunk-XKXWK2KP.js} +108 -64
- package/dist/chunk-XKXWK2KP.js.map +1 -0
- package/dist/{chunk-COHO25CZ.js → chunk-YDSIVHRR.js} +553 -7
- package/dist/chunk-YDSIVHRR.js.map +1 -0
- package/dist/chunk-YXMZ2N6J.js +1884 -0
- package/dist/chunk-YXMZ2N6J.js.map +1 -0
- package/dist/composition/index.cjs +102 -57
- package/dist/composition/index.cjs.map +1 -1
- package/dist/composition/index.d.cts +4 -4
- package/dist/composition/index.d.ts +4 -4
- package/dist/composition/index.js +6 -5
- package/dist/core/index.cjs +102 -57
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +5 -4
- package/dist/cqrs/index.cjs.map +1 -1
- package/dist/cqrs/index.d.cts +4 -4
- package/dist/cqrs/index.d.ts +4 -4
- package/dist/cqrs/index.js +3 -2
- package/dist/cqrs/index.js.map +1 -1
- package/dist/cqrs/messaging.cjs +312 -0
- package/dist/cqrs/messaging.cjs.map +1 -0
- package/dist/cqrs/messaging.d.cts +57 -0
- package/dist/cqrs/messaging.d.ts +57 -0
- package/dist/cqrs/messaging.js +274 -0
- package/dist/cqrs/messaging.js.map +1 -0
- package/dist/cqrs/work-queue.cjs +329 -0
- package/dist/cqrs/work-queue.cjs.map +1 -0
- package/dist/cqrs/work-queue.d.cts +90 -0
- package/dist/cqrs/work-queue.d.ts +90 -0
- package/dist/cqrs/work-queue.js +292 -0
- package/dist/cqrs/work-queue.js.map +1 -0
- package/dist/data/index.cjs +19 -0
- package/dist/data/index.cjs.map +1 -0
- package/dist/data/index.d.cts +36 -0
- package/dist/data/index.d.ts +36 -0
- package/dist/data/index.js +1 -0
- package/dist/data/index.js.map +1 -0
- package/dist/data-structures/index.cjs +105 -57
- package/dist/data-structures/index.cjs.map +1 -1
- package/dist/data-structures/index.d.cts +8 -8
- package/dist/data-structures/index.d.ts +8 -8
- package/dist/data-structures/index.js +7 -6
- package/dist/{describe-BZb7AS2y.d.ts → describe-BpyJuWkw.d.ts} +1 -1
- package/dist/{describe-Ciu8SUnN.d.cts → describe-DYMw_l1C.d.cts} +1 -1
- package/dist/executors/work-queue.cjs +342 -0
- package/dist/executors/work-queue.cjs.map +1 -0
- package/dist/executors/work-queue.d.cts +90 -0
- package/dist/executors/work-queue.d.ts +90 -0
- package/dist/executors/work-queue.js +306 -0
- package/dist/executors/work-queue.js.map +1 -0
- package/dist/graph/index.cjs +112 -58
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.d.cts +9 -9
- package/dist/graph/index.d.ts +9 -9
- package/dist/graph/index.js +18 -17
- package/dist/{graph-DfdF9zy4.d.ts → graph-D-1-SQeC.d.ts} +3 -3
- package/dist/{graph-s23RbbFO.d.cts → graph-DCEWh4T2.d.cts} +3 -3
- package/dist/{index-CAEmLCYF.d.cts → index-72VZC0-E.d.cts} +2 -2
- package/dist/{index-SnzZu3x7.d.ts → index-Bmxeu0nK.d.ts} +2 -2
- package/dist/index.cjs +112 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -10
- package/dist/index.d.ts +11 -10
- package/dist/index.js +118 -113
- package/dist/inspection/boundary.cjs +98 -0
- package/dist/inspection/boundary.cjs.map +1 -0
- package/dist/inspection/boundary.d.cts +61 -0
- package/dist/inspection/boundary.d.ts +61 -0
- package/dist/inspection/boundary.js +75 -0
- package/dist/inspection/boundary.js.map +1 -0
- package/dist/{messages-BZqrGGm1.d.ts → messages-CAzUPPJM.d.cts} +10 -5
- package/dist/{messages-BZqrGGm1.d.cts → messages-CAzUPPJM.d.ts} +10 -5
- package/dist/messaging/index.cjs +744 -613
- package/dist/messaging/index.cjs.map +1 -1
- package/dist/messaging/index.d.cts +216 -160
- package/dist/messaging/index.d.ts +216 -160
- package/dist/messaging/index.js +19 -749
- package/dist/messaging/index.js.map +1 -1
- package/dist/operators/index.cjs +102 -57
- package/dist/operators/index.cjs.map +1 -1
- package/dist/operators/index.d.cts +6 -6
- package/dist/operators/index.d.ts +6 -6
- package/dist/operators/index.js +8 -7
- package/dist/orchestration/index.cjs +3333 -59
- package/dist/orchestration/index.cjs.map +1 -1
- package/dist/orchestration/index.d.cts +7 -4
- package/dist/orchestration/index.d.ts +7 -4
- package/dist/orchestration/index.js +49 -8
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/messaging.cjs +314 -0
- package/dist/orchestration/messaging.cjs.map +1 -0
- package/dist/orchestration/messaging.d.cts +59 -0
- package/dist/orchestration/messaging.d.ts +59 -0
- package/dist/orchestration/messaging.js +276 -0
- package/dist/orchestration/messaging.js.map +1 -0
- package/dist/orchestration/work-queue.cjs +262 -0
- package/dist/orchestration/work-queue.cjs.map +1 -0
- package/dist/orchestration/work-queue.d.cts +85 -0
- package/dist/orchestration/work-queue.d.ts +85 -0
- package/dist/orchestration/work-queue.js +226 -0
- package/dist/orchestration/work-queue.js.map +1 -0
- package/dist/patterns/event-flow.cjs +447 -0
- package/dist/patterns/event-flow.cjs.map +1 -0
- package/dist/patterns/event-flow.d.cts +115 -0
- package/dist/patterns/event-flow.d.ts +115 -0
- package/dist/patterns/event-flow.js +14 -0
- package/dist/patterns/event-flow.js.map +1 -0
- package/dist/patterns/index.cjs +423 -18
- package/dist/patterns/index.cjs.map +1 -1
- package/dist/patterns/index.d.cts +8 -5
- package/dist/patterns/index.d.ts +8 -5
- package/dist/patterns/index.js +13 -4
- package/dist/{reactive-collection-Cb1II1Fi.d.ts → reactive-collection-BAmfrGjd.d.ts} +9 -9
- package/dist/{reactive-collection-BxBqtIOE.d.cts → reactive-collection-DNV0-gFi.d.cts} +9 -9
- package/dist/{reactive-collection-storage-D-KmjE0J.d.cts → reactive-collection-storage-BNEldDyi.d.cts} +5 -5
- package/dist/{reactive-collection-storage-BNiEc-Gd.d.ts → reactive-collection-storage-YZsAQsWK.d.ts} +5 -5
- package/dist/{reactive-map-D-g3dv8I.d.cts → reactive-map-DRD1LJ2H.d.cts} +6 -6
- package/dist/{reactive-map-BcB4KsQR.d.ts → reactive-map-EsDiCmJk.d.ts} +6 -6
- package/dist/render/index.d.cts +3 -3
- package/dist/render/index.d.ts +3 -3
- package/dist/render/index.js +1 -0
- package/dist/{semantic-memory-graph-BYoIlP35.d.cts → semantic-memory-graph-DKuNzuWw.d.cts} +2 -2
- package/dist/{semantic-memory-graph-CxyXLms3.d.ts → semantic-memory-graph-uwbwJdhe.d.ts} +2 -2
- package/dist/solutions/index.cjs +4478 -2
- package/dist/solutions/index.cjs.map +1 -1
- package/dist/solutions/index.d.cts +13 -519
- package/dist/solutions/index.d.ts +13 -519
- package/dist/solutions/index.js +90 -6
- package/dist/solutions/reactive-layout/browser/index.cjs +449 -0
- package/dist/solutions/reactive-layout/browser/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/browser/index.d.cts +44 -0
- package/dist/solutions/reactive-layout/browser/index.d.ts +44 -0
- package/dist/solutions/reactive-layout/browser/index.js +69 -0
- package/dist/solutions/reactive-layout/browser/index.js.map +1 -0
- package/dist/solutions/reactive-layout/index.cjs +4266 -0
- package/dist/solutions/reactive-layout/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/index.d.cts +581 -0
- package/dist/solutions/reactive-layout/index.d.ts +581 -0
- package/dist/solutions/reactive-layout/index.js +86 -0
- package/dist/solutions/reactive-layout/index.js.map +1 -0
- package/dist/solutions/reactive-layout/node-canvas/index.cjs +545 -0
- package/dist/solutions/reactive-layout/node-canvas/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/node-canvas/index.d.cts +54 -0
- package/dist/solutions/reactive-layout/node-canvas/index.d.ts +54 -0
- package/dist/solutions/reactive-layout/node-canvas/index.js +131 -0
- package/dist/solutions/reactive-layout/node-canvas/index.js.map +1 -0
- package/dist/solutions/reactive-layout/react-native/index.cjs +494 -0
- package/dist/solutions/reactive-layout/react-native/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/react-native/index.d.cts +51 -0
- package/dist/solutions/reactive-layout/react-native/index.d.ts +51 -0
- package/dist/solutions/reactive-layout/react-native/index.js +77 -0
- package/dist/solutions/reactive-layout/react-native/index.js.map +1 -0
- package/dist/solutions/reactive-layout/skia/index.cjs +547 -0
- package/dist/solutions/reactive-layout/skia/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/skia/index.d.cts +64 -0
- package/dist/solutions/reactive-layout/skia/index.d.ts +64 -0
- package/dist/solutions/reactive-layout/skia/index.js +70 -0
- package/dist/solutions/reactive-layout/skia/index.js.map +1 -0
- package/dist/solutions/work-item/actions.cjs +2164 -0
- package/dist/solutions/work-item/actions.cjs.map +1 -0
- package/dist/solutions/work-item/actions.d.cts +201 -0
- package/dist/solutions/work-item/actions.d.ts +201 -0
- package/dist/solutions/work-item/actions.js +1454 -0
- package/dist/solutions/work-item/actions.js.map +1 -0
- package/dist/solutions/work-item/scheduling.cjs +2454 -0
- package/dist/solutions/work-item/scheduling.cjs.map +1 -0
- package/dist/solutions/work-item/scheduling.d.cts +433 -0
- package/dist/solutions/work-item/scheduling.d.ts +433 -0
- package/dist/solutions/work-item/scheduling.js +32 -0
- package/dist/solutions/work-item/scheduling.js.map +1 -0
- package/dist/solutions/work-item/work-queue.cjs +306 -0
- package/dist/solutions/work-item/work-queue.cjs.map +1 -0
- package/dist/solutions/work-item/work-queue.d.cts +71 -0
- package/dist/solutions/work-item/work-queue.d.ts +71 -0
- package/dist/solutions/work-item/work-queue.js +270 -0
- package/dist/solutions/work-item/work-queue.js.map +1 -0
- package/dist/sources/browser.cjs +169 -57
- package/dist/sources/browser.cjs.map +1 -1
- package/dist/sources/browser.d.cts +33 -6
- package/dist/sources/browser.d.ts +33 -6
- package/dist/sources/browser.js +73 -6
- package/dist/sources/browser.js.map +1 -1
- package/dist/sources/index.cjs +102 -57
- package/dist/sources/index.cjs.map +1 -1
- package/dist/sources/index.d.cts +5 -5
- package/dist/sources/index.d.ts +5 -5
- package/dist/sources/index.js +6 -5
- package/dist/sources/node.cjs.map +1 -1
- package/dist/sources/node.d.cts +4 -4
- package/dist/sources/node.d.ts +4 -4
- package/dist/sources/node.js +2 -1
- package/dist/sources/node.js.map +1 -1
- package/dist/storage/browser.js +1 -0
- package/dist/storage/browser.js.map +1 -1
- package/dist/storage/index.d.cts +5 -5
- package/dist/storage/index.d.ts +5 -5
- package/dist/storage/index.js +5 -4
- package/dist/storage/node.js +1 -0
- package/dist/storage/node.js.map +1 -1
- package/dist/store-C-joM4gh.d.ts +123 -0
- package/dist/store-CNJwmT-h.d.cts +123 -0
- package/dist/testing/index.cjs +1 -0
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +3 -2
- package/dist/{types-h12mNYbq.d.ts → types-BsJvElYZ.d.ts} +31 -31
- package/dist/{types-bNMSWKqF.d.cts → types-CcPIn7sy.d.cts} +31 -31
- package/dist/work-item-runtime-C3M79vE9.d.ts +228 -0
- package/dist/work-item-runtime-qaVgsL0T.d.cts +228 -0
- package/dist/work-queue/index.cjs +1132 -0
- package/dist/work-queue/index.cjs.map +1 -0
- package/dist/work-queue/index.d.cts +369 -0
- package/dist/work-queue/index.d.ts +369 -0
- package/dist/work-queue/index.js +1078 -0
- package/dist/work-queue/index.js.map +1 -0
- package/package.json +266 -2
- package/dist/chunk-COHO25CZ.js.map +0 -1
- package/dist/chunk-DK554R7P.js.map +0 -1
- package/dist/chunk-I3IHOHCJ.js.map +0 -1
- package/dist/chunk-RIIOUTGM.js.map +0 -1
- package/dist/chunk-SWTLEQL6.js.map +0 -1
- /package/dist/{chunk-JR4IKCR2.js.map → chunk-2747WN4Y.js.map} +0 -0
- /package/dist/{chunk-GDL26N2T.js.map → chunk-3KN7NJDR.js.map} +0 -0
- /package/dist/{chunk-DJC4CHLQ.js.map → chunk-43BKLFZU.js.map} +0 -0
- /package/dist/{chunk-SCRFRCGR.js.map → chunk-BSQGE5PS.js.map} +0 -0
- /package/dist/{chunk-Y3ZLRGHC.js.map → chunk-CZNV3VXM.js.map} +0 -0
- /package/dist/{chunk-JIMUDQN3.js.map → chunk-FBUU43PM.js.map} +0 -0
- /package/dist/{chunk-D6BG7U6A.js.map → chunk-IXZBUWSP.js.map} +0 -0
- /package/dist/{chunk-PKVBHGBM.js.map → chunk-SS2A464I.js.map} +0 -0
- /package/dist/{chunk-G4M3NHRJ.js.map → chunk-V7CIJE4B.js.map} +0 -0
- /package/dist/{chunk-TEW47IVR.js.map → chunk-VPEFSDME.js.map} +0 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import {
|
|
2
|
+
depBatch
|
|
3
|
+
} from "../chunk-WQIA3GFB.js";
|
|
4
|
+
import "../chunk-S6HXABGL.js";
|
|
5
|
+
import "../chunk-DGUM43GV.js";
|
|
6
|
+
|
|
7
|
+
// src/cqrs/messaging.ts
|
|
8
|
+
function cqrsMessagingRecipe(graph, opts) {
|
|
9
|
+
const name = opts.name ?? "cqrsMessaging";
|
|
10
|
+
const runtime = graph.node(
|
|
11
|
+
[opts.deliveries],
|
|
12
|
+
(ctx) => {
|
|
13
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
14
|
+
const page = raw;
|
|
15
|
+
for (const message of page.messages) {
|
|
16
|
+
const delivery = messageDelivery(page, message);
|
|
17
|
+
const command = cqrsMessageCommand(message, delivery, opts.policy);
|
|
18
|
+
if (command === void 0) {
|
|
19
|
+
ctx.down([["DATA", { kind: "issue", issue: messageIssue(message, delivery) }]]);
|
|
20
|
+
} else {
|
|
21
|
+
ctx.down([["DATA", { kind: "command", command }]]);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: `${name}/runtime`,
|
|
28
|
+
factory: "cqrsMessagingRuntime",
|
|
29
|
+
partial: true,
|
|
30
|
+
completeWhenDepsComplete: false,
|
|
31
|
+
errorWhenDepsError: false
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
const issues = project(
|
|
35
|
+
graph,
|
|
36
|
+
runtime,
|
|
37
|
+
`${name}/issues`,
|
|
38
|
+
"cqrsMessagingIssues",
|
|
39
|
+
(fact) => fact.kind === "issue" ? fact.issue : void 0
|
|
40
|
+
);
|
|
41
|
+
const commands = project(
|
|
42
|
+
graph,
|
|
43
|
+
runtime,
|
|
44
|
+
`${name}/commands`,
|
|
45
|
+
"cqrsMessagingCommands",
|
|
46
|
+
(fact) => fact.kind === "command" ? fact.command : void 0
|
|
47
|
+
);
|
|
48
|
+
const ackCommands = cqrsMessageAckCommands(graph, {
|
|
49
|
+
name: `${name}/ackCommands`,
|
|
50
|
+
commands,
|
|
51
|
+
status: opts.status,
|
|
52
|
+
issues,
|
|
53
|
+
ackRejected: opts.policy?.ackRejected ?? true
|
|
54
|
+
});
|
|
55
|
+
return {
|
|
56
|
+
commands,
|
|
57
|
+
ackCommands,
|
|
58
|
+
...opts.events === void 0 || opts.policy?.outboxTopic === void 0 ? {} : {
|
|
59
|
+
outboxCommands: cqrsEventOutboxCommands(graph, opts.events, opts.policy.outboxTopic, {
|
|
60
|
+
name: `${name}/outboxCommands`
|
|
61
|
+
})
|
|
62
|
+
},
|
|
63
|
+
issues
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function cqrsMessageCommand(message, delivery, policy) {
|
|
67
|
+
const mapped = policy?.command?.(message, delivery);
|
|
68
|
+
if (mapped !== void 0) return commandWithDelivery(mapped, delivery);
|
|
69
|
+
if (!isObjectRecord(message.payload)) return void 0;
|
|
70
|
+
const id = stringField(message.payload, "id") ?? delivery.commandId;
|
|
71
|
+
const type = stringField(message.payload, "type");
|
|
72
|
+
if (type === void 0) return void 0;
|
|
73
|
+
return commandWithDelivery(
|
|
74
|
+
{
|
|
75
|
+
id,
|
|
76
|
+
type,
|
|
77
|
+
payload: message.payload.payload,
|
|
78
|
+
aggregateId: stringField(message.payload, "aggregateId"),
|
|
79
|
+
correlationId: stringField(message.payload, "correlationId"),
|
|
80
|
+
causationId: stringField(message.payload, "causationId"),
|
|
81
|
+
metadata: {
|
|
82
|
+
...objectField(message.payload, "metadata") ?? {}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
delivery
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
function cqrsMessageAckCommands(graph, opts) {
|
|
89
|
+
return graph.node(
|
|
90
|
+
opts.issues === void 0 ? [opts.commands, opts.status] : [opts.commands, opts.status, opts.issues],
|
|
91
|
+
(ctx) => {
|
|
92
|
+
const deliveries = ctx.state.get() ?? /* @__PURE__ */ new Map();
|
|
93
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
94
|
+
const command = raw;
|
|
95
|
+
const delivery = commandDelivery(command);
|
|
96
|
+
if (delivery !== void 0) pushDelivery(deliveries, command.id, delivery);
|
|
97
|
+
}
|
|
98
|
+
for (const raw of depBatch(ctx, 1) ?? []) {
|
|
99
|
+
const status = raw;
|
|
100
|
+
if (status.state === "rejected" && opts.ackRejected === false) continue;
|
|
101
|
+
if (status.commandId === void 0) continue;
|
|
102
|
+
const delivery = shiftDelivery(deliveries, status.commandId);
|
|
103
|
+
if (delivery === void 0) continue;
|
|
104
|
+
ctx.down([["DATA", ackCommand(delivery, ackCommandId("cqrs", delivery, "status"))]]);
|
|
105
|
+
}
|
|
106
|
+
if (opts.issues !== void 0) {
|
|
107
|
+
for (const raw of depBatch(ctx, 2) ?? []) {
|
|
108
|
+
const issue = raw;
|
|
109
|
+
const delivery = issueDelivery(issue);
|
|
110
|
+
if (delivery !== void 0) {
|
|
111
|
+
ctx.down([["DATA", ackCommand(delivery, ackCommandId("cqrs", delivery, "issue"))]]);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
ctx.state.set(deliveries);
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: opts.name ?? "cqrsMessaging/ackCommands",
|
|
119
|
+
factory: "cqrsMessagingAckCommands",
|
|
120
|
+
partial: true,
|
|
121
|
+
completeWhenDepsComplete: false,
|
|
122
|
+
errorWhenDepsError: false
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
function cqrsEventOutboxCommands(graph, events, topic, opts = {}) {
|
|
127
|
+
return graph.node(
|
|
128
|
+
[events],
|
|
129
|
+
(ctx) => {
|
|
130
|
+
for (const event of depBatch(ctx, 0) ?? []) {
|
|
131
|
+
const typed = event;
|
|
132
|
+
ctx.down([
|
|
133
|
+
[
|
|
134
|
+
"DATA",
|
|
135
|
+
{
|
|
136
|
+
kind: "publish",
|
|
137
|
+
topic,
|
|
138
|
+
payload: typed,
|
|
139
|
+
key: typed.aggregateId,
|
|
140
|
+
commandId: `${typed.id}:cqrs-outbox`,
|
|
141
|
+
idempotencyKey: typed.id
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
]);
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: opts.name ?? "cqrsMessaging/outboxCommands",
|
|
149
|
+
factory: "cqrsMessagingOutboxCommands",
|
|
150
|
+
completeWhenDepsComplete: false,
|
|
151
|
+
errorWhenDepsError: false
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
function project(graph, runtime, name, factory, pick) {
|
|
156
|
+
return graph.node(
|
|
157
|
+
[runtime],
|
|
158
|
+
(ctx) => {
|
|
159
|
+
for (const fact of depBatch(ctx, 0) ?? []) {
|
|
160
|
+
const value = pick(fact);
|
|
161
|
+
if (value !== void 0) ctx.down([["DATA", value]]);
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
{ name, factory, partial: true, completeWhenDepsComplete: false, errorWhenDepsError: false }
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
function messageIssue(message, delivery) {
|
|
168
|
+
return {
|
|
169
|
+
kind: "issue",
|
|
170
|
+
code: "cqrs-message-lowering-rejected",
|
|
171
|
+
message: "CQRS messaging recipe could not lower retained message to a command fact",
|
|
172
|
+
severity: "error",
|
|
173
|
+
source: "cqrs.messaging",
|
|
174
|
+
metadata: {
|
|
175
|
+
messageBus: {
|
|
176
|
+
topic: delivery.topic,
|
|
177
|
+
seq: delivery.seq,
|
|
178
|
+
subscriptionId: delivery.subscriptionId,
|
|
179
|
+
commandId: delivery.commandId
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
details: message
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function ackCommand(delivery, commandId) {
|
|
186
|
+
return {
|
|
187
|
+
kind: "ack",
|
|
188
|
+
topic: delivery.topic,
|
|
189
|
+
subscriptionId: delivery.subscriptionId,
|
|
190
|
+
seq: delivery.seq,
|
|
191
|
+
commandId
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function ackCommandId(namespace, delivery, reason) {
|
|
195
|
+
return `${namespace}:${delivery.topic}:${delivery.subscriptionId}:${delivery.seq}:${reason}-ack`;
|
|
196
|
+
}
|
|
197
|
+
function commandWithDelivery(command, delivery) {
|
|
198
|
+
return {
|
|
199
|
+
...command,
|
|
200
|
+
metadata: {
|
|
201
|
+
...command.metadata ?? {},
|
|
202
|
+
messageBus: delivery
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function messageDelivery(page, message) {
|
|
207
|
+
return {
|
|
208
|
+
topic: page.topic,
|
|
209
|
+
seq: message.seq,
|
|
210
|
+
subscriptionId: page.subscriptionId,
|
|
211
|
+
commandId: isObjectRecord(message.payload) && typeof message.payload.id === "string" ? message.payload.id : message.commandId ?? `${page.topic}:${message.seq}`
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function pushDelivery(deliveries, commandId, delivery) {
|
|
215
|
+
const queue = deliveries.get(commandId) ?? [];
|
|
216
|
+
deliveries.set(commandId, [...queue, delivery]);
|
|
217
|
+
}
|
|
218
|
+
function shiftDelivery(deliveries, commandId) {
|
|
219
|
+
const queue = deliveries.get(commandId);
|
|
220
|
+
if (queue === void 0 || queue.length === 0) return void 0;
|
|
221
|
+
const [first, ...rest] = queue;
|
|
222
|
+
if (rest.length === 0) deliveries.delete(commandId);
|
|
223
|
+
else deliveries.set(commandId, rest);
|
|
224
|
+
return first;
|
|
225
|
+
}
|
|
226
|
+
function issueDelivery(issue) {
|
|
227
|
+
const metadata = isObjectRecord(issue.metadata) ? issue.metadata : void 0;
|
|
228
|
+
const messageBus = isObjectRecord(metadata?.messageBus) ? metadata.messageBus : void 0;
|
|
229
|
+
if (messageBus === void 0) return void 0;
|
|
230
|
+
if (typeof messageBus.topic !== "string" || typeof messageBus.seq !== "number") return void 0;
|
|
231
|
+
if (typeof messageBus.subscriptionId !== "string") return void 0;
|
|
232
|
+
if (typeof messageBus.commandId !== "string") return void 0;
|
|
233
|
+
return {
|
|
234
|
+
topic: messageBus.topic,
|
|
235
|
+
seq: messageBus.seq,
|
|
236
|
+
subscriptionId: messageBus.subscriptionId,
|
|
237
|
+
commandId: messageBus.commandId
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
function commandDelivery(command) {
|
|
241
|
+
const metadata = isObjectRecord(command.metadata) ? command.metadata : void 0;
|
|
242
|
+
const messageBus = isObjectRecord(metadata?.messageBus) ? metadata.messageBus : void 0;
|
|
243
|
+
if (messageBus === void 0) return void 0;
|
|
244
|
+
return messageBusDelivery(messageBus);
|
|
245
|
+
}
|
|
246
|
+
function messageBusDelivery(messageBus) {
|
|
247
|
+
if (typeof messageBus.topic !== "string" || typeof messageBus.seq !== "number") return void 0;
|
|
248
|
+
if (typeof messageBus.subscriptionId !== "string") return void 0;
|
|
249
|
+
const commandId = typeof messageBus.commandId === "string" ? messageBus.commandId : "";
|
|
250
|
+
return {
|
|
251
|
+
topic: messageBus.topic,
|
|
252
|
+
seq: messageBus.seq,
|
|
253
|
+
subscriptionId: messageBus.subscriptionId,
|
|
254
|
+
commandId
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
function stringField(record, key) {
|
|
258
|
+
const value = record[key];
|
|
259
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
260
|
+
}
|
|
261
|
+
function objectField(record, key) {
|
|
262
|
+
const value = record[key];
|
|
263
|
+
return isObjectRecord(value) ? value : void 0;
|
|
264
|
+
}
|
|
265
|
+
function isObjectRecord(value) {
|
|
266
|
+
return typeof value === "object" && value !== null;
|
|
267
|
+
}
|
|
268
|
+
export {
|
|
269
|
+
cqrsEventOutboxCommands,
|
|
270
|
+
cqrsMessageAckCommands,
|
|
271
|
+
cqrsMessageCommand,
|
|
272
|
+
cqrsMessagingRecipe
|
|
273
|
+
};
|
|
274
|
+
//# sourceMappingURL=messaging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cqrs/messaging.ts"],"sourcesContent":["/**\n * Optional CQRS-over-messageBus recipe (D350/D351/D353).\n *\n * Retained message delivery is lowered to CQRS command facts. Ack commands are\n * derived only after visible CQRS accepted/rejected/error/audit material exists.\n */\n\nimport type { CqrsCommand, CqrsError, CqrsEvent, CqrsStatus } from \"../cqrs/index.js\";\nimport { depBatch } from \"../ctx/types.js\";\nimport type { DataIssue } from \"../data/index.js\";\nimport type { Graph } from \"../graph/graph.js\";\nimport type {\n\tMessageBusAvailablePage,\n\tMessageBusCommand,\n\tMessageBusMessage,\n} from \"../messaging/index.js\";\nimport type { Node } from \"../node/node.js\";\n\nexport interface CqrsMessagingPolicy<TPayload = unknown, TCommand = unknown> {\n\treadonly command?: (\n\t\tmessage: MessageBusMessage<TPayload>,\n\t\tdelivery: MessageBusDelivery,\n\t) => CqrsCommand<TCommand> | undefined;\n\treadonly ackRejected?: boolean;\n\treadonly outboxTopic?: string;\n}\n\nexport interface CqrsMessagingRecipeOptions<\n\tTPayload = unknown,\n\tTCommand = unknown,\n\tTEvent = unknown,\n> {\n\treadonly name?: string;\n\treadonly deliveries: Node<MessageBusAvailablePage<TPayload>>;\n\treadonly status: Node<CqrsStatus>;\n\treadonly errors?: Node<CqrsError>;\n\treadonly events?: Node<CqrsEvent<TEvent>>;\n\treadonly policy?: CqrsMessagingPolicy<TPayload, TCommand>;\n}\n\nexport interface CqrsMessagingRecipeBundle<TCommand = unknown> {\n\treadonly commands: Node<CqrsCommand<TCommand>>;\n\treadonly ackCommands: Node<MessageBusCommand>;\n\treadonly outboxCommands?: Node<MessageBusCommand>;\n\treadonly issues: Node<DataIssue>;\n}\n\ntype CqrsMessagingFact<TCommand> =\n\t| { readonly kind: \"command\"; readonly command: CqrsCommand<TCommand> }\n\t| { readonly kind: \"issue\"; readonly issue: DataIssue };\n\nexport interface MessageBusDelivery {\n\treadonly topic: string;\n\treadonly seq: number;\n\treadonly subscriptionId: string;\n\treadonly commandId: string;\n}\n\n/** Build the optional D350/D351 CQRS messaging recipe. */\nexport function cqrsMessagingRecipe<TPayload = unknown, TCommand = unknown, TEvent = unknown>(\n\tgraph: Graph,\n\topts: CqrsMessagingRecipeOptions<TPayload, TCommand, TEvent>,\n): CqrsMessagingRecipeBundle<TCommand> {\n\tconst name = opts.name ?? \"cqrsMessaging\";\n\tconst runtime = graph.node<CqrsMessagingFact<TCommand>>(\n\t\t[opts.deliveries],\n\t\t(ctx) => {\n\t\t\tfor (const raw of depBatch(ctx, 0) ?? []) {\n\t\t\t\tconst page = raw as MessageBusAvailablePage<TPayload>;\n\t\t\t\tfor (const message of page.messages) {\n\t\t\t\t\tconst delivery = messageDelivery(page, message);\n\t\t\t\t\tconst command = cqrsMessageCommand(message, delivery, opts.policy);\n\t\t\t\t\tif (command === undefined) {\n\t\t\t\t\t\tctx.down([[\"DATA\", { kind: \"issue\", issue: messageIssue(message, delivery) }]]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tctx.down([[\"DATA\", { kind: \"command\", command }]]);\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}/runtime`,\n\t\t\tfactory: \"cqrsMessagingRuntime\",\n\t\t\tpartial: true,\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\terrorWhenDepsError: false,\n\t\t},\n\t);\n\tconst issues = project(graph, runtime, `${name}/issues`, \"cqrsMessagingIssues\", (fact) =>\n\t\tfact.kind === \"issue\" ? fact.issue : undefined,\n\t);\n\tconst commands = project(graph, runtime, `${name}/commands`, \"cqrsMessagingCommands\", (fact) =>\n\t\tfact.kind === \"command\" ? fact.command : undefined,\n\t);\n\tconst ackCommands = cqrsMessageAckCommands(graph, {\n\t\tname: `${name}/ackCommands`,\n\t\tcommands,\n\t\tstatus: opts.status,\n\t\tissues,\n\t\tackRejected: opts.policy?.ackRejected ?? true,\n\t});\n\treturn {\n\t\tcommands,\n\t\tackCommands,\n\t\t...(opts.events === undefined || opts.policy?.outboxTopic === undefined\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\toutboxCommands: cqrsEventOutboxCommands(graph, opts.events, opts.policy.outboxTopic, {\n\t\t\t\t\t\tname: `${name}/outboxCommands`,\n\t\t\t\t\t}),\n\t\t\t\t}),\n\t\tissues,\n\t};\n}\n\nexport function cqrsMessageCommand<TPayload = unknown, TCommand = unknown>(\n\tmessage: MessageBusMessage<TPayload>,\n\tdelivery: MessageBusDelivery,\n\tpolicy?: CqrsMessagingPolicy<TPayload, TCommand>,\n): CqrsCommand<TCommand> | undefined {\n\tconst mapped = policy?.command?.(message, delivery);\n\tif (mapped !== undefined) return commandWithDelivery(mapped, delivery);\n\tif (!isObjectRecord(message.payload)) return undefined;\n\tconst id = stringField(message.payload, \"id\") ?? delivery.commandId;\n\tconst type = stringField(message.payload, \"type\");\n\tif (type === undefined) return undefined;\n\treturn commandWithDelivery(\n\t\t{\n\t\t\tid,\n\t\t\ttype,\n\t\t\tpayload: message.payload.payload as TCommand,\n\t\t\taggregateId: stringField(message.payload, \"aggregateId\"),\n\t\t\tcorrelationId: stringField(message.payload, \"correlationId\"),\n\t\t\tcausationId: stringField(message.payload, \"causationId\"),\n\t\t\tmetadata: {\n\t\t\t\t...(objectField(message.payload, \"metadata\") ?? {}),\n\t\t\t},\n\t\t},\n\t\tdelivery,\n\t);\n}\n\nexport function cqrsMessageAckCommands(\n\tgraph: Graph,\n\topts: {\n\t\treadonly name?: string;\n\t\treadonly commands: Node<CqrsCommand>;\n\t\treadonly status: Node<CqrsStatus>;\n\t\treadonly issues?: Node<DataIssue>;\n\t\treadonly ackRejected?: boolean;\n\t},\n): Node<MessageBusCommand> {\n\treturn graph.node<MessageBusCommand>(\n\t\topts.issues === undefined\n\t\t\t? [opts.commands, opts.status]\n\t\t\t: [opts.commands, opts.status, opts.issues],\n\t\t(ctx) => {\n\t\t\tconst deliveries =\n\t\t\t\tctx.state.get<Map<string, MessageBusDelivery[]>>() ??\n\t\t\t\tnew Map<string, MessageBusDelivery[]>();\n\t\t\tfor (const raw of depBatch(ctx, 0) ?? []) {\n\t\t\t\tconst command = raw as CqrsCommand;\n\t\t\t\tconst delivery = commandDelivery(command);\n\t\t\t\tif (delivery !== undefined) pushDelivery(deliveries, command.id, delivery);\n\t\t\t}\n\t\t\tfor (const raw of depBatch(ctx, 1) ?? []) {\n\t\t\t\tconst status = raw as CqrsStatus;\n\t\t\t\tif (status.state === \"rejected\" && opts.ackRejected === false) continue;\n\t\t\t\tif (status.commandId === undefined) continue;\n\t\t\t\tconst delivery = shiftDelivery(deliveries, status.commandId);\n\t\t\t\tif (delivery === undefined) continue;\n\t\t\t\tctx.down([[\"DATA\", ackCommand(delivery, ackCommandId(\"cqrs\", delivery, \"status\"))]]);\n\t\t\t}\n\t\t\tif (opts.issues !== undefined) {\n\t\t\t\tfor (const raw of depBatch(ctx, 2) ?? []) {\n\t\t\t\t\tconst issue = raw as DataIssue;\n\t\t\t\t\tconst delivery = issueDelivery(issue);\n\t\t\t\t\tif (delivery !== undefined) {\n\t\t\t\t\t\tctx.down([[\"DATA\", ackCommand(delivery, ackCommandId(\"cqrs\", delivery, \"issue\"))]]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tctx.state.set(deliveries);\n\t\t},\n\t\t{\n\t\t\tname: opts.name ?? \"cqrsMessaging/ackCommands\",\n\t\t\tfactory: \"cqrsMessagingAckCommands\",\n\t\t\tpartial: true,\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\terrorWhenDepsError: false,\n\t\t},\n\t);\n}\n\nexport function cqrsEventOutboxCommands<TEvent>(\n\tgraph: Graph,\n\tevents: Node<CqrsEvent<TEvent>>,\n\ttopic: string,\n\topts: { readonly name?: string } = {},\n): Node<MessageBusCommand> {\n\treturn graph.node<MessageBusCommand>(\n\t\t[events],\n\t\t(ctx) => {\n\t\t\tfor (const event of depBatch(ctx, 0) ?? []) {\n\t\t\t\tconst typed = event as CqrsEvent<TEvent>;\n\t\t\t\tctx.down([\n\t\t\t\t\t[\n\t\t\t\t\t\t\"DATA\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind: \"publish\",\n\t\t\t\t\t\t\ttopic,\n\t\t\t\t\t\t\tpayload: typed,\n\t\t\t\t\t\t\tkey: typed.aggregateId,\n\t\t\t\t\t\t\tcommandId: `${typed.id}:cqrs-outbox`,\n\t\t\t\t\t\t\tidempotencyKey: typed.id,\n\t\t\t\t\t\t} satisfies MessageBusCommand,\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: opts.name ?? \"cqrsMessaging/outboxCommands\",\n\t\t\tfactory: \"cqrsMessagingOutboxCommands\",\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\terrorWhenDepsError: false,\n\t\t},\n\t);\n}\n\nfunction project<T, TCommand>(\n\tgraph: Graph,\n\truntime: Node<CqrsMessagingFact<TCommand>>,\n\tname: string,\n\tfactory: string,\n\tpick: (fact: CqrsMessagingFact<TCommand>) => T | undefined,\n): Node<T> {\n\treturn graph.node<T>(\n\t\t[runtime],\n\t\t(ctx) => {\n\t\t\tfor (const fact of depBatch(ctx, 0) ?? []) {\n\t\t\t\tconst value = pick(fact as CqrsMessagingFact<TCommand>);\n\t\t\t\tif (value !== undefined) ctx.down([[\"DATA\", value]]);\n\t\t\t}\n\t\t},\n\t\t{ name, factory, partial: true, completeWhenDepsComplete: false, errorWhenDepsError: false },\n\t);\n}\n\nfunction messageIssue(message: MessageBusMessage, delivery: MessageBusDelivery): DataIssue {\n\treturn {\n\t\tkind: \"issue\",\n\t\tcode: \"cqrs-message-lowering-rejected\",\n\t\tmessage: \"CQRS messaging recipe could not lower retained message to a command fact\",\n\t\tseverity: \"error\",\n\t\tsource: \"cqrs.messaging\",\n\t\tmetadata: {\n\t\t\tmessageBus: {\n\t\t\t\ttopic: delivery.topic,\n\t\t\t\tseq: delivery.seq,\n\t\t\t\tsubscriptionId: delivery.subscriptionId,\n\t\t\t\tcommandId: delivery.commandId,\n\t\t\t},\n\t\t},\n\t\tdetails: message,\n\t};\n}\n\nfunction ackCommand(delivery: MessageBusDelivery, commandId: string): MessageBusCommand {\n\treturn {\n\t\tkind: \"ack\",\n\t\ttopic: delivery.topic,\n\t\tsubscriptionId: delivery.subscriptionId,\n\t\tseq: delivery.seq,\n\t\tcommandId,\n\t};\n}\n\nfunction ackCommandId(namespace: string, delivery: MessageBusDelivery, reason: string): string {\n\treturn `${namespace}:${delivery.topic}:${delivery.subscriptionId}:${delivery.seq}:${reason}-ack`;\n}\n\nfunction commandWithDelivery<TCommand>(\n\tcommand: CqrsCommand<TCommand>,\n\tdelivery: MessageBusDelivery,\n): CqrsCommand<TCommand> {\n\treturn {\n\t\t...command,\n\t\tmetadata: {\n\t\t\t...(command.metadata ?? {}),\n\t\t\tmessageBus: delivery,\n\t\t},\n\t};\n}\n\nfunction messageDelivery(\n\tpage: MessageBusAvailablePage,\n\tmessage: MessageBusMessage,\n): MessageBusDelivery {\n\treturn {\n\t\ttopic: page.topic,\n\t\tseq: message.seq,\n\t\tsubscriptionId: page.subscriptionId,\n\t\tcommandId:\n\t\t\tisObjectRecord(message.payload) && typeof message.payload.id === \"string\"\n\t\t\t\t? message.payload.id\n\t\t\t\t: (message.commandId ?? `${page.topic}:${message.seq}`),\n\t};\n}\n\nfunction pushDelivery(\n\tdeliveries: Map<string, MessageBusDelivery[]>,\n\tcommandId: string,\n\tdelivery: MessageBusDelivery,\n): void {\n\tconst queue = deliveries.get(commandId) ?? [];\n\tdeliveries.set(commandId, [...queue, delivery]);\n}\n\nfunction shiftDelivery(\n\tdeliveries: Map<string, MessageBusDelivery[]>,\n\tcommandId: string,\n): MessageBusDelivery | undefined {\n\tconst queue = deliveries.get(commandId);\n\tif (queue === undefined || queue.length === 0) return undefined;\n\tconst [first, ...rest] = queue;\n\tif (rest.length === 0) deliveries.delete(commandId);\n\telse deliveries.set(commandId, rest);\n\treturn first;\n}\n\nfunction issueDelivery(issue: DataIssue): MessageBusDelivery | undefined {\n\tconst metadata = isObjectRecord(issue.metadata) ? issue.metadata : undefined;\n\tconst messageBus = isObjectRecord(metadata?.messageBus) ? metadata.messageBus : undefined;\n\tif (messageBus === undefined) return undefined;\n\tif (typeof messageBus.topic !== \"string\" || typeof messageBus.seq !== \"number\") return undefined;\n\tif (typeof messageBus.subscriptionId !== \"string\") return undefined;\n\tif (typeof messageBus.commandId !== \"string\") return undefined;\n\treturn {\n\t\ttopic: messageBus.topic,\n\t\tseq: messageBus.seq,\n\t\tsubscriptionId: messageBus.subscriptionId,\n\t\tcommandId: messageBus.commandId,\n\t};\n}\n\nfunction commandDelivery(command: CqrsCommand): MessageBusDelivery | undefined {\n\tconst metadata = isObjectRecord(command.metadata) ? command.metadata : undefined;\n\tconst messageBus = isObjectRecord(metadata?.messageBus) ? metadata.messageBus : undefined;\n\tif (messageBus === undefined) return undefined;\n\treturn messageBusDelivery(messageBus);\n}\n\nfunction messageBusDelivery(messageBus: Record<string, unknown>): MessageBusDelivery | undefined {\n\tif (typeof messageBus.topic !== \"string\" || typeof messageBus.seq !== \"number\") return undefined;\n\tif (typeof messageBus.subscriptionId !== \"string\") return undefined;\n\tconst commandId = typeof messageBus.commandId === \"string\" ? messageBus.commandId : \"\";\n\treturn {\n\t\ttopic: messageBus.topic,\n\t\tseq: messageBus.seq,\n\t\tsubscriptionId: messageBus.subscriptionId,\n\t\tcommandId,\n\t};\n}\n\nfunction stringField(record: Record<string, unknown>, key: string): string | undefined {\n\tconst value = record[key];\n\treturn typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction objectField(\n\trecord: Record<string, unknown>,\n\tkey: string,\n): Record<string, unknown> | undefined {\n\tconst value = record[key];\n\treturn isObjectRecord(value) ? value : undefined;\n}\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/cqrs/work-queue.ts
|
|
21
|
+
var work_queue_exports = {};
|
|
22
|
+
__export(work_queue_exports, {
|
|
23
|
+
cqrsSubmitCommand: () => cqrsSubmitCommand,
|
|
24
|
+
cqrsWorkQueueDispositionCommand: () => cqrsWorkQueueDispositionCommand,
|
|
25
|
+
cqrsWorkQueueRecipe: () => cqrsWorkQueueRecipe
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(work_queue_exports);
|
|
28
|
+
|
|
29
|
+
// src/protocol/messages.ts
|
|
30
|
+
var SENTINEL = void 0;
|
|
31
|
+
|
|
32
|
+
// src/ctx/types.ts
|
|
33
|
+
function depWaves(ctx, depIndex) {
|
|
34
|
+
return ctx.waveData[depIndex] ?? [];
|
|
35
|
+
}
|
|
36
|
+
function depBatch(ctx, depIndex) {
|
|
37
|
+
const waves = depWaves(ctx, depIndex);
|
|
38
|
+
if (waves.length === 0) return null;
|
|
39
|
+
const flattened = waves.flat().filter((v) => v !== SENTINEL);
|
|
40
|
+
return flattened.length === 0 ? [] : flattened;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/cqrs/work-queue.ts
|
|
44
|
+
function cqrsWorkQueueRecipe(graph, opts) {
|
|
45
|
+
const name = opts.name ?? "cqrsWorkQueue";
|
|
46
|
+
const deps = opts.errors === void 0 ? [opts.records, opts.status] : [opts.records, opts.status, opts.errors];
|
|
47
|
+
const runtime = graph.node(
|
|
48
|
+
deps,
|
|
49
|
+
(ctx) => {
|
|
50
|
+
const state = ctx.state.get() ?? emptyState();
|
|
51
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
52
|
+
reduceRecord(ctx, state, raw, opts);
|
|
53
|
+
}
|
|
54
|
+
if (opts.errors !== void 0) {
|
|
55
|
+
for (const raw of depBatch(ctx, 2) ?? []) {
|
|
56
|
+
const error = raw;
|
|
57
|
+
if (error.commandId !== void 0) state.errors.set(error.commandId, error);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
for (const raw of depBatch(ctx, 1) ?? []) {
|
|
61
|
+
reduceStatus(ctx, state, raw, opts);
|
|
62
|
+
}
|
|
63
|
+
ctx.state.set(state);
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: `${name}/runtime`,
|
|
67
|
+
factory: "cqrsWorkQueueRuntime",
|
|
68
|
+
partial: true,
|
|
69
|
+
completeWhenDepsComplete: false,
|
|
70
|
+
errorWhenDepsError: false
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
return {
|
|
74
|
+
attempts: project(
|
|
75
|
+
graph,
|
|
76
|
+
runtime,
|
|
77
|
+
`${name}/attempts`,
|
|
78
|
+
"cqrsWorkQueueAttempts",
|
|
79
|
+
(fact) => fact.kind === "attempt" ? fact.attempt : void 0
|
|
80
|
+
),
|
|
81
|
+
dispatches: project(
|
|
82
|
+
graph,
|
|
83
|
+
runtime,
|
|
84
|
+
`${name}/dispatches`,
|
|
85
|
+
"cqrsWorkQueueDispatches",
|
|
86
|
+
(fact) => fact.kind === "dispatch" ? fact.command : void 0
|
|
87
|
+
),
|
|
88
|
+
commands: project(
|
|
89
|
+
graph,
|
|
90
|
+
runtime,
|
|
91
|
+
`${name}/commands`,
|
|
92
|
+
"cqrsWorkQueueCommands",
|
|
93
|
+
(fact) => fact.kind === "command" ? fact.command : void 0
|
|
94
|
+
),
|
|
95
|
+
issues: project(
|
|
96
|
+
graph,
|
|
97
|
+
runtime,
|
|
98
|
+
`${name}/issues`,
|
|
99
|
+
"cqrsWorkQueueIssues",
|
|
100
|
+
(fact) => fact.kind === "issue" ? fact.issue : void 0
|
|
101
|
+
)
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function cqrsSubmitCommand(command, opts = {}) {
|
|
105
|
+
const payload = {
|
|
106
|
+
kind: "cqrs-queued-command",
|
|
107
|
+
command,
|
|
108
|
+
idempotencyKey: opts.idempotencyKey ?? command.id,
|
|
109
|
+
sourceRefs: opts.sourceRefs,
|
|
110
|
+
policyRefs: opts.policyRefs,
|
|
111
|
+
actorRefs: opts.actorRefs,
|
|
112
|
+
auditRefs: opts.auditRefs,
|
|
113
|
+
metadata: opts.metadata
|
|
114
|
+
};
|
|
115
|
+
return {
|
|
116
|
+
kind: "submit",
|
|
117
|
+
commandId: opts.commandId ?? `${command.id}:cqrs-work-queue-submit`,
|
|
118
|
+
workId: opts.workId ?? `cqrs:${command.id}`,
|
|
119
|
+
payload,
|
|
120
|
+
idempotencyKey: opts.idempotencyKey ?? command.id,
|
|
121
|
+
sourceRefs: opts.sourceRefs,
|
|
122
|
+
policyRefs: opts.policyRefs,
|
|
123
|
+
actorRefs: opts.actorRefs,
|
|
124
|
+
auditRefs: opts.auditRefs
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function cqrsWorkQueueDispositionCommand(attempt, outcome, policy) {
|
|
128
|
+
if (outcome.kind === "release") {
|
|
129
|
+
return {
|
|
130
|
+
kind: "release",
|
|
131
|
+
commandId: dispositionCommandId(attempt, "release"),
|
|
132
|
+
workId: attempt.workId,
|
|
133
|
+
leaseId: attempt.leaseId,
|
|
134
|
+
attempt: attempt.queueAttempt,
|
|
135
|
+
workerId: attempt.workerId,
|
|
136
|
+
reason: outcome.reason ?? policy?.releaseReason?.(attempt)
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
if (outcome.kind === "accepted") {
|
|
140
|
+
return completeCommand(attempt, {
|
|
141
|
+
kind: "cqrs-accepted-result",
|
|
142
|
+
commandId: outcome.status.commandId,
|
|
143
|
+
commandType: outcome.status.commandType,
|
|
144
|
+
eventCount: outcome.status.eventCount,
|
|
145
|
+
cursor: outcome.status.cursor
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
const code = outcome.status.errorCode;
|
|
149
|
+
if (code === "handler-threw" || code === "clock-threw" || code === void 0) {
|
|
150
|
+
return {
|
|
151
|
+
kind: "fail",
|
|
152
|
+
commandId: dispositionCommandId(attempt, "fail"),
|
|
153
|
+
workId: attempt.workId,
|
|
154
|
+
leaseId: attempt.leaseId,
|
|
155
|
+
attempt: attempt.queueAttempt,
|
|
156
|
+
workerId: attempt.workerId,
|
|
157
|
+
error: outcome.error ?? {
|
|
158
|
+
kind: "issue",
|
|
159
|
+
code: code ?? "cqrs-outcome-ambiguous",
|
|
160
|
+
message: "CQRS rejected without deterministic rejection evidence"
|
|
161
|
+
},
|
|
162
|
+
retryable: code === void 0 ? true : policy?.retryableFailure?.(code, outcome) ?? true
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
return completeCommand(attempt, {
|
|
166
|
+
kind: "cqrs-rejected-result",
|
|
167
|
+
commandId: outcome.status.commandId,
|
|
168
|
+
commandType: outcome.status.commandType,
|
|
169
|
+
errorCode: code,
|
|
170
|
+
error: outcome.error,
|
|
171
|
+
eventCount: outcome.status.eventCount,
|
|
172
|
+
cursor: outcome.status.cursor
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function completeCommand(attempt, result) {
|
|
176
|
+
return {
|
|
177
|
+
kind: "complete",
|
|
178
|
+
commandId: dispositionCommandId(attempt, "complete"),
|
|
179
|
+
workId: attempt.workId,
|
|
180
|
+
leaseId: attempt.leaseId,
|
|
181
|
+
attempt: attempt.queueAttempt,
|
|
182
|
+
workerId: attempt.workerId,
|
|
183
|
+
result
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function reduceRecord(ctx, state, record, opts) {
|
|
187
|
+
if (record.kind === "work-admitted") {
|
|
188
|
+
if (isQueuedPayload(record.payload)) state.payloads.set(record.workId, record.payload);
|
|
189
|
+
else emit(ctx, { kind: "issue", issue: queueIssue(record, "cqrs-queue-malformed-payload") });
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (record.kind !== "work-claimed") return;
|
|
193
|
+
if (opts.workerId !== void 0 && record.workerId !== opts.workerId) return;
|
|
194
|
+
const payload = state.payloads.get(record.workId);
|
|
195
|
+
if (payload === void 0) {
|
|
196
|
+
emit(ctx, { kind: "issue", issue: queueIssue(record, "cqrs-claim-without-payload") });
|
|
197
|
+
emit(ctx, {
|
|
198
|
+
kind: "command",
|
|
199
|
+
command: {
|
|
200
|
+
kind: "release",
|
|
201
|
+
commandId: `cqrs:${record.workId}:${record.leaseId}:${record.attempt}:release-no-payload`,
|
|
202
|
+
workId: record.workId,
|
|
203
|
+
leaseId: record.leaseId,
|
|
204
|
+
attempt: record.attempt,
|
|
205
|
+
workerId: record.workerId,
|
|
206
|
+
reason: "cqrs-claim-without-payload"
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const attempt = {
|
|
212
|
+
kind: "cqrs-work-queue-attempt",
|
|
213
|
+
workId: record.workId,
|
|
214
|
+
leaseId: record.leaseId,
|
|
215
|
+
queueAttempt: record.attempt,
|
|
216
|
+
workerId: record.workerId,
|
|
217
|
+
command: payload.command,
|
|
218
|
+
payload,
|
|
219
|
+
sourceRefs: [...payload.sourceRefs ?? [], `work-queue-record:${record.recordSeq}`]
|
|
220
|
+
};
|
|
221
|
+
pushActiveClaim(state, payload.command.id, attempt);
|
|
222
|
+
emit(ctx, { kind: "attempt", attempt });
|
|
223
|
+
emit(ctx, { kind: "dispatch", command: payload.command });
|
|
224
|
+
}
|
|
225
|
+
function reduceStatus(ctx, state, status, opts) {
|
|
226
|
+
if (status.commandId === void 0) return;
|
|
227
|
+
const attempt = shiftActiveClaim(state, status.commandId);
|
|
228
|
+
if (attempt === void 0) {
|
|
229
|
+
emit(ctx, {
|
|
230
|
+
kind: "issue",
|
|
231
|
+
issue: {
|
|
232
|
+
kind: "issue",
|
|
233
|
+
code: "cqrs-status-without-active-queue-claim",
|
|
234
|
+
message: "CQRS workQueue recipe observed a CQRS status without an active queue claim; no queue disposition was emitted",
|
|
235
|
+
severity: "error",
|
|
236
|
+
source: "cqrs.workQueue",
|
|
237
|
+
refs: [`cqrs-command:${status.commandId}`],
|
|
238
|
+
details: status
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const claimKey = queueClaimKey(attempt);
|
|
244
|
+
if (state.terminalClaims.has(claimKey)) {
|
|
245
|
+
emit(ctx, {
|
|
246
|
+
kind: "issue",
|
|
247
|
+
issue: {
|
|
248
|
+
kind: "issue",
|
|
249
|
+
code: "cqrs-duplicate-terminal-outcome-for-queue-claim",
|
|
250
|
+
message: `CQRS queue claim '${claimKey}' already produced a terminal queue disposition`,
|
|
251
|
+
refs: [`cqrs-command:${status.commandId}`, `work-queue-work:${attempt.workId}`]
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
state.terminalClaims.add(claimKey);
|
|
257
|
+
const command = cqrsWorkQueueDispositionCommand(
|
|
258
|
+
attempt,
|
|
259
|
+
status.state === "accepted" ? { kind: "accepted", status } : { kind: "rejected", status, error: state.errors.get(status.commandId) },
|
|
260
|
+
opts.policy
|
|
261
|
+
);
|
|
262
|
+
emit(ctx, { kind: "command", command });
|
|
263
|
+
}
|
|
264
|
+
function emptyState() {
|
|
265
|
+
return {
|
|
266
|
+
payloads: /* @__PURE__ */ new Map(),
|
|
267
|
+
activeClaims: /* @__PURE__ */ new Map(),
|
|
268
|
+
errors: /* @__PURE__ */ new Map(),
|
|
269
|
+
terminalClaims: /* @__PURE__ */ new Set()
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
function pushActiveClaim(state, commandId, attempt) {
|
|
273
|
+
const claims = state.activeClaims.get(commandId) ?? [];
|
|
274
|
+
state.activeClaims.set(commandId, [...claims, attempt]);
|
|
275
|
+
}
|
|
276
|
+
function shiftActiveClaim(state, commandId) {
|
|
277
|
+
const claims = state.activeClaims.get(commandId);
|
|
278
|
+
if (claims === void 0 || claims.length === 0) return void 0;
|
|
279
|
+
const [first, ...rest] = claims;
|
|
280
|
+
if (rest.length === 0) state.activeClaims.delete(commandId);
|
|
281
|
+
else state.activeClaims.set(commandId, rest);
|
|
282
|
+
return first;
|
|
283
|
+
}
|
|
284
|
+
function queueClaimKey(attempt) {
|
|
285
|
+
return `${attempt.workId}:${attempt.leaseId}:${attempt.queueAttempt}`;
|
|
286
|
+
}
|
|
287
|
+
function dispositionCommandId(attempt, kind) {
|
|
288
|
+
return `${attempt.command.id}:${attempt.workId}:${attempt.leaseId}:${attempt.queueAttempt}:cqrs-queue-${kind}`;
|
|
289
|
+
}
|
|
290
|
+
function project(graph, runtime, name, factory, pick) {
|
|
291
|
+
return graph.node(
|
|
292
|
+
[runtime],
|
|
293
|
+
(ctx) => {
|
|
294
|
+
for (const fact of depBatch(ctx, 0) ?? []) {
|
|
295
|
+
const value = pick(fact);
|
|
296
|
+
if (value !== void 0) ctx.down([["DATA", value]]);
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
{ name, factory, partial: true, completeWhenDepsComplete: false, errorWhenDepsError: false }
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
function emit(ctx, fact) {
|
|
303
|
+
ctx.down([["DATA", fact]]);
|
|
304
|
+
}
|
|
305
|
+
function isQueuedPayload(value) {
|
|
306
|
+
if (!isObjectRecord(value) || value.kind !== "cqrs-queued-command") return false;
|
|
307
|
+
return isObjectRecord(value.command) && typeof value.command.id === "string";
|
|
308
|
+
}
|
|
309
|
+
function queueIssue(record, code) {
|
|
310
|
+
return {
|
|
311
|
+
kind: "issue",
|
|
312
|
+
code,
|
|
313
|
+
message: `CQRS workQueue recipe could not map record '${record.kind}'`,
|
|
314
|
+
severity: "error",
|
|
315
|
+
source: "cqrs.workQueue",
|
|
316
|
+
refs: record.workId === void 0 ? void 0 : [`work-queue-work:${record.workId}`],
|
|
317
|
+
details: record
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
function isObjectRecord(value) {
|
|
321
|
+
return typeof value === "object" && value !== null;
|
|
322
|
+
}
|
|
323
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
324
|
+
0 && (module.exports = {
|
|
325
|
+
cqrsSubmitCommand,
|
|
326
|
+
cqrsWorkQueueDispositionCommand,
|
|
327
|
+
cqrsWorkQueueRecipe
|
|
328
|
+
});
|
|
329
|
+
//# sourceMappingURL=work-queue.cjs.map
|