@aotter/mantle-runtime 0.0.11-alpha.59 → 0.0.11-alpha.61
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 +5 -0
- package/dist/domain/model/HandlerContext.d.ts +7 -1
- package/dist/domain/model/HandlerContext.d.ts.map +1 -1
- package/dist/domain/port/DeferredHookDispatcher.d.ts +21 -17
- package/dist/domain/port/DeferredHookDispatcher.d.ts.map +1 -1
- package/dist/domain/port/DeferredHookDispatcher.js +17 -1
- package/dist/domain/port/DeferredHookDispatcher.js.map +1 -1
- package/dist/domain/port/EntryRepository.d.ts +2 -1
- package/dist/domain/port/EntryRepository.d.ts.map +1 -1
- package/dist/domain/port/IdGenerator.d.ts +2 -1
- package/dist/domain/port/IdGenerator.d.ts.map +1 -1
- package/dist/domain/port/IdGenerator.js.map +1 -1
- package/dist/domain/port/index.d.ts +2 -2
- package/dist/domain/port/index.d.ts.map +1 -1
- package/dist/domain/port/index.js +1 -1
- package/dist/domain/port/index.js.map +1 -1
- package/dist/domain/service/BuiltinProjector.d.ts +2 -2
- package/dist/domain/service/TriggerIndex.d.ts +0 -4
- package/dist/domain/service/TriggerIndex.d.ts.map +1 -1
- package/dist/domain/service/TriggerIndex.js +0 -6
- package/dist/domain/service/TriggerIndex.js.map +1 -1
- package/dist/domain/service/ViewSqlCompiler.d.ts +7 -6
- package/dist/domain/service/ViewSqlCompiler.d.ts.map +1 -1
- package/dist/domain/service/ViewSqlCompiler.js +31 -18
- package/dist/domain/service/ViewSqlCompiler.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/boot/canonicalMigrations.d.ts +1 -1
- package/dist/infrastructure/boot/canonicalMigrations.d.ts.map +1 -1
- package/dist/infrastructure/boot/canonicalMigrations.js +80 -19
- package/dist/infrastructure/boot/canonicalMigrations.js.map +1 -1
- package/dist/infrastructure/boot/index.d.ts +1 -1
- package/dist/infrastructure/boot/index.d.ts.map +1 -1
- package/dist/infrastructure/boot/index.js +1 -1
- package/dist/infrastructure/boot/index.js.map +1 -1
- package/dist/infrastructure/mcp/McpJsonRpcDispatcher.d.ts.map +1 -1
- package/dist/infrastructure/mcp/McpJsonRpcDispatcher.js +27 -10
- package/dist/infrastructure/mcp/McpJsonRpcDispatcher.js.map +1 -1
- package/dist/infrastructure/persistence/DatabaseEntryRepository.d.ts +3 -1
- package/dist/infrastructure/persistence/DatabaseEntryRepository.d.ts.map +1 -1
- package/dist/infrastructure/persistence/DatabaseEntryRepository.js +19 -19
- package/dist/infrastructure/persistence/DatabaseEntryRepository.js.map +1 -1
- package/dist/infrastructure/persistence/LifecycleHookingEntryRepository.d.ts +9 -46
- package/dist/infrastructure/persistence/LifecycleHookingEntryRepository.d.ts.map +1 -1
- package/dist/infrastructure/persistence/LifecycleHookingEntryRepository.js +82 -99
- package/dist/infrastructure/persistence/LifecycleHookingEntryRepository.js.map +1 -1
- package/dist/runtime.d.ts +6 -9
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +9 -10
- package/dist/runtime.js.map +1 -1
- package/dist/usecase/boot/ValidateBootUseCase.d.ts +1 -0
- package/dist/usecase/boot/ValidateBootUseCase.d.ts.map +1 -1
- package/dist/usecase/boot/ValidateBootUseCase.js +13 -1
- package/dist/usecase/boot/ValidateBootUseCase.js.map +1 -1
- package/dist/usecase/dto/content/index.d.ts +3 -5
- package/dist/usecase/dto/content/index.d.ts.map +1 -1
- package/dist/usecase/dto/lifecycle/index.d.ts +3 -2
- package/dist/usecase/dto/lifecycle/index.d.ts.map +1 -1
- package/dist/usecase/lifecycle/RunDeferredHookUseCase.d.ts +7 -15
- package/dist/usecase/lifecycle/RunDeferredHookUseCase.d.ts.map +1 -1
- package/dist/usecase/lifecycle/RunDeferredHookUseCase.js +96 -24
- package/dist/usecase/lifecycle/RunDeferredHookUseCase.js.map +1 -1
- package/dist/usecase/lifecycle/RunLifecycleHooksUseCase.d.ts +15 -26
- package/dist/usecase/lifecycle/RunLifecycleHooksUseCase.d.ts.map +1 -1
- package/dist/usecase/lifecycle/RunLifecycleHooksUseCase.js +66 -31
- package/dist/usecase/lifecycle/RunLifecycleHooksUseCase.js.map +1 -1
- package/dist/usecase/procedure/InvokeBuiltinUseCase.d.ts +3 -3
- package/dist/usecase/procedure/InvokeBuiltinUseCase.js +3 -3
- package/dist/usecase/view/ExecuteViewUseCase.d.ts +3 -2
- package/dist/usecase/view/ExecuteViewUseCase.d.ts.map +1 -1
- package/dist/usecase/view/ExecuteViewUseCase.js +4 -2
- package/dist/usecase/view/ExecuteViewUseCase.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,22 +1,14 @@
|
|
|
1
1
|
import type { RunDeferredHookRequest } from "../dto/lifecycle/index.js";
|
|
2
2
|
import type { RunLifecycleHooksUseCase } from "./RunLifecycleHooksUseCase.js";
|
|
3
3
|
/**
|
|
4
|
-
* Consume side of
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Consume side of deferred lifecycle delivery. Queue bodies are
|
|
5
|
+
* untrusted: the versioned envelope is validated before any field is
|
|
6
|
+
* read, then the original identity snapshot is rebuilt with the
|
|
7
|
+
* consume invocation's fresh adapter bindings.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* absent — the consume invocation owns its own request lifetime, and
|
|
13
|
-
* chaining another fire-and-forget here would just reintroduce the
|
|
14
|
-
* durability gap the deferred path closes.
|
|
15
|
-
*
|
|
16
|
-
* Errors from the underlying hook surface per the Trigger's
|
|
17
|
-
* `errorPolicy`. The adapter is expected to translate a throw into
|
|
18
|
-
* the platform's retry signal (e.g. `message.retry()` on CF Queues)
|
|
19
|
-
* so the hook eventually succeeds or hits the dead-letter queue.
|
|
9
|
+
* Deferred failures intentionally escape. The Queue adapter converts
|
|
10
|
+
* a throw into retry/DLQ behavior; the already-committed entry
|
|
11
|
+
* mutation is unaffected.
|
|
20
12
|
*/
|
|
21
13
|
export declare class RunDeferredHookUseCase {
|
|
22
14
|
private readonly hooks;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RunDeferredHookUseCase.d.ts","sourceRoot":"","sources":["../../../src/usecase/lifecycle/RunDeferredHookUseCase.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RunDeferredHookUseCase.d.ts","sourceRoot":"","sources":["../../../src/usecase/lifecycle/RunDeferredHookUseCase.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAqE9E;;;;;;;;;GASG;AACH,qBAAa,sBAAsB;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,IAAI,CAAC,wBAAwB,EAAE,KAAK,CAAC;IAEnE,OAAO,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;CAqB9D"}
|
|
@@ -1,20 +1,78 @@
|
|
|
1
|
+
import { ContentState, DiagnosticError, STAFF_ROLES, firstZodIssueAsJsonPointer, runtimeDiagnostic, } from "@aotter/mantle-spec";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { DEFERRED_HOOK_ENVELOPE_VERSION, } from "../../domain/port/DeferredHookDispatcher.js";
|
|
4
|
+
const nonEmpty = z.string().min(1);
|
|
5
|
+
const authSchema = z.object({
|
|
6
|
+
credential: z.enum(["session", "oauth", "api-key", "personal-token"]),
|
|
7
|
+
credentialId: nonEmpty.nullable(),
|
|
8
|
+
clientId: nonEmpty.nullable(),
|
|
9
|
+
scopes: z.array(nonEmpty),
|
|
10
|
+
}).strict();
|
|
11
|
+
const ctxSnapshotSchema = z.object({
|
|
12
|
+
userId: nonEmpty.nullable(),
|
|
13
|
+
staffId: nonEmpty.nullable(),
|
|
14
|
+
staffRole: z.enum(STAFF_ROLES).nullable(),
|
|
15
|
+
auth: authSchema.nullable(),
|
|
16
|
+
}).strict().superRefine((snapshot, ctx) => {
|
|
17
|
+
if ((snapshot.staffId === null) !== (snapshot.staffRole === null)) {
|
|
18
|
+
ctx.addIssue({
|
|
19
|
+
code: "custom",
|
|
20
|
+
path: ["staffId"],
|
|
21
|
+
message: "staffId and staffRole must both be null or both be set",
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if (snapshot.staffId !== null && snapshot.staffId !== snapshot.userId) {
|
|
25
|
+
ctx.addIssue({
|
|
26
|
+
code: "custom",
|
|
27
|
+
path: ["staffId"],
|
|
28
|
+
message: "staffId must match userId",
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
const entrySchema = z.object({
|
|
33
|
+
id: nonEmpty,
|
|
34
|
+
collection: nonEmpty,
|
|
35
|
+
locale: nonEmpty.optional(),
|
|
36
|
+
status: z.enum(ContentState),
|
|
37
|
+
version: z.number().int().positive(),
|
|
38
|
+
data: z.record(z.string(), z.json()),
|
|
39
|
+
authorId: nonEmpty.nullable(),
|
|
40
|
+
createdAt: z.number().finite(),
|
|
41
|
+
updatedAt: z.number().finite(),
|
|
42
|
+
}).strict();
|
|
43
|
+
const envelopeSchema = z.object({
|
|
44
|
+
version: z.literal(DEFERRED_HOOK_ENVELOPE_VERSION),
|
|
45
|
+
eventId: nonEmpty,
|
|
46
|
+
triggerNames: z.array(nonEmpty).min(1),
|
|
47
|
+
hook: z.enum(["after_create", "after_update", "after_delete", "after_publish"]),
|
|
48
|
+
schema: nonEmpty,
|
|
49
|
+
entry: entrySchema,
|
|
50
|
+
ctxSnapshot: ctxSnapshotSchema.nullable(),
|
|
51
|
+
}).strict().superRefine((envelope, ctx) => {
|
|
52
|
+
if (new Set(envelope.triggerNames).size !== envelope.triggerNames.length) {
|
|
53
|
+
ctx.addIssue({
|
|
54
|
+
code: "custom",
|
|
55
|
+
path: ["triggerNames"],
|
|
56
|
+
message: "triggerNames must be unique",
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
if (envelope.entry.collection !== envelope.schema) {
|
|
60
|
+
ctx.addIssue({
|
|
61
|
+
code: "custom",
|
|
62
|
+
path: ["entry", "collection"],
|
|
63
|
+
message: "entry.collection must match schema",
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
});
|
|
1
67
|
/**
|
|
2
|
-
* Consume side of
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* Reconstructs a `HandlerContext` mirroring the original firing
|
|
8
|
-
* context's identity (user / staff snapshot from the envelope), with
|
|
9
|
-
* `env` filled by the consume invocation. `waitUntil` is intentionally
|
|
10
|
-
* absent — the consume invocation owns its own request lifetime, and
|
|
11
|
-
* chaining another fire-and-forget here would just reintroduce the
|
|
12
|
-
* durability gap the deferred path closes.
|
|
68
|
+
* Consume side of deferred lifecycle delivery. Queue bodies are
|
|
69
|
+
* untrusted: the versioned envelope is validated before any field is
|
|
70
|
+
* read, then the original identity snapshot is rebuilt with the
|
|
71
|
+
* consume invocation's fresh adapter bindings.
|
|
13
72
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* so the hook eventually succeeds or hits the dead-letter queue.
|
|
73
|
+
* Deferred failures intentionally escape. The Queue adapter converts
|
|
74
|
+
* a throw into retry/DLQ behavior; the already-committed entry
|
|
75
|
+
* mutation is unaffected.
|
|
18
76
|
*/
|
|
19
77
|
export class RunDeferredHookUseCase {
|
|
20
78
|
hooks;
|
|
@@ -22,24 +80,38 @@ export class RunDeferredHookUseCase {
|
|
|
22
80
|
this.hooks = hooks;
|
|
23
81
|
}
|
|
24
82
|
async execute(request) {
|
|
25
|
-
const
|
|
83
|
+
const envelope = parseEnvelope(request.envelope);
|
|
84
|
+
const snapshot = envelope.ctxSnapshot;
|
|
26
85
|
const ctx = {
|
|
27
|
-
user:
|
|
28
|
-
|
|
86
|
+
user: snapshot?.userId ? { id: snapshot.userId } : null,
|
|
87
|
+
staff: snapshot?.staffId && snapshot.staffRole
|
|
88
|
+
? { id: snapshot.staffId, role: snapshot.staffRole }
|
|
29
89
|
: null,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
: null,
|
|
33
|
-
auth: envelope.ctxSnapshot?.auth ?? undefined,
|
|
34
|
-
env,
|
|
90
|
+
...(snapshot?.auth ? { auth: snapshot.auth } : {}),
|
|
91
|
+
env: request.env,
|
|
35
92
|
};
|
|
36
93
|
await this.hooks.run({
|
|
94
|
+
eventId: envelope.eventId,
|
|
95
|
+
triggerNames: envelope.triggerNames,
|
|
96
|
+
delivery: "deferred",
|
|
37
97
|
hook: envelope.hook,
|
|
38
98
|
schema: envelope.schema,
|
|
39
99
|
entry: envelope.entry,
|
|
40
100
|
ctx,
|
|
41
|
-
originalInput: envelope.originalInput,
|
|
42
101
|
});
|
|
43
102
|
}
|
|
44
103
|
}
|
|
104
|
+
function parseEnvelope(value) {
|
|
105
|
+
const result = envelopeSchema.safeParse(value);
|
|
106
|
+
if (result.success)
|
|
107
|
+
return result.data;
|
|
108
|
+
const { instancePath, message } = firstZodIssueAsJsonPointer(result.error);
|
|
109
|
+
throw new DiagnosticError(runtimeDiagnostic({
|
|
110
|
+
code: "INPUT_VALIDATION_FAILED",
|
|
111
|
+
severity: "error",
|
|
112
|
+
path: `usecase/RunDeferredHook/envelope${instancePath}`,
|
|
113
|
+
expected: message,
|
|
114
|
+
message: `Deferred lifecycle envelope rejected at '${instancePath || "/"}': ${message}.`,
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
45
117
|
//# sourceMappingURL=RunDeferredHookUseCase.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RunDeferredHookUseCase.js","sourceRoot":"","sources":["../../../src/usecase/lifecycle/RunDeferredHookUseCase.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RunDeferredHookUseCase.js","sourceRoot":"","sources":["../../../src/usecase/lifecycle/RunDeferredHookUseCase.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,46 +3,35 @@ import type { EntryRow } from "../../domain/model/EntryRow.js";
|
|
|
3
3
|
import type { HandlerContext } from "../../domain/model/HandlerContext.js";
|
|
4
4
|
import type { TriggerIndex } from "../../domain/service/TriggerIndex.js";
|
|
5
5
|
import type { InvokeProcedureRequest, InvokeProcedureResponse } from "../dto/procedure/index.js";
|
|
6
|
-
/**
|
|
7
|
-
* Resolves matching Triggers via `TriggerIndex`, dispatches each
|
|
8
|
-
* to its target Procedure through the injected invoker (so input
|
|
9
|
-
* validation, auth, output validation all reuse the shared pipeline),
|
|
10
|
-
* and applies per-Trigger `errorPolicy`.
|
|
11
|
-
*
|
|
12
|
-
* The invoker is taken as a function rather than a concrete class so
|
|
13
|
-
* this use case does NOT import from a sibling under `usecase/` —
|
|
14
|
-
* `usecase → usecase` coupling would bypass the port boundary.
|
|
15
|
-
* Assembly root passes `(req) => invokeProcedure.execute(req)`.
|
|
16
|
-
*
|
|
17
|
-
* Defaults from the parser-locked grammar (POC ADR-0014):
|
|
18
|
-
* - before_*: errorPolicy default `abort` — handler failure throws
|
|
19
|
-
* a `DiagnosticError` and the chokepoint decorator cancels the
|
|
20
|
-
* mutation.
|
|
21
|
-
* - after_*: errorPolicy default `continue` — handler failure is
|
|
22
|
-
* logged via `console.error` and swallowed; the mutation already
|
|
23
|
-
* succeeded. Author override (`errorPolicy: continue` on a
|
|
24
|
-
* before_* hook) is honored.
|
|
25
|
-
*
|
|
26
|
-
* `Trigger.errorPolicy: 'abort'` on after_* is parser-rejected, so the
|
|
27
|
-
* use case never has to reconcile that combination.
|
|
28
|
-
*/
|
|
29
6
|
export type InvokeProcedureFn = (request: InvokeProcedureRequest) => Promise<InvokeProcedureResponse>;
|
|
30
7
|
export interface RunLifecycleHookRequest {
|
|
8
|
+
/** One event id is shared by every captured Trigger. */
|
|
9
|
+
readonly eventId: string;
|
|
10
|
+
/** Ordered Trigger names captured before dispatch. */
|
|
11
|
+
readonly triggerNames: readonly string[];
|
|
12
|
+
readonly delivery: "inline" | "deferred";
|
|
31
13
|
readonly hook: LifecycleHook;
|
|
32
14
|
readonly schema: string;
|
|
33
|
-
/** Pre-mutation row for `before_
|
|
34
|
-
*
|
|
15
|
+
/** Pre-mutation row for `before_*`; persisted row for `after_*`.
|
|
16
|
+
* `null` only on `before_create`. */
|
|
35
17
|
readonly entry: EntryRow | null;
|
|
36
18
|
readonly ctx: HandlerContext;
|
|
37
|
-
/** Pre-projection input
|
|
19
|
+
/** Pre-projection caller input. Used only by `before_*` hooks. */
|
|
38
20
|
readonly originalInput?: unknown;
|
|
39
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Runs one captured lifecycle event. Inline `continue` failures are
|
|
24
|
+
* logged and swallowed so the mutation result stands. Deferred runs
|
|
25
|
+
* still execute every captured Trigger, then throw an aggregate so
|
|
26
|
+
* the delivery adapter retries the event.
|
|
27
|
+
*/
|
|
40
28
|
export declare class RunLifecycleHooksUseCase {
|
|
41
29
|
private readonly triggers;
|
|
42
30
|
private readonly proceduresByName;
|
|
43
31
|
private readonly invoke;
|
|
44
32
|
constructor(triggers: TriggerIndex, proceduresByName: ReadonlyMap<string, ProcedureManifest>, invoke: InvokeProcedureFn);
|
|
45
33
|
run(request: RunLifecycleHookRequest): Promise<void>;
|
|
34
|
+
private resolveCapturedTriggers;
|
|
46
35
|
private runOne;
|
|
47
36
|
}
|
|
48
37
|
//# sourceMappingURL=RunLifecycleHooksUseCase.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RunLifecycleHooksUseCase.d.ts","sourceRoot":"","sources":["../../../src/usecase/lifecycle/RunLifecycleHooksUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAEvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAyB,MAAM,sCAAsC,CAAC;AAClG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,KAAK,EACV,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,2BAA2B,CAAC;AAEnC
|
|
1
|
+
{"version":3,"file":"RunLifecycleHooksUseCase.d.ts","sourceRoot":"","sources":["../../../src/usecase/lifecycle/RunLifecycleHooksUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAEvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAyB,MAAM,sCAAsC,CAAC;AAClG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,KAAK,EACV,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,MAAM,iBAAiB,GAAG,CAC9B,OAAO,EAAE,sBAAsB,KAC5B,OAAO,CAAC,uBAAuB,CAAC,CAAC;AAEtC,MAAM,WAAW,uBAAuB;IACtC,wDAAwD;IACxD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;0CACsC;IACtC,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;;;GAKG;AACH,qBAAa,wBAAwB;IAEjC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAFN,QAAQ,EAAE,YAAY,EACtB,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACxD,MAAM,EAAE,iBAAiB;IAGtC,GAAG,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgC1D,OAAO,CAAC,uBAAuB;YA0BjB,MAAM;CAqCrB"}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { DiagnosticError, runtimeDiagnostic, } from "@aotter/mantle-spec";
|
|
2
|
+
/**
|
|
3
|
+
* Runs one captured lifecycle event. Inline `continue` failures are
|
|
4
|
+
* logged and swallowed so the mutation result stands. Deferred runs
|
|
5
|
+
* still execute every captured Trigger, then throw an aggregate so
|
|
6
|
+
* the delivery adapter retries the event.
|
|
7
|
+
*/
|
|
2
8
|
export class RunLifecycleHooksUseCase {
|
|
3
9
|
triggers;
|
|
4
10
|
proceduresByName;
|
|
@@ -9,18 +15,55 @@ export class RunLifecycleHooksUseCase {
|
|
|
9
15
|
this.invoke = invoke;
|
|
10
16
|
}
|
|
11
17
|
async run(request) {
|
|
12
|
-
const matching = this.
|
|
13
|
-
if (matching.length === 0)
|
|
14
|
-
return;
|
|
18
|
+
const matching = this.resolveCapturedTriggers(request);
|
|
15
19
|
const isBefore = request.hook.startsWith("before_");
|
|
20
|
+
const failures = [];
|
|
16
21
|
for (const trigger of matching) {
|
|
17
|
-
|
|
22
|
+
try {
|
|
23
|
+
await this.runOne(trigger, request, isBefore);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (request.delivery === "deferred") {
|
|
27
|
+
failures.push(error);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (errorPolicy(trigger, isBefore) === "abort")
|
|
31
|
+
throw error;
|
|
32
|
+
console.error("[lifecycle] hook failed; continuing", {
|
|
33
|
+
eventId: request.eventId,
|
|
34
|
+
trigger: trigger.metadata.name,
|
|
35
|
+
hook: request.hook,
|
|
36
|
+
schema: request.schema,
|
|
37
|
+
error,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
18
40
|
}
|
|
41
|
+
if (failures.length > 0) {
|
|
42
|
+
throw new AggregateError(failures, `Deferred lifecycle event '${request.eventId}' failed in ${failures.length} Trigger(s).`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
resolveCapturedTriggers(request) {
|
|
46
|
+
const available = new Map(this.triggers
|
|
47
|
+
.forHook(request.schema, request.hook)
|
|
48
|
+
.map((trigger) => [trigger.metadata.name, trigger]));
|
|
49
|
+
return request.triggerNames.map((name) => {
|
|
50
|
+
const trigger = available.get(name);
|
|
51
|
+
if (!trigger) {
|
|
52
|
+
throw new DiagnosticError(runtimeDiagnostic({
|
|
53
|
+
code: "INPUT_VALIDATION_FAILED",
|
|
54
|
+
severity: "error",
|
|
55
|
+
path: `lifecycle:event/${request.eventId}/triggerNames`,
|
|
56
|
+
value: name,
|
|
57
|
+
expected: "name of a current Trigger for this schema and hook",
|
|
58
|
+
message: `Lifecycle event '${request.eventId}' references unavailable Trigger '${name}'.`,
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
return trigger;
|
|
62
|
+
});
|
|
19
63
|
}
|
|
20
64
|
async runOne(trigger, request, isBefore) {
|
|
21
65
|
const procedure = this.proceduresByName.get(trigger.spec.target.procedure);
|
|
22
66
|
if (!procedure) {
|
|
23
|
-
// Boot validator should have caught this; defense-in-depth.
|
|
24
67
|
throw new DiagnosticError(runtimeDiagnostic({
|
|
25
68
|
code: "TRIGGER_TARGET_PROCEDURE_UNKNOWN",
|
|
26
69
|
severity: "error",
|
|
@@ -31,37 +74,29 @@ export class RunLifecycleHooksUseCase {
|
|
|
31
74
|
}));
|
|
32
75
|
}
|
|
33
76
|
const event = {
|
|
77
|
+
id: request.eventId,
|
|
78
|
+
trigger: trigger.metadata.name,
|
|
34
79
|
hook: request.hook,
|
|
35
80
|
schema: request.schema,
|
|
36
81
|
entry: request.entry,
|
|
37
82
|
};
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
input,
|
|
49
|
-
ctx: ctxWithEvent,
|
|
50
|
-
pathPrefix: `lifecycle:Trigger/${trigger.metadata.name}->${procedure.metadata.name}`,
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
catch (err) {
|
|
54
|
-
if (policy === "abort")
|
|
55
|
-
throw err;
|
|
56
|
-
console.error(`[lifecycle] after_* hook ${trigger.metadata.name} threw`, err);
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
if (result.ok)
|
|
60
|
-
return;
|
|
61
|
-
if (policy === "abort") {
|
|
83
|
+
const input = isBefore
|
|
84
|
+
? request.originalInput ?? request.entry?.data ?? {}
|
|
85
|
+
: request.entry?.data ?? {};
|
|
86
|
+
const result = await this.invoke({
|
|
87
|
+
procedure,
|
|
88
|
+
input,
|
|
89
|
+
ctx: { ...request.ctx, event },
|
|
90
|
+
pathPrefix: `lifecycle:Trigger/${trigger.metadata.name}->${procedure.metadata.name}`,
|
|
91
|
+
});
|
|
92
|
+
if (!result.ok)
|
|
62
93
|
throw new DiagnosticError(result.diagnostic);
|
|
63
|
-
}
|
|
64
|
-
console.error(`[lifecycle] hook ${trigger.metadata.name} returned diagnostic`, result.diagnostic);
|
|
65
94
|
}
|
|
66
95
|
}
|
|
96
|
+
function errorPolicy(trigger, isBefore) {
|
|
97
|
+
const declared = trigger.spec.source.kind === "lifecycle"
|
|
98
|
+
? trigger.spec.source.errorPolicy
|
|
99
|
+
: undefined;
|
|
100
|
+
return declared ?? (isBefore ? "abort" : "continue");
|
|
101
|
+
}
|
|
67
102
|
//# sourceMappingURL=RunLifecycleHooksUseCase.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RunLifecycleHooksUseCase.js","sourceRoot":"","sources":["../../../src/usecase/lifecycle/RunLifecycleHooksUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,iBAAiB,GAIlB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"RunLifecycleHooksUseCase.js","sourceRoot":"","sources":["../../../src/usecase/lifecycle/RunLifecycleHooksUseCase.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,9 +20,9 @@ import type { InvokeBuiltinRequest } from "../dto/procedure/index.js";
|
|
|
20
20
|
* - `delete` → guarded `entries.delete(...)` over the loaded row snapshot.
|
|
21
21
|
*
|
|
22
22
|
* Pre-projection original input is forwarded to the chokepoint via
|
|
23
|
-
* `originalInput`, so
|
|
24
|
-
* fields (CAPTCHA tokens, etc.) declared on the Procedure input but
|
|
25
|
-
*
|
|
23
|
+
* `originalInput`, so synchronous `before_*` hooks can read side-channel
|
|
24
|
+
* fields (CAPTCHA tokens, etc.) declared on the Procedure input but not
|
|
25
|
+
* on the Schema.
|
|
26
26
|
*
|
|
27
27
|
* Auth + input/output validation happen upstream in
|
|
28
28
|
* `InvokeProcedureUseCase`. This use case trusts its `validatedInput`.
|
|
@@ -19,9 +19,9 @@ import { assertEntryWritable } from "../../domain/service/io/EntryWriteGuard.js"
|
|
|
19
19
|
* - `delete` → guarded `entries.delete(...)` over the loaded row snapshot.
|
|
20
20
|
*
|
|
21
21
|
* Pre-projection original input is forwarded to the chokepoint via
|
|
22
|
-
* `originalInput`, so
|
|
23
|
-
* fields (CAPTCHA tokens, etc.) declared on the Procedure input but
|
|
24
|
-
*
|
|
22
|
+
* `originalInput`, so synchronous `before_*` hooks can read side-channel
|
|
23
|
+
* fields (CAPTCHA tokens, etc.) declared on the Procedure input but not
|
|
24
|
+
* on the Schema.
|
|
25
25
|
*
|
|
26
26
|
* Auth + input/output validation happen upstream in
|
|
27
27
|
* `InvokeProcedureUseCase`. This use case trusts its `validatedInput`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Diagnostic } from "@aotter/mantle-spec";
|
|
1
|
+
import { type Diagnostic, type SchemaManifest } from "@aotter/mantle-spec";
|
|
2
2
|
import type { DatabaseDriver } from "../../domain/port/DatabaseDriver.js";
|
|
3
3
|
import type { ExecuteViewRequest } from "../dto/view/ExecuteViewRequest.js";
|
|
4
4
|
import type { InvokeProcedureResponse } from "../dto/procedure/index.js";
|
|
@@ -34,8 +34,9 @@ export type InvokeViewGuard = (request: {
|
|
|
34
34
|
export declare class ExecuteViewUseCase {
|
|
35
35
|
private readonly db;
|
|
36
36
|
private readonly invokeGuard?;
|
|
37
|
+
private readonly schemasByName;
|
|
37
38
|
private readonly paramsCache;
|
|
38
|
-
constructor(db: DatabaseDriver, invokeGuard?: InvokeViewGuard | undefined);
|
|
39
|
+
constructor(db: DatabaseDriver, invokeGuard?: InvokeViewGuard | undefined, schemasByName?: ReadonlyMap<string, SchemaManifest>);
|
|
39
40
|
execute<R = Record<string, unknown>>(request: ExecuteViewRequest): Promise<ExecuteViewResponse<R>>;
|
|
40
41
|
}
|
|
41
42
|
//# sourceMappingURL=ExecuteViewUseCase.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExecuteViewUseCase.d.ts","sourceRoot":"","sources":["../../../src/usecase/view/ExecuteViewUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"ExecuteViewUseCase.d.ts","sourceRoot":"","sources":["../../../src/usecase/view/ExecuteViewUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,UAAU,EACf,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAG1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAE3E;;;;;GAKG;AAEH,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC1D,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;4DAEwD;IACxD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,MAAM,mBAAmB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACvD;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,CAAA;CAAE,GAC1D;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAAC;AAE5D,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;AAEvC,qBAAa,kBAAkB;IAI3B,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAC7B,OAAO,CAAC,QAAQ,CAAC,aAAa;IALhC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8B;gBAGvC,EAAE,EAAE,cAAc,EAClB,WAAW,CAAC,EAAE,eAAe,YAAA,EAC7B,aAAa,GAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAa;IAG3E,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;CA4InC"}
|
|
@@ -4,10 +4,12 @@ import { compileView } from "../../domain/service/ViewSqlCompiler.js";
|
|
|
4
4
|
export class ExecuteViewUseCase {
|
|
5
5
|
db;
|
|
6
6
|
invokeGuard;
|
|
7
|
+
schemasByName;
|
|
7
8
|
paramsCache = new Map();
|
|
8
|
-
constructor(db, invokeGuard) {
|
|
9
|
+
constructor(db, invokeGuard, schemasByName = new Map()) {
|
|
9
10
|
this.db = db;
|
|
10
11
|
this.invokeGuard = invokeGuard;
|
|
12
|
+
this.schemasByName = schemasByName;
|
|
11
13
|
}
|
|
12
14
|
async execute(request) {
|
|
13
15
|
const viewPath = request.pathPrefix ?? `manifest:View/${request.view.metadata.name}`;
|
|
@@ -100,7 +102,7 @@ export class ExecuteViewUseCase {
|
|
|
100
102
|
compiled = compileView(request.view, {
|
|
101
103
|
...request.options,
|
|
102
104
|
params: validatedParams,
|
|
103
|
-
});
|
|
105
|
+
}, this.schemasByName.get(request.view.spec.from));
|
|
104
106
|
}
|
|
105
107
|
catch (err) {
|
|
106
108
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExecuteViewUseCase.js","sourceRoot":"","sources":["../../../src/usecase/view/ExecuteViewUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,eAAe,EACf,cAAc,EACd,eAAe,EACf,iBAAiB,
|
|
1
|
+
{"version":3,"file":"ExecuteViewUseCase.js","sourceRoot":"","sources":["../../../src/usecase/view/ExecuteViewUseCase.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aotter/mantle-runtime",
|
|
3
|
-
"version": "0.0.11-alpha.
|
|
3
|
+
"version": "0.0.11-alpha.61",
|
|
4
4
|
"description": "Runtime engine for mantle: dispatcher + entry-writer + view executor + content-ops + render pipeline + auth + MCP. Defines adapter-agnostic ports. MUST NOT import D1Database / KVNamespace types.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://mantle.tools/",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"README.md"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@aotter/mantle-spec": "0.0.11-alpha.
|
|
32
|
+
"@aotter/mantle-spec": "0.0.11-alpha.61"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"zod": "^4.0.0"
|