onWelcome method
Imports the room state of a welcome, then queues everything the relay does not hold.
The state is merged (merge: true) into the document: on a reconnect
the document already holds local state that must not be clobbered.
History is kept (pruneHistory: false) so this client can later
upload a snapshot covering it.
A welcome carries the whole room — the snapshot plus the log after it — so its version vector is exactly what the relay has. Whatever the document holds beyond that is queued and pushed, whoever wrote it. That covers three cases with one rule: unacknowledged changes that survived the reconnect, changes restored from storage after a restart (which reach the document as imported ones, so nothing else would ever push them), and changes of another peer the relay lost.
One limit comes with the version vector: it cannot describe a hole in the middle of one peer's sequence, only how far that peer got.
Re-delivering a change the relay already had is harmless: the relay appends it and every peer discards it as known.
A malformed welcome throws out of here, from Snapshot.fromBytes or
Change.fromBytes. The transport is expected to drop the connection.
Implementation
Future<void> onWelcome(RelayWelcomeMessage message) async {
final snapshot = message.snapshot != null
? Snapshot.fromBytes(base64Decode(message.snapshot!))
: null;
final changes = [
for (final blob in message.changes) Change.fromBytes(base64Decode(blob)),
];
document.import(
snapshot: snapshot,
changes: changes,
merge: true,
pruneHistory: false,
);
_seqTracker.markThrough(message.seq);
_handshaken = true;
_queue.resetInFlight();
_queueUnknownToRelay(snapshot, changes);
await flush();
if (message.compact) {
await uploadSnapshot(message.seq);
}
}