Skip to main content
Markdown

Server reference: @wordplus/realtime/server

Node 20 or later, and every edge runtime: it runs on Web Crypto and fetch. For PHP and Laravel, see the PHP reference; for Python, the Python reference. All three take the same options and answer the browser the same way.

createRealtime( options ) → Realtime​

Option
site, secretyour app's key and secret (WORDPLUS_SITE, WORDPLUS_SECRET)
localKey64 hex characters of your own (WORDPLUS_LOCAL_KEY) (encryption)
user( request )the request's user's id, or null: what route asks
profile( user ){ name, avatar?, url?, … } or null: their directory entry, their presence info and call info by default
hasKeys( user )false cuts a user off every key
generations{ get( name ), set( name, n ) }, for rotateChannel() and rotateUser()
sealfalse sends everything plain
basewhere your routes are, /api/realtime by default, for config()
headersheaders the browser sends to your routes, such as a CSRF token, for config()
worker, roomswhere your app serves the two files, for config()
tokenTtl, callTokenTtlseconds: 6 hours by default; a channels token at most a day, a calls token at most 6 hours
server, apiWordPlus Cloud by default
fetchyour own, for publishing

Owners​

Method
channel( prefix, ( user, channel ) => answer )private and presence channels by the start of their names; false, true, or { id, info } (channels, presence)
calls( prefix, ( user, call, withUser ) => answer )calls and rooms; false, true, or { info, publish, subscribe, admin, hidden } (calls)
kind( kind, ( rest, user, label ) => boolean, newest? )keys of your own kind (encryption)

Callbacks may be async. The longest prefix that fits decides.

Routes​

route( request: Request ) => Promise<Response>: POST …/auth, …/calls, …/keys, the action from the path's last part; Next.js export const POST = realtime.route
node( ( req ) => user )( req, res ) for Node's own servers and Express; a body express.json() parsed is taken as it is
handle( action, body, user )→ { status, body }: one route, for a framework of your own

They take JSON POSTs only (415 otherwise): a page on another site can't send one without asking first, which it is never allowed. A refusal is an answer (denied), not an HTTP error.

MethodWhat it answers
authorize( channels, user ){ token, exp, keys, denied }
authorizeCall( request, user ){ token, exp, key } or { denied }
keysAnswer( labels, user ){ keys, identity? }
identity( user ){ token, exp } or null
token( channels, { user, info, ttl } )a channels token, signed as the auth route signs
config( user )the browser's settings, with a signed-in user's keys and identity

Publishing​

Method
publish( channels, event, data, { except, seal } )(publishing)
publishBatch( [ { channels, event, data, except, seal } ] )10 events a request
channelInfo( channel ){ subscriptions, members? }
rotateChannel( channel ), rotateUser( user )moves a key on
keysthe Keys: seal( text, label ), sealJson, open, entry( label ), dayLabel(), channelLabel( channel )

All throw RealtimeError (code, status) for the server's refusal (errors).