@mooloo-ai/eutaxy 0.1.0 → 0.2.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/README.md +1 -1
- package/dist/aws.d.mts +15464 -0
- package/dist/aws.d.mts.map +1 -0
- package/dist/aws.mjs +24057 -0
- package/dist/aws.mjs.map +1 -0
- package/dist/bin.mjs +2 -2
- package/dist/checksum-DhS6ofSm.mjs +6049 -0
- package/dist/checksum-DhS6ofSm.mjs.map +1 -0
- package/dist/cli-DnPkIL8h.mjs +2 -0
- package/dist/cli.mjs +2 -2
- package/dist/cloudflare.d.mts +17 -1
- package/dist/cloudflare.d.mts.map +1 -1
- package/dist/cloudflare.mjs +41 -9
- package/dist/cloudflare.mjs.map +1 -1
- package/dist/es5-DtZuPEgt.mjs +1721 -0
- package/dist/es5-DtZuPEgt.mjs.map +1 -0
- package/dist/event-streams-BANyO9xt.mjs +801 -0
- package/dist/event-streams-BANyO9xt.mjs.map +1 -0
- package/dist/explore-C5fDFOoY.d.mts +63 -0
- package/dist/explore-C5fDFOoY.d.mts.map +1 -0
- package/dist/index.d.mts +2 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +4 -2
- package/dist/{explore-BB77_V0x.d.mts → platform-CGVkTa16.d.mts} +30 -65
- package/dist/platform-CGVkTa16.d.mts.map +1 -0
- package/dist/rolldown-runtime-C1I3wEg2.mjs +43 -0
- package/dist/{src-dP-0Apun.mjs → src-B66we2mG.mjs} +3 -2
- package/dist/{src-dP-0Apun.mjs.map → src-B66we2mG.mjs.map} +1 -1
- package/dist/{src-Bef00JwK.mjs → src-BP6Iqc_9.mjs} +3 -88
- package/dist/src-BP6Iqc_9.mjs.map +1 -0
- package/dist/{src-Dn3Lm5Us.mjs → src-BrCsF5RZ.mjs} +223 -28
- package/dist/src-BrCsF5RZ.mjs.map +1 -0
- package/dist/src-s6uYyC0B.mjs +89 -0
- package/dist/src-s6uYyC0B.mjs.map +1 -0
- package/dist/verdict-evEM5Gxx.mjs +12 -0
- package/dist/verdict-evEM5Gxx.mjs.map +1 -0
- package/package.json +20 -3
- package/dist/cli-DTuDOgGM.mjs +0 -2
- package/dist/explore-BB77_V0x.d.mts.map +0 -1
- package/dist/src-Bef00JwK.mjs.map +0 -1
- package/dist/src-Dn3Lm5Us.mjs.map +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { t as main } from "./src-
|
|
2
|
-
import "./cli-
|
|
1
|
+
export { t as main } from "./src-B66we2mG.mjs";
|
|
2
|
+
import "./cli-DnPkIL8h.mjs";
|
package/dist/cloudflare.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { E as JsonValue, _ as StateQuery, a as PlatformData, c as WorkerRef, d as AtMostOncePerKey, f as EffectSelector, g as RowCondition, h as Invariant, i as ExternalDecl, m as Implies, n as Platform, o as ScenarioSpec, p as EveryRow, r as Bounds, s as ScriptedResponse, u as AtLeastOnce } from "./platform-CGVkTa16.mjs";
|
|
2
|
+
import { c as Violated, o as ScenarioVerdict, t as ExploreOptions } from "./explore-C5fDFOoY.mjs";
|
|
2
3
|
interface CloudflareRegressionOptions {
|
|
3
4
|
/** Import path of the scenario module, relative to the emitted file. */
|
|
4
5
|
readonly scenarioPath: string;
|
|
@@ -119,6 +120,21 @@ export declare function everyRow(name: string, query: StateQuery, holds: readonl
|
|
|
119
120
|
export declare function implies(name: string, when: EffectSelector, key: string, state: StateQuery, column: string): Implies;
|
|
120
121
|
/** Selects the acknowledgement that took effect for each message (explicit or implicit; not one ignored after a retry). */
|
|
121
122
|
export declare function queueAck(queueName: string): EffectSelector;
|
|
123
|
+
/**
|
|
124
|
+
* Declare an external service: requests to `host` are answered from
|
|
125
|
+
* `responses` (every request gets 200 and an empty body when omitted), and
|
|
126
|
+
* `dedupeBy` names the header whose value makes repeated requests
|
|
127
|
+
* idempotent at that service.
|
|
128
|
+
*/
|
|
129
|
+
export declare function external(name: string, host: string, options?: {
|
|
130
|
+
readonly dedupeBy?: string;
|
|
131
|
+
readonly responses?: readonly ScriptedResponse[];
|
|
132
|
+
}): ExternalDecl;
|
|
133
|
+
/**
|
|
134
|
+
* Selects the requests to an external that took effect: a request replayed
|
|
135
|
+
* under a dedupe key the external had already seen is not counted.
|
|
136
|
+
*/
|
|
137
|
+
export declare function fetchCall(externalName: string, method?: string): EffectSelector;
|
|
122
138
|
/** Build and validate a scenario spec; throws with every problem listed. */
|
|
123
139
|
export declare function defineScenario(input: CloudflareScenarioInput): ScenarioSpec;
|
|
124
140
|
export type { CloudflarePlatformOptions, CloudflareRegressionOptions, CloudflareScenarioInput, D1Setup, DifferentialResult, QueueDrive, QueueHandler, QueueMessage };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare.d.mts","names":[],"sources":["../../cli/src/regression.ts","../../cloudflare/src/check.ts","../../cloudflare/src/d1.ts","../../cloudflare/src/platform.ts","../../cloudflare/src/differential.ts","../../cloudflare/src/scenario.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"cloudflare.d.mts","names":[],"sources":["../../cli/src/regression.ts","../../cloudflare/src/check.ts","../../cloudflare/src/d1.ts","../../cloudflare/src/platform.ts","../../cloudflare/src/differential.ts","../../cloudflare/src/scenario.ts"],"mappings":";;UAGiB;;WAEN;;WAEA;;WAEA,aAAa,SAAS;;WAEtB;WACA;WACA;;;wBAIK,yBACd,SAAS,UACT,SAAS;;wBCVK,MACd,MAAM,cACN,UAAU,UACV,UAAS,iBACR,QAAQ;;wBAKW,YACpB,MAAM,cACN,UAAU,UACV,UAAU,iBACT;;wBCiOmB,WACpB,MAAM,aACL;YAAoB,yBAAyB;;UClO/B;EACf,OAAO,OAAO,uBAAuB,cAAc,KAAK,0BAA0B;;UAGnE;;WAEN;;WAEA,SAAS;;WAET,SAAS,SAAS;;WAElB;;wBAoCK,yBAAyB,SAAS,4BAA4B;UC1C7D;WACN;WACA;WACA;WACA;;UAGM;WACN,mBAAmB;WACnB;cACG;gBAA8B,yBAAyB;;;;UAIpD;;WAEN;WACA,QAAQ;WACR,KAAK;WACL;;WAEA;;;wBAkPW,gBACpB,MAAM,cACN,SAAS,4BACR,QAAQ;;UC1QM;WACN;WACA,MAAM;;;UAIA,mBAAmB;WACzB;WACA;WACA;aAA8B;aAAqB,MAAM;;;;UAInD,gBAAgB;WACtB;WACA;WACA;;UAGM;WACN;WACA,QAAQ;WACR,OACL;aAEW;aACA;aACA,mBAAmB;;WAEzB,iBAAiB;WACjB,qBAAqB;WACrB,qBAAqB;WACrB,SAAS,QAAQ;;wBAGZ,MAAM,cAAc,mBAAmB,iBAAiB;wBAQxD,SAAS,iBAAiB,qBAAqB;;;;;;;wBAU/C,QAAQ,iBAAiB,uBAA8B;;wBAKvD,QAAQ;wBAIR,iBACd,cACA,QAAQ,gBACR,cACC;wBAIa,YACd,cACA,QAAQ,gBACR,aACA,mBAAmB,cAClB;;;;;wBAQa,sBACd,cACA,OAAO,YACP,QAAQ,gBACR,aACA,kBACC;;wBAaa,OACd,iBACA,eACA,iBAAiB,iBAChB;;wBAKa,SACd,cACA,OAAO,YACP,gBAAgB,iBACf;;wBAKa,QACd,cACA,MAAM,gBACN,aACA,OAAO,YACP,iBACC;;wBAKa,SAAS,oBAAoB;;;;;;;wBAe7B,SACd,cACA,cACA;WAAoB;WAA4B,qBAAqB;IACpE;;;;;wBAaa,UAAU,sBAAsB,kBAAkB;;wBAUlD,eAAe,OAAO,0BAA0B"}
|
package/dist/cloudflare.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as Run,
|
|
3
|
-
import {
|
|
1
|
+
import { i as canonicalJson } from "./src-s6uYyC0B.mjs";
|
|
2
|
+
import { a as Run, d as validateScenario, i as CrashSignal, l as settleOn, m as getPath, o as installScriptedFetch, s as patchGlobals, t as explore, u as defaultBounds } from "./src-BrCsF5RZ.mjs";
|
|
3
|
+
import { t as describeVerdict } from "./verdict-evEM5Gxx.mjs";
|
|
4
|
+
import { n as cloudflareRegressionTest } from "./src-B66we2mG.mjs";
|
|
4
5
|
// packages/cloudflare/src/check.ts
|
|
5
6
|
/** Explore a scenario on a platform and return its verdict. */
|
|
6
7
|
function check(spec, platform, options = { seed: spec.name }) {
|
|
@@ -452,8 +453,8 @@ function createCloudflarePlatform(options) {
|
|
|
452
453
|
/** The raw side cannot abandon an invocation the way the engine does; a stuck handler ends the comparison. */
|
|
453
454
|
var StuckError = class extends Error {
|
|
454
455
|
name = "StuckError";
|
|
455
|
-
constructor() {
|
|
456
|
-
super(
|
|
456
|
+
constructor(message = "the handler is waiting on something outside the run (no timer due, no effect in flight)") {
|
|
457
|
+
super(message);
|
|
457
458
|
}
|
|
458
459
|
};
|
|
459
460
|
/**
|
|
@@ -517,9 +518,9 @@ async function eutaxySide(spec, options) {
|
|
|
517
518
|
faultProbability: 0
|
|
518
519
|
});
|
|
519
520
|
const attempts = [];
|
|
520
|
-
|
|
521
|
+
await platform.reset(spec);
|
|
522
|
+
run.install(spec.externals);
|
|
521
523
|
try {
|
|
522
|
-
await platform.reset(spec);
|
|
523
524
|
const pending = [...platform.initialEvents(spec)];
|
|
524
525
|
while (pending.length > 0) {
|
|
525
526
|
const event = pending.shift();
|
|
@@ -535,10 +536,10 @@ async function eutaxySide(spec, options) {
|
|
|
535
536
|
});
|
|
536
537
|
pending.push(...result.followUps);
|
|
537
538
|
}
|
|
538
|
-
await platform.finish?.(spec, run);
|
|
539
539
|
} finally {
|
|
540
540
|
run.uninstall();
|
|
541
541
|
}
|
|
542
|
+
await platform.finish?.(spec, run);
|
|
542
543
|
return {
|
|
543
544
|
attempts,
|
|
544
545
|
state: await snapshotAll(spec, options),
|
|
@@ -566,6 +567,8 @@ async function rawSide(spec, options) {
|
|
|
566
567
|
data: m.body
|
|
567
568
|
}));
|
|
568
569
|
const patched = patchGlobals(0);
|
|
570
|
+
const unsupported = [];
|
|
571
|
+
const restoreFetch = installScriptedFetch(spec.externals, null, (r) => unsupported.push(r), () => patched.clock.advance(1));
|
|
569
572
|
const io = { n: 0 };
|
|
570
573
|
const counting = /* @__PURE__ */ new Map();
|
|
571
574
|
const countedEnv = new Proxy(env, { get(target, prop, receiver) {
|
|
@@ -642,8 +645,10 @@ async function rawSide(spec, options) {
|
|
|
642
645
|
});
|
|
643
646
|
}
|
|
644
647
|
} finally {
|
|
648
|
+
restoreFetch();
|
|
645
649
|
patched.restore();
|
|
646
650
|
}
|
|
651
|
+
if (unsupported.length > 0) throw new StuckError(`raw side: ${unsupported.join("; ")}`);
|
|
647
652
|
return {
|
|
648
653
|
attempts,
|
|
649
654
|
state: await snapshotAll(spec, options)
|
|
@@ -790,12 +795,39 @@ function queueAck(queueName) {
|
|
|
790
795
|
where: { "result.effective": true }
|
|
791
796
|
};
|
|
792
797
|
}
|
|
798
|
+
/**
|
|
799
|
+
* Declare an external service: requests to `host` are answered from
|
|
800
|
+
* `responses` (every request gets 200 and an empty body when omitted), and
|
|
801
|
+
* `dedupeBy` names the header whose value makes repeated requests
|
|
802
|
+
* idempotent at that service.
|
|
803
|
+
*/
|
|
804
|
+
function external(name, host, options = {}) {
|
|
805
|
+
return {
|
|
806
|
+
name,
|
|
807
|
+
host,
|
|
808
|
+
guarantees: options.dedupeBy ? { dedupeBy: options.dedupeBy } : {},
|
|
809
|
+
...options.responses ? { responses: options.responses } : {}
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Selects the requests to an external that took effect: a request replayed
|
|
814
|
+
* under a dedupe key the external had already seen is not counted.
|
|
815
|
+
*/
|
|
816
|
+
function fetchCall(externalName, method) {
|
|
817
|
+
return {
|
|
818
|
+
target: `Fetch:${externalName}`,
|
|
819
|
+
...method ? { op: method.toUpperCase() } : {},
|
|
820
|
+
kind: "result",
|
|
821
|
+
where: { "result.effective": true }
|
|
822
|
+
};
|
|
823
|
+
}
|
|
793
824
|
/** Build and validate a scenario spec; throws with every problem listed. */
|
|
794
825
|
function defineScenario(input) {
|
|
795
826
|
const drive = "messages" in input.drive && input.drive.messages.every((m) => "id" in m && typeof m.id === "string") ? input.drive : queue(input.drive.queue, input.drive.messages);
|
|
796
827
|
const spec = {
|
|
797
828
|
version: 1,
|
|
798
829
|
name: input.name,
|
|
830
|
+
platform: "cloudflare",
|
|
799
831
|
worker: input.worker,
|
|
800
832
|
drive,
|
|
801
833
|
setup: input.setup ?? [],
|
|
@@ -810,6 +842,6 @@ function defineScenario(input) {
|
|
|
810
842
|
if (errors.length > 0) throw new Error(`invalid scenario ${JSON.stringify(input.name)}:\n- ${errors.join("\n- ")}`);
|
|
811
843
|
return spec;
|
|
812
844
|
}
|
|
813
|
-
export { atLeastOnce, atLeastOncePerMessage, atMostOncePerKey, check, cloudflareRegressionTest, createCloudflarePlatform, d1Param, d1Rows, d1Schema, d1Write, defineScenario, everyRow, expectHolds, implies, queue, queueAck, runDifferential, snapshotD1 };
|
|
845
|
+
export { atLeastOnce, atLeastOncePerMessage, atMostOncePerKey, check, cloudflareRegressionTest, createCloudflarePlatform, d1Param, d1Rows, d1Schema, d1Write, defineScenario, everyRow, expectHolds, external, fetchCall, implies, queue, queueAck, runDifferential, snapshotD1 };
|
|
814
846
|
|
|
815
847
|
//# sourceMappingURL=cloudflare.mjs.map
|
package/dist/cloudflare.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare.mjs","names":["isD1"],"sources":["../../cloudflare/src/check.ts","../../cloudflare/src/json.ts","../../cloudflare/src/d1.ts","../../cloudflare/src/platform.ts","../../cloudflare/src/differential.ts","../../cloudflare/src/scenario.ts"],"sourcesContent":["import {\n describeVerdict,\n type Platform,\n type ScenarioSpec,\n type ScenarioVerdict,\n} from \"@eutaxy/core\";\nimport { type ExploreOptions, explore } from \"@eutaxy/engine\";\n\n/** Explore a scenario on a platform and return its verdict. */\nexport function check(\n spec: ScenarioSpec,\n platform: Platform,\n options: ExploreOptions = { seed: spec.name },\n): Promise<ScenarioVerdict> {\n return explore(spec, platform, options);\n}\n\n/** For use from a test: passes only when the scenario is BOUNDED. */\nexport async function expectHolds(\n spec: ScenarioSpec,\n platform: Platform,\n options?: ExploreOptions,\n): Promise<void> {\n const verdict = await check(spec, platform, options);\n if (verdict.kind !== \"BOUNDED\") throw new Error(describeVerdict(verdict));\n}\n","import type { JsonValue } from \"@eutaxy/core\";\n\n/** Reduce any runtime value to JSON data for the effect log; never throws. */\nexport function toJson(value: unknown, depth = 0): JsonValue {\n if (value === null || value === undefined) return null;\n switch (typeof value) {\n case \"boolean\":\n case \"string\":\n return value;\n case \"number\":\n return Number.isFinite(value) ? value : String(value);\n case \"bigint\":\n return value.toString();\n case \"object\": {\n if (depth > 8) return \"<nested>\";\n if (Array.isArray(value)) return value.map((v) => toJson(v, depth + 1));\n if (value instanceof ArrayBuffer) return `<bytes ${value.byteLength}>`;\n if (ArrayBuffer.isView(value)) return `<bytes ${value.byteLength}>`;\n if (value instanceof Date) return value.toISOString();\n const out: Record<string, JsonValue> = {};\n for (const k of Object.keys(value).sort()) {\n out[k] = toJson((value as Record<string, unknown>)[k], depth + 1);\n }\n return out;\n }\n default:\n return `<${typeof value}>`;\n }\n}\n","/**\n * The D1 binding proxy. Every statement execution is an effect point: the\n * engine decides the fault, the real Miniflare-backed D1 performs the query,\n * and the log records call, result and fault in the documented shape.\n */\n\nimport {\n canonicalJson,\n type EffectPoint,\n type FaultKind,\n type JsonValue,\n type RunHooks,\n} from \"@eutaxy/core\";\nimport { toJson } from \"./json.ts\";\n\nconst WRITE: readonly FaultKind[] = [\"crash_before\", \"crash_after\", \"ambiguous\", \"error\"];\nconst READ: readonly FaultKind[] = [\"crash_before\", \"crash_after\", \"error\"];\n\nexport interface ProxyContext {\n readonly hooks: RunHooks;\n /** The invocation currently running; one at a time for now. */\n readonly currentInvocation: () => string;\n}\n\nfunction point(\n ctx: ProxyContext,\n target: string,\n op: string,\n args: JsonValue,\n allowed: readonly FaultKind[],\n): EffectPoint {\n return { invocation: ctx.currentInvocation(), target, op, args, allowed };\n}\n\nfunction metaOf(result: D1Result<unknown>): JsonValue {\n return { changes: result.meta.changes ?? 0, lastRowId: result.meta.last_row_id ?? null };\n}\n\nclass StatementProxy {\n private readonly real: D1PreparedStatement;\n private readonly target: string;\n private readonly ctx: ProxyContext;\n readonly sql: string;\n readonly params: readonly unknown[];\n\n constructor(\n real: D1PreparedStatement,\n target: string,\n ctx: ProxyContext,\n sql: string,\n params: readonly unknown[],\n ) {\n this.real = real;\n this.target = target;\n this.ctx = ctx;\n this.sql = sql;\n this.params = params;\n }\n\n /** The real statement, for `batch()`. */\n get statement(): D1PreparedStatement {\n return this.real;\n }\n\n private args(): JsonValue {\n return { sql: this.sql, params: toJson(this.params) };\n }\n\n bind(...values: unknown[]): StatementProxy {\n return new StatementProxy(this.real.bind(...values), this.target, this.ctx, this.sql, values);\n }\n\n run<T = Record<string, unknown>>(): Promise<D1Result<T>> {\n return this.ctx.hooks.effect(\n point(this.ctx, this.target, \"run\", this.args(), WRITE),\n () => this.real.run<T>(),\n (r) => metaOf(r),\n );\n }\n\n all<T = Record<string, unknown>>(): Promise<D1Result<T>> {\n return this.ctx.hooks.effect(\n point(this.ctx, this.target, \"all\", this.args(), READ),\n () => this.real.all<T>(),\n (r) => ({ rows: r.results.length, changes: r.meta.changes ?? 0 }),\n );\n }\n\n first<T = unknown>(colName?: string): Promise<T | null> {\n return this.ctx.hooks.effect(\n point(\n this.ctx,\n this.target,\n \"first\",\n { ...(this.args() as object), column: colName ?? null } as JsonValue,\n READ,\n ),\n () => (colName === undefined ? this.real.first<T>() : this.real.first<T>(colName)),\n (r) => ({ row: toJson(r) }),\n );\n }\n\n raw<T = unknown[]>(options?: { columnNames?: boolean }): Promise<T[]> {\n return this.ctx.hooks.effect(\n point(this.ctx, this.target, \"raw\", this.args(), READ),\n () =>\n (options\n ? this.real.raw<T>(options as { columnNames: true })\n : this.real.raw<T>()) as Promise<T[]>,\n (r) => ({ rows: r.length }),\n );\n }\n}\n\n/** Wrap a D1 binding. Methods not modelled fall through to the real binding and mark the run unsupported. */\nexport function proxyD1(real: D1Database, binding: string, ctx: ProxyContext): D1Database {\n const target = `D1:${binding}`;\n const modelled = {\n prepare(sql: string): StatementProxy {\n return new StatementProxy(real.prepare(sql), target, ctx, sql, []);\n },\n batch<T = Record<string, unknown>>(\n statements: readonly (StatementProxy | D1PreparedStatement)[],\n ): Promise<D1Result<T>[]> {\n const unwrapped = statements.map((s) => (s instanceof StatementProxy ? s.statement : s));\n const args = {\n statements: statements.map((s) =>\n s instanceof StatementProxy\n ? { sql: s.sql, params: toJson(s.params) }\n : \"<unproxied statement>\",\n ),\n };\n return ctx.hooks.effect(\n point(ctx, target, \"batch\", args, WRITE),\n () => real.batch<T>(unwrapped as D1PreparedStatement[]),\n (rs) => ({\n changes: rs.reduce((n, r) => n + (r.meta.changes ?? 0), 0),\n statements: rs.length,\n }),\n );\n },\n exec(sql: string): Promise<D1ExecResult> {\n return ctx.hooks.effect(\n point(ctx, target, \"exec\", { sql }, WRITE),\n () => real.exec(sql),\n (r) => ({ count: r.count, duration: 0 }),\n );\n },\n };\n return new Proxy(real, {\n get(obj, prop, receiver) {\n if (prop in modelled) return modelled[prop as keyof typeof modelled];\n const value = Reflect.get(obj, prop, receiver) as unknown;\n if (typeof value === \"function\") {\n ctx.hooks.unsupported(`D1 ${binding}.${String(prop)} is not modelled`);\n return (value as (...a: unknown[]) => unknown).bind(obj);\n }\n return value;\n },\n }) as D1Database;\n}\n\n/**\n * Statements in a schema file. Splits on semicolons outside string literals,\n * quoted identifiers and comments, and keeps CREATE TRIGGER bodies (and CASE\n * expressions) whole by tracking BEGIN/CASE ... END nesting.\n */\nexport function splitSql(sql: string): readonly string[] {\n const out: string[] = [];\n let cur = \"\";\n let depth = 0;\n let i = 0;\n const isWordChar = (c: string | undefined): boolean => c !== undefined && /[A-Za-z0-9_]/.test(c);\n while (i < sql.length) {\n const c = sql[i] as string;\n const next = sql[i + 1];\n if (c === \"-\" && next === \"-\") {\n while (i < sql.length && sql[i] !== \"\\n\") i++;\n continue;\n }\n if (c === \"/\" && next === \"*\") {\n const end = sql.indexOf(\"*/\", i + 2);\n i = end === -1 ? sql.length : end + 2;\n continue;\n }\n if (c === \"'\" || c === '\"' || c === \"`\" || c === \"[\") {\n const close = c === \"[\" ? \"]\" : c;\n let j = i + 1;\n for (;;) {\n const k = sql.indexOf(close, j);\n if (k === -1) {\n j = sql.length;\n break;\n }\n if (close !== \"]\" && sql[k + 1] === close) {\n j = k + 2; // a doubled quote inside the literal\n continue;\n }\n j = k + 1;\n break;\n }\n cur += sql.slice(i, j);\n i = j;\n continue;\n }\n if (isWordChar(c) && !isWordChar(sql[i - 1])) {\n let j = i;\n while (isWordChar(sql[j])) j++;\n const word = sql.slice(i, j);\n const upper = word.toUpperCase();\n if (upper === \"BEGIN\" || upper === \"CASE\") depth++;\n else if (upper === \"END\" && depth > 0) depth--;\n cur += word;\n i = j;\n continue;\n }\n if (c === \";\" && depth === 0) {\n const statement = cur.trim();\n if (statement.length > 0) out.push(statement);\n cur = \"\";\n i++;\n continue;\n }\n cur += c;\n i++;\n }\n const last = cur.trim();\n if (last.length > 0) out.push(last);\n return out;\n}\n\n/** Drop every user table and re-apply the schema, using the real binding (not an effect). */\nexport async function resetD1(real: D1Database, schema: string): Promise<void> {\n const tables = await real\n .prepare(\n \"SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '\\\\_cf\\\\_%' ESCAPE '\\\\'\",\n )\n .all<{ name: string }>();\n for (const { name } of tables.results) {\n await real.prepare(`DROP TABLE IF EXISTS \"${name.replace(/\"/g, '\"\"')}\"`).run();\n }\n for (const statement of splitSql(schema)) {\n await real.prepare(statement).run();\n }\n}\n\n/** Every user table's rows, sorted canonically, read through the real binding (not an effect). */\nexport async function snapshotD1(\n real: D1Database,\n): Promise<{ readonly [table: string]: readonly JsonValue[] }> {\n const tables = await real\n .prepare(\n \"SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '\\\\_cf\\\\_%' ESCAPE '\\\\' ORDER BY name\",\n )\n .all<{ name: string }>();\n const out: Record<string, JsonValue[]> = {};\n for (const { name } of tables.results) {\n const rows = await real\n .prepare(`SELECT * FROM \"${name.replace(/\"/g, '\"\"')}\"`)\n .all<Record<string, unknown>>();\n out[name] = rows.results\n .map((r) => toJson(r))\n .map((j) => [canonicalJson(j), j] as const)\n .sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))\n .map(([, j]) => j);\n }\n return out;\n}\n","/**\n * The Cloudflare platform: delivers queue messages to the Worker's `queue()`\n * handler with proxied bindings and proxied messages, and applies Queues'\n * at-least-once semantics (explicit and implicit ack, retry, redelivery up\n * to max_retries, dead-lettering) as documented by Cloudflare.\n */\n\nimport type {\n DeliveryResult,\n EventRef,\n FaultKind,\n JsonValue,\n Platform,\n RunHooks,\n ScenarioSpec,\n} from \"@eutaxy/core\";\nimport { CrashSignal } from \"@eutaxy/engine\";\nimport { type ProxyContext, proxyD1, resetD1, snapshotD1 } from \"./d1.ts\";\nimport type { QueueDrive } from \"./scenario.ts\";\n\nconst ACK: readonly FaultKind[] = [\"crash_before\", \"crash_after\"];\nconst CUT_OFF: readonly FaultKind[] = [\"cut_off\"];\n\nexport interface QueueHandler {\n queue?(batch: MessageBatch<unknown>, env: unknown, ctx: ExecutionContext): void | Promise<void>;\n}\n\nexport interface CloudflarePlatformOptions {\n /** The bindings from `cloudflare:workers`. */\n readonly env: object;\n /** The Worker's default export. */\n readonly handler: QueueHandler;\n /** Schema SQL per D1 binding named in the scenario's setup. */\n readonly schemas: Readonly<Record<string, string>>;\n /** Cloudflare's default when the consumer does not set max_retries. */\n readonly maxRetries?: number;\n}\n\nfunction isD1(value: unknown): value is D1Database {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { prepare?: unknown }).prepare === \"function\" &&\n typeof (value as { batch?: unknown }).batch === \"function\"\n );\n}\n\nfunction isBindingLike(value: unknown): boolean {\n if (typeof value === \"function\") return true;\n if (typeof value !== \"object\" || value === null) return false;\n const proto = Object.getPrototypeOf(value) as object | null;\n const names = [...Object.getOwnPropertyNames(value), ...Object.getOwnPropertyNames(proto ?? {})];\n return names.some(\n (k) => k !== \"constructor\" && typeof (value as Record<string, unknown>)[k] === \"function\",\n );\n}\n\n/** Deep-copy JSON data so a handler that mutates its message cannot leak into other runs. */\nfunction cloneJson(value: JsonValue): JsonValue {\n return JSON.parse(JSON.stringify(value)) as JsonValue;\n}\n\nconst assumptions: readonly string[] = [\n \"platform model: Cloudflare Queues at-least-once delivery; the first ack or retry decision per message wins; unacked messages are redelivered up to max_retries then dead-lettered\",\n \"D1 statements run against Miniflare's SQLite; each run/first/all/raw/batch/exec is one effect\",\n \"message.timestamp is the virtual clock's time at delivery\",\n \"only D1 bindings are proxied; touching any other binding makes the run UNSUPPORTED\",\n \"state invariants read a snapshot of every D1 binding named in setup, taken after the last event\",\n \"work passed to ctx.waitUntil runs after the handler returns and never affects acknowledgement; a cut_off fault at that point loses work not yet started, and an effect in flight commits without its continuation\",\n];\n\nexport function createCloudflarePlatform(options: CloudflarePlatformOptions): Platform {\n const env = options.env as Record<string, unknown>;\n const maxRetries = options.maxRetries ?? 3;\n let currentInvocation = \"\";\n let hooksRef: RunHooks | null = null;\n\n const ctx: ProxyContext = {\n get hooks() {\n if (!hooksRef) throw new Error(\"no run in progress\");\n return hooksRef;\n },\n currentInvocation: () => currentInvocation,\n };\n\n const d1Proxies = new Map<string, D1Database>();\n const proxiedEnv = new Proxy(env, {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver) as unknown;\n if (typeof prop !== \"string\") return value;\n if (isD1(value)) {\n let p = d1Proxies.get(prop);\n if (!p) {\n p = proxyD1(value, prop, ctx);\n d1Proxies.set(prop, p);\n }\n return p;\n }\n if (isBindingLike(value)) ctx.hooks.unsupported(`binding ${prop} is not proxied`);\n return value;\n },\n });\n\n /** Platform-level actions (dead-lettering) are recorded under an invocation no fault can crash. */\n const platformInvocations = new WeakMap<RunHooks, string>();\n function platformInvocation(hooks: RunHooks): string {\n let id = platformInvocations.get(hooks);\n if (id === undefined) {\n id = \"platform\";\n hooks.startInvocation(id);\n platformInvocations.set(hooks, id);\n }\n return id;\n }\n\n return {\n name: \"cloudflare\",\n assumptions,\n\n async reset(spec: ScenarioSpec): Promise<void> {\n for (const step of spec.setup) {\n if (step.kind !== \"d1\") continue;\n const binding = String(step[\"binding\"]);\n const schema = options.schemas[binding];\n if (schema === undefined) throw new Error(`no schema provided for D1 binding ${binding}`);\n const real = env[binding];\n if (!isD1(real)) throw new Error(`env.${binding} is not a D1 binding`);\n await resetD1(real, schema);\n }\n },\n\n restrictEvents(spec: ScenarioSpec, keepIds: readonly string[]): ScenarioSpec {\n const drive = spec.drive as QueueDrive;\n return {\n ...spec,\n drive: { ...drive, messages: drive.messages.filter((m) => keepIds.includes(m.id)) },\n };\n },\n\n async finish(spec: ScenarioSpec, hooks: RunHooks): Promise<void> {\n for (const step of spec.setup) {\n if (step.kind !== \"d1\") continue;\n const binding = String(step[\"binding\"]);\n const real = env[binding];\n if (!isD1(real)) continue;\n const tables = await snapshotD1(real);\n hooks.snapshot(platformInvocation(hooks), `D1:${binding}`, { tables });\n }\n },\n\n initialEvents(spec: ScenarioSpec): readonly EventRef[] {\n const drive = spec.drive as QueueDrive;\n if (drive.kind !== \"queue\") {\n throw new Error(`drive ${drive.kind} is not supported by the Cloudflare platform yet`);\n }\n return drive.messages.map((m) => ({ id: m.id, attempt: 1, data: m.body }));\n },\n\n async deliver(event: EventRef, hooks: RunHooks, spec: ScenarioSpec): Promise<DeliveryResult> {\n const drive = spec.drive as QueueDrive;\n const queueTarget = `Queue:${drive.queue}`;\n const invocation = `${event.id}#${event.attempt}`;\n hooksRef = hooks;\n currentInvocation = invocation;\n const inv = hooks.startInvocation(invocation);\n /** Cloudflare honours the first ack or retry decision per message; later ones are ignored. */\n const state: { decision: \"ack\" | \"retry\" | null } = { decision: null };\n const background: Promise<unknown>[] = [];\n\n /** Records the call; the result says whether it took effect (the first decision wins). */\n const decide = (op: \"ack\" | \"retry\", args: JsonValue): void => {\n hooks.effectSync(\n { invocation, target: queueTarget, op, args, allowed: ACK },\n () => {\n if (state.decision !== null) return false;\n state.decision = op;\n return true;\n },\n (effective) => ({ effective }),\n );\n };\n const message: Message<unknown> = {\n id: event.id,\n timestamp: new Date(),\n body: cloneJson(event.data),\n attempts: event.attempt,\n ack: () => decide(\"ack\", { messageId: event.id, implicit: false, body: event.data }),\n retry: () => decide(\"retry\", { messageId: event.id, body: event.data }),\n };\n const batch: MessageBatch<unknown> = {\n queue: drive.queue,\n messages: [message],\n metadata: { metrics: { backlogCount: 0, backlogBytes: 0 } },\n ackAll: () => message.ack(),\n retryAll: () => message.retry(),\n };\n const execution: ExecutionContext = {\n waitUntil: (promise: Promise<unknown>) => {\n background.push(\n promise.then(\n () => undefined,\n () => undefined,\n ),\n );\n },\n passThroughOnException: () => {},\n props: {},\n } as unknown as ExecutionContext;\n\n const handler = options.handler.queue;\n if (!handler) throw new Error(\"the Worker has no queue() handler\");\n const outcome = Promise.resolve()\n .then(() => handler.call(options.handler, batch, proxiedEnv, execution))\n .then(\n () => \"completed\" as const,\n (err: unknown) =>\n err instanceof CrashSignal ? (\"crashed\" as const) : (\"errored\" as const),\n );\n let status = await Promise.race([\n hooks.settle(outcome, invocation),\n inv.crashed.then(() => \"crashed\" as const),\n ]);\n\n if (status === \"completed\" && state.decision === null) {\n try {\n decide(\"ack\", { messageId: event.id, implicit: true, body: event.data });\n } catch (err) {\n if (err instanceof CrashSignal) status = \"crashed\";\n else throw err;\n }\n }\n\n // Background work extends the invocation but never changes the acknowledgement.\n // A cut-off here is the isolate dying after the acknowledgement: work not yet started is lost.\n if (background.length > 0 && !inv.isCrashed()) {\n try {\n hooks.effectSync(\n {\n invocation,\n target: queueTarget,\n op: \"background\",\n args: { pending: background.length },\n allowed: CUT_OFF,\n },\n () => null,\n () => null,\n );\n await Promise.race([hooks.settle(Promise.all(background), invocation), inv.crashed]);\n } catch (err) {\n if (!(err instanceof CrashSignal)) throw err;\n status = \"crashed\";\n }\n }\n\n const followUps: EventRef[] = [];\n if (state.decision !== \"ack\") {\n const redeliveries = event.attempt - 1;\n if (event.attempt <= maxRetries && redeliveries < spec.bounds.maxRedeliveries) {\n followUps.push({ ...event, attempt: event.attempt + 1 });\n } else {\n hooks.effectSync(\n {\n invocation: platformInvocation(hooks),\n target: queueTarget,\n op: \"dead_letter\",\n args: { messageId: event.id, attempts: event.attempt },\n allowed: [],\n },\n () => null,\n () => null,\n );\n }\n }\n currentInvocation = \"\";\n return { status, followUps };\n },\n };\n}\n","/**\n * Differential check: the same fault-free scenario run once through Eutaxy's\n * proxies and once against the raw bindings, with the queue model applied by\n * hand on the raw side. Any difference in the per-attempt decisions or in\n * the final D1 state is a bug in the proxies or the platform model, not in\n * the Worker. The raw side shares Eutaxy's *reading* of Cloudflare's queue\n * semantics; what it does not share is any proxy code.\n */\n\nimport {\n canonicalJson,\n type EventRef,\n getPath,\n type JsonValue,\n type ScenarioSpec,\n} from \"@eutaxy/core\";\nimport {\n CrashSignal,\n effectLatencyMs,\n patchGlobals,\n Run,\n settleOn,\n type VirtualClock,\n} from \"@eutaxy/engine\";\nimport { resetD1, snapshotD1 } from \"./d1.ts\";\nimport { type CloudflarePlatformOptions, createCloudflarePlatform } from \"./platform.ts\";\nimport type { QueueDrive } from \"./scenario.ts\";\n\nexport interface AttemptRecord {\n readonly event: string;\n readonly attempt: number;\n readonly status: \"completed\" | \"errored\";\n readonly decision: \"ack\" | \"retry\" | null;\n}\n\nexport interface Side {\n readonly attempts: readonly AttemptRecord[];\n readonly state: {\n readonly [binding: string]: { readonly [table: string]: readonly JsonValue[] };\n };\n}\n\nexport interface DifferentialResult {\n /** True only when both sides agree and the proxied run touched nothing unmodelled. */\n readonly equal: boolean;\n readonly eutaxy: Side;\n readonly raw: Side;\n readonly differences: readonly string[];\n /** What the proxied run could not control; non-empty means the comparison proves nothing. */\n readonly unsupported: readonly string[];\n}\n\n/** The raw side cannot abandon an invocation the way the engine does; a stuck handler ends the comparison. */\nclass StuckError extends Error {\n override readonly name = \"StuckError\";\n constructor() {\n super(\n \"the handler is waiting on something outside the run (no timer due, no effect in flight)\",\n );\n }\n}\n\n/**\n * The raw side's only wrapper: counts D1 calls in flight (so the settle loop\n * knows real I/O is pending) and advances the clock as the proxies do. It\n * records nothing and injects nothing.\n */\nfunction countingD1(real: D1Database, io: { n: number }, clock: VirtualClock): D1Database {\n const realOf = new WeakMap<object, D1PreparedStatement>();\n const track = async <T>(p: Promise<T>): Promise<T> => {\n io.n++;\n try {\n return await p;\n } finally {\n io.n--;\n clock.advance(effectLatencyMs);\n }\n };\n const wrapStatement = (s: D1PreparedStatement): D1PreparedStatement => {\n const proxy = new Proxy(s, {\n get(t, prop, r) {\n const v = Reflect.get(t, prop, r) as unknown;\n if (prop === \"bind\") return (...a: unknown[]) => wrapStatement(t.bind(...a));\n if (prop === \"run\" || prop === \"all\" || prop === \"first\" || prop === \"raw\") {\n return (...a: unknown[]) =>\n track((v as (...x: unknown[]) => Promise<unknown>).apply(t, a));\n }\n return typeof v === \"function\" ? (v as (...x: unknown[]) => unknown).bind(t) : v;\n },\n });\n realOf.set(proxy, s);\n return proxy;\n };\n return new Proxy(real, {\n get(t, prop, r) {\n const v = Reflect.get(t, prop, r) as unknown;\n if (prop === \"prepare\") return (sql: string) => wrapStatement(t.prepare(sql));\n if (prop === \"batch\") {\n return (stmts: D1PreparedStatement[]) =>\n track(t.batch(stmts.map((s) => realOf.get(s) ?? s)));\n }\n if (prop === \"exec\") return (sql: string) => track(t.exec(sql));\n return typeof v === \"function\" ? (v as (...x: unknown[]) => unknown).bind(t) : v;\n },\n });\n}\n\nfunction isD1(value: unknown): value is D1Database {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { prepare?: unknown }).prepare === \"function\"\n );\n}\n\nasync function snapshotAll(\n spec: ScenarioSpec,\n options: CloudflarePlatformOptions,\n): Promise<Side[\"state\"]> {\n const env = options.env as Record<string, unknown>;\n const out: Record<string, { readonly [table: string]: readonly JsonValue[] }> = {};\n for (const step of spec.setup) {\n if (step.kind !== \"d1\") continue;\n const binding = String(step[\"binding\"]);\n const real = env[binding];\n if (isD1(real)) out[binding] = await snapshotD1(real);\n }\n return out;\n}\n\n/** The Eutaxy side: one run with no faults, driven like `runOnce` but keeping each delivery's status. */\nasync function eutaxySide(\n spec: ScenarioSpec,\n options: CloudflarePlatformOptions,\n): Promise<Side & { readonly unsupported: readonly string[] }> {\n const platform = createCloudflarePlatform(options);\n const run = new Run({\n mode: \"replay\",\n schedule: { seed: 0, faults: [] },\n bounds: spec.bounds,\n faultProbability: 0,\n });\n const attempts: AttemptRecord[] = [];\n run.install();\n try {\n await platform.reset(spec);\n const pending: EventRef[] = [...platform.initialEvents(spec)];\n while (pending.length > 0) {\n const event = pending.shift() as EventRef;\n const invocation = `${event.id}#${event.attempt}`;\n const before = run.log.entries.length;\n const result = await platform.deliver(event, run, spec);\n const decision = run.log.entries\n .slice(before)\n .find(\n (e) =>\n e.invocation === invocation &&\n e.kind === \"result\" &&\n (e.op === \"ack\" || e.op === \"retry\") &&\n getPath(e.payload, \"result.effective\") === true,\n )?.op as \"ack\" | \"retry\" | undefined;\n attempts.push({\n event: event.id,\n attempt: event.attempt,\n status: result.status === \"completed\" ? \"completed\" : \"errored\",\n decision: decision ?? null,\n });\n pending.push(...result.followUps);\n }\n await platform.finish?.(spec, run);\n } finally {\n run.uninstall();\n }\n return { attempts, state: await snapshotAll(spec, options), unsupported: run.unsupportedReasons };\n}\n\n/** The raw side: the handler called directly with the real bindings and plain message objects. */\nasync function rawSide(spec: ScenarioSpec, options: CloudflarePlatformOptions): Promise<Side> {\n const env = options.env as Record<string, unknown>;\n const drive = spec.drive as QueueDrive;\n const maxRetries = options.maxRetries ?? 3;\n for (const step of spec.setup) {\n if (step.kind !== \"d1\") continue;\n const binding = String(step[\"binding\"]);\n const schema = options.schemas[binding];\n const real = env[binding];\n if (schema !== undefined && isD1(real)) await resetD1(real, schema);\n }\n const handler = options.handler.queue;\n if (!handler) throw new Error(\"the Worker has no queue() handler\");\n const attempts: AttemptRecord[] = [];\n const pending: EventRef[] = drive.messages.map((m) => ({ id: m.id, attempt: 1, data: m.body }));\n // The same virtual globals as the proxied side, from the same seed, so Date.now and randomness agree.\n const patched = patchGlobals(0);\n const io = { n: 0 };\n const counting = new Map<string, D1Database>();\n const countedEnv = new Proxy(env, {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver) as unknown;\n if (typeof prop !== \"string\" || !isD1(value)) return value;\n let c = counting.get(prop);\n if (!c) {\n c = countingD1(value, io, patched.clock);\n counting.set(prop, c);\n }\n return c;\n },\n });\n const settle = <T>(p: Promise<T>): Promise<T> =>\n settleOn(p, {\n clock: patched.clock,\n inFlight: () => io.n,\n crashed: () => false,\n stuck: () => {\n throw new StuckError();\n },\n });\n try {\n while (pending.length > 0) {\n const event = pending.shift() as EventRef;\n let decision: \"ack\" | \"retry\" | null = null;\n const background: Promise<unknown>[] = [];\n const message: Message<unknown> = {\n id: event.id,\n timestamp: new Date(),\n body: JSON.parse(JSON.stringify(event.data)) as JsonValue,\n attempts: event.attempt,\n ack: () => {\n decision ??= \"ack\";\n },\n retry: () => {\n decision ??= \"retry\";\n },\n };\n const batch: MessageBatch<unknown> = {\n queue: drive.queue,\n messages: [message],\n metadata: { metrics: { backlogCount: 0, backlogBytes: 0 } },\n ackAll: () => message.ack(),\n retryAll: () => message.retry(),\n };\n const ctx = {\n waitUntil: (p: Promise<unknown>) => {\n background.push(\n p.then(\n () => undefined,\n () => undefined,\n ),\n );\n },\n passThroughOnException: () => {},\n props: {},\n } as unknown as ExecutionContext;\n let status: \"completed\" | \"errored\";\n try {\n await settle(\n Promise.resolve().then(() => handler.call(options.handler, batch, countedEnv, ctx)),\n );\n status = \"completed\";\n } catch (err) {\n if (err instanceof CrashSignal || err instanceof StuckError) throw err;\n status = \"errored\";\n }\n if (status === \"completed\") decision ??= \"ack\";\n await settle(Promise.all(background));\n attempts.push({ event: event.id, attempt: event.attempt, status, decision });\n if (\n decision !== \"ack\" &&\n event.attempt <= maxRetries &&\n event.attempt - 1 < spec.bounds.maxRedeliveries\n ) {\n pending.push({ ...event, attempt: event.attempt + 1 });\n }\n }\n } finally {\n patched.restore();\n }\n return { attempts, state: await snapshotAll(spec, options) };\n}\n\n/** Run both sides and compare. The Eutaxy side runs first; both start from the schema. */\nexport async function runDifferential(\n spec: ScenarioSpec,\n options: CloudflarePlatformOptions,\n): Promise<DifferentialResult> {\n const { unsupported, ...eutaxy } = await eutaxySide(spec, options);\n const raw = await rawSide(spec, options);\n const differences: string[] = [];\n if (unsupported.length > 0) {\n differences.push(`the proxied run touched unsupported APIs: ${unsupported.join(\"; \")}`);\n }\n const a = canonicalJson(eutaxy.attempts as unknown as JsonValue);\n const b = canonicalJson(raw.attempts as unknown as JsonValue);\n if (a !== b) differences.push(`attempts differ:\\n eutaxy ${a}\\n raw ${b}`);\n const bindings = new Set([...Object.keys(eutaxy.state), ...Object.keys(raw.state)]);\n for (const binding of [...bindings].sort()) {\n const tables = new Set([\n ...Object.keys(eutaxy.state[binding] ?? {}),\n ...Object.keys(raw.state[binding] ?? {}),\n ]);\n for (const table of [...tables].sort()) {\n const x = canonicalJson((eutaxy.state[binding]?.[table] ?? []) as unknown as JsonValue);\n const y = canonicalJson((raw.state[binding]?.[table] ?? []) as unknown as JsonValue);\n if (x !== y) differences.push(`${binding}.${table} differs:\\n eutaxy ${x}\\n raw ${y}`);\n }\n }\n return { equal: differences.length === 0, eutaxy, raw, differences, unsupported };\n}\n","/**\n * Typed construction of scenario specs for Cloudflare Workers. Everything here\n * produces the plain-data `ScenarioSpec` from core; this module only knows the\n * Cloudflare shapes (queues, D1 bindings) and the effect conventions the\n * proxies follow.\n */\n\nimport {\n type AtLeastOnce,\n type AtMostOncePerKey,\n type Bounds,\n defaultBounds,\n type EffectSelector,\n type EveryRow,\n type ExternalDecl,\n getPath,\n type Implies,\n type Invariant,\n type JsonValue,\n type PlatformData,\n type RowCondition,\n type ScenarioSpec,\n type StateQuery,\n validateScenario,\n type WorkerRef,\n} from \"@eutaxy/core\";\n\n/** One queue message to deliver; `id` defaults to its position. */\nexport interface QueueMessage {\n readonly id?: string;\n readonly body: JsonValue;\n}\n\n/** Drive the Worker's `queue()` handler with these messages. */\nexport interface QueueDrive extends PlatformData {\n readonly kind: \"queue\";\n readonly queue: string;\n readonly messages: readonly { readonly id: string; readonly body: JsonValue }[];\n}\n\n/** Apply a SQL file to a D1 binding before each run. */\nexport interface D1Setup extends PlatformData {\n readonly kind: \"d1\";\n readonly binding: string;\n readonly schemaFile: string;\n}\n\nexport interface CloudflareScenarioInput {\n readonly name: string;\n readonly worker: WorkerRef;\n readonly drive:\n | QueueDrive\n | {\n readonly kind: \"queue\";\n readonly queue: string;\n readonly messages: readonly QueueMessage[];\n };\n readonly setup?: readonly D1Setup[];\n readonly externals?: readonly ExternalDecl[];\n readonly invariants: readonly Invariant[];\n readonly bounds?: Partial<Bounds>;\n}\n\nexport function queue(name: string, messages: readonly QueueMessage[]): QueueDrive {\n return {\n kind: \"queue\",\n queue: name,\n messages: messages.map((m, i) => ({ id: m.id ?? `msg-${i + 1}`, body: m.body })),\n };\n}\n\nexport function d1Schema(binding: string, schemaFile: string): D1Setup {\n return { kind: \"d1\", binding, schemaFile };\n}\n\n/**\n * Effect conventions for D1 (what the proxies record):\n * call payload { args: { sql, params } }\n * result payload { args: { sql, params }, result: { changes, lastRowId } }\n * A committed write is a `result` whose `result.changes` is at least 1.\n */\nexport function d1Write(binding: string, op: \"run\" | \"batch\" = \"run\"): EffectSelector {\n return { target: `D1:${binding}`, op, kind: \"result\", atLeast: { \"result.changes\": 1 } };\n}\n\n/** Dot path to the Nth bound parameter of a D1 statement, in an effect payload. */\nexport function d1Param(index: number): string {\n return `args.params.${index}`;\n}\n\nexport function atMostOncePerKey(\n name: string,\n effect: EffectSelector,\n key: string,\n): AtMostOncePerKey {\n return { kind: \"atMostOncePerKey\", name, effect, key };\n}\n\nexport function atLeastOnce(\n name: string,\n effect: EffectSelector,\n key: string,\n expected: readonly JsonValue[],\n): AtLeastOnce {\n return { kind: \"atLeastOnce\", name, effect, key, expected };\n}\n\n/**\n * Every message's `bodyKey` value must appear at least once as `key` in a\n * selected effect: nothing the queue delivered may be lost.\n */\nexport function atLeastOncePerMessage(\n name: string,\n drive: QueueDrive,\n effect: EffectSelector,\n key: string,\n bodyKey: string,\n): AtLeastOnce {\n const expected: JsonValue[] = [];\n for (const m of drive.messages) {\n const v = getPath(m.body, bodyKey);\n if (v === undefined) {\n throw new Error(`message ${m.id} has no ${JSON.stringify(bodyKey)} in its body`);\n }\n expected.push(v);\n }\n return { ...atLeastOnce(name, effect, key, expected), perMessage: { bodyKey } };\n}\n\n/** Rows of a D1 table in the end-of-run snapshot, optionally filtered. */\nexport function d1Rows(\n binding: string,\n table: string,\n where?: readonly RowCondition[],\n): StateQuery {\n return where ? { target: `D1:${binding}`, table, where } : { target: `D1:${binding}`, table };\n}\n\n/** Every row the query selects satisfies all conditions. */\nexport function everyRow(\n name: string,\n query: StateQuery,\n holds: readonly RowCondition[],\n): EveryRow {\n return { kind: \"everyRow\", name, query, holds };\n}\n\n/** Every selected effect has a row whose column equals the effect's key. */\nexport function implies(\n name: string,\n when: EffectSelector,\n key: string,\n state: StateQuery,\n column: string,\n): Implies {\n return { kind: \"implies\", name, when, key, state, column };\n}\n\n/** Selects the acknowledgement that took effect for each message (explicit or implicit; not one ignored after a retry). */\nexport function queueAck(queueName: string): EffectSelector {\n return {\n target: `Queue:${queueName}`,\n op: \"ack\",\n kind: \"result\",\n where: { \"result.effective\": true },\n };\n}\n\n/** Build and validate a scenario spec; throws with every problem listed. */\nexport function defineScenario(input: CloudflareScenarioInput): ScenarioSpec {\n const drive: QueueDrive =\n \"messages\" in input.drive &&\n input.drive.messages.every((m) => \"id\" in m && typeof m.id === \"string\")\n ? (input.drive as QueueDrive)\n : queue(input.drive.queue, input.drive.messages);\n const spec: ScenarioSpec = {\n version: 1,\n name: input.name,\n worker: input.worker,\n drive,\n setup: input.setup ?? [],\n externals: input.externals ?? [],\n invariants: input.invariants,\n bounds: { ...defaultBounds, ...input.bounds },\n };\n const errors = validateScenario(spec);\n if (errors.length > 0) {\n throw new Error(`invalid scenario ${JSON.stringify(input.name)}:\\n- ${errors.join(\"\\n- \")}`);\n }\n return spec;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cloudflare.mjs","names":["isD1"],"sources":["../../cloudflare/src/check.ts","../../cloudflare/src/json.ts","../../cloudflare/src/d1.ts","../../cloudflare/src/platform.ts","../../cloudflare/src/differential.ts","../../cloudflare/src/scenario.ts"],"sourcesContent":["import {\n describeVerdict,\n type Platform,\n type ScenarioSpec,\n type ScenarioVerdict,\n} from \"@eutaxy/core\";\nimport { type ExploreOptions, explore } from \"@eutaxy/engine\";\n\n/** Explore a scenario on a platform and return its verdict. */\nexport function check(\n spec: ScenarioSpec,\n platform: Platform,\n options: ExploreOptions = { seed: spec.name },\n): Promise<ScenarioVerdict> {\n return explore(spec, platform, options);\n}\n\n/** For use from a test: passes only when the scenario is BOUNDED. */\nexport async function expectHolds(\n spec: ScenarioSpec,\n platform: Platform,\n options?: ExploreOptions,\n): Promise<void> {\n const verdict = await check(spec, platform, options);\n if (verdict.kind !== \"BOUNDED\") throw new Error(describeVerdict(verdict));\n}\n","import type { JsonValue } from \"@eutaxy/core\";\n\n/** Reduce any runtime value to JSON data for the effect log; never throws. */\nexport function toJson(value: unknown, depth = 0): JsonValue {\n if (value === null || value === undefined) return null;\n switch (typeof value) {\n case \"boolean\":\n case \"string\":\n return value;\n case \"number\":\n return Number.isFinite(value) ? value : String(value);\n case \"bigint\":\n return value.toString();\n case \"object\": {\n if (depth > 8) return \"<nested>\";\n if (Array.isArray(value)) return value.map((v) => toJson(v, depth + 1));\n if (value instanceof ArrayBuffer) return `<bytes ${value.byteLength}>`;\n if (ArrayBuffer.isView(value)) return `<bytes ${value.byteLength}>`;\n if (value instanceof Date) return value.toISOString();\n const out: Record<string, JsonValue> = {};\n for (const k of Object.keys(value).sort()) {\n out[k] = toJson((value as Record<string, unknown>)[k], depth + 1);\n }\n return out;\n }\n default:\n return `<${typeof value}>`;\n }\n}\n","/**\n * The D1 binding proxy. Every statement execution is an effect point: the\n * engine decides the fault, the real Miniflare-backed D1 performs the query,\n * and the log records call, result and fault in the documented shape.\n */\n\nimport {\n canonicalJson,\n type EffectPoint,\n type FaultKind,\n type JsonValue,\n type RunHooks,\n} from \"@eutaxy/core\";\nimport { toJson } from \"./json.ts\";\n\nconst WRITE: readonly FaultKind[] = [\"crash_before\", \"crash_after\", \"ambiguous\", \"error\"];\nconst READ: readonly FaultKind[] = [\"crash_before\", \"crash_after\", \"error\"];\n\nexport interface ProxyContext {\n readonly hooks: RunHooks;\n /** The invocation currently running; one at a time for now. */\n readonly currentInvocation: () => string;\n}\n\nfunction point(\n ctx: ProxyContext,\n target: string,\n op: string,\n args: JsonValue,\n allowed: readonly FaultKind[],\n): EffectPoint {\n return { invocation: ctx.currentInvocation(), target, op, args, allowed };\n}\n\nfunction metaOf(result: D1Result<unknown>): JsonValue {\n return { changes: result.meta.changes ?? 0, lastRowId: result.meta.last_row_id ?? null };\n}\n\nclass StatementProxy {\n private readonly real: D1PreparedStatement;\n private readonly target: string;\n private readonly ctx: ProxyContext;\n readonly sql: string;\n readonly params: readonly unknown[];\n\n constructor(\n real: D1PreparedStatement,\n target: string,\n ctx: ProxyContext,\n sql: string,\n params: readonly unknown[],\n ) {\n this.real = real;\n this.target = target;\n this.ctx = ctx;\n this.sql = sql;\n this.params = params;\n }\n\n /** The real statement, for `batch()`. */\n get statement(): D1PreparedStatement {\n return this.real;\n }\n\n private args(): JsonValue {\n return { sql: this.sql, params: toJson(this.params) };\n }\n\n bind(...values: unknown[]): StatementProxy {\n return new StatementProxy(this.real.bind(...values), this.target, this.ctx, this.sql, values);\n }\n\n run<T = Record<string, unknown>>(): Promise<D1Result<T>> {\n return this.ctx.hooks.effect(\n point(this.ctx, this.target, \"run\", this.args(), WRITE),\n () => this.real.run<T>(),\n (r) => metaOf(r),\n );\n }\n\n all<T = Record<string, unknown>>(): Promise<D1Result<T>> {\n return this.ctx.hooks.effect(\n point(this.ctx, this.target, \"all\", this.args(), READ),\n () => this.real.all<T>(),\n (r) => ({ rows: r.results.length, changes: r.meta.changes ?? 0 }),\n );\n }\n\n first<T = unknown>(colName?: string): Promise<T | null> {\n return this.ctx.hooks.effect(\n point(\n this.ctx,\n this.target,\n \"first\",\n { ...(this.args() as object), column: colName ?? null } as JsonValue,\n READ,\n ),\n () => (colName === undefined ? this.real.first<T>() : this.real.first<T>(colName)),\n (r) => ({ row: toJson(r) }),\n );\n }\n\n raw<T = unknown[]>(options?: { columnNames?: boolean }): Promise<T[]> {\n return this.ctx.hooks.effect(\n point(this.ctx, this.target, \"raw\", this.args(), READ),\n () =>\n (options\n ? this.real.raw<T>(options as { columnNames: true })\n : this.real.raw<T>()) as Promise<T[]>,\n (r) => ({ rows: r.length }),\n );\n }\n}\n\n/** Wrap a D1 binding. Methods not modelled fall through to the real binding and mark the run unsupported. */\nexport function proxyD1(real: D1Database, binding: string, ctx: ProxyContext): D1Database {\n const target = `D1:${binding}`;\n const modelled = {\n prepare(sql: string): StatementProxy {\n return new StatementProxy(real.prepare(sql), target, ctx, sql, []);\n },\n batch<T = Record<string, unknown>>(\n statements: readonly (StatementProxy | D1PreparedStatement)[],\n ): Promise<D1Result<T>[]> {\n const unwrapped = statements.map((s) => (s instanceof StatementProxy ? s.statement : s));\n const args = {\n statements: statements.map((s) =>\n s instanceof StatementProxy\n ? { sql: s.sql, params: toJson(s.params) }\n : \"<unproxied statement>\",\n ),\n };\n return ctx.hooks.effect(\n point(ctx, target, \"batch\", args, WRITE),\n () => real.batch<T>(unwrapped as D1PreparedStatement[]),\n (rs) => ({\n changes: rs.reduce((n, r) => n + (r.meta.changes ?? 0), 0),\n statements: rs.length,\n }),\n );\n },\n exec(sql: string): Promise<D1ExecResult> {\n return ctx.hooks.effect(\n point(ctx, target, \"exec\", { sql }, WRITE),\n () => real.exec(sql),\n (r) => ({ count: r.count, duration: 0 }),\n );\n },\n };\n return new Proxy(real, {\n get(obj, prop, receiver) {\n if (prop in modelled) return modelled[prop as keyof typeof modelled];\n const value = Reflect.get(obj, prop, receiver) as unknown;\n if (typeof value === \"function\") {\n ctx.hooks.unsupported(`D1 ${binding}.${String(prop)} is not modelled`);\n return (value as (...a: unknown[]) => unknown).bind(obj);\n }\n return value;\n },\n }) as D1Database;\n}\n\n/**\n * Statements in a schema file. Splits on semicolons outside string literals,\n * quoted identifiers and comments, and keeps CREATE TRIGGER bodies (and CASE\n * expressions) whole by tracking BEGIN/CASE ... END nesting.\n */\nexport function splitSql(sql: string): readonly string[] {\n const out: string[] = [];\n let cur = \"\";\n let depth = 0;\n let i = 0;\n const isWordChar = (c: string | undefined): boolean => c !== undefined && /[A-Za-z0-9_]/.test(c);\n while (i < sql.length) {\n const c = sql[i] as string;\n const next = sql[i + 1];\n if (c === \"-\" && next === \"-\") {\n while (i < sql.length && sql[i] !== \"\\n\") i++;\n continue;\n }\n if (c === \"/\" && next === \"*\") {\n const end = sql.indexOf(\"*/\", i + 2);\n i = end === -1 ? sql.length : end + 2;\n continue;\n }\n if (c === \"'\" || c === '\"' || c === \"`\" || c === \"[\") {\n const close = c === \"[\" ? \"]\" : c;\n let j = i + 1;\n for (;;) {\n const k = sql.indexOf(close, j);\n if (k === -1) {\n j = sql.length;\n break;\n }\n if (close !== \"]\" && sql[k + 1] === close) {\n j = k + 2; // a doubled quote inside the literal\n continue;\n }\n j = k + 1;\n break;\n }\n cur += sql.slice(i, j);\n i = j;\n continue;\n }\n if (isWordChar(c) && !isWordChar(sql[i - 1])) {\n let j = i;\n while (isWordChar(sql[j])) j++;\n const word = sql.slice(i, j);\n const upper = word.toUpperCase();\n if (upper === \"BEGIN\" || upper === \"CASE\") depth++;\n else if (upper === \"END\" && depth > 0) depth--;\n cur += word;\n i = j;\n continue;\n }\n if (c === \";\" && depth === 0) {\n const statement = cur.trim();\n if (statement.length > 0) out.push(statement);\n cur = \"\";\n i++;\n continue;\n }\n cur += c;\n i++;\n }\n const last = cur.trim();\n if (last.length > 0) out.push(last);\n return out;\n}\n\n/** Drop every user table and re-apply the schema, using the real binding (not an effect). */\nexport async function resetD1(real: D1Database, schema: string): Promise<void> {\n const tables = await real\n .prepare(\n \"SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '\\\\_cf\\\\_%' ESCAPE '\\\\'\",\n )\n .all<{ name: string }>();\n for (const { name } of tables.results) {\n await real.prepare(`DROP TABLE IF EXISTS \"${name.replace(/\"/g, '\"\"')}\"`).run();\n }\n for (const statement of splitSql(schema)) {\n await real.prepare(statement).run();\n }\n}\n\n/** Every user table's rows, sorted canonically, read through the real binding (not an effect). */\nexport async function snapshotD1(\n real: D1Database,\n): Promise<{ readonly [table: string]: readonly JsonValue[] }> {\n const tables = await real\n .prepare(\n \"SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '\\\\_cf\\\\_%' ESCAPE '\\\\' ORDER BY name\",\n )\n .all<{ name: string }>();\n const out: Record<string, JsonValue[]> = {};\n for (const { name } of tables.results) {\n const rows = await real\n .prepare(`SELECT * FROM \"${name.replace(/\"/g, '\"\"')}\"`)\n .all<Record<string, unknown>>();\n out[name] = rows.results\n .map((r) => toJson(r))\n .map((j) => [canonicalJson(j), j] as const)\n .sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))\n .map(([, j]) => j);\n }\n return out;\n}\n","/**\n * The Cloudflare platform: delivers queue messages to the Worker's `queue()`\n * handler with proxied bindings and proxied messages, and applies Queues'\n * at-least-once semantics (explicit and implicit ack, retry, redelivery up\n * to max_retries, dead-lettering) as documented by Cloudflare.\n */\n\nimport type {\n DeliveryResult,\n EventRef,\n FaultKind,\n JsonValue,\n Platform,\n RunHooks,\n ScenarioSpec,\n} from \"@eutaxy/core\";\nimport { CrashSignal } from \"@eutaxy/engine\";\nimport { type ProxyContext, proxyD1, resetD1, snapshotD1 } from \"./d1.ts\";\nimport type { QueueDrive } from \"./scenario.ts\";\n\nconst ACK: readonly FaultKind[] = [\"crash_before\", \"crash_after\"];\nconst CUT_OFF: readonly FaultKind[] = [\"cut_off\"];\n\nexport interface QueueHandler {\n queue?(batch: MessageBatch<unknown>, env: unknown, ctx: ExecutionContext): void | Promise<void>;\n}\n\nexport interface CloudflarePlatformOptions {\n /** The bindings from `cloudflare:workers`. */\n readonly env: object;\n /** The Worker's default export. */\n readonly handler: QueueHandler;\n /** Schema SQL per D1 binding named in the scenario's setup. */\n readonly schemas: Readonly<Record<string, string>>;\n /** Cloudflare's default when the consumer does not set max_retries. */\n readonly maxRetries?: number;\n}\n\nfunction isD1(value: unknown): value is D1Database {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { prepare?: unknown }).prepare === \"function\" &&\n typeof (value as { batch?: unknown }).batch === \"function\"\n );\n}\n\nfunction isBindingLike(value: unknown): boolean {\n if (typeof value === \"function\") return true;\n if (typeof value !== \"object\" || value === null) return false;\n const proto = Object.getPrototypeOf(value) as object | null;\n const names = [...Object.getOwnPropertyNames(value), ...Object.getOwnPropertyNames(proto ?? {})];\n return names.some(\n (k) => k !== \"constructor\" && typeof (value as Record<string, unknown>)[k] === \"function\",\n );\n}\n\n/** Deep-copy JSON data so a handler that mutates its message cannot leak into other runs. */\nfunction cloneJson(value: JsonValue): JsonValue {\n return JSON.parse(JSON.stringify(value)) as JsonValue;\n}\n\nconst assumptions: readonly string[] = [\n \"platform model: Cloudflare Queues at-least-once delivery; the first ack or retry decision per message wins; unacked messages are redelivered up to max_retries then dead-lettered\",\n \"D1 statements run against Miniflare's SQLite; each run/first/all/raw/batch/exec is one effect\",\n \"message.timestamp is the virtual clock's time at delivery\",\n \"only D1 bindings are proxied; touching any other binding makes the run UNSUPPORTED\",\n \"state invariants read a snapshot of every D1 binding named in setup, taken after the last event\",\n \"work passed to ctx.waitUntil runs after the handler returns and never affects acknowledgement; a cut_off fault at that point loses work not yet started, and an effect in flight commits without its continuation\",\n];\n\nexport function createCloudflarePlatform(options: CloudflarePlatformOptions): Platform {\n const env = options.env as Record<string, unknown>;\n const maxRetries = options.maxRetries ?? 3;\n let currentInvocation = \"\";\n let hooksRef: RunHooks | null = null;\n\n const ctx: ProxyContext = {\n get hooks() {\n if (!hooksRef) throw new Error(\"no run in progress\");\n return hooksRef;\n },\n currentInvocation: () => currentInvocation,\n };\n\n const d1Proxies = new Map<string, D1Database>();\n const proxiedEnv = new Proxy(env, {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver) as unknown;\n if (typeof prop !== \"string\") return value;\n if (isD1(value)) {\n let p = d1Proxies.get(prop);\n if (!p) {\n p = proxyD1(value, prop, ctx);\n d1Proxies.set(prop, p);\n }\n return p;\n }\n if (isBindingLike(value)) ctx.hooks.unsupported(`binding ${prop} is not proxied`);\n return value;\n },\n });\n\n /** Platform-level actions (dead-lettering) are recorded under an invocation no fault can crash. */\n const platformInvocations = new WeakMap<RunHooks, string>();\n function platformInvocation(hooks: RunHooks): string {\n let id = platformInvocations.get(hooks);\n if (id === undefined) {\n id = \"platform\";\n hooks.startInvocation(id);\n platformInvocations.set(hooks, id);\n }\n return id;\n }\n\n return {\n name: \"cloudflare\",\n assumptions,\n\n async reset(spec: ScenarioSpec): Promise<void> {\n for (const step of spec.setup) {\n if (step.kind !== \"d1\") continue;\n const binding = String(step[\"binding\"]);\n const schema = options.schemas[binding];\n if (schema === undefined) throw new Error(`no schema provided for D1 binding ${binding}`);\n const real = env[binding];\n if (!isD1(real)) throw new Error(`env.${binding} is not a D1 binding`);\n await resetD1(real, schema);\n }\n },\n\n restrictEvents(spec: ScenarioSpec, keepIds: readonly string[]): ScenarioSpec {\n const drive = spec.drive as QueueDrive;\n return {\n ...spec,\n drive: { ...drive, messages: drive.messages.filter((m) => keepIds.includes(m.id)) },\n };\n },\n\n async finish(spec: ScenarioSpec, hooks: RunHooks): Promise<void> {\n for (const step of spec.setup) {\n if (step.kind !== \"d1\") continue;\n const binding = String(step[\"binding\"]);\n const real = env[binding];\n if (!isD1(real)) continue;\n const tables = await snapshotD1(real);\n hooks.snapshot(platformInvocation(hooks), `D1:${binding}`, { tables });\n }\n },\n\n initialEvents(spec: ScenarioSpec): readonly EventRef[] {\n const drive = spec.drive as QueueDrive;\n if (drive.kind !== \"queue\") {\n throw new Error(`drive ${drive.kind} is not supported by the Cloudflare platform yet`);\n }\n return drive.messages.map((m) => ({ id: m.id, attempt: 1, data: m.body }));\n },\n\n async deliver(event: EventRef, hooks: RunHooks, spec: ScenarioSpec): Promise<DeliveryResult> {\n const drive = spec.drive as QueueDrive;\n const queueTarget = `Queue:${drive.queue}`;\n const invocation = `${event.id}#${event.attempt}`;\n hooksRef = hooks;\n currentInvocation = invocation;\n const inv = hooks.startInvocation(invocation);\n /** Cloudflare honours the first ack or retry decision per message; later ones are ignored. */\n const state: { decision: \"ack\" | \"retry\" | null } = { decision: null };\n const background: Promise<unknown>[] = [];\n\n /** Records the call; the result says whether it took effect (the first decision wins). */\n const decide = (op: \"ack\" | \"retry\", args: JsonValue): void => {\n hooks.effectSync(\n { invocation, target: queueTarget, op, args, allowed: ACK },\n () => {\n if (state.decision !== null) return false;\n state.decision = op;\n return true;\n },\n (effective) => ({ effective }),\n );\n };\n const message: Message<unknown> = {\n id: event.id,\n timestamp: new Date(),\n body: cloneJson(event.data),\n attempts: event.attempt,\n ack: () => decide(\"ack\", { messageId: event.id, implicit: false, body: event.data }),\n retry: () => decide(\"retry\", { messageId: event.id, body: event.data }),\n };\n const batch: MessageBatch<unknown> = {\n queue: drive.queue,\n messages: [message],\n metadata: { metrics: { backlogCount: 0, backlogBytes: 0 } },\n ackAll: () => message.ack(),\n retryAll: () => message.retry(),\n };\n const execution: ExecutionContext = {\n waitUntil: (promise: Promise<unknown>) => {\n background.push(\n promise.then(\n () => undefined,\n () => undefined,\n ),\n );\n },\n passThroughOnException: () => {},\n props: {},\n } as unknown as ExecutionContext;\n\n const handler = options.handler.queue;\n if (!handler) throw new Error(\"the Worker has no queue() handler\");\n const outcome = Promise.resolve()\n .then(() => handler.call(options.handler, batch, proxiedEnv, execution))\n .then(\n () => \"completed\" as const,\n (err: unknown) =>\n err instanceof CrashSignal ? (\"crashed\" as const) : (\"errored\" as const),\n );\n let status = await Promise.race([\n hooks.settle(outcome, invocation),\n inv.crashed.then(() => \"crashed\" as const),\n ]);\n\n if (status === \"completed\" && state.decision === null) {\n try {\n decide(\"ack\", { messageId: event.id, implicit: true, body: event.data });\n } catch (err) {\n if (err instanceof CrashSignal) status = \"crashed\";\n else throw err;\n }\n }\n\n // Background work extends the invocation but never changes the acknowledgement.\n // A cut-off here is the isolate dying after the acknowledgement: work not yet started is lost.\n if (background.length > 0 && !inv.isCrashed()) {\n try {\n hooks.effectSync(\n {\n invocation,\n target: queueTarget,\n op: \"background\",\n args: { pending: background.length },\n allowed: CUT_OFF,\n },\n () => null,\n () => null,\n );\n await Promise.race([hooks.settle(Promise.all(background), invocation), inv.crashed]);\n } catch (err) {\n if (!(err instanceof CrashSignal)) throw err;\n status = \"crashed\";\n }\n }\n\n const followUps: EventRef[] = [];\n if (state.decision !== \"ack\") {\n const redeliveries = event.attempt - 1;\n if (event.attempt <= maxRetries && redeliveries < spec.bounds.maxRedeliveries) {\n followUps.push({ ...event, attempt: event.attempt + 1 });\n } else {\n hooks.effectSync(\n {\n invocation: platformInvocation(hooks),\n target: queueTarget,\n op: \"dead_letter\",\n args: { messageId: event.id, attempts: event.attempt },\n allowed: [],\n },\n () => null,\n () => null,\n );\n }\n }\n currentInvocation = \"\";\n return { status, followUps };\n },\n };\n}\n","/**\n * Differential check: the same fault-free scenario run once through Eutaxy's\n * proxies and once against the raw bindings, with the queue model applied by\n * hand on the raw side. Any difference in the per-attempt decisions or in\n * the final D1 state is a bug in the proxies or the platform model, not in\n * the Worker. The raw side shares Eutaxy's *reading* of Cloudflare's queue\n * semantics; what it does not share is any proxy code.\n */\n\nimport {\n canonicalJson,\n type EventRef,\n getPath,\n type JsonValue,\n type ScenarioSpec,\n} from \"@eutaxy/core\";\nimport {\n CrashSignal,\n effectLatencyMs,\n installScriptedFetch,\n patchGlobals,\n Run,\n settleOn,\n type VirtualClock,\n} from \"@eutaxy/engine\";\nimport { resetD1, snapshotD1 } from \"./d1.ts\";\nimport { type CloudflarePlatformOptions, createCloudflarePlatform } from \"./platform.ts\";\nimport type { QueueDrive } from \"./scenario.ts\";\n\nexport interface AttemptRecord {\n readonly event: string;\n readonly attempt: number;\n readonly status: \"completed\" | \"errored\";\n readonly decision: \"ack\" | \"retry\" | null;\n}\n\nexport interface Side {\n readonly attempts: readonly AttemptRecord[];\n readonly state: {\n readonly [binding: string]: { readonly [table: string]: readonly JsonValue[] };\n };\n}\n\nexport interface DifferentialResult {\n /** True only when both sides agree and the proxied run touched nothing unmodelled. */\n readonly equal: boolean;\n readonly eutaxy: Side;\n readonly raw: Side;\n readonly differences: readonly string[];\n /** What the proxied run could not control; non-empty means the comparison proves nothing. */\n readonly unsupported: readonly string[];\n}\n\n/** The raw side cannot abandon an invocation the way the engine does; a stuck handler ends the comparison. */\nclass StuckError extends Error {\n override readonly name = \"StuckError\";\n constructor(\n message = \"the handler is waiting on something outside the run (no timer due, no effect in flight)\",\n ) {\n super(message);\n }\n}\n\n/**\n * The raw side's only wrapper: counts D1 calls in flight (so the settle loop\n * knows real I/O is pending) and advances the clock as the proxies do. It\n * records nothing and injects nothing.\n */\nfunction countingD1(real: D1Database, io: { n: number }, clock: VirtualClock): D1Database {\n const realOf = new WeakMap<object, D1PreparedStatement>();\n const track = async <T>(p: Promise<T>): Promise<T> => {\n io.n++;\n try {\n return await p;\n } finally {\n io.n--;\n clock.advance(effectLatencyMs);\n }\n };\n const wrapStatement = (s: D1PreparedStatement): D1PreparedStatement => {\n const proxy = new Proxy(s, {\n get(t, prop, r) {\n const v = Reflect.get(t, prop, r) as unknown;\n if (prop === \"bind\") return (...a: unknown[]) => wrapStatement(t.bind(...a));\n if (prop === \"run\" || prop === \"all\" || prop === \"first\" || prop === \"raw\") {\n return (...a: unknown[]) =>\n track((v as (...x: unknown[]) => Promise<unknown>).apply(t, a));\n }\n return typeof v === \"function\" ? (v as (...x: unknown[]) => unknown).bind(t) : v;\n },\n });\n realOf.set(proxy, s);\n return proxy;\n };\n return new Proxy(real, {\n get(t, prop, r) {\n const v = Reflect.get(t, prop, r) as unknown;\n if (prop === \"prepare\") return (sql: string) => wrapStatement(t.prepare(sql));\n if (prop === \"batch\") {\n return (stmts: D1PreparedStatement[]) =>\n track(t.batch(stmts.map((s) => realOf.get(s) ?? s)));\n }\n if (prop === \"exec\") return (sql: string) => track(t.exec(sql));\n return typeof v === \"function\" ? (v as (...x: unknown[]) => unknown).bind(t) : v;\n },\n });\n}\n\nfunction isD1(value: unknown): value is D1Database {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { prepare?: unknown }).prepare === \"function\"\n );\n}\n\nasync function snapshotAll(\n spec: ScenarioSpec,\n options: CloudflarePlatformOptions,\n): Promise<Side[\"state\"]> {\n const env = options.env as Record<string, unknown>;\n const out: Record<string, { readonly [table: string]: readonly JsonValue[] }> = {};\n for (const step of spec.setup) {\n if (step.kind !== \"d1\") continue;\n const binding = String(step[\"binding\"]);\n const real = env[binding];\n if (isD1(real)) out[binding] = await snapshotD1(real);\n }\n return out;\n}\n\n/** The Eutaxy side: one run with no faults, driven like `runOnce` but keeping each delivery's status. */\nasync function eutaxySide(\n spec: ScenarioSpec,\n options: CloudflarePlatformOptions,\n): Promise<Side & { readonly unsupported: readonly string[] }> {\n const platform = createCloudflarePlatform(options);\n const run = new Run({\n mode: \"replay\",\n schedule: { seed: 0, faults: [] },\n bounds: spec.bounds,\n faultProbability: 0,\n });\n const attempts: AttemptRecord[] = [];\n await platform.reset(spec);\n run.install(spec.externals);\n try {\n const pending: EventRef[] = [...platform.initialEvents(spec)];\n while (pending.length > 0) {\n const event = pending.shift() as EventRef;\n const invocation = `${event.id}#${event.attempt}`;\n const before = run.log.entries.length;\n const result = await platform.deliver(event, run, spec);\n const decision = run.log.entries\n .slice(before)\n .find(\n (e) =>\n e.invocation === invocation &&\n e.kind === \"result\" &&\n (e.op === \"ack\" || e.op === \"retry\") &&\n getPath(e.payload, \"result.effective\") === true,\n )?.op as \"ack\" | \"retry\" | undefined;\n attempts.push({\n event: event.id,\n attempt: event.attempt,\n status: result.status === \"completed\" ? \"completed\" : \"errored\",\n decision: decision ?? null,\n });\n pending.push(...result.followUps);\n }\n } finally {\n run.uninstall();\n }\n await platform.finish?.(spec, run);\n return { attempts, state: await snapshotAll(spec, options), unsupported: run.unsupportedReasons };\n}\n\n/** The raw side: the handler called directly with the real bindings and plain message objects. */\nasync function rawSide(spec: ScenarioSpec, options: CloudflarePlatformOptions): Promise<Side> {\n const env = options.env as Record<string, unknown>;\n const drive = spec.drive as QueueDrive;\n const maxRetries = options.maxRetries ?? 3;\n for (const step of spec.setup) {\n if (step.kind !== \"d1\") continue;\n const binding = String(step[\"binding\"]);\n const schema = options.schemas[binding];\n const real = env[binding];\n if (schema !== undefined && isD1(real)) await resetD1(real, schema);\n }\n const handler = options.handler.queue;\n if (!handler) throw new Error(\"the Worker has no queue() handler\");\n const attempts: AttemptRecord[] = [];\n const pending: EventRef[] = drive.messages.map((m) => ({ id: m.id, attempt: 1, data: m.body }));\n // The same virtual globals as the proxied side, from the same seed, so Date.now and randomness agree,\n // and the same scripted externals, without recording.\n const patched = patchGlobals(0);\n const unsupported: string[] = [];\n const restoreFetch = installScriptedFetch(\n spec.externals,\n null,\n (r) => unsupported.push(r),\n () => patched.clock.advance(effectLatencyMs), // the proxied side advances per effect; match it\n );\n const io = { n: 0 };\n const counting = new Map<string, D1Database>();\n const countedEnv = new Proxy(env, {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver) as unknown;\n if (typeof prop !== \"string\" || !isD1(value)) return value;\n let c = counting.get(prop);\n if (!c) {\n c = countingD1(value, io, patched.clock);\n counting.set(prop, c);\n }\n return c;\n },\n });\n const settle = <T>(p: Promise<T>): Promise<T> =>\n settleOn(p, {\n clock: patched.clock,\n inFlight: () => io.n,\n crashed: () => false,\n stuck: () => {\n throw new StuckError();\n },\n });\n try {\n while (pending.length > 0) {\n const event = pending.shift() as EventRef;\n let decision: \"ack\" | \"retry\" | null = null;\n const background: Promise<unknown>[] = [];\n const message: Message<unknown> = {\n id: event.id,\n timestamp: new Date(),\n body: JSON.parse(JSON.stringify(event.data)) as JsonValue,\n attempts: event.attempt,\n ack: () => {\n decision ??= \"ack\";\n },\n retry: () => {\n decision ??= \"retry\";\n },\n };\n const batch: MessageBatch<unknown> = {\n queue: drive.queue,\n messages: [message],\n metadata: { metrics: { backlogCount: 0, backlogBytes: 0 } },\n ackAll: () => message.ack(),\n retryAll: () => message.retry(),\n };\n const ctx = {\n waitUntil: (p: Promise<unknown>) => {\n background.push(\n p.then(\n () => undefined,\n () => undefined,\n ),\n );\n },\n passThroughOnException: () => {},\n props: {},\n } as unknown as ExecutionContext;\n let status: \"completed\" | \"errored\";\n try {\n await settle(\n Promise.resolve().then(() => handler.call(options.handler, batch, countedEnv, ctx)),\n );\n status = \"completed\";\n } catch (err) {\n if (err instanceof CrashSignal || err instanceof StuckError) throw err;\n status = \"errored\";\n }\n if (status === \"completed\") decision ??= \"ack\";\n await settle(Promise.all(background));\n attempts.push({ event: event.id, attempt: event.attempt, status, decision });\n if (\n decision !== \"ack\" &&\n event.attempt <= maxRetries &&\n event.attempt - 1 < spec.bounds.maxRedeliveries\n ) {\n pending.push({ ...event, attempt: event.attempt + 1 });\n }\n }\n } finally {\n restoreFetch();\n patched.restore();\n }\n if (unsupported.length > 0) throw new StuckError(`raw side: ${unsupported.join(\"; \")}`);\n return { attempts, state: await snapshotAll(spec, options) };\n}\n\n/** Run both sides and compare. The Eutaxy side runs first; both start from the schema. */\nexport async function runDifferential(\n spec: ScenarioSpec,\n options: CloudflarePlatformOptions,\n): Promise<DifferentialResult> {\n const { unsupported, ...eutaxy } = await eutaxySide(spec, options);\n const raw = await rawSide(spec, options);\n const differences: string[] = [];\n if (unsupported.length > 0) {\n differences.push(`the proxied run touched unsupported APIs: ${unsupported.join(\"; \")}`);\n }\n const a = canonicalJson(eutaxy.attempts as unknown as JsonValue);\n const b = canonicalJson(raw.attempts as unknown as JsonValue);\n if (a !== b) differences.push(`attempts differ:\\n eutaxy ${a}\\n raw ${b}`);\n const bindings = new Set([...Object.keys(eutaxy.state), ...Object.keys(raw.state)]);\n for (const binding of [...bindings].sort()) {\n const tables = new Set([\n ...Object.keys(eutaxy.state[binding] ?? {}),\n ...Object.keys(raw.state[binding] ?? {}),\n ]);\n for (const table of [...tables].sort()) {\n const x = canonicalJson((eutaxy.state[binding]?.[table] ?? []) as unknown as JsonValue);\n const y = canonicalJson((raw.state[binding]?.[table] ?? []) as unknown as JsonValue);\n if (x !== y) differences.push(`${binding}.${table} differs:\\n eutaxy ${x}\\n raw ${y}`);\n }\n }\n return { equal: differences.length === 0, eutaxy, raw, differences, unsupported };\n}\n","/**\n * Typed construction of scenario specs for Cloudflare Workers. Everything here\n * produces the plain-data `ScenarioSpec` from core; this module only knows the\n * Cloudflare shapes (queues, D1 bindings) and the effect conventions the\n * proxies follow.\n */\n\nimport {\n type AtLeastOnce,\n type AtMostOncePerKey,\n type Bounds,\n defaultBounds,\n type EffectSelector,\n type EveryRow,\n type ExternalDecl,\n getPath,\n type Implies,\n type Invariant,\n type JsonValue,\n type PlatformData,\n type RowCondition,\n type ScenarioSpec,\n type ScriptedResponse,\n type StateQuery,\n validateScenario,\n type WorkerRef,\n} from \"@eutaxy/core\";\n\n/** One queue message to deliver; `id` defaults to its position. */\nexport interface QueueMessage {\n readonly id?: string;\n readonly body: JsonValue;\n}\n\n/** Drive the Worker's `queue()` handler with these messages. */\nexport interface QueueDrive extends PlatformData {\n readonly kind: \"queue\";\n readonly queue: string;\n readonly messages: readonly { readonly id: string; readonly body: JsonValue }[];\n}\n\n/** Apply a SQL file to a D1 binding before each run. */\nexport interface D1Setup extends PlatformData {\n readonly kind: \"d1\";\n readonly binding: string;\n readonly schemaFile: string;\n}\n\nexport interface CloudflareScenarioInput {\n readonly name: string;\n readonly worker: WorkerRef;\n readonly drive:\n | QueueDrive\n | {\n readonly kind: \"queue\";\n readonly queue: string;\n readonly messages: readonly QueueMessage[];\n };\n readonly setup?: readonly D1Setup[];\n readonly externals?: readonly ExternalDecl[];\n readonly invariants: readonly Invariant[];\n readonly bounds?: Partial<Bounds>;\n}\n\nexport function queue(name: string, messages: readonly QueueMessage[]): QueueDrive {\n return {\n kind: \"queue\",\n queue: name,\n messages: messages.map((m, i) => ({ id: m.id ?? `msg-${i + 1}`, body: m.body })),\n };\n}\n\nexport function d1Schema(binding: string, schemaFile: string): D1Setup {\n return { kind: \"d1\", binding, schemaFile };\n}\n\n/**\n * Effect conventions for D1 (what the proxies record):\n * call payload { args: { sql, params } }\n * result payload { args: { sql, params }, result: { changes, lastRowId } }\n * A committed write is a `result` whose `result.changes` is at least 1.\n */\nexport function d1Write(binding: string, op: \"run\" | \"batch\" = \"run\"): EffectSelector {\n return { target: `D1:${binding}`, op, kind: \"result\", atLeast: { \"result.changes\": 1 } };\n}\n\n/** Dot path to the Nth bound parameter of a D1 statement, in an effect payload. */\nexport function d1Param(index: number): string {\n return `args.params.${index}`;\n}\n\nexport function atMostOncePerKey(\n name: string,\n effect: EffectSelector,\n key: string,\n): AtMostOncePerKey {\n return { kind: \"atMostOncePerKey\", name, effect, key };\n}\n\nexport function atLeastOnce(\n name: string,\n effect: EffectSelector,\n key: string,\n expected: readonly JsonValue[],\n): AtLeastOnce {\n return { kind: \"atLeastOnce\", name, effect, key, expected };\n}\n\n/**\n * Every message's `bodyKey` value must appear at least once as `key` in a\n * selected effect: nothing the queue delivered may be lost.\n */\nexport function atLeastOncePerMessage(\n name: string,\n drive: QueueDrive,\n effect: EffectSelector,\n key: string,\n bodyKey: string,\n): AtLeastOnce {\n const expected: JsonValue[] = [];\n for (const m of drive.messages) {\n const v = getPath(m.body, bodyKey);\n if (v === undefined) {\n throw new Error(`message ${m.id} has no ${JSON.stringify(bodyKey)} in its body`);\n }\n expected.push(v);\n }\n return { ...atLeastOnce(name, effect, key, expected), perMessage: { bodyKey } };\n}\n\n/** Rows of a D1 table in the end-of-run snapshot, optionally filtered. */\nexport function d1Rows(\n binding: string,\n table: string,\n where?: readonly RowCondition[],\n): StateQuery {\n return where ? { target: `D1:${binding}`, table, where } : { target: `D1:${binding}`, table };\n}\n\n/** Every row the query selects satisfies all conditions. */\nexport function everyRow(\n name: string,\n query: StateQuery,\n holds: readonly RowCondition[],\n): EveryRow {\n return { kind: \"everyRow\", name, query, holds };\n}\n\n/** Every selected effect has a row whose column equals the effect's key. */\nexport function implies(\n name: string,\n when: EffectSelector,\n key: string,\n state: StateQuery,\n column: string,\n): Implies {\n return { kind: \"implies\", name, when, key, state, column };\n}\n\n/** Selects the acknowledgement that took effect for each message (explicit or implicit; not one ignored after a retry). */\nexport function queueAck(queueName: string): EffectSelector {\n return {\n target: `Queue:${queueName}`,\n op: \"ack\",\n kind: \"result\",\n where: { \"result.effective\": true },\n };\n}\n\n/**\n * Declare an external service: requests to `host` are answered from\n * `responses` (every request gets 200 and an empty body when omitted), and\n * `dedupeBy` names the header whose value makes repeated requests\n * idempotent at that service.\n */\nexport function external(\n name: string,\n host: string,\n options: { readonly dedupeBy?: string; readonly responses?: readonly ScriptedResponse[] } = {},\n): ExternalDecl {\n return {\n name,\n host,\n guarantees: options.dedupeBy ? { dedupeBy: options.dedupeBy } : {},\n ...(options.responses ? { responses: options.responses } : {}),\n };\n}\n\n/**\n * Selects the requests to an external that took effect: a request replayed\n * under a dedupe key the external had already seen is not counted.\n */\nexport function fetchCall(externalName: string, method?: string): EffectSelector {\n return {\n target: `Fetch:${externalName}`,\n ...(method ? { op: method.toUpperCase() } : {}),\n kind: \"result\",\n where: { \"result.effective\": true },\n };\n}\n\n/** Build and validate a scenario spec; throws with every problem listed. */\nexport function defineScenario(input: CloudflareScenarioInput): ScenarioSpec {\n const drive: QueueDrive =\n \"messages\" in input.drive &&\n input.drive.messages.every((m) => \"id\" in m && typeof m.id === \"string\")\n ? (input.drive as QueueDrive)\n : queue(input.drive.queue, input.drive.messages);\n const spec: ScenarioSpec = {\n version: 1,\n name: input.name,\n platform: \"cloudflare\",\n worker: input.worker,\n drive,\n setup: input.setup ?? [],\n externals: input.externals ?? [],\n invariants: input.invariants,\n bounds: { ...defaultBounds, ...input.bounds },\n };\n const errors = validateScenario(spec);\n if (errors.length > 0) {\n throw new Error(`invalid scenario ${JSON.stringify(input.name)}:\\n- ${errors.join(\"\\n- \")}`);\n }\n return spec;\n}\n"],"mappings":"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"}
|