pub enum ServerMessage {
Show 22 variants
Pong,
Settings {
document: SettingsDocument,
},
SettingsRefused {
reason: SettingsRefusal,
message: String,
id: u64,
key_path: Option<String>,
},
SettingsSaved {
id: u64,
},
Greeting {
version: u32,
forge_version: String,
forge_version_short: String,
settings: ClientSettings,
},
Snapshot {
subject: Subject,
data: Value,
},
Update {
update: Box<SessionUpdate>,
seq: Option<u64>,
span: u64,
},
Page {
conversation: SessionSlot,
turns: Vec<TurnWire>,
cursor: Option<String>,
cron_names: BTreeMap<String, CronName>,
},
SeatFrames {
slot: SessionSlot,
epoch: Option<SessionId>,
frames: Vec<SeatFrameWire>,
},
CommitDiff {
sha: String,
files: LayerState<Vec<FileContent>>,
truncated: bool,
},
FileContent {
session: SessionSlot,
path: String,
sha: Option<String>,
content: FileContentWire,
},
Reply {
reply_to: u64,
body: Value,
},
BrowserView {
id: u16,
profile: String,
tab: u16,
controller: Option<u64>,
viewers: u32,
viewer: u64,
},
TerminalView {
seat: SessionSlot,
id: u16,
cols: u16,
rows: u16,
seq: u32,
screen: String,
viewers: u32,
viewer: u64,
controller: Option<u64>,
},
TerminalControl {
seat: SessionSlot,
id: u16,
controller: Option<u64>,
},
BrowserNavState {
id: u16,
tab: u16,
can_back: bool,
can_forward: bool,
},
BrowserSurfaceFailed {
id: u16,
tab: u16,
reason: String,
},
BrowserTabs {
id: u16,
profile: String,
up: bool,
connected: bool,
closing_at_ms: Option<u64>,
rows: Vec<BrowserTabRow>,
},
BrowserFileDialog {
id: u64,
tab: u16,
multiple: bool,
},
BrowserDownload {
tab: Option<u16>,
name: String,
data: Option<String>,
error: Option<String>,
dropped: bool,
lost: Option<u64>,
},
Error {
what: String,
why: String,
seat: Option<SessionSlot>,
dispatch_id: Option<u64>,
},
DocumentRead {
session: SessionSlot,
path: String,
document_kind: DocumentKind,
bytes: String,
reviewable: bool,
content_hash: String,
threads: Vec<ReviewedThreadWire>,
reviews: Vec<ReviewSet>,
},
}Expand description
What the server sends.
Variants§
Pong
The answer to ClientMessage::Ping, and proof the peer is reading.
Settings
The effective config, pushed once after the greeting and again after every applied reload. Server-wide rather than seat-scoped: every connection draws the same document, and a connection that attaches while a reload is in flight reads the current load here - which is why no settings read verb exists.
Fields
document: SettingsDocumentSettingsRefused
A settings save that wrote nothing. message is the loader’s own
words for an invalid candidate or the guard’s own for a refusal;
key_path anchors it at one of the save’s keys where one is known.
SettingsSaved
A settings save that wrote. The reload push carries the new document;
this is the saver’s own acknowledgement, matched by id, so a page
clears its draft only for its own save.
Greeting
Fields
forge_version: StringThe build that sent this, in the two forms a view’s own header draws. The greeting is the only thing a client is guaranteed to have before it reads or refuses anything, so a skew can name both halves from here and nowhere else.
settings: ClientSettingsSnapshot
Update
Boxed for the same reason as a command: the update is the largest thing on this wire and every other variant is small beside it.
Fields
update: Box<SessionUpdate>seq: Option<u64>The number the frame’s oldest update was minted under, None for
a frame belonging to no seat.
A client reads the numbers to see what it missed. Every frame
the workspace emits for a seat is numbered on that seat’s counter,
so a client that reads 5 and then 7 knows exactly one frame went
missing and asks the seat for it (seat_range); the snapshot’s
header.seq says where a fresh reader joins.
span: u64How many of the seat’s numbers this frame stands for: 1 for a frame that is one update, and n for a run the batch folded into one - a run of token appends crosses as the single frame they draw as, and its span is what keeps the client from reading the numbers it already drew as a gap.
0 only on the turn the batch forges from a delivery, which
has no number; every other frame stands for at least one, the
out-of-band read_call_output answer (seq: null, span: 1)
included.
Page
A page of one conversation, in answer to more: whole turns, each with
the key the server named it by and the messages it ran as. Grouping a
run of calls inside a turn is the client’s, so the messages cross and no
drawing of them does.
Fields
conversation: SessionSlotSeatFrames
The answer to seat_range: the frames numbered in from..=to, each
with the number it was minted under, oldest first.
Answered from the seat’s own window while it holds them, and from the
transcript below that. A range the window has shed comes back as the
conversation’s own rows numbered to END at the range’s end, so a client
resumes where it was reading instead of asking again for a stretch that
cannot arrive. A range from another epoch, or one forge holds no seat
for, is an error naming seat_range.
CommitDiff
The answer to commit_diff: one commit’s own bounded diff, in the
same layer shape the record’s content read carries, so a client
draws both scopes through one parse.
A sha git cannot read is the scan’s own scan_failed layer, not
an error - the diff-viewer contract keeps a read that answered
something apart from a read that could not run, and the client draws
the state as itself. Only a seat forge holds no session for is an
error naming commit_diff.
Fields
files: LayerState<Vec<FileContent>>FileContent
The answer to file_content: the file’s lines at the revision asked
for, or why the read could not run.
session, path and sha are named back so a page holding two
seats, two scopes or several files routes each answer to its own ask.
Reply
The answer to a Command that carried a reply_to, including a
refusal, so a client awaiting one is never left watching a channel
that stays empty.
BrowserView
One tab’s viewer state: which viewer controls it, and how many are attached.
Sent on attach and whenever either changes, so every viewer draws the
same truth about who is driving. id is the profile’s wire id, the
same one the binary frames carry; tab is the tab this state is for;
and viewer is THIS connection’s own - the number controller names
when this viewer holds the role, so a bar can say “Take control”
rather than guessing.
TerminalView
One terminal’s screen, as a VT stream a client can draw, and where the byte stream continues from.
Fields
seat: SessionSlotTerminalControl
Who holds a terminal’s input, pushed to every viewer of it on a take or a release.
Where the viewed tab’s history sits: what the bar’s arrows may do.
BrowserSurfaceFailed
The viewed tab’s browser stopped.
A host that died under a viewer is said out loud: a frozen last frame reads as a slow page, and the person has no way to tell the two apart.
BrowserTabs
The tabs of the viewer’s profile, as a client’s strip draws them.
Pushed to a connection that asked with browser_tabs, once per change:
up is the host process, connected is a driver attached to it, and
closing_at_ms is the idle clock’s deadline.
Fields
rows: Vec<BrowserTabRow>BrowserFileDialog
A page asked for a file: the shell opens its picker and answers
ClientMessage::BrowserFileAnswer under the same id. tab is the
tab that asked, so a viewer is asked only for the one it is on.
BrowserDownload
A page’s download finished on the server: the shell opens its save
door and writes the bytes, or says error and writes nothing. tab
is the tab it started from.
Fields
tab: Option<u16>The tab the download started from. Absent on a profile-level notice: the backlog carries every tab’s offers, so the ones it dropped may belong to any tab of the profile.
Error
Fields
seat: Option<SessionSlot>The conversation the refusal belongs to, where it belongs to one: a
more for a seat the server could not answer names its seat, so a
client holding several seats’ asks drains only its own. Optional and
additive - a client of either age reads it, and a refusal that names
no seat is read the way it always was.
DocumentRead
One document, as the read answered: the seat it was read for, the path it resolved to, the bytes, the detected kind, the flag the hand-off passed, the document’s own hash, and the review the document already carries.
session is named back so a client holding two seats routes each
answer to its own viewer - the same reason a refusal names its seat.
bytes are base64: the ceiling makes a document up to a third
larger than its file, well inside the socket’s own frame bound.
document_kind and not kind: a field named kind collides with
the envelope’s own tag.
threads and reviews are the document scope’s own (doc:<path>)
store read, taken in the same handler: the viewer draws its comments,
and each thread carries where its anchor sits in THIS document - the
code review’s re-anchoring, resolved here because only the server
holds the whole file’s lines. A thread the revision left nowhere is
carried with an outdated landing rather than dropped.
content_hash crosses as DECIMAL DIGITS for the same reason a
thread’s anchor hash does - JS numbers are exact only to 2^53.
Trait Implementations§
Source§impl Debug for ServerMessage
impl Debug for ServerMessage
Source§impl<'de> Deserialize<'de> for ServerMessage
impl<'de> Deserialize<'de> for ServerMessage
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for ServerMessage
impl RefUnwindSafe for ServerMessage
impl Send for ServerMessage
impl Sync for ServerMessage
impl Unpin for ServerMessage
impl UnsafeUnpin for ServerMessage
impl UnwindSafe for ServerMessage
Blanket Implementations§
§impl<T> AnySync for T
impl<T> AnySync for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more