import type { POJO, Scalar } from '../augmented'; export { POJO, Scalar }; /** * Type of a plain JavaScript object, with arbitrary keys. */ export declare type PlainObject = { [field: string]: any; }; export declare type CallbackOnNetworkChange = (prev: T) => void; /** * Holds an augmented object, but also can be serialized and synchronized, peer-to-peer or hub-and-spoke, * and which can hook change-events, whether originating locally or from a remote replica. */ export interface IDocument { /** * Globally-unique ID. Can be used as a primary key to refer to the document. */ readonly docId: string; /** * Augmented Object: Looks and acts like native JavaScript objects, arrays, scalars, Sets, RegExp, and so on, * but whose content is automatically tracked. Any fields can be added, changed, or deleted, including arbitrary * recursion, but the root object itself is fixed. */ readonly content: T; /** * The Replica this document is attached to. */ readonly replica: IReplica; /** * [async] Saves the Document to the local Replica, possibly also triggering sharing over a network. * If the Document hasn't changed since the last time it was saved or read, this silently does nothing. */ save(): Promise; /** * Asserts that this Document is no longer in use; Replica will forget it, and reload from storage if requested again. */ close(): void; /** * Helpful for debugging state. */ toDebugString(): string; /** * Registers a call-back function that will be invoked whenever this document has been updated due to * changes on the network, i.e. changes from other replicas as opposed to changes from the current replica. * * @returns the argument that was passed in */ onNetworkChange(cb: CallbackOnNetworkChange): CallbackOnNetworkChange; /** * Removes a call-back function previously set with `onNetworkChange()`. */ offNetworkChange(cb: CallbackOnNetworkChange): void; } /** * Holds the state of a local Replica -- a collection of Documents that can be stored locally, as well as * synchronized with other Replicas, either peer-to-peer or hub-and-spoke. */ export interface IReplica { /** * Globally-unique ID. The ID will remain stable over time, if a local storage system is configured. */ readonly replicaId: string; /** * Closes down the Replica, releasing memory and networking resources */ close(): Promise; /** * [async] Sets the network provider for synchronizing with other Replicas. This is not required. * You can call it more than once to switch out network providers, or with `null` to remove one. */ setNetworkProvider(network: INetworkClientSideAPI | null): Promise; /** * [async] Gets a document from local storage, or returns existing document object if it has already been loaded. * Returns `undefined` if the document isn't in the Replica. */ getDocument(id: string): Promise | undefined>; /** * Creates a new document, with a new globally-unique ID, which has not yet been saved. * You can save it any time; having it just in-memory allows you to have temporary documents, or * to start using a document but then change your mind and not save it. * * @param docId if given, create a document with this specific ID, otherwise a globally-unique ID is generated */ createDocument(docId?: string): IDocument; /** * [async] Retrieves arbitrary application-specific data stored in the local Replica, or `null` if it is not present. */ getApplicationData(key: string): Promise; /** * [async] Stores arbitrary application-specific data that should be in the local replica. */ putApplicationData(key: string, data: POJO): Promise; /** * [async] Sends local changes to the network, and receives changes from the network. * In production, this should be executed on a timer, but it's useful to be able to call it directly. * * @return Promise of a boolean: `true` if something new was downloaded from the network, `false` otherwise. */ synchronizeWithNetwork(): Promise; } /** * Backend storage system for a Replica. * Can read and write key/value pairs, both strings. * The interface is intentionally simple, making it trivial to support implementations ranging from in-browser, * to disk, to memory, to globally-replicated databases. */ export interface ISerializedStorageProvider { /** * Reads a byte-array-typed item asynchronously, or `null` if not found. */ getBytes(key: string): Promise; /** * Writes a byte-array-typed item asynchronously. */ putBytes(key: string, data: Uint8Array): Promise; /** * Reads a string-typed value asynchronously, or `null` if not found. */ getString(key: string): Promise; /** * Writes a string-typed value asynchronously. */ putString(key: string, data: string): Promise; } /** * A document but encoded over the network, as opposed to `IDocument` which is the live object. */ export interface NetworkDocument { docId: string; vers: { [verId: string]: Uint8Array; }; } /** * Provides functionality for the client-side of a network protocol. Connects to server or peer, can be asked to transmit * changes, and proactively sends changes to replicas. * * Protocols can include CouchDB, WebSocket, Firebase, and in-memory for real-time synchronization, or polling for slower but * very compatible and flexible protocols. */ export declare abstract class INetworkClientSideAPI { /** * Attached Replicas. Typically just one, but can be multiple for demos or unit tests. */ readonly replicas: any[]; /** * Instructs the provider to connect to the network. This must be called async, * and no other commands may be called until this completes, with the exception of `close()`. * If already connected, returns immediately. * * Saves the given replica, as the one who opened the connection. Multiple replicas can open the network connection. */ connect(r: any): Promise; /** * Called by the parent object to actually connect the network. Won't be called if already connected. */ protected abstract _connect(): Promise; /** * Close the connection to the network, the the replica object that opened it. No other commands may be * used until `connect()` is successfully called again. Does nothing if already closed. * You can re-open a closed connection. */ close(r: any): Promise; /** * Called by the parent object to actually close the network connection. Won't be called if not already connected. */ protected abstract _close(): Promise; /** * Send a document that has been updated, as well as GC older versions that are now dominated and therefore obsolite. * * @param docId globally unique ID of the document * @param versionId The version ID originally provided by the replica that created this version * @param data serialized data * @param obsoliteVersionIds list of version IDs for this document that are no longer relevant, because the current version supercedes them; they can be deleted. */ abstract putDocument(docId: string, versionId: string, data: Uint8Array, obsoliteVersionIds: string[]): Promise; /** * Request all versions of all documents. In future this will be paired down to just newer versions of documents. */ abstract getDocuments(): Promise; /** * Returns the number of (likely but not necessarily conflicting) versions of the document currently stored in the network. * This is `0` if the document isn't stored, `1` if the document is unconflicted, or greater if there are multiple versions. */ abstract getNumVersions(docId: string): Promise; }