Skip to content
D
Documentation

classes

reference
4 min readUpdated

Import these from @grafloria/engine.

Classes

BroadcastChannelTransport

ts
class BroadcastChannelTransport implements SyncTransport

Methods

  • constructor(private readonly options: BroadcastChannelTransportOptions)
  • get status(): TransportStatus
  • static isSupported(): boolean (static) — True when this environment can actually do cross-tab sync.
  • connect(): void — Open (or re-open) the channel. Idempotent.
  • send(message: SyncMessage): void — Broadcast to the other peers. A no-op — NOT an error — while disconnected.
  • onMessage(handler: (m: SyncMessage) => void): Unsubscribe — Inbound messages from other peers. Never our own.
  • onStatus(handler: (s: TransportStatus) => void): Unsubscribe — Connection transitions. THE hook the whole reconnect story hangs on: the adapter subscribes here and fires an anti-entropy round the moment it hears 'connected' again. A transport that never reports its status can never be caught up.
  • disconnect(): void — Simulates (and, on pagehide, effects) a drop. Re-connect() to come back.
  • close(): void — Tear down for good.

CausalBuffer

Holds ops whose entity has not been added yet, and releases them the instant it is.

Sits BETWEEN the transport and the Replica. Nothing it holds has touched the log, the clock or the LWW registry — which is the whole point: an op the replica has never seen is an op that can still be applied later.

ts
class CausalBuffer

Properties

NameTypeDefaultDescription
overflowed0Ops force-released because the buffer was full. Should be 0. Watch it.

Methods

  • constructor( private readonly diagram: DiagramModel, options: CausalBufferOptions = {} )
  • get pendingCount(): number
  • noteLocal(op: Op): void — WE created an entity. Record it — the transport will never tell us about it.
  • admit(incoming: readonly Op[]): CausalSplit — Split an arriving batch into what can be applied now and what must wait — and fold in anything that was already waiting and has just become releasable.
  • pending(): Op[] — Everything we are still holding — for a status panel, and for the tests.

MemoryHub

A shared bus. One hub = one document = one "room".

ts
class MemoryHub

Properties

NameTypeDefaultDescription
trafficArray<{ from: ActorId; message: SyncMessage }>[]Every message that crossed the bus — the wire tap the tests assert against.

Methods

  • connect(actor: ActorId): MemoryTransport
  • deliver(from: MemoryTransport, message: SyncMessage): void — Deliver to everyone EXCEPT the sender. A peer never hears its own echo.
  • detach(port: MemoryTransport): void
  • get peerCount(): number

MemoryTransport

ts
class MemoryTransport implements SyncTransport

Methods

  • constructor( private readonly hub: MemoryHub, readonly actor: ActorId )
  • get status(): TransportStatus
  • send(message: SyncMessage): void — Broadcast to the other peers. A no-op — NOT an error — while disconnected.
  • accept(message: SyncMessage): void — Inbound. Ignored while disconnected — a dropped peer hears nothing, by definition.
  • onMessage(handler: Handler): Unsubscribe — Inbound messages from other peers. Never our own.
  • onStatus(handler: (s: TransportStatus) => void): Unsubscribe — Connection transitions. THE hook the whole reconnect story hangs on: the adapter subscribes here and fires an anti-entropy round the moment it hears 'connected' again. A transport that never reports its status can never be caught up.
  • connect(): void — Open (or re-open) the channel. Idempotent.
  • disconnect(): void — Close the channel but stay re-openable — this is what a "drop" is.
  • close(): void — Tear down for good.

OpBatcher

Accumulates local ops and flushes them as one coalesced, correctly-ordered batch.

ts
class OpBatcher

Properties

NameTypeDefaultDescription
queued0Ops that went in.
sent0Ops that went out. queued - sent is what coalescing saved.
batches0Flushes performed.

Methods

  • constructor(private readonly options: OpBatcherOptions)
  • get size(): number
  • push(op: Op): void
  • flush(): void — Send whatever is queued, right now. Idempotent, and a no-op when empty.
  • discard(): void — Drop the queue WITHOUT sending.
  • dispose(): void

UnreliableHub

Also has every member of MemoryHub, listed on its own entry.

A MemoryHub with the network's malice put back.

Same API, same adapters, same protocol — the ONLY difference is that this one behaves like the internet. If the sync layer is correct, nothing above it needs to change; if it is not, this is where you find out.

ts
class UnreliableHub extends MemoryHub

Properties

NameTypeDefaultDescription
faultsWhat the network actually did. Asserted on — a fuzz whose faults never fired is a lie.

Methods

  • constructor(options: UnreliableOptions = {})
  • override deliver(from: MemoryTransport, message: SyncMessage): void — Deliver to everyone EXCEPT the sender. A peer never hears its own echo.
  • step(fraction = 0.5): number — Release some of the in-flight queue, in a RANDOM order.
  • heal(): void — Stop breaking things. The network has recovered; from here on it is a plain, honest bus. Anything still lost was lost DURING the storm, and anti-entropy — not the transport — is what has to find it.
  • settle(): void — Deliver everything still in flight.
  • get inFlightCount(): number
  • override connect(actor: ActorId): MemoryTransport

VersionVector

A peer's exact position in the shared history, per actor.

Fed ONLY with ops the log genuinely accepted (Replica.receive() returns exactly those). Feed it a duplicate and count over-counts, which fakes a hole and triggers a pointless repair — wasteful, not wrong, but the discipline is worth keeping.

ts
class VersionVector

Methods

  • observe(op: Op): void — Record ONE op we now hold. Must be genuinely new — see the class doc.
  • observeAll(ops: Iterable<Op>): void
  • frontier(actor: ActorId): ActorFrontier
  • get actorCount(): number
  • toJSON(): VersionVectorJSON
  • static fromOps(ops: Iterable<Op>): VersionVector (static) — Rebuild from a log — used on resume-from-disk, and by the tests as an oracle.

WebSocketTransport

ts
class WebSocketTransport implements SyncTransport

Properties

NameTypeDefaultDescription
attempts0Reconnect attempts made. Asserted on by the backoff test.

Methods

  • constructor(private readonly options: WebSocketTransportOptions)
  • get status(): TransportStatus
  • connect(): void — Open (or re-open) the channel. Idempotent.
  • send(message: SyncMessage): void — Broadcast to the other peers. A no-op — NOT an error — while disconnected.
  • onMessage(handler: (m: SyncMessage) => void): Unsubscribe — Inbound messages from other peers. Never our own.
  • onStatus(handler: (s: TransportStatus) => void): Unsubscribe — Connection transitions. THE hook the whole reconnect story hangs on: the adapter subscribes here and fires an anti-entropy round the moment it hears 'connected' again. A transport that never reports its status can never be caught up.
  • disconnect(): void — Close the channel but stay re-openable — this is what a "drop" is.
  • close(): void — Tear down for good.

Was this page helpful?