UNPKG

tinybase

Version:

A reactive data store and sync engine.

161 lines (157 loc) 6.3 kB
/** * The synchronizer-ws module of the TinyBase project lets you synchronize * MergeableStore data to and from other MergeableStore instances via WebSockets * facilitated by a server. * @see Synchronization guide * @see Todo App v6 (collaboration) demo * @packageDocumentation * @module synchronizer-ws-client * @since v5.0.0 */ import type {MergeableStore} from '../../mergeable-store/index.d.ts'; import type {Receive, Send, Synchronizer} from '../index.d.ts'; import type {WebSocket as WsWebSocket} from 'ws'; /** * The WebSocketTypes type represents the valid types of WebSocket that can be * used with the WsSynchronizer. * * This includes the browser-native WebSocket type, as well as the WebSocket * type from the well-known `ws` package (such that the Synchronizer can be used * in a server environment). * @category Creation * @since v5.0.0 */ export type WebSocketTypes = WebSocket | WsWebSocket; /** * The WsSynchronizer interface represents a Synchronizer that lets you * synchronize MergeableStore data to and from other MergeableStore instances * via WebSockets facilitated by a server. * * You should use the createWsSynchronizer function to create a WsSynchronizer * object. * * It is a minor extension to the Synchronizer interface and simply provides an * extra getWebSocket method for accessing a reference to the WebSocket being * used. * @category Synchronizer * @since v5.0.0 */ export interface WsSynchronizer<WebSocketType extends WebSocketTypes> extends Synchronizer { /** * The getWebSocket method returns a reference to the WebSocket being used for * synchronization. * @returns The WebSocket reference. * @example * This example creates a server and WsSynchronizer object for a newly-created * MergeableStore and then gets the WebSocket reference back out again. * * ```js * import {createMergeableStore} from 'tinybase'; * import {createWsSynchronizer} from 'tinybase/synchronizers/synchronizer-ws-client'; * import {createWsServer} from 'tinybase/synchronizers/synchronizer-ws-server'; * import {WebSocket, WebSocketServer} from 'ws'; * * const server = createWsServer(new WebSocketServer({port: 8046})); * * const store = createMergeableStore(); * const webSocket = new WebSocket('ws://localhost:8046'); * const synchronizer = await createWsSynchronizer(store, webSocket); * * console.log(synchronizer.getWebSocket() == webSocket); * // -> true * * synchronizer.destroy(); * server.destroy(); * ``` * @category Getter * @since v5.0.0 */ getWebSocket(): WebSocketType; } /** * The createWsSynchronizer function creates a WsSynchronizer object that can * synchronize MergeableStore data to and from other MergeableStore instances * via WebSockets facilitated by a WsServer. * * As well as providing a reference to the MergeableStore to persist, you must * provide a configured WebSocket to send synchronization messages over. * * Instead of the raw browser implementation of WebSocket, you may prefer to use * the [Reconnecting * WebSocket](https://github.com/pladaria/reconnecting-websocket) wrapper so * that if a client goes offline, it can easily re-establish a connection when * it comes back online. Its API is compatible with this Synchronizer. * * You can indicate how long the Synchronizer will wait for responses to message * requests before timing out. A final set of optional handlers can be provided * to help debug sends, receives, and errors respectively. * * This method is asynchronous because it will await the websocket's connection * to the server. You will need to `await` a call to this function or handle the * return type natively as a Promise. * @param store The MergeableStore to synchronize. * @param webSocket The WebSocket to send synchronization messages over. * @param requestTimeoutSeconds An optional time in seconds that the * Synchronizer will wait for responses to request messages, defaulting to 1. * @param onSend An optional handler for the messages that this Synchronizer * sends. This is suitable for debugging synchronization issues in a development * environment, since v5.1. * @param onReceive An optional handler for the messages that this Synchronizer * receives. This is suitable for debugging synchronization issues in a * development environment, since v5.1. * @param onIgnoredError An optional handler for the errors that the * Synchronizer would otherwise ignore when trying to synchronize data. This is * suitable for debugging synchronization issues in a development environment. * @returns A reference to the new WsSynchronizer object. * @example * This example creates two WsSynchronizer objects to synchronize one * MergeableStore to another via a server. * * ```js * import {createMergeableStore} from 'tinybase'; * import {createWsSynchronizer} from 'tinybase/synchronizers/synchronizer-ws-client'; * import {createWsServer} from 'tinybase/synchronizers/synchronizer-ws-server'; * import {WebSocket, WebSocketServer} from 'ws'; * * const server = createWsServer(new WebSocketServer({port: 8047})); * * const store1 = createMergeableStore(); * const store2 = createMergeableStore(); * * const synchronizer1 = await createWsSynchronizer( * store1, * new WebSocket('ws://localhost:8047'), * ); * const synchronizer2 = await createWsSynchronizer( * store2, * new WebSocket('ws://localhost:8047'), * ); * * await synchronizer1.startSync(); * await synchronizer2.startSync(); * * store1.setTables({pets: {fido: {species: 'dog'}}}); * store2.setTables({pets: {felix: {species: 'cat'}}}); * * // ... * console.log(store1.getTables()); * // -> {pets: {fido: {species: 'dog'}, felix: {species: 'cat'}}} * console.log(store2.getTables()); * // -> {pets: {fido: {species: 'dog'}, felix: {species: 'cat'}}} * * synchronizer1.destroy(); * synchronizer2.destroy(); * server.destroy(); * ``` * @category Creation * @since v5.0.0 */ export function createWsSynchronizer<WebSocketType extends WebSocketTypes>( store: MergeableStore, webSocket: WebSocketType, requestTimeoutSeconds?: number, onSend?: Send, onReceive?: Receive, onIgnoredError?: (error: any) => void, ): Promise<WsSynchronizer<WebSocketType>>;