tinybase
Version:
A reactive data store and sync engine.
166 lines (163 loc) • 6.27 kB
TypeScript
/**
* The persister-automerge module of the TinyBase project provides a way to save
* and load Store data to and from an Automerge document.
*
* A single entry point, the createAutomergePersister function, is provided,
* which returns a new Persister object that can bind a Store to a provided
* Automerge document handle (and in turn, its document).
* @see Third-Party CRDT Persistence guide
* @packageDocumentation
* @module persister-automerge
* @since v4.0.0
*/
import type {Store} from '../../store/index.d.ts';
import type {Persister} from '../index.d.ts';
import type {DocHandle} from '@automerge/automerge-repo';
/**
* The AutomergePersister interface represents a Persister that lets you save
* and load Store data to and from an Automerge document.
*
* You should use the createAutomergePersister function to create an
* AutomergePersister object.
*
* It is a minor extension to the Persister interface and simply provides an
* extra getDocHandle method for accessing the Automerge document handler the
* Store is being persisted to.
* @category Persister
* @since v4.3.14
*/
export interface AutomergePersister extends Persister {
/**
* The getDocHandle method returns the Automerge document handler the Store is
* being persisted to.
* @returns The Automerge document handler.
* @example
* This example creates a Persister object against a newly-created Store and
* then gets the Automerge document handler back out again.
*
* ```js
* import {Repo} from '@automerge/automerge-repo';
* import {createStore} from 'tinybase';
* import {createAutomergePersister} from 'tinybase/persisters/persister-automerge';
*
* const docHandler = new Repo({network: []}).create();
* const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
* const persister = createAutomergePersister(store, docHandler);
*
* console.log(persister.getDocHandle() == docHandler);
* // -> true
*
* persister.destroy();
* ```
* @category Getter
* @since v4.3.14
*/
getDocHandle(): DocHandle<any>;
}
/**
* The createAutomergePersister function creates an AutomergePersister object
* that can persist the Store to an Automerge document.
*
* An AutomergePersister only supports regular Store objects, and cannot be used
* to persist the metadata of a MergeableStore.
*
* As well as providing a reference to the Store to persist, you must provide
* the Automerge document handler to persist it with.
* @param store The Store to persist.
* @param docHandle The Automerge document handler to persist the Store with.
* @param docMapName The name of the map used inside the Automerge document to
* sync the Store to (which otherwise will default to 'tinybase').
* @param onIgnoredError An optional handler for the errors that the Persister
* would otherwise ignore when trying to save or load data. This is suitable for
* debugging persistence issues in a development environment, since v4.0.4.
* @returns A reference to the new AutomergePersister object.
* @example
* This example creates a AutomergePersister object and persists the Store to an
* Automerge document.
*
* ```js
* import {Repo} from '@automerge/automerge-repo';
* import {createStore} from 'tinybase';
* import {createAutomergePersister} from 'tinybase/persisters/persister-automerge';
*
* const docHandler = new Repo({network: []}).create();
* const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
* const persister = createAutomergePersister(store, docHandler);
*
* await persister.save();
* // Store will be saved to the document.
*
* console.log(await docHandler.doc());
* // -> {tinybase: {t: {pets: {fido: {species: 'dog'}}}, v: {}}}
*
* persister.destroy();
* ```
* @example
* This more complex example uses Automerge networking to keep two Store objects
* (each with their own Persister objects and Automerge documents) in sync with
* each other using a network.
*
* ```js
* import {Repo} from '@automerge/automerge-repo';
* import {BroadcastChannelNetworkAdapter} from '@automerge/automerge-repo-network-broadcastchannel';
* import {createStore} from 'tinybase';
* import {createAutomergePersister} from 'tinybase/persisters/persister-automerge';
*
* // Bind the first Store to a network-enabled automerge-repo
* const repo1 = new Repo({
* network: [new BroadcastChannelNetworkAdapter()],
* });
* const docHandler1 = repo1.create();
* await docHandler1.doc();
* const store1 = createStore();
* const persister1 = createAutomergePersister(store1, docHandler1);
* await persister1.startAutoLoad();
* await persister1.startAutoSave();
*
* // Bind the second Store to a different network-enabled automerge-repo
* const repo2 = new Repo({
* network: [new BroadcastChannelNetworkAdapter()],
* });
* const docHandler2 = repo2.find(docHandler1.documentId);
* await docHandler2.doc();
* const store2 = createStore();
* const persister2 = createAutomergePersister(store2, docHandler2);
* await persister2.startAutoLoad();
* await persister2.startAutoSave();
*
* // A function that waits briefly and then for the documents to synchronize
* // with each other, merely for the purposes of sequentiality in this example.
* const syncDocsWait = async () => {
* await new Promise((resolve) => setTimeout(() => resolve(0), 100));
* await docHandler1.doc();
* await docHandler2.doc();
* };
*
* // Wait for the documents to synchronize in their initial state.
* await syncDocsWait();
*
* // Make a change to each of the two Stores.
* store1.setTables({pets: {fido: {species: 'dog'}}});
* store2.setValues({open: true});
*
* // Wait for the documents to synchronize in their new state.
* await syncDocsWait();
*
* // Ensure the Stores are in sync.
* console.log(store1.getContent());
* // -> [{pets: {fido: {species: 'dog'}}}, {open: true}]
* console.log(store2.getContent());
* // -> [{pets: {fido: {species: 'dog'}}}, {open: true}]
*
* persister1.destroy();
* persister2.destroy();
* ```
* @category Creation
* @since v4.0.0
*/
export function createAutomergePersister(
store: Store,
docHandle: DocHandle<any>,
docMapName?: string,
onIgnoredError?: (error: any) => void,
): AutomergePersister;