Skip to content
Quickstart

Quickstart

Durable email submission and recipient delivery tracking

This sends one email through an in-memory node:sqlite store and a fake transport. Swap the transport for a real provider and the store for your Durable Object storage when you deploy.

quickstart.ts
import { DatabaseSync } from "node:sqlite";
import { fromNodeSqlite } from "@fungi.computer/watchdog/node-sqlite";
import { createCarrier } from "@fungi.computer/carrier";
const database = new DatabaseSync(":memory:");
const owner = fromNodeSqlite(database);
const carrier = await createCarrier({
storage: owner,
now: Date.now,
host: {
// Commit the mutation together with a durable wake. A demo needs no wake.
commit: async (mutation) => mutation(),
requestWake: async () => {},
},
transport: async (email) => {
console.log(`provider got "${email.subject}"`);
return { kind: "provider_accepted", providerMessageId: "demo-1" };
},
});
const receipt = await carrier.send({
id: "welcome:user-123:v1",
from: { email: "hello@example.com", name: "Example" },
to: ["ada@example.net"],
subject: "Welcome",
text: "Your account is ready.",
});
console.log(receipt.status); // "queued"
await carrier.tick(); // your wake calls this
console.log((await carrier.get(receipt.id))?.status); // "provider_accepted"
database.close();

send() only accepts the email. The provider call happens on tick(), which a real host runs from its durable wake. The Cloudflare adapter does this for you from the Durable Object alarm.

In a Durable Object, ctx.storage is already the SQLite owner.

createMemoryOutbox() stores encoded string rows in process memory for tests and quick starts. It provides put, read, key-ordered list(limit, afterKey) and delete. Each instance is independent; it is not durable storage. BirdDog’s quick start uses this helper.

TS
import { createMemoryOutbox } from "@fungi.computer/carrier/testing";
const outbox = createMemoryOutbox();
await outbox.put("mail:one", "encoded mail");
console.log(await outbox.list(1));
// [{ key: "mail:one", value: "encoded mail" }]