Skip to content
Strata is pre-1.0. APIs, protocol, and storage format may change.

strata_server/document_channel

Beryl channel handler for strata document topics.

Topic pattern: doc:* (registered by strata_server.run).

Lifecycle per socket+topic:

  • join: on success, the join acknowledgment carries a snapshot frame with the current authoritative state (or null when the document is brand new). A presence_state push follows, listing everyone already on the topic so the new client can render their cursors.
  • delta (event strata.delta): merge into the store, then broadcast a server delta push to every other socket on the topic.
  • create (event strata.create): call store.create synchronously. On success, broadcast_from the parent delta so other subscribers learn about the new child. On failure (ChildExists or one of the Create* diagnostic variants), push an error frame (child_exists or invalid_create) to the sender.
  • delete (event strata.delete): call store.delete synchronously. On success, broadcast a deleted frame to each removed id's topic via PubSub, then broadcast_from the parent delta. Deleting an already deleted child succeeds again: the parent delta still applies, which removes a reference a concurrent edit re-added, and the child's deleted frame is sent once more. On failure (NotAChild for a live child owned by another parent, or DeleteParentStateInvalid), push an error frame (not_a_child or invalid_delete) to the sender. Deleted sockets are not forcibly left; the store tombstone prevents resurrection via apply.
  • presence_set (event strata.presence_set): channel.presence_track (key = socket id, meta = the supplied payload). beryl's runtime broadcasts the resulting presence_diff; the strata codec wraps that diff in a strata envelope.
  • terminate: beryl untracks this socket's presence and broadcasts the leave diff itself; the channel only updates the socket tracker.

Shared dependencies every document channel needs.

pub type Context {
Context(store: store.Store, tracker: doc_presence.Tracker, pubsub: pubsub.PubSub(json.Json))
}

Private per-socket state for one joined document topic.

pub type Model {
Model(doc_id: String, socket_id: String)
}

Build the doc:* channel handler. Pass it to channel.child_spec.

pub fn handler(Context) -> channel.Handler

Convert a beryl presence entry into a strata presence record.

pub fn presence_from_entry(presence.PresenceEntry) -> presence.Presence

Build a protocol_presence.Presence from a session id and the JSON meta blob the client supplied. Missing fields fall back to defaults.

pub fn presence_from_meta(
String,
json.Json
) -> presence.Presence