import { Message } from './Message'; import { Repo } from './Repo'; /** * One instance of `Synchronizer` keeps one local document in sync with one remote peer's replica of the * same document. * * This class works with a local `Repo`; it listens for changes to documents, and if it thinks it * has changes that the remote peer doesn't know about, it generates a message to be sent the peer. * It also processes messages from its counterpart on the peer, and applies them to local documents * as needed. * * This class doesn't get involved in the actual transmission of the messages; it only generates * them for someone else to send, and processes them when someone else receives them. To integrate a * connection with a particular networking stack, two functions are used: * * - `send` (callback passed to the constructor, will be called when local state is updated) takes a * message as argument, and sends it out to the remote peer. * - `receive` (method on the connection object) should be called by the network stack when a * message is received from the remote peer. * * In this context, networking is provided by the `ConnectionManager`. * * The document to be synced is managed by a `Repo`. Whenever it is changed locally, call `setDoc()` * on the Repo. The connection registers a callback on the repo, and it figures out whenever there * are changes that need to be sent to the remote peer. * * To do this, we keep track of two clocks: ours and theirs. * * - "Their" clock is the most recent VClock that we think the peer has (either because they've told * us that it's their clock, or because it corresponds to a state we have sent to them on this * connection). Thus, everything more recent than theirClock should be sent to the peer. * * - "Our" clock is the most recent VClock that we've advertised to the peer (i.e. where we've told * the peer that we have it). * * > Note: This class began life as a vendored & refactored copy of the `Automerge.Connection` * > class; if you're familiar with that class, this one plays exactly the same role. */ export declare class Synchronizer { repo: Repo; private send; private theirClock; private isOpen; private log; /** * @param repo A `Repo` containing the document being synchronized. * @param send Callback function, called when the local document changes. Provided by the * networking stack. Should send the given message to the remote peer. */ constructor(repo: Repo, send: (msg: Message) => void); open(): Promise; close(): void; /** Called by the network stack whenever it receives a message from a peer */ receive(msg: Message): Promise; /** Event listener that fires when any document is modified on the repo */ private onDocChanged; /** Sends a hello message including our document count */ private sendHello; /** Checks whether we have more recent information than they do; if so, sends changes */ private maybeSendChanges; /** Sends a changeset to our peer, bringing them up to date with our latest info */ private sendChanges; /** Sends a single message containing each documentId along with our clock value for it */ private advertiseAll; /** Requests a document that we don't have, indicating that we need its entire history */ private requestDoc; /** Send snapshots for all documents */ private sendSnapshots; /** Send all changes for all documents (for initialization) */ private sendHistory; /** Load a history of all changes sent by peer */ private receiveHistory; /** Load a snapshot of the entire repo */ private receiveSnapshots; /** Looks up our last recorded clock for the requested document. * Our clocks are managed by the repo. */ private getOurClock; /** We keep track of their clocks here. */ private getTheirClock; /** Updates their vector clock by merging in the new vector clock `clock`, setting each node's * sequence number to the maximum for that node */ private updateTheirClock; }