Skip to content

Realtime adapters

Copy page

Realtime adapters implement:

interface RealtimeAdapter {
publish(bucket: string): void;
subscribe(buckets: string[], onPing: (bucket: string) => void): Unsubscribe;
}

publish is called only from the mutator commit chokepoint. Payload is the bucket key — clients pull for data.

import { inProcessRealtime } from "@nizhal/server/adapters";
createNizhalServer({ ..., realtime: inProcessRealtime() });

In-memory bucket → WebSocket set registry. Zero extra deps; correct for single-process self-host on any database.

import { listenNotifyRealtime } from "@nizhal/server/adapters";
createNizhalServer({
...,
realtime: listenNotifyRealtime({ connectionString: process.env.DATABASE_URL! }),
});

Multi-instance Postgres via LISTEN/NOTIFY. buildListenNotifyProvisionPlan adds channel DDL.

import { cloudflareRealtime, cloudflareHttpRealtime } from "@nizhal/server/adapters/cloudflare";
import { NizhalBucket } from "@nizhal/server/adapters/cloudflare";

cloudflareRealtime — Durable Object hub (PartyServer). createNizhalWorkerFetchHandler wires HTTP + WS on Workers.

cloudflareHttpRealtime — HTTP long-poll fallback when native WS is constrained.

See Cloudflare self-hosting.

Default client uses PartySocket-compatible reconnect. @nizhal/db-collection exports createPartySocketSource and createCloudflareSubscribeSource.

Missed pings self-heal via cursor pull; optional pull.intervalMs on the client.