@nwire/forge 0.7.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/README.md +77 -0
- package/dist/__tests__/actor-methods.test.d.ts +9 -0
- package/dist/__tests__/actor-methods.test.d.ts.map +1 -0
- package/dist/__tests__/actor-methods.test.js +210 -0
- package/dist/__tests__/actor-methods.test.js.map +1 -0
- package/dist/__tests__/actor-schema-bound.test.d.ts +6 -0
- package/dist/__tests__/actor-schema-bound.test.d.ts.map +1 -0
- package/dist/__tests__/actor-schema-bound.test.js +112 -0
- package/dist/__tests__/actor-schema-bound.test.js.map +1 -0
- package/dist/__tests__/app-capabilities.test.d.ts +19 -0
- package/dist/__tests__/app-capabilities.test.d.ts.map +1 -0
- package/dist/__tests__/app-capabilities.test.js +57 -0
- package/dist/__tests__/app-capabilities.test.js.map +1 -0
- package/dist/__tests__/cli-runner.test.d.ts +6 -0
- package/dist/__tests__/cli-runner.test.d.ts.map +1 -0
- package/dist/__tests__/cli-runner.test.js +158 -0
- package/dist/__tests__/cli-runner.test.js.map +1 -0
- package/dist/__tests__/create-app.test.d.ts +18 -0
- package/dist/__tests__/create-app.test.d.ts.map +1 -0
- package/dist/__tests__/create-app.test.js +189 -0
- package/dist/__tests__/create-app.test.js.map +1 -0
- package/dist/__tests__/cross-service-bus.test.d.ts +8 -0
- package/dist/__tests__/cross-service-bus.test.d.ts.map +1 -0
- package/dist/__tests__/cross-service-bus.test.js +139 -0
- package/dist/__tests__/cross-service-bus.test.js.map +1 -0
- package/dist/__tests__/define-schema.test.d.ts +5 -0
- package/dist/__tests__/define-schema.test.d.ts.map +1 -0
- package/dist/__tests__/define-schema.test.js +83 -0
- package/dist/__tests__/define-schema.test.js.map +1 -0
- package/dist/__tests__/dev-logger.test.d.ts +9 -0
- package/dist/__tests__/dev-logger.test.d.ts.map +1 -0
- package/dist/__tests__/dev-logger.test.js +126 -0
- package/dist/__tests__/dev-logger.test.js.map +1 -0
- package/dist/__tests__/external-call.test.d.ts +14 -0
- package/dist/__tests__/external-call.test.d.ts.map +1 -0
- package/dist/__tests__/external-call.test.js +99 -0
- package/dist/__tests__/external-call.test.js.map +1 -0
- package/dist/__tests__/framework-events.test.d.ts +13 -0
- package/dist/__tests__/framework-events.test.d.ts.map +1 -0
- package/dist/__tests__/framework-events.test.js +204 -0
- package/dist/__tests__/framework-events.test.js.map +1 -0
- package/dist/__tests__/inline-handler.test.d.ts +8 -0
- package/dist/__tests__/inline-handler.test.d.ts.map +1 -0
- package/dist/__tests__/inline-handler.test.js +101 -0
- package/dist/__tests__/inline-handler.test.js.map +1 -0
- package/dist/__tests__/lifecycle-logging.test.d.ts +12 -0
- package/dist/__tests__/lifecycle-logging.test.d.ts.map +1 -0
- package/dist/__tests__/lifecycle-logging.test.js +112 -0
- package/dist/__tests__/lifecycle-logging.test.js.map +1 -0
- package/dist/__tests__/middleware.test.d.ts +7 -0
- package/dist/__tests__/middleware.test.d.ts.map +1 -0
- package/dist/__tests__/middleware.test.js +109 -0
- package/dist/__tests__/middleware.test.js.map +1 -0
- package/dist/__tests__/module-needs.test.d.ts +10 -0
- package/dist/__tests__/module-needs.test.d.ts.map +1 -0
- package/dist/__tests__/module-needs.test.js +77 -0
- package/dist/__tests__/module-needs.test.js.map +1 -0
- package/dist/__tests__/module-topo-sort.test.d.ts +15 -0
- package/dist/__tests__/module-topo-sort.test.d.ts.map +1 -0
- package/dist/__tests__/module-topo-sort.test.js +105 -0
- package/dist/__tests__/module-topo-sort.test.js.map +1 -0
- package/dist/__tests__/multi-tenancy.test.d.ts +10 -0
- package/dist/__tests__/multi-tenancy.test.d.ts.map +1 -0
- package/dist/__tests__/multi-tenancy.test.js +122 -0
- package/dist/__tests__/multi-tenancy.test.js.map +1 -0
- package/dist/__tests__/needs-topology.test.d.ts +11 -0
- package/dist/__tests__/needs-topology.test.d.ts.map +1 -0
- package/dist/__tests__/needs-topology.test.js +82 -0
- package/dist/__tests__/needs-topology.test.js.map +1 -0
- package/dist/__tests__/plugin-closure.test.d.ts +15 -0
- package/dist/__tests__/plugin-closure.test.d.ts.map +1 -0
- package/dist/__tests__/plugin-closure.test.js +140 -0
- package/dist/__tests__/plugin-closure.test.js.map +1 -0
- package/dist/__tests__/plugin.test.d.ts +10 -0
- package/dist/__tests__/plugin.test.d.ts.map +1 -0
- package/dist/__tests__/plugin.test.js +225 -0
- package/dist/__tests__/plugin.test.js.map +1 -0
- package/dist/__tests__/primitives.test.d.ts +9 -0
- package/dist/__tests__/primitives.test.d.ts.map +1 -0
- package/dist/__tests__/primitives.test.js +434 -0
- package/dist/__tests__/primitives.test.js.map +1 -0
- package/dist/__tests__/production-readiness.test.d.ts +22 -0
- package/dist/__tests__/production-readiness.test.d.ts.map +1 -0
- package/dist/__tests__/production-readiness.test.js +196 -0
- package/dist/__tests__/production-readiness.test.js.map +1 -0
- package/dist/__tests__/provider.test.d.ts +6 -0
- package/dist/__tests__/provider.test.d.ts.map +1 -0
- package/dist/__tests__/provider.test.js +122 -0
- package/dist/__tests__/provider.test.js.map +1 -0
- package/dist/__tests__/public-marker.test.d.ts +7 -0
- package/dist/__tests__/public-marker.test.d.ts.map +1 -0
- package/dist/__tests__/public-marker.test.js +54 -0
- package/dist/__tests__/public-marker.test.js.map +1 -0
- package/dist/__tests__/retry-dlq.test.d.ts +6 -0
- package/dist/__tests__/retry-dlq.test.d.ts.map +1 -0
- package/dist/__tests__/retry-dlq.test.js +68 -0
- package/dist/__tests__/retry-dlq.test.js.map +1 -0
- package/dist/__tests__/validate.test.d.ts +5 -0
- package/dist/__tests__/validate.test.d.ts.map +1 -0
- package/dist/__tests__/validate.test.js +53 -0
- package/dist/__tests__/validate.test.js.map +1 -0
- package/dist/__tests__/workflow-saga.test.d.ts +7 -0
- package/dist/__tests__/workflow-saga.test.d.ts.map +1 -0
- package/dist/__tests__/workflow-saga.test.js +239 -0
- package/dist/__tests__/workflow-saga.test.js.map +1 -0
- package/dist/actor-store.d.ts +83 -0
- package/dist/actor-store.d.ts.map +1 -0
- package/dist/actor-store.js +85 -0
- package/dist/actor-store.js.map +1 -0
- package/dist/cli-runner.d.ts +46 -0
- package/dist/cli-runner.d.ts.map +1 -0
- package/dist/cli-runner.js +164 -0
- package/dist/cli-runner.js.map +1 -0
- package/dist/create-app.d.ts +131 -0
- package/dist/create-app.d.ts.map +1 -0
- package/dist/create-app.js +593 -0
- package/dist/create-app.js.map +1 -0
- package/dist/define-action.d.ts +148 -0
- package/dist/define-action.d.ts.map +1 -0
- package/dist/define-action.js +52 -0
- package/dist/define-action.js.map +1 -0
- package/dist/define-actor.d.ts +302 -0
- package/dist/define-actor.d.ts.map +1 -0
- package/dist/define-actor.js +294 -0
- package/dist/define-actor.js.map +1 -0
- package/dist/define-app.d.ts +104 -0
- package/dist/define-app.d.ts.map +1 -0
- package/dist/define-app.js +49 -0
- package/dist/define-app.js.map +1 -0
- package/dist/define-cron.d.ts +50 -0
- package/dist/define-cron.d.ts.map +1 -0
- package/dist/define-cron.js +34 -0
- package/dist/define-cron.js.map +1 -0
- package/dist/define-error.d.ts +10 -0
- package/dist/define-error.d.ts.map +1 -0
- package/dist/define-error.js +10 -0
- package/dist/define-error.js.map +1 -0
- package/dist/define-external-call.d.ts +85 -0
- package/dist/define-external-call.d.ts.map +1 -0
- package/dist/define-external-call.js +38 -0
- package/dist/define-external-call.js.map +1 -0
- package/dist/define-handler.d.ts +98 -0
- package/dist/define-handler.d.ts.map +1 -0
- package/dist/define-handler.js +29 -0
- package/dist/define-handler.js.map +1 -0
- package/dist/define-inbound-webhook.d.ts +82 -0
- package/dist/define-inbound-webhook.d.ts.map +1 -0
- package/dist/define-inbound-webhook.js +42 -0
- package/dist/define-inbound-webhook.js.map +1 -0
- package/dist/define-inbox.d.ts +40 -0
- package/dist/define-inbox.d.ts.map +1 -0
- package/dist/define-inbox.js +31 -0
- package/dist/define-inbox.js.map +1 -0
- package/dist/define-initializer.d.ts +54 -0
- package/dist/define-initializer.d.ts.map +1 -0
- package/dist/define-initializer.js +38 -0
- package/dist/define-initializer.js.map +1 -0
- package/dist/define-middleware.d.ts +8 -0
- package/dist/define-middleware.d.ts.map +1 -0
- package/dist/define-middleware.js +8 -0
- package/dist/define-middleware.js.map +1 -0
- package/dist/define-model.d.ts +10 -0
- package/dist/define-model.d.ts.map +1 -0
- package/dist/define-model.js +13 -0
- package/dist/define-model.js.map +1 -0
- package/dist/define-module.d.ts +157 -0
- package/dist/define-module.d.ts.map +1 -0
- package/dist/define-module.js +60 -0
- package/dist/define-module.js.map +1 -0
- package/dist/define-outbox.d.ts +47 -0
- package/dist/define-outbox.d.ts.map +1 -0
- package/dist/define-outbox.js +36 -0
- package/dist/define-outbox.js.map +1 -0
- package/dist/define-plugin.d.ts +171 -0
- package/dist/define-plugin.d.ts.map +1 -0
- package/dist/define-plugin.js +134 -0
- package/dist/define-plugin.js.map +1 -0
- package/dist/define-projection.d.ts +56 -0
- package/dist/define-projection.d.ts.map +1 -0
- package/dist/define-projection.js +44 -0
- package/dist/define-projection.js.map +1 -0
- package/dist/define-provider.d.ts +49 -0
- package/dist/define-provider.d.ts.map +1 -0
- package/dist/define-provider.js +45 -0
- package/dist/define-provider.js.map +1 -0
- package/dist/define-query.d.ts +50 -0
- package/dist/define-query.d.ts.map +1 -0
- package/dist/define-query.js +33 -0
- package/dist/define-query.js.map +1 -0
- package/dist/define-resolver.d.ts +111 -0
- package/dist/define-resolver.d.ts.map +1 -0
- package/dist/define-resolver.js +146 -0
- package/dist/define-resolver.js.map +1 -0
- package/dist/define-schema.d.ts +88 -0
- package/dist/define-schema.d.ts.map +1 -0
- package/dist/define-schema.js +72 -0
- package/dist/define-schema.js.map +1 -0
- package/dist/define-workflow.d.ts +193 -0
- package/dist/define-workflow.d.ts.map +1 -0
- package/dist/define-workflow.js +345 -0
- package/dist/define-workflow.js.map +1 -0
- package/dist/dev-logger.d.ts +41 -0
- package/dist/dev-logger.d.ts.map +1 -0
- package/dist/dev-logger.js +135 -0
- package/dist/dev-logger.js.map +1 -0
- package/dist/event-message.d.ts +37 -0
- package/dist/event-message.d.ts.map +1 -0
- package/dist/event-message.js +51 -0
- package/dist/event-message.js.map +1 -0
- package/dist/foundation.d.ts +14 -0
- package/dist/foundation.d.ts.map +1 -0
- package/dist/foundation.js +14 -0
- package/dist/foundation.js.map +1 -0
- package/dist/framework-event-bus.d.ts +13 -0
- package/dist/framework-event-bus.d.ts.map +1 -0
- package/dist/framework-event-bus.js +13 -0
- package/dist/framework-event-bus.js.map +1 -0
- package/dist/framework-events.d.ts +121 -0
- package/dist/framework-events.d.ts.map +1 -0
- package/dist/framework-events.js +67 -0
- package/dist/framework-events.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/module-surface.d.ts +47 -0
- package/dist/module-surface.d.ts.map +1 -0
- package/dist/module-surface.js +65 -0
- package/dist/module-surface.js.map +1 -0
- package/dist/projection-store.d.ts +26 -0
- package/dist/projection-store.d.ts.map +1 -0
- package/dist/projection-store.js +28 -0
- package/dist/projection-store.js.map +1 -0
- package/dist/public-marker.d.ts +35 -0
- package/dist/public-marker.d.ts.map +1 -0
- package/dist/public-marker.js +45 -0
- package/dist/public-marker.js.map +1 -0
- package/dist/response.d.ts +8 -0
- package/dist/response.d.ts.map +1 -0
- package/dist/response.js +8 -0
- package/dist/response.js.map +1 -0
- package/dist/runtime.d.ts +497 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +1083 -0
- package/dist/runtime.js.map +1 -0
- package/dist/validate.d.ts +33 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +48 -0
- package/dist/validate.js.map +1 -0
- package/dist/when.d.ts +101 -0
- package/dist/when.d.ts.map +1 -0
- package/dist/when.js +57 -0
- package/dist/when.js.map +1 -0
- package/dist/workflow-timer-store.d.ts +78 -0
- package/dist/workflow-timer-store.d.ts.map +1 -0
- package/dist/workflow-timer-store.js +56 -0
- package/dist/workflow-timer-store.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-schema.test.js","sourceRoot":"","sources":["../../src/__tests__/define-schema.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev logger — formatting + filter + createApp default attach behavior.
|
|
3
|
+
*
|
|
4
|
+
* Doesn't test colors (terminal-dependent); asserts the structural parts
|
|
5
|
+
* of the output and proves the attach/detach lifecycle works through
|
|
6
|
+
* createApp's start() + stop().
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=dev-logger.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-logger.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/dev-logger.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev logger — formatting + filter + createApp default attach behavior.
|
|
3
|
+
*
|
|
4
|
+
* Doesn't test colors (terminal-dependent); asserts the structural parts
|
|
5
|
+
* of the output and proves the attach/detach lifecycle works through
|
|
6
|
+
* createApp's start() + stop().
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
import { defineEvent } from "@nwire/messages";
|
|
11
|
+
import { attachDevLogger, formatTelemetry } from "../dev-logger.js";
|
|
12
|
+
import * as forge from "../foundation.js";
|
|
13
|
+
const { defineAction, defineHandler, defineModule, createApp, eventFactory } = forge;
|
|
14
|
+
const NoteWasAddedDef = defineEvent({
|
|
15
|
+
name: "notes.was-added",
|
|
16
|
+
schema: z.object({ noteId: z.string(), text: z.string() }),
|
|
17
|
+
});
|
|
18
|
+
const NoteWasAdded = eventFactory(NoteWasAddedDef);
|
|
19
|
+
const AddNote = defineAction({
|
|
20
|
+
name: "notes.add",
|
|
21
|
+
schema: z.object({ noteId: z.string(), text: z.string() }),
|
|
22
|
+
emits: [NoteWasAddedDef],
|
|
23
|
+
});
|
|
24
|
+
const addNoteHandler = defineHandler(AddNote, async (input) => {
|
|
25
|
+
return NoteWasAdded({ noteId: input.noteId, text: input.text });
|
|
26
|
+
});
|
|
27
|
+
const notesModule = defineModule("notes", {
|
|
28
|
+
actions: [AddNote],
|
|
29
|
+
handlers: [addNoteHandler],
|
|
30
|
+
events: [NoteWasAddedDef],
|
|
31
|
+
});
|
|
32
|
+
describe("formatTelemetry", () => {
|
|
33
|
+
it("renders an action.dispatched line with the action name", () => {
|
|
34
|
+
const line = formatTelemetry({
|
|
35
|
+
kind: "action.dispatched",
|
|
36
|
+
action: "notes.add",
|
|
37
|
+
input: {},
|
|
38
|
+
envelope: { messageId: "m1", correlationId: "c1" },
|
|
39
|
+
appName: "test",
|
|
40
|
+
ts: "2026-05-25T21:30:45.123Z",
|
|
41
|
+
});
|
|
42
|
+
expect(line).toContain("notes.add");
|
|
43
|
+
expect(line).toContain("21:30:45.123");
|
|
44
|
+
expect(line).toContain("action");
|
|
45
|
+
});
|
|
46
|
+
it("renders action.completed with durationMs and emitted-event count", () => {
|
|
47
|
+
const line = formatTelemetry({
|
|
48
|
+
kind: "action.completed",
|
|
49
|
+
action: "notes.add",
|
|
50
|
+
durationMs: 5,
|
|
51
|
+
emittedEvents: ["notes.was-added"],
|
|
52
|
+
envelope: {},
|
|
53
|
+
appName: "test",
|
|
54
|
+
ts: "2026-05-25T21:30:45.500Z",
|
|
55
|
+
});
|
|
56
|
+
expect(line).toContain("5ms");
|
|
57
|
+
expect(line).toContain("+1 event");
|
|
58
|
+
});
|
|
59
|
+
it("renders an event.published line with the event name", () => {
|
|
60
|
+
const line = formatTelemetry({
|
|
61
|
+
kind: "event.published",
|
|
62
|
+
event: { eventName: "notes.was-added", payload: {} },
|
|
63
|
+
envelope: {},
|
|
64
|
+
source: "in-process",
|
|
65
|
+
appName: "test",
|
|
66
|
+
ts: "2026-05-25T21:30:45.000Z",
|
|
67
|
+
});
|
|
68
|
+
expect(line).toContain("notes.was-added");
|
|
69
|
+
expect(line).toContain("event");
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe("attachDevLogger filter", () => {
|
|
73
|
+
it("only emits records whose kind matches the configured filter", async () => {
|
|
74
|
+
const lines = [];
|
|
75
|
+
const app = createApp({ modules: [notesModule], devLogs: false });
|
|
76
|
+
await app.start();
|
|
77
|
+
const detach = attachDevLogger(app.runtime, {
|
|
78
|
+
kinds: ["action.completed"],
|
|
79
|
+
write: (line) => lines.push(line),
|
|
80
|
+
});
|
|
81
|
+
await app.runtime.dispatch(AddNote, { noteId: "n1", text: "hi" });
|
|
82
|
+
detach();
|
|
83
|
+
await app.stop();
|
|
84
|
+
// Only completed lines — no dispatched, no event.published.
|
|
85
|
+
expect(lines.length).toBeGreaterThan(0);
|
|
86
|
+
for (const l of lines)
|
|
87
|
+
expect(l).toContain("notes.add");
|
|
88
|
+
expect(lines.some((l) => l.match(/✓|action\b/))).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe("createApp default dev logger", () => {
|
|
92
|
+
let writeSpy;
|
|
93
|
+
beforeEach(() => {
|
|
94
|
+
writeSpy = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
|
|
95
|
+
});
|
|
96
|
+
afterEach(() => {
|
|
97
|
+
writeSpy.mockRestore();
|
|
98
|
+
});
|
|
99
|
+
it("auto-attaches when NODE_ENV != production and writes telemetry", async () => {
|
|
100
|
+
const previousEnv = process.env.NODE_ENV;
|
|
101
|
+
process.env.NODE_ENV = "development";
|
|
102
|
+
try {
|
|
103
|
+
const app = createApp({ modules: [notesModule] });
|
|
104
|
+
await app.start();
|
|
105
|
+
await app.runtime.dispatch(AddNote, { noteId: "n2", text: "hello" });
|
|
106
|
+
await app.stop();
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
if (previousEnv === undefined)
|
|
110
|
+
delete process.env.NODE_ENV;
|
|
111
|
+
else
|
|
112
|
+
process.env.NODE_ENV = previousEnv;
|
|
113
|
+
}
|
|
114
|
+
const allWrites = writeSpy.mock.calls.map((c) => String(c[0])).join("");
|
|
115
|
+
expect(allWrites).toContain("notes.add");
|
|
116
|
+
});
|
|
117
|
+
it("stays silent when devLogs:false is explicit", async () => {
|
|
118
|
+
const app = createApp({ modules: [notesModule], devLogs: false });
|
|
119
|
+
await app.start();
|
|
120
|
+
await app.runtime.dispatch(AddNote, { noteId: "n3", text: "quiet" });
|
|
121
|
+
await app.stop();
|
|
122
|
+
const allWrites = writeSpy.mock.calls.map((c) => String(c[0])).join("");
|
|
123
|
+
expect(allWrites).not.toContain("notes.add");
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
//# sourceMappingURL=dev-logger.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-logger.test.js","sourceRoot":"","sources":["../../src/__tests__/dev-logger.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 47 — orchestrator primitives. Smoke tests for `defineExternalCall`
|
|
3
|
+
* + runtime execution + telemetry emission.
|
|
4
|
+
*
|
|
5
|
+
* The declarative shape is pure data; what we want to verify is:
|
|
6
|
+
* 1. The runtime registers external-call definitions when a module declares them.
|
|
7
|
+
* 2. `ctx.externalCall(def, request)` runs the registered executor, validates
|
|
8
|
+
* response, threads the idempotency key, applies retry policy.
|
|
9
|
+
* 3. Each call emits `external.call.started` / `.completed` / `.failed`
|
|
10
|
+
* records on the canonical telemetry stream.
|
|
11
|
+
* 4. Missing executor → loud failure (no silent dropped call).
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=external-call.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-call.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/external-call.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 47 — orchestrator primitives. Smoke tests for `defineExternalCall`
|
|
3
|
+
* + runtime execution + telemetry emission.
|
|
4
|
+
*
|
|
5
|
+
* The declarative shape is pure data; what we want to verify is:
|
|
6
|
+
* 1. The runtime registers external-call definitions when a module declares them.
|
|
7
|
+
* 2. `ctx.externalCall(def, request)` runs the registered executor, validates
|
|
8
|
+
* response, threads the idempotency key, applies retry policy.
|
|
9
|
+
* 3. Each call emits `external.call.started` / `.completed` / `.failed`
|
|
10
|
+
* records on the canonical telemetry stream.
|
|
11
|
+
* 4. Missing executor → loud failure (no silent dropped call).
|
|
12
|
+
*/
|
|
13
|
+
import { describe, it, expect } from "vitest";
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
import * as forge from "../foundation.js";
|
|
16
|
+
const NotifyRequest = z.object({ to: z.string(), template: z.string() });
|
|
17
|
+
const NotifyResponse = z.object({ notificationId: z.string(), delivered: z.boolean() });
|
|
18
|
+
const notify = forge.defineExternalCall({
|
|
19
|
+
name: "notifications.send",
|
|
20
|
+
target: { provider: "notifications", endpoint: "/v1/notify" },
|
|
21
|
+
request: NotifyRequest,
|
|
22
|
+
response: NotifyResponse,
|
|
23
|
+
idempotencyKey: (req) => `notify-${req.to}-${req.template}`,
|
|
24
|
+
slo: { p95LatencyMs: 200, successRate: 0.99 },
|
|
25
|
+
retry: { max: 2, backoff: "fixed", baseDelayMs: 1 },
|
|
26
|
+
});
|
|
27
|
+
const SendNudgeInput = z.object({ to: z.string() });
|
|
28
|
+
const sendNudge = forge.defineAction({
|
|
29
|
+
name: "ops.send-nudge",
|
|
30
|
+
schema: SendNudgeInput,
|
|
31
|
+
handler: async (input, ctx) => {
|
|
32
|
+
await ctx.externalCall(notify, { to: input.to, template: "hello" });
|
|
33
|
+
return undefined;
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
const opsModule = forge.defineModule("ops", {
|
|
37
|
+
actions: [sendNudge],
|
|
38
|
+
externalCalls: [notify],
|
|
39
|
+
});
|
|
40
|
+
const opsApp = forge.defineApp("ops-app", { modules: [opsModule] });
|
|
41
|
+
describe("defineExternalCall + ctx.externalCall", () => {
|
|
42
|
+
it("executes the registered executor and emits started/completed telemetry", async () => {
|
|
43
|
+
const app = opsApp.create();
|
|
44
|
+
await app.start();
|
|
45
|
+
let executorCalls = 0;
|
|
46
|
+
app.runtime.registerExternalCallExecutor(notify, async (req, meta) => {
|
|
47
|
+
executorCalls++;
|
|
48
|
+
expect(req.to).toBe("avi");
|
|
49
|
+
expect(meta.idempotencyKey).toBe("notify-avi-hello");
|
|
50
|
+
return { notificationId: "n1", delivered: true };
|
|
51
|
+
});
|
|
52
|
+
const seen = [];
|
|
53
|
+
app.runtime.onTelemetry((rec) => seen.push(rec));
|
|
54
|
+
await app.runtime.dispatch(sendNudge, { to: "avi" });
|
|
55
|
+
expect(executorCalls).toBe(1);
|
|
56
|
+
const kinds = seen.map((r) => r.kind);
|
|
57
|
+
expect(kinds).toContain("external.call.started");
|
|
58
|
+
expect(kinds).toContain("external.call.completed");
|
|
59
|
+
const completed = seen.find((r) => r.kind === "external.call.completed");
|
|
60
|
+
expect(completed?.call).toBe("notifications.send");
|
|
61
|
+
expect(completed?.target).toBe("notifications//v1/notify");
|
|
62
|
+
expect(completed?.idempotencyKey).toBe("notify-avi-hello");
|
|
63
|
+
expect(typeof completed?.durationMs).toBe("number");
|
|
64
|
+
});
|
|
65
|
+
it("retries on failure and emits external.call.failed per attempt", async () => {
|
|
66
|
+
const app = opsApp.create();
|
|
67
|
+
await app.start();
|
|
68
|
+
let attempts = 0;
|
|
69
|
+
app.runtime.registerExternalCallExecutor(notify, async () => {
|
|
70
|
+
attempts++;
|
|
71
|
+
if (attempts < 3)
|
|
72
|
+
throw new Error(`flake #${attempts}`);
|
|
73
|
+
return { notificationId: "n1", delivered: true };
|
|
74
|
+
});
|
|
75
|
+
const seen = [];
|
|
76
|
+
app.runtime.onTelemetry((rec) => seen.push(rec));
|
|
77
|
+
await app.runtime.dispatch(sendNudge, { to: "dina" });
|
|
78
|
+
expect(attempts).toBe(3);
|
|
79
|
+
const failures = seen.filter((r) => r.kind === "external.call.failed");
|
|
80
|
+
expect(failures).toHaveLength(2);
|
|
81
|
+
expect(seen.some((r) => r.kind === "external.call.completed")).toBe(true);
|
|
82
|
+
});
|
|
83
|
+
it("throws when no executor is registered and emits external.call.failed", async () => {
|
|
84
|
+
const app = opsApp.create();
|
|
85
|
+
await app.start();
|
|
86
|
+
const seen = [];
|
|
87
|
+
app.runtime.onTelemetry((rec) => seen.push(rec));
|
|
88
|
+
await expect(app.runtime.dispatch(sendNudge, { to: "miri" })).rejects.toThrow(/no executor registered/);
|
|
89
|
+
const failures = seen.filter((r) => r.kind === "external.call.failed");
|
|
90
|
+
expect(failures).toHaveLength(1);
|
|
91
|
+
});
|
|
92
|
+
it("registers external calls into the runtime registry", async () => {
|
|
93
|
+
const app = opsApp.create();
|
|
94
|
+
await app.start();
|
|
95
|
+
expect(app.runtime.listExternalCalls()).toContain("notifications.send");
|
|
96
|
+
expect(app.runtime.getExternalCall("notifications.send")?.target.provider).toBe("notifications");
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
//# sourceMappingURL=external-call.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-call.test.js","sourceRoot":"","sources":["../../src/__tests__/external-call.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework events — lifecycle + dispatch hooks expressed as values.
|
|
3
|
+
*
|
|
4
|
+
* Verifies:
|
|
5
|
+
* - dispatch modes: parallel / series / series-bail
|
|
6
|
+
* - priority ordering (higher runs first in serial modes)
|
|
7
|
+
* - subscriber unsubscribe
|
|
8
|
+
* - lifecycle wiring: createApp fires AppBooting/Booted/ShuttingDown/Shutdown
|
|
9
|
+
* - dispatch wiring: runtime fires ActionDispatching/Completed/Failed
|
|
10
|
+
* - ActionDispatching can veto a dispatch with `return false`
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=framework-events.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-events.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/framework-events.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework events — lifecycle + dispatch hooks expressed as values.
|
|
3
|
+
*
|
|
4
|
+
* Verifies:
|
|
5
|
+
* - dispatch modes: parallel / series / series-bail
|
|
6
|
+
* - priority ordering (higher runs first in serial modes)
|
|
7
|
+
* - subscriber unsubscribe
|
|
8
|
+
* - lifecycle wiring: createApp fires AppBooting/Booted/ShuttingDown/Shutdown
|
|
9
|
+
* - dispatch wiring: runtime fires ActionDispatching/Completed/Failed
|
|
10
|
+
* - ActionDispatching can veto a dispatch with `return false`
|
|
11
|
+
*/
|
|
12
|
+
import { describe, it, expect } from "vitest";
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
import { ActionDispatching, ActionCompleted, ActionFailed, AppBooting, AppBooted, AppShuttingDown, AppShutdown, createApp, defineAction, defineFrameworkEvent, defineHandler, defineModule, FrameworkEventBus, NoopLogger, } from "../foundation.js";
|
|
15
|
+
// ─── Bus mechanics ─────────────────────────────────────────────────
|
|
16
|
+
describe("FrameworkEventBus dispatch modes", () => {
|
|
17
|
+
const logger = new NoopLogger();
|
|
18
|
+
it("parallel: every subscriber runs; throws are isolated", async () => {
|
|
19
|
+
const bus = new FrameworkEventBus(logger);
|
|
20
|
+
const evt = defineFrameworkEvent("test.completed", "parallel");
|
|
21
|
+
const calls = [];
|
|
22
|
+
bus.on(evt, async () => {
|
|
23
|
+
throw new Error("first");
|
|
24
|
+
});
|
|
25
|
+
bus.on(evt, async (p) => {
|
|
26
|
+
calls.push(p.n);
|
|
27
|
+
});
|
|
28
|
+
bus.on(evt, async (p) => {
|
|
29
|
+
calls.push(p.n * 2);
|
|
30
|
+
});
|
|
31
|
+
const ok = await bus.fire(evt, { n: 5 });
|
|
32
|
+
expect(ok).toBe(true);
|
|
33
|
+
expect(calls.sort((a, b) => a - b)).toEqual([5, 10]);
|
|
34
|
+
});
|
|
35
|
+
it("series: subscribers run sequentially; throws propagate", async () => {
|
|
36
|
+
const bus = new FrameworkEventBus(logger);
|
|
37
|
+
const evt = defineFrameworkEvent("test.transition", "series");
|
|
38
|
+
const order = [];
|
|
39
|
+
bus.on(evt, async (p) => {
|
|
40
|
+
order.push(`a:${p.s}`);
|
|
41
|
+
});
|
|
42
|
+
bus.on(evt, async () => {
|
|
43
|
+
throw new Error("boom");
|
|
44
|
+
});
|
|
45
|
+
bus.on(evt, async (p) => {
|
|
46
|
+
order.push(`c:${p.s}`);
|
|
47
|
+
});
|
|
48
|
+
await expect(bus.fire(evt, { s: "x" })).rejects.toThrow("boom");
|
|
49
|
+
expect(order).toEqual(["a:x"]); // third never ran
|
|
50
|
+
});
|
|
51
|
+
it("series-bail: returning false stops the chain and returns false", async () => {
|
|
52
|
+
const bus = new FrameworkEventBus(logger);
|
|
53
|
+
const evt = defineFrameworkEvent("test.starting", "series-bail");
|
|
54
|
+
const order = [];
|
|
55
|
+
bus.on(evt, async (p) => {
|
|
56
|
+
order.push(`a:${p.go}`);
|
|
57
|
+
});
|
|
58
|
+
bus.on(evt, async () => false); // bail
|
|
59
|
+
bus.on(evt, async () => {
|
|
60
|
+
order.push("c");
|
|
61
|
+
});
|
|
62
|
+
const ok = await bus.fire(evt, { go: true });
|
|
63
|
+
expect(ok).toBe(false);
|
|
64
|
+
expect(order).toEqual(["a:true"]);
|
|
65
|
+
});
|
|
66
|
+
it("priority orders subscribers (higher first)", async () => {
|
|
67
|
+
const bus = new FrameworkEventBus(logger);
|
|
68
|
+
const evt = defineFrameworkEvent("test.ordered", "series");
|
|
69
|
+
const order = [];
|
|
70
|
+
bus.on(evt, () => {
|
|
71
|
+
order.push("low");
|
|
72
|
+
}, -10);
|
|
73
|
+
bus.on(evt, () => {
|
|
74
|
+
order.push("high");
|
|
75
|
+
}, 100);
|
|
76
|
+
bus.on(evt, () => {
|
|
77
|
+
order.push("normal");
|
|
78
|
+
}, 0);
|
|
79
|
+
await bus.fire(evt, undefined);
|
|
80
|
+
expect(order).toEqual(["high", "normal", "low"]);
|
|
81
|
+
});
|
|
82
|
+
it("unsubscribe removes the listener", async () => {
|
|
83
|
+
const bus = new FrameworkEventBus(logger);
|
|
84
|
+
const evt = defineFrameworkEvent("test.unsub", "parallel");
|
|
85
|
+
let calls = 0;
|
|
86
|
+
const off = bus.on(evt, () => {
|
|
87
|
+
calls++;
|
|
88
|
+
});
|
|
89
|
+
await bus.fire(evt, undefined);
|
|
90
|
+
off();
|
|
91
|
+
await bus.fire(evt, undefined);
|
|
92
|
+
expect(calls).toBe(1);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
// ─── Lifecycle wiring ──────────────────────────────────────────────
|
|
96
|
+
describe("createApp fires lifecycle framework events", () => {
|
|
97
|
+
it("fires AppBooting → AppBooted around start; AppShuttingDown → AppShutdown around stop", async () => {
|
|
98
|
+
const app = createApp({ modules: [] });
|
|
99
|
+
const seen = [];
|
|
100
|
+
app.runtime.onFramework(AppBooting, () => {
|
|
101
|
+
seen.push("booting");
|
|
102
|
+
});
|
|
103
|
+
app.runtime.onFramework(AppBooted, () => {
|
|
104
|
+
seen.push("booted");
|
|
105
|
+
});
|
|
106
|
+
app.runtime.onFramework(AppShuttingDown, () => {
|
|
107
|
+
seen.push("shutting");
|
|
108
|
+
});
|
|
109
|
+
app.runtime.onFramework(AppShutdown, () => {
|
|
110
|
+
seen.push("shutdown");
|
|
111
|
+
});
|
|
112
|
+
await app.start();
|
|
113
|
+
await app.stop("test-teardown");
|
|
114
|
+
expect(seen).toEqual(["booting", "booted", "shutting", "shutdown"]);
|
|
115
|
+
});
|
|
116
|
+
it("AppShuttingDown can prevent shutdown by returning false", async () => {
|
|
117
|
+
const app = createApp({ modules: [] });
|
|
118
|
+
await app.start();
|
|
119
|
+
app.runtime.onFramework(AppShuttingDown, () => false);
|
|
120
|
+
await expect(app.stop()).rejects.toThrow(/prevented/i);
|
|
121
|
+
});
|
|
122
|
+
it("AppShuttingDown receives the reason", async () => {
|
|
123
|
+
const app = createApp({ modules: [] });
|
|
124
|
+
let received;
|
|
125
|
+
app.runtime.onFramework(AppShuttingDown, (p) => {
|
|
126
|
+
received = p.reason;
|
|
127
|
+
});
|
|
128
|
+
await app.start();
|
|
129
|
+
await app.stop("SIGTERM-received");
|
|
130
|
+
expect(received).toBe("SIGTERM-received");
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
// ─── Dispatch wiring ───────────────────────────────────────────────
|
|
134
|
+
describe("runtime fires action framework events", () => {
|
|
135
|
+
const Ping = defineAction({
|
|
136
|
+
name: "test/ping",
|
|
137
|
+
schema: z.object({ n: z.number() }),
|
|
138
|
+
});
|
|
139
|
+
const handler = defineHandler(Ping, async (input) => {
|
|
140
|
+
if (input.n < 0)
|
|
141
|
+
throw new Error("negative");
|
|
142
|
+
return undefined;
|
|
143
|
+
});
|
|
144
|
+
const mod = defineModule("test", {
|
|
145
|
+
actions: [Ping],
|
|
146
|
+
handlers: [handler],
|
|
147
|
+
});
|
|
148
|
+
it("fires ActionDispatching → ActionCompleted on success", async () => {
|
|
149
|
+
const app = createApp({ modules: [mod] });
|
|
150
|
+
await app.start();
|
|
151
|
+
const seen = [];
|
|
152
|
+
app.runtime.onFramework(ActionDispatching, (p) => {
|
|
153
|
+
seen.push(`pre:${p.action.name}`);
|
|
154
|
+
});
|
|
155
|
+
app.runtime.onFramework(ActionCompleted, (p) => {
|
|
156
|
+
seen.push(`ok:${p.action.name}`);
|
|
157
|
+
});
|
|
158
|
+
app.runtime.onFramework(ActionFailed, () => {
|
|
159
|
+
seen.push("fail");
|
|
160
|
+
});
|
|
161
|
+
await app.runtime.dispatch(Ping, { n: 1 });
|
|
162
|
+
// ActionCompleted fires in parallel/non-awaited; wait a tick.
|
|
163
|
+
await new Promise((r) => setImmediate(r));
|
|
164
|
+
expect(seen).toEqual(["pre:test/ping", "ok:test/ping"]);
|
|
165
|
+
await app.stop();
|
|
166
|
+
});
|
|
167
|
+
it("fires ActionDispatching → ActionFailed when the handler throws", async () => {
|
|
168
|
+
const app = createApp({ modules: [mod] });
|
|
169
|
+
await app.start();
|
|
170
|
+
const seen = [];
|
|
171
|
+
app.runtime.onFramework(ActionDispatching, () => {
|
|
172
|
+
seen.push("pre");
|
|
173
|
+
});
|
|
174
|
+
app.runtime.onFramework(ActionCompleted, () => {
|
|
175
|
+
seen.push("ok");
|
|
176
|
+
});
|
|
177
|
+
app.runtime.onFramework(ActionFailed, (p) => {
|
|
178
|
+
seen.push(`fail:${p.error.message}`);
|
|
179
|
+
});
|
|
180
|
+
await expect(app.runtime.dispatch(Ping, { n: -1 })).rejects.toThrow("negative");
|
|
181
|
+
await new Promise((r) => setImmediate(r));
|
|
182
|
+
expect(seen).toEqual(["pre", "fail:negative"]);
|
|
183
|
+
await app.stop();
|
|
184
|
+
});
|
|
185
|
+
it("ActionDispatching returning false cancels the dispatch", async () => {
|
|
186
|
+
const app = createApp({ modules: [mod] });
|
|
187
|
+
await app.start();
|
|
188
|
+
let handlerRan = false;
|
|
189
|
+
app.runtime.onFramework(ActionDispatching, () => false);
|
|
190
|
+
// Add a second handler subscription to ensure veto comes from anywhere
|
|
191
|
+
// in the chain.
|
|
192
|
+
let completed = false;
|
|
193
|
+
app.runtime.onFramework(ActionCompleted, () => {
|
|
194
|
+
completed = true;
|
|
195
|
+
});
|
|
196
|
+
const result = await app.runtime.dispatch(Ping, { n: 1 });
|
|
197
|
+
await new Promise((r) => setImmediate(r));
|
|
198
|
+
expect(result).toBeUndefined();
|
|
199
|
+
expect(completed).toBe(false); // veto skipped the handler entirely
|
|
200
|
+
expect(handlerRan).toBe(false); // unused; satisfies prior style
|
|
201
|
+
await app.stop();
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
//# sourceMappingURL=framework-events.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-events.test.js","sourceRoot":"","sources":["../../src/__tests__/framework-events.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline-handler shortcut — `defineAction({..., handler})` collapses the
|
|
3
|
+
* action contract + handler into a single declaration. createApp auto-
|
|
4
|
+
* registers the inline handler when walking `manifest.actions`. The
|
|
5
|
+
* separate `defineHandler(action, fn)` form keeps working alongside.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=inline-handler.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inline-handler.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/inline-handler.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline-handler shortcut — `defineAction({..., handler})` collapses the
|
|
3
|
+
* action contract + handler into a single declaration. createApp auto-
|
|
4
|
+
* registers the inline handler when walking `manifest.actions`. The
|
|
5
|
+
* separate `defineHandler(action, fn)` form keeps working alongside.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect } from "vitest";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { defineAction, defineHandler, defineModule, createApp, Runtime } from "../foundation.js";
|
|
10
|
+
describe("inline-handler shortcut", () => {
|
|
11
|
+
it("dispatches an action with an inline handler", async () => {
|
|
12
|
+
let calls = 0;
|
|
13
|
+
const ping = defineAction({
|
|
14
|
+
name: "ping.inline",
|
|
15
|
+
schema: z.object({}),
|
|
16
|
+
handler: async () => {
|
|
17
|
+
calls++;
|
|
18
|
+
return undefined;
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
expect(ping.handler).toBeDefined();
|
|
22
|
+
expect(ping.handler?.action.name).toBe("ping.inline");
|
|
23
|
+
const runtime = new Runtime();
|
|
24
|
+
// Register via the synthesized handler.
|
|
25
|
+
runtime.registerHandler(ping.handler);
|
|
26
|
+
await runtime.dispatch(ping, {});
|
|
27
|
+
expect(calls).toBe(1);
|
|
28
|
+
});
|
|
29
|
+
it("createApp auto-registers inline handlers from manifest.actions", async () => {
|
|
30
|
+
let calls = 0;
|
|
31
|
+
const ping = defineAction({
|
|
32
|
+
name: "ping.via-app",
|
|
33
|
+
schema: z.object({}),
|
|
34
|
+
handler: async () => {
|
|
35
|
+
calls++;
|
|
36
|
+
return undefined;
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
const module = defineModule("ping-module", {
|
|
40
|
+
actions: [ping],
|
|
41
|
+
// No separate `handlers:` — the inline form is enough.
|
|
42
|
+
});
|
|
43
|
+
const app = createApp({ modules: [module] });
|
|
44
|
+
await app.runtime.dispatch(ping, {});
|
|
45
|
+
expect(calls).toBe(1);
|
|
46
|
+
});
|
|
47
|
+
it("inline handler coexists with separate defineHandler in the same module", async () => {
|
|
48
|
+
const inlineAction = defineAction({
|
|
49
|
+
name: "mixed.inline",
|
|
50
|
+
schema: z.object({}),
|
|
51
|
+
handler: async () => undefined,
|
|
52
|
+
});
|
|
53
|
+
const separateAction = defineAction({
|
|
54
|
+
name: "mixed.separate",
|
|
55
|
+
schema: z.object({}),
|
|
56
|
+
});
|
|
57
|
+
const separateHandler = defineHandler(separateAction, async () => undefined);
|
|
58
|
+
const module = defineModule("mixed-module", {
|
|
59
|
+
actions: [inlineAction, separateAction],
|
|
60
|
+
handlers: [separateHandler],
|
|
61
|
+
});
|
|
62
|
+
const app = createApp({ modules: [module] });
|
|
63
|
+
// Both dispatch without "no handler registered" errors.
|
|
64
|
+
await app.runtime.dispatch(inlineAction, {});
|
|
65
|
+
await app.runtime.dispatch(separateAction, {});
|
|
66
|
+
});
|
|
67
|
+
it("inline handler receives typed input and ctx", async () => {
|
|
68
|
+
let seen;
|
|
69
|
+
let seenRequestId = "";
|
|
70
|
+
const enroll = defineAction({
|
|
71
|
+
name: "enroll.typed",
|
|
72
|
+
schema: z.object({ studentId: z.string() }),
|
|
73
|
+
handler: async (input, ctx) => {
|
|
74
|
+
seen = input;
|
|
75
|
+
seenRequestId = ctx.requestId;
|
|
76
|
+
return undefined;
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
const app = createApp({ modules: [defineModule("m", { actions: [enroll] })] });
|
|
80
|
+
await app.runtime.dispatch(enroll, { studentId: "avi-1" });
|
|
81
|
+
expect(seen).toEqual({ studentId: "avi-1" });
|
|
82
|
+
expect(seenRequestId).toMatch(/^[0-9a-f-]{36}$/i);
|
|
83
|
+
});
|
|
84
|
+
it("registering the same action via both inline AND defineHandler throws", () => {
|
|
85
|
+
const action = defineAction({
|
|
86
|
+
name: "dup.action",
|
|
87
|
+
schema: z.object({}),
|
|
88
|
+
handler: async () => undefined,
|
|
89
|
+
});
|
|
90
|
+
const duplicateHandler = defineHandler(action, async () => undefined);
|
|
91
|
+
expect(() => createApp({
|
|
92
|
+
modules: [
|
|
93
|
+
defineModule("dup", {
|
|
94
|
+
actions: [action],
|
|
95
|
+
handlers: [duplicateHandler],
|
|
96
|
+
}),
|
|
97
|
+
],
|
|
98
|
+
})).toThrow(/already registered/);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=inline-handler.test.js.map
|