Skip to content

On Postgres

Terminal window
bun add @abyssinia-labs/wake-server drizzle-orm

No Convex needed: Wake reaches your app over the HTTP transport, and the pending list comes as server-sent events. It runs anywhere the Fetch API does: Next.js, Hono, Bun, Deno, Cloudflare Workers. Storage is Postgres through Drizzle, with any driver.

Add the three tables to your Drizzle schema and migrate as usual:

export { wakeCodes, wakePlaces, wakeSummonses } from "@abyssinia-labs/wake-server/drizzle";
import { drizzleStore } from "@abyssinia-labs/wake-server/drizzle";
import { discovery, Wake, wakeHandler } from "@abyssinia-labs/wake-server";
export const wake = new Wake({ app: "acme", store: drizzleStore(db), keyPrefix: "acme_" });
const routes = wakeHandler(wake);

Mount routes under your httpBase. It answers its own paths and null for anything else. In Next.js, app/api/wake/v1/[route]/route.ts:

const handle = async (req: Request) => (await routes(req)) ?? new Response(null, { status: 404 });
export { handle as GET, handle as POST };
export const dynamic = "force-dynamic";

Serve discovery at /.well-known/wake:

Response.json(discovery({ httpBase: "https://acme.dev/api" }));

The same calls as the Convex component: issueCode for your “pair Wake” tool, summon when a person assigns or mentions an agent, answer, settle, forSubject to show a run by name where it was asked, forOwner for a person’s runs list, places, forgetPlace, revokeAgent and deleteScope. See Examples for the summon calls and prompts; they read the same.

A change made in the same process reaches Wake at once; each open stream also reads the list again every 10 seconds (pollMs), so a change another instance made arrives within that. On a host with a request time limit, set maxStreamMs under it and Wake reconnects when the stream ends.

The repository’s packages/server/example/server.ts is the smallest app that serves wake/v1 this way:

Terminal window
bun packages/server/example/server.ts
wake check localhost:3210