// Backwards-compatible protocol version. const VERSION = 1; // From the frontend to the relay. struct CommandMessage { // The command sequence number will be repeated in responses // in the respective fields. u32 command_seq; union CommandData switch (enum Command { HELLO, ACTIVE, BUFFER_INPUT, BUFFER_ACTIVATE, PING_RESPONSE, PING, BUFFER_COMPLETE, BUFFER_LOG, } command) { case HELLO: u32 version; // If the version check succeeds, the client will receive // an initial stream of BUFFER_UPDATE, BUFFER_STATS, BUFFER_LINE, // and finally a BUFFER_ACTIVATE message. case ACTIVE: void; case BUFFER_INPUT: string buffer_name; string text; case BUFFER_ACTIVATE: string buffer_name; case PING_RESPONSE: u32 event_seq; // Only these commands may produce Event.RESPONSE, as below, // but any command may produce an error. case PING: void; case BUFFER_COMPLETE: string buffer_name; string text; u32 position; case BUFFER_LOG: string buffer_name; } data; }; // From the relay to the frontend. struct EventMessage { u32 event_seq; union EventData switch (enum Event { PING, BUFFER_UPDATE, BUFFER_STATS, BUFFER_RENAME, BUFFER_REMOVE, BUFFER_ACTIVATE, BUFFER_LINE, BUFFER_CLEAR, ERROR, RESPONSE, } event) { case PING: void; case BUFFER_UPDATE: string buffer_name; bool hide_unimportant; case BUFFER_STATS: string buffer_name; // These are cumulative, even for lines flushed out from buffers. // Updates to these values aren't broadcasted, thus handle: // - BUFFER_LINE by bumping/setting them as appropriate, // - BUFFER_ACTIVATE by clearing them for the previous buffer // (this way, they can be used to mark unread messages). u32 new_messages; u32 new_unimportant_messages; bool highlighted; case BUFFER_RENAME: string buffer_name; string new; case BUFFER_REMOVE: string buffer_name; case BUFFER_ACTIVATE: string buffer_name; case BUFFER_LINE: string buffer_name; // Whether the line should also be displayed in the active buffer. bool leak_to_active; bool is_unimportant; bool is_highlight; enum Rendition { BARE, INDENT, STATUS, ERROR, JOIN, PART, ACTION, } rendition; // Unix timestamp in milliseconds. u64 when; // Broken-up text, with in-band formatting. union ItemData switch (enum Item { TEXT, RESET, FG_COLOR, BG_COLOR, FLIP_BOLD, FLIP_ITALIC, FLIP_UNDERLINE, FLIP_INVERSE, FLIP_CROSSED_OUT, FLIP_MONOSPACE, } kind) { case TEXT: string text; case RESET: void; case FG_COLOR: i16 color; case BG_COLOR: i16 color; case FLIP_BOLD: case FLIP_ITALIC: case FLIP_UNDERLINE: case FLIP_INVERSE: case FLIP_CROSSED_OUT: case FLIP_MONOSPACE: void; } items<>; case BUFFER_CLEAR: string buffer_name; // Restriction: command_seq strictly follows the sequence received // by the relay, across both of these replies. case ERROR: u32 command_seq; string error; case RESPONSE: u32 command_seq; union ResponseData switch (Command command) { case PING: void; case BUFFER_COMPLETE: u32 start; string completions<>; case BUFFER_LOG: // UTF-8, but not guaranteed. u8 log<>; } data; } data; };