actor-gateway
v0.4.24
Published
Server-authoritative actors with durable commands, realtime events, and resumable clients.
Readme
Actor Gateway
Server-authoritative actors with durable commands, realtime events, resumable clients, and a Vercel adapter. Actors are addressed by a logical ID; the runtime persists each accepted command before confirming it and replays missed events after reconnect.
Install
npm install actor-gatewayFor the optional collaboration model, install its peers too:
npm install actor-gateway yjs y-protocolsThe published package is the runtime library. It does not include this repository's demo application, test scripts, or research documentation.
Managed Vercel actor platform
Declare the deployment's actors in actor-gateway.ts:
import crypto from 'node:crypto';
import { Actor, event, defineActorGateway } from 'actor-gateway/server';
class Room extends Actor {
static state = () => ({ messages: [] });
static events = { message: event() };
send(text) {
if (typeof text !== 'string' || text.length > 500) throw new Error('invalid_message');
const message = { id: crypto.randomUUID(), text, author: this.ctx.scope.principal };
this.state.messages.push(message);
this.emit('message', message);
return message;
}
}
export default defineActorGateway({
actors: { room: Room },
authenticate: async ({ request }) => {
const session = await requireSession(request);
return {
principal: session.user.id,
teamId: session.teamId,
projectId: process.env.VERCEL_PROJECT_ID,
allowedActorScope: 'room:*',
};
},
onBeforeConnect: async ({ actor, scope }) => ({ allow: actor.key[0] === scope.teamId }),
});
Responsibilities
- Your
actor-gateway.ts: declares actor classes and maps a consumer session to a scoped actor identity inauthenticate. Actor methods execute application behavior and state-aware authorization. - The
actor-gatewayCLI: reads that entrypoint, validates and bundles it, generates/.well-known/actor/v1/*integration routes, deploys the consumer application when needed, and registers the immutable bundle. - The managed service: stores the deployment directory and durable actor state, verifies actor JWTs, orders commands, fences checkpoints, supervises effects, and coordinates Sandbox replacement. It never executes actor code or relays live WebSocket frames.
- The consumer-owned Sandbox: runs actor instances, timers, PartyKit lifecycle hooks, effect handlers, and the direct browser WebSocket data path.
The generated platform routes are versioned and internal to the SDK:
/.well-known/actor/v1/config.json/.well-known/actor/v1/token/.well-known/actor/v1/jwks/.well-known/actor/v1/resolve
Build and deploy from the consumer deployment:
npx actor-gateway build
npx actor-gateway deploy
npx actor-gateway verifybuild writes .actor-gateway/managed-runner.mjs, its manifest, and the
generated routes. deploy registers the content-addressed bundle with the
managed service, asks the consumer deployment's private upgrade agent to start
a fresh Sandbox, verifies it, and activates it. The browser SDK handles token
issuance and active-Sandbox resolution internally; product code never needs
the managed service URL or a Sandbox URL.
The generated token route calls authenticate, signs a short-lived JWT, and
keeps the signing key, consumer session, and OAuth credentials inside the
consumer deployment. The managed service receives only the issuer, audience,
and public JWKS URL needed to verify that JWT.
The deployment build needs one protected environment variable:
AGW_GATEWAY_API_KEY— the control-plane registration credential.
Optionally set AGW_GATEWAY_URL for a non-production gateway. The default is
the production gateway. Do not expose this credential or an actor token to the
browser.
Authentication and clients
Managed browser clients obtain their short-lived actor JWT from the generated
/.well-known/actor/v1/token route. They resolve the active Sandbox through
the generated platform route and connect directly to it; application code does
not pass a Gateway URL, Sandbox URL, session cookie, signing key, or token
endpoint to the client SDK.
The consumer deployment must have the Vercel CLI installed and authenticated
before running actor-gateway deploy. The CLI uses those consumer credentials
to deploy the application when needed and to create its Sandboxes.
Package entry points
actor-gateway/server— actor definitions, events, effects, and registry setup.actor-gateway/client— resumable browser/client SDK.actor-gateway/react— React integration.actor-gateway/vercel— Vercel WebSocket and HTTP adapter.actor-gateway/partykit,actor-gateway/partysocket, andactor-gateway/partysocket/react— PartyKit-compatible server and client APIs.actor-gateway/yjsandactor-gateway/yjs/client— optional Yjs model and browser provider; requires theyjsandy-protocolspeer dependencies.
Experimental models and Yjs
The actor APIs above are stable. Cell models and the Yjs subpaths are experimental, deployment-pinned trusted code. They receive scoped cell capabilities only: model code cannot receive a database client, a physical cell ID, system scope, or another tenant/model slot.
Yjs documents use bounded updates, state-vector repair, fenced compaction, and strictly ephemeral awareness. Configure document, retained-tail, sync-chunk, and awareness budgets for the largest document your product supports. The gateway records per-model operation latency, inbound/rejected bytes, receipt dedupes, sync volume, compaction lag, and fencing conflicts through its metrics sink.
Fanout is an advisory latency path, not a delivery guarantee; clients repair from durable state vectors after reconnect or dropped notifications. The runtime intentionally does not support tenant-supplied model code, raw storage access, cross-model atomicity, synchronous cross-actor RPC, or distributed multi-actor transactions.
The PartyKit adapter is a runtime API. It does not load partykit.json or
provide a PartyKit development server: define and deploy it through the normal
Actor Gateway setup.
