Docs
Server
Introduction

Introduction

Secsync requires a centralized server to ensure the correct order of snapshots and updates. It should reject invalid updates and snapshots.

While ideally secsync would have been designed to be decentralized, this would have resulted in various trade-offs that were not desired.

Secsync ships with a server utility that handles a Websocket connection including validations and handling expected error cases e.g. trying to send snapshot without having synced first. This is mean as a helfpul utility to simplify development, but of course you can implement your own replicating the logic.

secsync-server utilities

The secsync-server package exports createWebSocketConnection which requires 5 callbacks to be defined:

  • getDocument
  • createSnaphot
  • createUpdate
  • hasAccess
  • hasBroadcastAccess
import { createWebSocketConnection } from "secsync-server";
import { WebSocketServer } from "ws";
 
const webSocketServer = new WebSocketServer();
webSocketServer.on(
  "connection",
  createWebSocketConnection({
    createSnapshot,
    createUpdate,
    getDocument,
    hasAccess,
    hasBroadcastAccess,
  })
);

Callbacks

createSnapshot

A callback that receives an object containing the snapshot structure sent by clients. The Snapshot should be persistet to a database. In case persisting fails an error should be thrown.

createUpdate

A callback that receives an object containing the update structure sent by clients. The Update should be persistet to a database. In case persisting fails an error should be thrown.

getDocument

A callback that should return the necessary document information. The simples implementation would just return the latest snapshot, the proofs for snapshot ancestor chain and all related updates.

A more advanced implementation should take into account if the full document or just a delta was requested and idenitfy if and if so which updates are necessary to send and only return those.

hasAccess

A callback to verify if the client has read or write access to the requested document. Should return true if the client has access and false in case not.

The callback is invoked with the following argument:

type HasAccessParams =
  | {
      action: "read";
      documentId: string;
      websocketSessionKey: string | undefined;
    }
  | {
      action: "write-snapshot" | "write-update" | "send-ephemeral-message";
      documentId: string;
      publicKey: string;
      websocketSessionKey: string | undefined;
    };

hasBroadcastAccess

A callback to verify if clients are allowed to receive a new message. Should an array of true or false values matching the index of the websocketSessionKeys to indicate which client has access.

The callback is invoked with the following argument:

export type HasBroadcastAccessParams = {
  documentId: string;
  websocketSessionKeys: string[];
};

Documentation Example Server

A fully functional server can be found here https://github.com/serenity-kit/secsync/tree/main/examples/backend (opens in a new tab). Keep in mind that it accepts any client and does not verify the Websocket session key/token.