← All @molecule/* packages · App templates
@molecule/api-realtime-wsProvider bond · realtime · API (Node) · v1.0.1 · Apache-2.0
Raw WebSocket (ws) realtime provider for molecule.dev
npm install @molecule/api-realtime-wsnpm · Source on GitHub · Implements @molecule/api-realtime
@molecule/api-realtime-ws is a provider bond on the API (Node) side: it implements the realtime core interface (@molecule/api-realtime) with a concrete vendor or library behind it.
Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.
import { createProvider } from '@molecule/api-realtime-ws'
import { setProvider } from '@molecule/api-realtime'
import http from 'node:http'
const server = http.createServer()
const realtimeProvider = createProvider({ httpServer: server })
setProvider(realtimeProvider)
server.listen(3000)Works with: @molecule/api-bond, @molecule/api-realtime
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Raw WebSocket (ws) realtime provider for molecule.dev.
Provides a ws-backed implementation of the
@molecule/api-realtime {@link RealtimeProvider} interface.
broadcast() throws Room "<id>" does not exist when the room matches no
managed room and no protocol room — a protocol room ceases to exist when its last
member leaves/disconnects, so a push to a room nobody is viewing is an ERROR here
(the -socketio bond silently no-ops instead). Reserved protocol frames use the
same JSON framing: { event: 'molecule:join' | 'molecule:leave' | 'molecule:room-send', data: { room, … } }.import { createProvider } from '@molecule/api-realtime-ws'
import { setProvider } from '@molecule/api-realtime'
import http from 'node:http'
const server = http.createServer()
const realtimeProvider = createProvider({ httpServer: server })
setProvider(realtimeProvider)
server.listen(3000)
provider
npm install @molecule/api-realtime-ws @molecule/api-bond @molecule/api-realtime ws
npm install -D @types/ws
WsRealtimeConfigConfiguration options for the raw WebSocket realtime provider.
interface WsRealtimeConfig {
/**
* `ws` server options passed to the `WebSocketServer` constructor.
*
* @see https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback
*/
serverOptions?: ServerOptions
/**
* An existing Node.js HTTP server to attach the WebSocket server to. This
* is itself an explicit attach step — when given, a standalone WebSocket
* server is created and attached immediately, regardless of `deferAttach`.
*/
httpServer?: Server
/**
* Port to listen on for a standalone server. Passing this **explicitly**
* is an explicit instruction to bind a standalone server immediately (no
* `httpServer` needed) — env-aware for the actual value: `WS_PORT` if set,
* else `PORT + 1000` (one above the API convention), else `3000`, so
* multiple apps can run side-by-side.
*
* **Omitting `port` (along with `httpServer` and `deferAttach`) does NOT
* bind a default port** — creating a provider must never bind a port as a
* side effect. A zero-config `createProvider()` behaves exactly like
* `{ deferAttach: true }` instead: it waits for
* {@link RealtimeProvider.attachHttpServer} and logs an info line naming
* the bond so the omission is visible.
*/
port?: number
/**
* Defer creating the standalone WebSocket server until
* {@link RealtimeProvider.attachHttpServer} is called, instead of binding
* eagerly at creation. Used by the server factory so `ws` attaches to the
* API's HTTP server (shared port) once it exists — avoiding a standalone
* port a sandbox/proxy may not expose and that collides with the API's own
* port by default. Ignored when `httpServer` is already provided (that is
* itself an explicit attach — see the module `@remarks`). Zero-config
* (no `port`, no `httpServer`, no `deferAttach`) already behaves as if
* this were `true` — set it explicitly for readability/intent at the call
* site, not because it changes behavior over omitting it.
*
* @defaultValue false
*/
deferAttach?: boolean
/**
* Currently UNUSED — the provider never reads this option. Clients send
* JSON frames shaped `{ event, data, room? }` and the frame's own `event`
* field (defaulting to `'message'` when absent) is what reaches `onMessage`
* handlers; there is no configurable envelope event name.
*/
messageEvent?: string
}
createProvider(config)Creates a raw WebSocket-backed {@link RealtimeProvider}.
function createProvider(config?: WsRealtimeConfig): RealtimeProvider
config — WebSocket provider configuration.Returns: A fully initialised RealtimeProvider backed by ws.
Implements @molecule/api-realtime interface.
Peer dependencies:
@molecule/api-bond ^1.0.1@molecule/api-realtime ^1.0.1@molecule/api-bond
@molecule/api-realtime
ws
createProvider() with NO port, NO httpServer, and NO
deferAttach does NOT bind anything — creating a provider must never
bind a port as a side effect. It behaves exactly like { deferAttach: true } (waits for attachHttpServer(server)), logging an info line so
the omission is visible instead of silent. An explicit port still
binds a standalone server immediately (unchanged, back-compat for
existing standalone callers) — it just no longer happens by accident. In
a real deployment prefer deferring and attaching once the API's HTTP
server exists:
const realtimeProvider = createProvider({ deferAttach: true })
setProvider(realtimeProvider)
// once the API's http.Server exists (e.g. a server-created hook):
realtimeProvider.attachHttpServer(server)
so ws shares the API's port instead of a separate one. A standalone
bind failure (e.g. EADDRINUSE) is logged via the bonded logger naming
this bond and the port, instead of crashing the process with an
unattributed error.
Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual screens/flows, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:
onJoinRequest was never registered — an integration bug.