onWelcome method

Future<void> onWelcome(
  1. RelayWelcomeMessage message
)

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);
  }
}