PlayMesh/Docs
HomeGitHubnpm

Server API

Complete reference for @playmesh/server - PlayMesh, Domain, Instance, and Session.

PlayMesh

The root class. Import from @playmesh/server.

Constructor

import { PlayMesh } from '@playmesh/server';
const mesh = new PlayMesh(options?: PlayMeshOptions);
Method / PropertyDescriptionReturns
portPort to listen on. Defaults to 3000. Pass 0 for ephemeral port.number
serverAttach to a pre-existing HTTP server.http.Server
redisRedis connection options or URL string. Enables distributed mode.RedisOptions | string
socketOptions forwarded to the Socket.IO server.Partial<ServerOptions>
signingSign all application events with ECDSA P-256. Clients must enable signing too.boolean
uniqueUserOne live session per userId: 'replace' kicks existing sessions, 'reject' refuses the new login. Omit to allow concurrent sessions.'replace' | 'reject'

Topology

Method / PropertyDescriptionReturns
createDomain(id, options?)Create and register a new Domain. { roles: [...] } restricts joining to those roles.Domain
domain(id)Get an existing Domain by id. Throws if not found.Domain
hasDomain(id)Check whether a Domain with this id exists.boolean
domainsAll registered Domains.Domain[]
sessionsAll active Sessions on this node.Session[]
resolveInstance(ref)Resolve "domainId/instanceId" or a bare instance id.Instance
getDomain(id)Non-throwing lookup: Domain or undefined.Domain | undefined
getInstance(ref)Non-throwing lookup by path or unique bare id.Instance | undefined
getSession(sessionId)Session by id on this node.Session | undefined
getUserSessions(userId)All of a user's sessions on this node.Session[]

Hooks

Method / PropertyDescriptionReturns
bootstrap(hook)Async setup before the server accepts connections.this
onAuthenticate(hook)Register the authentication hook.this
onAdmission(hook)Decide which instances a session joins.this
onChatMessage(hook)Moderate built-in chat: return true, a rewritten string, or false/throw to block.this
onSessionCreate(hook)Called once per session, after authentication.this
onConnect(hook)Called when a session connects.this
onDisconnect(hook)Called when a session disconnects.this
onStarted(hook)Called after the server is listening.this
onShutdown(hook)Called at the start of graceful shutdown.this

Messaging & extensions

Method / PropertyDescriptionReturns
broadcast(event, payload?)Send an event to every connected session across all nodes.void
sessionsOf(userId)Session ids of a user across all nodes.Promise<string[]>
use(middleware)Register a middleware function.this
use(plugin)Install a plugin with an install() method.this

Infrastructure & lifecycle

Method / PropertyDescriptionReturns
ioThe underlying Socket.IO server. Available after start().SocketIOServer
redisThe shared Redis client (when Redis is configured).Redis
queuesThe QueueManager (requires Redis).QueueManager
start()Start the server.Promise<{ port: number }>
shutdown()Gracefully shut down.Promise<void>
metrics()Current runtime metrics.Metrics
const mesh = new PlayMesh({ port: 4000, redis: { host: 'localhost', port: 6379 } });

mesh.bootstrap(async ({ mesh }) => { /* create domains and instances */ });
mesh.onAuthenticate(async request => ({ userId: request.auth.userId as string }));
mesh.onStarted(() => console.log('Server ready'));

const { port } = await mesh.start();

process.on('SIGTERM', () => mesh.shutdown());

Domain

Retrieved via mesh.createDomain(id) or mesh.domain(id).
Method / PropertyDescriptionReturns
idThe domain identifier.string
instancesAll Instances in this domain.Instance[]
createInstance(id, options?)Create a new Instance. { autoDestroy: ms | true } makes it temporary; { roles: [...] } restricts joining (on top of domain roles).Instance
on(event, handler)Domain-level event handler - runs for events from sessions inside this domain.this
off(event, handler)Remove a domain-level handler.this
instance(id)Get an Instance by id.Instance
hasInstance(id)Check whether an Instance exists.boolean
destroyInstance(id)Remove sessions, clear state, delete the instance.Promise<void>
broadcast(event, payload?)Send to every session in any instance of this domain.void
onInstanceCreated(hook)Called when a new instance is created.this
onInstanceDestroyed(hook)Called when an instance is destroyed.this

Instance

An isolated multiplayer environment. Sessions join to receive broadcasts and have events routed.
Method / PropertyDescriptionReturns
idThe instance identifier.string
domainThe owning Domain.Domain
path"domainId/instanceId" - globally unique reference.string
sessionsSessions on this node that are members.Session[]
stateServer-only runtime key-value state.ScopedState
publicStateState synced live to every client in this instance.ScopedState
userState(userId)Private state synced only to that user's clients.ScopedState
temporaryWhether this instance auto-destroys when it empties out.boolean
on(event, handler)Register an event handler.this
off(event, handler)Remove an event handler.this
broadcast(event, payload?)Send to all member sessions across all nodes.void
memberCount()Presence-backed total member count across all nodes.Promise<number>
onJoin(hook)Called when a session joins.this
onLeave(hook)Called when a session leaves.this
onJoinRequest(hook)Allow/veto client-initiated joins. Without this hook, client joins are denied.this
instance.sessions is local-node only. Use instance.memberCount() for the cluster total.

Session

Represents a single connected client.
Method / PropertyDescriptionReturns
idSocket ID (unique per connection).string
userIdAssigned by your authenticate hook.string
rolesRoles granted by the authenticate hook.string[]
hasRole(role)Check whether the session holds a role.boolean
dataApplication data from the auth result.Record<string, unknown>
instancesInstances this session is currently a member of.Instance[]
isIn(instance)Check membership by Instance or id string.boolean
join(instance)Join an instance. No-op if already a member.Promise<void>
leave(instance)Leave an instance. No-op if not a member.Promise<void>
send(event, payload?)Send an event to this client only.void
kick(reason?)Notify the client why (playmesh:kicked), then force-disconnect it.void
disconnect()Forcibly disconnect this client.void

Typed events

Both SDKs accept event-map generics that type emit, on, send, and broadcast payloads end to end. Compile-time only - still validate payloads at runtime.
type ClientEvents = { 'player:move': { x: number; y: number } };
type ServerEvents = { 'player:update': { x: number; y: number; by: string } };

const mesh = new PlayMesh<ClientEvents, ServerEvents>();
city.on('player:move', (session, payload) => {
  // payload is { x: number; y: number }
  session.send('player:update', { ...payload, by: session.userId });
});

ScopedState

Method / PropertyDescriptionReturns
get(key)Get a value. Returns undefined if not set.Promise<unknown>
set(key, value)Set a value (JSON-serialized).Promise<void>
delete(key)Delete a key.Promise<void>
keys()List all keys in this instance scope.Promise<string[]>
clear()Delete all keys in this instance scope.Promise<void>

Metrics

const m = mesh.metrics();
// {
//   sessions: number,   - active sessions on this node
//   domains: number,
//   instances: number,
//   uptimeMs: number,
// }