feat: add application productivity foundations
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { createDb } from "@wrnexus/db";
|
||||
import { sqlite } from "@wrnexus/db/sqlite";
|
||||
import {
|
||||
createDurableQueue,
|
||||
defineSaga,
|
||||
drainOutbox,
|
||||
memoryQueueStore,
|
||||
testQueue,
|
||||
withOutbox,
|
||||
} from "../src/index.ts";
|
||||
|
||||
test("outbox commits intents and deterministic queue helpers dispatch them", async () => {
|
||||
const db = createDb(sqlite(":memory:"));
|
||||
const queue = createDurableQueue({ store: memoryQueueStore() });
|
||||
const seen: number[] = [];
|
||||
queue.process("email:send", async (job) => void seen.push((job.data as { id: number }).id));
|
||||
await withOutbox(db, async ({ enqueue }) => enqueue({ name: "email:send" } as never, { id: 7 }));
|
||||
expect(
|
||||
await drainOutbox(db, (name) =>
|
||||
name === "email:send"
|
||||
? { add: (data, options) => queue.add(name, data, options) }
|
||||
: undefined,
|
||||
),
|
||||
).toBe(1);
|
||||
expect(await testQueue(queue).runAll()).toBe(1);
|
||||
expect(seen).toEqual([7]);
|
||||
});
|
||||
|
||||
test("sagas compensate completed steps in reverse order", async () => {
|
||||
const calls: string[] = [];
|
||||
const saga = defineSaga({
|
||||
name: "send",
|
||||
steps: [
|
||||
{
|
||||
name: "reserve",
|
||||
run: () => void calls.push("reserve"),
|
||||
compensate: () => void calls.push("refund"),
|
||||
},
|
||||
{
|
||||
name: "queue",
|
||||
run: () => {
|
||||
throw new Error("down");
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
await expect(saga.run({})).rejects.toThrow("down");
|
||||
expect(calls).toEqual(["reserve", "refund"]);
|
||||
});
|
||||
Reference in New Issue
Block a user