How it works
tabus-js has a small, deliberately simple architecture: a single public class that delegates sending/receiving messages to a swappable transport.
Tabus<Events> │ └── ITransport ├── BroadcastTransport — wraps the native BroadcastChannel └── MemoryTransport — module-level Map of listenersTabus, the only public class
Section titled “Tabus, the only public class”Tabus is the entry point and the only class the library exposes. Its responsibilities:
- Chooses the transport when constructed: if
typeof BroadcastChannel !== "undefined"it usesBroadcastTransport; otherwise it usesMemoryTransport. See Transports. - Deduplicates messages: compares
msg.tabIdagainst its owntabIdso the tab that emits an event never delivers it to itself. - Defers
tab:joinwithsetTimeout(0), so whoever constructs the instance can register handlers synchronously before the notice is broadcast to peers. See Lifecycle events. - Guards
destroy()with an internal flag: if the instance is destroyed before thetab:jointimer fires, neither that event nortab:leaveare sent. - Throttles
emit()with a leading + trailing edge strategy. See Throttling.
For the full detail of every public member (on, off, emit, destroy, tabId), see the Tabus class reference.
ITransport, the transport contract
Section titled “ITransport, the transport contract”All message sending/receiving goes through a common interface:
interface ITransport { send(msg: TabusMessage): void; onMessage(listener: (msg: TabusMessage) => void): void; destroy(): void;}tabus-js ships two ready-to-use implementations:
BroadcastTransport: a thin wrapper around the nativeBroadcastChannelAPI. Communicates real tabs, windows, and workers of the same origin.MemoryTransport: an in-memory fallback that kicks in whenBroadcastChanneldoesn’t exist (Node, SSR, very old browsers). Only works within the same process.
Both are explained in detail, along with their differences and limitations, in Transports.
Next step
Section titled “Next step”- Transports: when each one is used and what the fallback implies.
- Lifecycle events:
tab:join,tab:leave, and why they’re deferred. - Throttling: how to limit the frequency of
emit().
