@aotter/mantle-cloudflare 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 +15 -0
- package/dist/bindings/D1DatabaseDriver.js +15 -1
- package/dist/bindings/D1DatabaseDriver.js.map +1 -1
- package/dist/bindings/WorkersQueueHookDispatcher.d.ts +8 -9
- package/dist/bindings/WorkersQueueHookDispatcher.d.ts.map +1 -1
- package/dist/bindings/WorkersQueueHookDispatcher.js +58 -23
- package/dist/bindings/WorkersQueueHookDispatcher.js.map +1 -1
- package/dist/mount/cmsConfig.d.ts +5 -4
- package/dist/mount/cmsConfig.d.ts.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -72,3 +72,18 @@ of the Core SDK skill contract or Day 1 landing path. Use the Cloudflare recipe
|
|
|
72
72
|
only when a site actually needs staff-managed images or files:
|
|
73
73
|
|
|
74
74
|
<https://raw.githubusercontent.com/aotter/mantle/develop/docs/media-uploads.md>
|
|
75
|
+
|
|
76
|
+
## Optional deferred lifecycle hooks
|
|
77
|
+
|
|
78
|
+
`WorkersQueueHookDispatcher` and `createQueueHandler` opt `after_*` lifecycle
|
|
79
|
+
Triggers into Cloudflare Queues. Delivery is at-least-once, not exactly-once;
|
|
80
|
+
the D1 write and Queue send are not atomic, and fallback through `waitUntil` is
|
|
81
|
+
best-effort. Handlers receive a stable `ctx.event.id` plus
|
|
82
|
+
`ctx.event.trigger` for idempotency. The adapter validates strict v1 JSON
|
|
83
|
+
envelopes, reserves metadata headroom under Cloudflare's 128 KB message limit,
|
|
84
|
+
and maps failures to per-message retry/DLQ behavior.
|
|
85
|
+
|
|
86
|
+
Producer/consumer bindings, Worker export, idempotent D1/upstream examples,
|
|
87
|
+
site-queue multiplexing, verification, and the legacy-envelope drain step are
|
|
88
|
+
in the shipped
|
|
89
|
+
[deferred lifecycle Queue guide](../../../docs/deferred-lifecycle-queues.md).
|
|
@@ -106,7 +106,21 @@ class D1Migrations {
|
|
|
106
106
|
ops.push(this.db
|
|
107
107
|
.prepare(`INSERT INTO _migrations (id, applied_at) VALUES (?, ?)`)
|
|
108
108
|
.bind(m.id, Date.now()));
|
|
109
|
-
|
|
109
|
+
try {
|
|
110
|
+
await this.db.batch(ops);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
// Two cold starts can read the same stale `seen` snapshot. The
|
|
114
|
+
// losing batch rolls back atomically; accept it only when the
|
|
115
|
+
// winner has recorded this exact migration in the meantime.
|
|
116
|
+
const winner = await this.db
|
|
117
|
+
.prepare(`SELECT id FROM _migrations WHERE id = ?`)
|
|
118
|
+
.bind(m.id)
|
|
119
|
+
.first();
|
|
120
|
+
if (winner?.id !== m.id)
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
seen.add(m.id);
|
|
110
124
|
}
|
|
111
125
|
}
|
|
112
126
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"D1DatabaseDriver.js","sourceRoot":"","sources":["../../src/bindings/D1DatabaseDriver.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"D1DatabaseDriver.js","sourceRoot":"","sources":["../../src/bindings/D1DatabaseDriver.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,10 +2,9 @@ import type { CmsRuntime, DeferredHookDispatcher, DeferredHookEnvelope } from "@
|
|
|
2
2
|
/**
|
|
3
3
|
* `DeferredHookDispatcher` impl backed by a Cloudflare Workers Queue
|
|
4
4
|
* binding. Producer side: serialises each `DeferredHookEnvelope` and
|
|
5
|
-
* sends it
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* caller decide.
|
|
5
|
+
* sends it explicitly as JSON. The runtime decorator handles a
|
|
6
|
+
* rejection with its best-effort fallback. Queue acceptance is not
|
|
7
|
+
* atomic with the preceding D1 mutation.
|
|
9
8
|
*
|
|
10
9
|
* Per ADR-0011 only this adapter package may import the CF binding
|
|
11
10
|
* type. The runtime sees only the `DeferredHookDispatcher` port.
|
|
@@ -17,7 +16,7 @@ export declare class WorkersQueueHookDispatcher implements DeferredHookDispatche
|
|
|
17
16
|
}
|
|
18
17
|
/**
|
|
19
18
|
* Build the `queue(batch, env, ctx)` Workers handler that consumes
|
|
20
|
-
* `
|
|
19
|
+
* `mantle-internal` messages and re-fires each `after_*` hook through
|
|
21
20
|
* the runtime. Consumers wire this alongside `fetch` in their default
|
|
22
21
|
* Worker export:
|
|
23
22
|
*
|
|
@@ -28,11 +27,11 @@ export declare class WorkersQueueHookDispatcher implements DeferredHookDispatche
|
|
|
28
27
|
* } satisfies ExportedHandler<Env>;
|
|
29
28
|
* ```
|
|
30
29
|
*
|
|
31
|
-
* Per-message ack / retry:
|
|
32
|
-
* message; success acks. CF Queues then
|
|
33
|
-
*
|
|
30
|
+
* Per-message ack / retry: any validation or handler failure retries
|
|
31
|
+
* the message; success acks. CF Queues then applies the consumer's
|
|
32
|
+
* retry delay, max_retries, and DLQ configuration.
|
|
34
33
|
*/
|
|
35
34
|
export declare function createQueueHandler<Env>(cmsRef: {
|
|
36
35
|
get(): Promise<CmsRuntime>;
|
|
37
|
-
}): (batch: MessageBatch<
|
|
36
|
+
}): (batch: MessageBatch<unknown>, env: Env) => Promise<void>;
|
|
38
37
|
//# sourceMappingURL=WorkersQueueHookDispatcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkersQueueHookDispatcher.d.ts","sourceRoot":"","sources":["../../src/bindings/WorkersQueueHookDispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"WorkersQueueHookDispatcher.d.ts","sourceRoot":"","sources":["../../src/bindings/WorkersQueueHookDispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAUhC;;;;;;;;;GASG;AACH,qBAAa,0BAA2B,YAAW,sBAAsB;IAC3D,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC;IAEzD,OAAO,CAAC,QAAQ,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;CAiC7D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EACpC,MAAM,EAAE;IAAE,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC,CAAA;CAAE,GACrC,CAAC,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAkC3D"}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// Cloudflare's 128 KB limit is decimal and includes roughly 100 bytes
|
|
3
|
+
// of platform metadata. Reserve a full 1 KB so accepted envelopes stay
|
|
4
|
+
// below the provider limit rather than failing only at queue.send.
|
|
5
|
+
const MAX_ENVELOPE_BYTES = 127_000;
|
|
6
|
+
const MAX_CONCURRENCY = 5;
|
|
7
|
+
const jsonValue = z.json();
|
|
1
8
|
/**
|
|
2
9
|
* `DeferredHookDispatcher` impl backed by a Cloudflare Workers Queue
|
|
3
10
|
* binding. Producer side: serialises each `DeferredHookEnvelope` and
|
|
4
|
-
* sends it
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* caller decide.
|
|
11
|
+
* sends it explicitly as JSON. The runtime decorator handles a
|
|
12
|
+
* rejection with its best-effort fallback. Queue acceptance is not
|
|
13
|
+
* atomic with the preceding D1 mutation.
|
|
8
14
|
*
|
|
9
15
|
* Per ADR-0011 only this adapter package may import the CF binding
|
|
10
16
|
* type. The runtime sees only the `DeferredHookDispatcher` port.
|
|
@@ -15,12 +21,36 @@ export class WorkersQueueHookDispatcher {
|
|
|
15
21
|
this.queue = queue;
|
|
16
22
|
}
|
|
17
23
|
async enqueue(envelope) {
|
|
18
|
-
|
|
24
|
+
// `EntryRow.locale?` may be present with value `undefined` in a
|
|
25
|
+
// repository object. JSON transport omits that optional field;
|
|
26
|
+
// normalize only this declared optional before the strict
|
|
27
|
+
// JSON-safe check so undefined values inside entry.data still
|
|
28
|
+
// fail instead of disappearing silently.
|
|
29
|
+
const { locale, ...entryWithoutLocale } = envelope.entry;
|
|
30
|
+
const wireEnvelope = locale === undefined
|
|
31
|
+
? { ...envelope, entry: entryWithoutLocale }
|
|
32
|
+
: envelope;
|
|
33
|
+
let json;
|
|
34
|
+
try {
|
|
35
|
+
json = jsonValue.safeParse(wireEnvelope);
|
|
36
|
+
}
|
|
37
|
+
catch (cause) {
|
|
38
|
+
throw new Error(`Deferred lifecycle envelope '${envelope.eventId}' is not JSON-safe.`, { cause });
|
|
39
|
+
}
|
|
40
|
+
if (!json.success) {
|
|
41
|
+
const issue = json.error.issues[0];
|
|
42
|
+
throw new Error(`Deferred lifecycle envelope '${envelope.eventId}' is not JSON-safe at '${issue?.path.join("/") ?? "unknown"}'.`);
|
|
43
|
+
}
|
|
44
|
+
const bytes = new TextEncoder().encode(JSON.stringify(json.data)).byteLength;
|
|
45
|
+
if (bytes >= MAX_ENVELOPE_BYTES) {
|
|
46
|
+
throw new Error(`Deferred lifecycle envelope '${envelope.eventId}' is ${bytes} bytes; this adapter requires less than ${MAX_ENVELOPE_BYTES} to leave room under Cloudflare's 128 KB message limit.`);
|
|
47
|
+
}
|
|
48
|
+
await this.queue.send(wireEnvelope, { contentType: "json" });
|
|
19
49
|
}
|
|
20
50
|
}
|
|
21
51
|
/**
|
|
22
52
|
* Build the `queue(batch, env, ctx)` Workers handler that consumes
|
|
23
|
-
* `
|
|
53
|
+
* `mantle-internal` messages and re-fires each `after_*` hook through
|
|
24
54
|
* the runtime. Consumers wire this alongside `fetch` in their default
|
|
25
55
|
* Worker export:
|
|
26
56
|
*
|
|
@@ -31,9 +61,9 @@ export class WorkersQueueHookDispatcher {
|
|
|
31
61
|
* } satisfies ExportedHandler<Env>;
|
|
32
62
|
* ```
|
|
33
63
|
*
|
|
34
|
-
* Per-message ack / retry:
|
|
35
|
-
* message; success acks. CF Queues then
|
|
36
|
-
*
|
|
64
|
+
* Per-message ack / retry: any validation or handler failure retries
|
|
65
|
+
* the message; success acks. CF Queues then applies the consumer's
|
|
66
|
+
* retry delay, max_retries, and DLQ configuration.
|
|
37
67
|
*/
|
|
38
68
|
export function createQueueHandler(cmsRef) {
|
|
39
69
|
return async (batch, env) => {
|
|
@@ -46,23 +76,28 @@ export function createQueueHandler(cmsRef) {
|
|
|
46
76
|
// batch.retryAll so each message's per-message attempt counter
|
|
47
77
|
// increments — letting wrangler's max_retries / DLQ rules
|
|
48
78
|
// engage instead of looping forever at the batch level.
|
|
49
|
-
console.error("[mantle-internal] runtime boot failed; retrying batch", err);
|
|
50
79
|
batch.retryAll();
|
|
80
|
+
console.error("[mantle-internal] runtime boot failed; retrying batch", err);
|
|
51
81
|
return;
|
|
52
82
|
}
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
83
|
+
// Bound fan-out even when a consumer raises max_batch_size.
|
|
84
|
+
for (let offset = 0; offset < batch.messages.length; offset += MAX_CONCURRENCY) {
|
|
85
|
+
const chunk = batch.messages.slice(offset, offset + MAX_CONCURRENCY);
|
|
86
|
+
await Promise.all(chunk.map(async (message) => {
|
|
87
|
+
try {
|
|
88
|
+
await cms.runDeferredHook.execute({ envelope: message.body, env });
|
|
89
|
+
message.ack();
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
message.retry();
|
|
93
|
+
console.error("[mantle-internal] deferred lifecycle consume failed; retrying", {
|
|
94
|
+
messageId: message.id,
|
|
95
|
+
attempts: message.attempts,
|
|
96
|
+
error: err,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
66
101
|
};
|
|
67
102
|
}
|
|
68
103
|
//# sourceMappingURL=WorkersQueueHookDispatcher.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkersQueueHookDispatcher.js","sourceRoot":"","sources":["../../src/bindings/WorkersQueueHookDispatcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WorkersQueueHookDispatcher.js","sourceRoot":"","sources":["../../src/bindings/WorkersQueueHookDispatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,10 +18,11 @@ export interface CmsConfig {
|
|
|
18
18
|
* `/admin/api/media/*` endpoints are registered. Forwarded to the
|
|
19
19
|
* runtime as `mediaStorage`. */
|
|
20
20
|
readonly mediaStorage?: CreateCmsRuntimeArgs["mediaStorage"];
|
|
21
|
-
/** Optional
|
|
22
|
-
* lifecycle hooks
|
|
23
|
-
* `ctx.waitUntil
|
|
24
|
-
*
|
|
21
|
+
/** Optional at-least-once dispatcher. When set, `after_*`
|
|
22
|
+
* lifecycle hooks enqueue after the entry write; a rejected send
|
|
23
|
+
* falls back to best-effort `ctx.waitUntil`/inline execution. The
|
|
24
|
+
* Cloudflare adapter expects a
|
|
25
|
+
* `WorkersQueueHookDispatcher` bound to the `mantle-internal` queue
|
|
25
26
|
* here. */
|
|
26
27
|
readonly deferredHookDispatcher?: CreateCmsRuntimeArgs["deferredHookDispatcher"];
|
|
27
28
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cmsConfig.d.ts","sourceRoot":"","sources":["../../src/mount/cmsConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAErE;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACrC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,oBAAoB,EAAE,IAAI,GAAG,IAAI,GAAG,QAAQ,CAAC,GAAG;QACtE;;yCAEiC;QACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAC;QAC7D
|
|
1
|
+
{"version":3,"file":"cmsConfig.d.ts","sourceRoot":"","sources":["../../src/mount/cmsConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAErE;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACrC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,oBAAoB,EAAE,IAAI,GAAG,IAAI,GAAG,QAAQ,CAAC,GAAG;QACtE;;yCAEiC;QACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAC;QAC7D;;;;;oBAKY;QACZ,QAAQ,CAAC,sBAAsB,CAAC,EAAE,oBAAoB,CAAC,wBAAwB,CAAC,CAAC;KAClF,CAAC;IACF,gEAAgE;IAChE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB;;yBAEqB;IACrB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,0BAA0B,CAAC;IACzD,sEAAsE;IACtE,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;KACrC,CAAC;CACH"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aotter/mantle-cloudflare",
|
|
3
|
-
"version": "0.0.11-alpha.
|
|
3
|
+
"version": "0.0.11-alpha.61",
|
|
4
4
|
"description": "Cloudflare Workers adapter for mantle. Hono-based mountServerEndpoints / createMcpApiHandler / mountAuthorize / mountPublicRoutes. Better Auth for staff sign-in; @cloudflare/workers-oauth-provider for the MCP OAuth AS surface.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://mantle.tools/",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@better-auth/oauth-provider": "^1.6.23",
|
|
33
|
-
"@aotter/mantle-admin-ui": "0.0.11-alpha.
|
|
34
|
-
"@aotter/mantle-runtime": "0.0.11-alpha.
|
|
35
|
-
"@aotter/mantle-spec": "0.0.11-alpha.
|
|
33
|
+
"@aotter/mantle-admin-ui": "0.0.11-alpha.61",
|
|
34
|
+
"@aotter/mantle-runtime": "0.0.11-alpha.61",
|
|
35
|
+
"@aotter/mantle-spec": "0.0.11-alpha.61"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@cloudflare/workers-oauth-provider": "^0.8.0",
|