Skip to content

Realtime rooms, without the plumbing

Seven small packages pulled out of a production realtime app — an engine that assembles them into one headless space, a WebSocket transport that survives deploys, and state stores you can test without a server.
$npm install @insession/space

Every extension ships a ready-made descriptor, so a working server-side feature is one line — see Getting started for what to do with the effects it hands back.

import { createSpace } from '@insession/space';
import { pomodoroExtension } from '@insession/extension-pomodoro';
const space = createSpace({ extensions: [pomodoroExtension()] });
space.dispatch('pomodoro', 'start'); // -> [broadcast, schedule-timer]

@insession/space

The parent package. Builds a headless space out of extensions: the contract (defineSpaceExtension), the aggregate registry, member/presence lifecycle, and an instance (createSpace) that turns accepted actions into effect descriptors. Performs no I/O itself.

0 dependencieseffect descriptors

@insession/ws-resilient-transport

A WebSocket transport that reconnects the way a deploy actually needs it to: fast on a service restart, jittered exponential backoff otherwise, and a full stop on terminal close codes.

0 dependencies~130 LOC

@insession/space-state

A state store for shared rooms — members, chat, presence, plugins. Inbound messages fold through a pure reducer; side effects come back as descriptors instead of firing.

0 dependenciespure reducer

@insession/extension-chat

A server-authoritative chat state machine: message normalization, sticker allowlisting, replies, reactions, and pins. reduce returns state plus effect descriptors — persistence, broadcast, and bot notification are the host’s job to execute.

0 dependenciespure reducer

@insession/extension-pomodoro

A server-authoritative Pomodoro timer state machine: a pure reduce over start/pause/skip/configure and declarations/cheers, plus restore/ persistState for the storage boundary.

0 dependenciespure reducer

@insession/extension-whiteboard

A server-authoritative Whiteboard state machine: shared free-draw strokes/shapes, plus an optional “drawing telephone” relay game with its own phase timing.

0 dependenciespure reducer

@insession/extension-watch-party

A server-authoritative Watch Party state machine: synchronized video/audio playback with a queue and history. reduce returns effect descriptors instead of performing I/O, so a host wires up broadcast/persist/title-lookup itself.

0 dependenciespure reducer

No edges between any of them. space, space-state, ws-resilient-transport, extension-chat, extension-pomodoro, extension-whiteboard, and extension-watch-party are each independent — carrying bytes, holding state, and assembling extensions are kept apart on purpose, so you can adopt any one alone. Even space, the package that ties the state machines together, does not import any of them: it only describes the shape (defaultState / reduce / …) they already have. Using React? There is no binding package to install: one line of your own is the whole hook.