TinyBase logoTinyBase β

createWsSynchronizer

Essential

The createWsSynchronizer function creates a WsSynchronizer object that can synchronize MergeableStore data to and from other MergeableStore instances via WebSockets facilitated by a WsServer.

createWsSynchronizer<WebSocketType>(
  store: MergeableStore,
  webSocket: WebSocketType,
  requestTimeoutSeconds?: number,
  onSend?: Send,
  onReceive?: Receive,
  onIgnoredError?: (error: any) => void,
  fragmentSize?: number,
): Promise<WsSynchronizer<WebSocketType>>
TypeDescription
storeMergeableStore

The MergeableStore to synchronize.

webSocketWebSocketType

The WebSocket to send synchronization messages over.

requestTimeoutSeconds?number

An optional time in seconds that the Synchronizer will wait for responses to request messages, defaulting to 1.

onSend?Send

An optional handler for the messages that this Synchronizer sends. This is suitable for debugging synchronization issues in a development environment, since v5.1.

onReceive?Receive

An optional handler for the messages that this Synchronizer receives. This is suitable for debugging synchronization issues in a development environment, since v5.1.

onIgnoredError?(error: any) => void

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.

fragmentSize?number

An optional target maximum UTF-8 byte size for each WebSocket message fragment. Unicode code points are never split and can exceed this size. TinyBase sends at most 1,000 fragments for one payload, increasing the target when needed. When set, larger synchronization payloads are split into fragments and reassembled by the receiving WsSynchronizer, since v9.0.

returnsPromise<WsSynchronizer<WebSocketType>>

A reference to the new WsSynchronizer object.

As well as providing a reference to the MergeableStore to persist, you must provide a configured WebSocket to send synchronization messages over. The path in the WebSocket URL is used by a WsServer as the path that the client joins. The MergeableStore Id does not select the server path.

The WsSynchronizer owns the WebSocket and closes it when it is destroyed. Instead of the raw browser implementation of WebSocket, you may prefer to use the 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.

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.

Example

This example creates two WsSynchronizer objects to synchronize one MergeableStore to another via a server.

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/petShop'),
);
const synchronizer2 = await createWsSynchronizer(
  store2,
  new WebSocket('ws://localhost:8047/petShop'),
);

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'}}}

await synchronizer1.destroy();
await synchronizer2.destroy();
await server.destroy();

Since

v5.0.0

This overload creates a WsSynchronizer that shares one WebSocket with other WsSynchronizer instances, each synchronizing a different MergeableStore.

createWsSynchronizer<WebSocketType>(
  store: MergeableStore,
  webSocket: WebSocketType,
  channelId: string,
  requestTimeoutSeconds?: number,
  onSend?: Send,
  onReceive?: Receive,
  onIgnoredError?: (error: any) => void,
  fragmentSize?: number,
): Promise<WsSynchronizer<WebSocketType>>
TypeDescription
storeMergeableStore

The MergeableStore to synchronize.

webSocketWebSocketType

The shared WebSocket to send synchronization messages over, constructed with the tinybase subprotocol.

channelIdstring

The channel Id to append to the WebSocket URL path.

requestTimeoutSeconds?number

An optional time in seconds that the Synchronizer will wait for responses to request messages, defaulting to 1.

onSend?Send

An optional handler for the messages that this Synchronizer sends. This is suitable for debugging synchronization issues in a development environment.

onReceive?Receive

An optional handler for the messages that this Synchronizer receives. This is suitable for debugging synchronization issues in a development environment.

onIgnoredError?(error: any) => void

An optional handler for errors that the Synchronizer would otherwise ignore when trying to synchronize data.

fragmentSize?number

An optional target maximum UTF-8 byte size for each WebSocket message fragment. Unicode code points are never split and can exceed this size. TinyBase sends at most 1,000 fragments for one payload, increasing the target when needed.

returnsPromise<WsSynchronizer<WebSocketType>>

A reference to the new WsSynchronizer object.

Construct the WebSocket with the tinybase subprotocol and provide a channel Id as the third argument. The channel Id is appended to the WebSocket URL path to form the server path; it is not taken from the MergeableStore Id.

Destroying the WsSynchronizer unsubscribes its channel. The shared WebSocket is closed only when the last WsSynchronizer using it is destroyed. Reconnecting WebSocket implementations will renegotiate and resubscribe all channels, then flush queued traffic.

Sharing a WebSocket requires a WsServer or WsServerSimple from v9.3 or later. It is not supported by WsServerDurableObject.

Example

This example creates two WsSynchronizer objects for different MergeableStore instances that share one WebSocket.

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: 8048}));
const webSocket = new WebSocket('ws://localhost:8048/petShop', 'tinybase');
const petsSynchronizer = await createWsSynchronizer(
  createMergeableStore(),
  webSocket,
  'pets',
);
const employeesSynchronizer = await createWsSynchronizer(
  createMergeableStore(),
  webSocket,
  'employees',
);

console.log(petsSynchronizer.getWebSocket() == webSocket);
// -> true
console.log(employeesSynchronizer.getWebSocket() == webSocket);
// -> true

await petsSynchronizer.destroy();
console.log(webSocket.readyState == WebSocket.OPEN);
// -> true

await employeesSynchronizer.destroy();
await server.destroy();

Since

v9.3.0