///|
pub(all) enum SyncMessage {
SyncStep1(StateVector)
SyncStep2(Bytes)
Update(Bytes)
}
///|
pub(all) enum Message {
Sync(SyncMessage)
Auth(String?)
AwarenessQuery
Awareness(AwarenessUpdate)
Custom(Byte, Bytes)
}
///|
fn Message::write(self : Message, writer : Writer) -> Unit {
match self {
Sync(message) => {
writer.uint(0UL)
match message {
SyncStep1(state) => {
writer.uint(0UL)
writer.buffer(state.encode_v1())
}
SyncStep2(bytes) => {
writer.uint(1UL)
writer.buffer(bytes)
}
Update(bytes) => {
writer.uint(2UL)
writer.buffer(bytes)
}
}
}
Auth(reason) => {
writer.uint(2UL)
match reason {
None => writer.uint(1UL)
Some(reason) => {
writer.uint(0UL)
writer.string(reason)
}
}
}
AwarenessQuery => writer.uint(3UL)
Awareness(update) => {
writer.uint(1UL)
writer.buffer(update.encode_v1())
}
Custom(tag, bytes) => {
writer.uint(tag.to_int().to_uint64())
writer.buffer(bytes)
}
}
}
///|
pub fn Message::encode_v1(self : Message) -> Bytes {
encode_messages([self])
}
///|
pub fn encode_messages(messages : Array[Message]) -> Bytes {
let writer : Writer = { bytes: [], }
for message in messages {
message.write(writer)
}
writer.finish()
}
///|
fn Reader::message(self : Reader) -> Message raise DecodeError {
let tag = self.uint()
guard tag <= 255UL else { raise InvalidData("message tag overflow") }
match tag {
0UL =>
Sync(
match self.uint() {
0UL => SyncStep1(StateVector::decode_v1(self.buffer()))
1UL => SyncStep2(self.buffer())
2UL => Update(self.buffer())
_ => raise InvalidData("unknown sync message")
},
)
1UL => Awareness(AwarenessUpdate::decode_v1(self.buffer()))
2UL => {
let permission = self.uint()
guard permission <= 255UL else {
raise InvalidData("permission tag overflow")
}
Auth(if permission == 0UL { Some(self.string()) } else { None })
}
3UL => AwarenessQuery
_ => Custom(tag.to_int().to_byte(), self.buffer())
}
}
///|
pub fn Message::decode_v1(bytes : Bytes) -> Message raise DecodeError {
let reader : Reader = { bytes, offset: 0, }
let result = reader.message()
reader.finish()
result
}
///|
pub fn decode_messages(bytes : Bytes) -> Array[Message] raise DecodeError {
let reader : Reader = { bytes, offset: 0, }
let result = []
while reader.offset < bytes.length() {
result.push(reader.message())
}
result
}
///|
pub(all) suberror ProtocolError {
PermissionDenied(String)
UnsupportedMessage(Byte)
} derive(Debug)
///|
pub extend ProtocolError with Debug::{to_repr}
///|
/// Encode the default y-sync handshake (state vector and live awareness).
pub fn Awareness::start_sync(self : Awareness) -> Bytes {
encode_messages([
Sync(SyncStep1(self.document.state_vector())),
Awareness(self.update()),
])
}
///|
pub fn Awareness::handle_message(
self : Awareness,
message : Message,
) -> Message? raise {
DefaultProtocol().handle_message(self, message)
}
///|
/// Process concatenated protocol messages in order. As upstream does, a later
/// invalid message does not roll back messages already applied from the packet.
pub fn Awareness::handle_sync(
self : Awareness,
bytes : Bytes,
) -> Array[Message] raise {
DefaultProtocol().handle(self, bytes)
}