Serving & Connecting
Stand up an acceptor with serveChannel and dial it with connectChannel.
serveChannel and connectChannel are the two high-level entry points. Each binds the shared facts — the channel, the runtime, and one crypto identity — into every transport, so you state them once.
Accepting — serveChannel
Section titled “Accepting — serveChannel”serveChannel builds the crypto identity once, fans it across every carrier, registers your handlers, wires hibernation, and returns a server object whose lifecycle methods you forward to the host.
import { ActionRuntime, RuntimeCoordinate, serveChannel, wsAcceptorCarrier, httpAcceptorCarrier,} from "@nice-code/action";
const runtime = new ActionRuntime(serverCoord);
const server = serveChannel(runtime, appChannel, { clientEnv: RuntimeCoordinate.env("frontend"), // env of connecting clients (optional) storage: storageAdapter, // backs identity + key pins (persistent) handlers: [userHandler], carriers: [ wsAcceptorCarrier({ send: (ws, frame) => ws.send(frame) /* upgrade, attachmentStore */ }), httpAcceptorCarrier(), // HTTP fallback on the same channel ],});It returns { handlers, fetch, receive, drop, pushToClient, broadcast }:
fetch— a web-standard handler doing the WS upgrade, the action POST, CORS preflight, and a 404 fallback. Forward the host’sfetchstraight to it.receive(conn, frame)/drop(conn)— the universal connection lifecycle. Forward your host’s message and close/error events here.pushToClient/broadcast— server-initiated pushes (see Bi-directional).
// Wire the host's events to the server:// fetch(req) => server.fetch(req)// webSocketMessage(ws, msg) => server.receive(ws, msg)// webSocketClose/Error(ws) => server.drop(ws)One server, several client envs.
clientEnvis optional. A result or push to a connected client always routes back over the carrier it connected on, so oneserveChannelaccepts clients of different envs (e.g. awalletand apartnerrole) over one acceptor. Only setclientEnvfor a scoring fallback when returning to a client that is no longer connected.
Connecting — connectChannel
Section titled “Connecting — connectChannel”The connector has one runtime and connectChannels to each acceptor. It routes the channel’s toAcceptor domains out over the transports (first = preferred, rest = fallback) and registers handlers for toConnector pushes from onPush.
import { ActionRuntime, RuntimeCoordinate, ESecurityLevel, connectChannel, wsCarrier, httpCarrier,} from "@nice-code/action";
export const clientRuntime = new ActionRuntime(RuntimeCoordinate.env("frontend"));
connectChannel(clientRuntime, appChannel, { peer: serverCoord, storage, // one crypto identity, fanned across secure transports securityLevel: ESecurityLevel.encrypted, transports: [ { carrier: wsCarrier(() => ({ url: "wss://api.example.com/ws" })) }, // secure WS, preferred { carrier: httpCarrier(() => ({ url: "https://api.example.com/action" })), secure: false }, // plain HTTP fallback ], // onPush: { ... } // handlers for toConnector pushes});Key options: peer (the acceptor’s coordinate), transports (by carrier, in preference order, with automatic fallback), storage (required when any transport is secure), securityLevel, onPush, defaultTimeout. It returns the ConnectorHandler so you can handler.clearTransportCache() on teardown.
Next: Calling actions →