UNPKG

json-crdt-server

Version:

JSON CRDT server and syncing local-first browser client

168 lines (167 loc) 5.34 kB
export interface StoreBlock { /** Block ID. */ id: string; /** Timestamp in (milliseconds) when the block was created. */ ts: number; /** Timestamp in (milliseconds) when the block was last updated. */ uts: number; /** The latest snapshot of the block. */ snapshot: StoreSnapshot; /** * The latest changes that have been stored, but not yet applied to the the * latest snapshot. */ tip: StoreBatch[]; } /** * Represents a state snapshot of a block at a certain point in time. */ export interface StoreSnapshot { /** Block ID. */ id: string; /** Sequence number. The seq number of the last applied {@link StoreBatch}. */ seq: number; /** Timestamp in (milliseconds) when the snapshot was created. */ ts: number; /** The state of the snapshot encoded in algorithm-specific format. */ blob: Uint8Array; } /** * Represents a list of changes to apply to a block. */ export interface StoreBatch { /** * Server enforced sequence number. The client must provide a sequence number * that is greater than the current sequence number of the block. */ seq: number; /** Timestamp (in milliseconds) when the batch was processed by the server. */ ts: number; /** Timestamp (in milliseconds) when the batch was created by the client. */ cts?: number; /** * A list of atomic changes to apply to the block. */ patches: StorePatch[]; } /** * Represents an atomic change unit in algorithm-specific format. */ export interface StorePatch { /** Time (in milliseconds) when the patch was created by the client. */ cts?: number; /** Client set, optional, user ID, who created the patch. */ uid?: string; /** The patch contents in algorithm-specific format. */ blob: Uint8Array; } export type StoreIncomingSnapshot = Omit<StoreSnapshot, 'ts' | 'uts'>; export type StoreIncomingBatch = Omit<StoreBatch, 'seq' | 'ts'>; export interface Store { /** * Create a new block. * * @param id Block ID. * @param batch Initial patches to apply to a new block. * @returns Newly created block data. */ create(start: StoreSnapshot, end: StoreSnapshot, batch?: StoreIncomingBatch): Promise<StoreCreateResult>; /** * Push changes to an existing block. * * @param id Block ID. * @param batch Patches to apply to the block. * @returns Updated block data. */ push(snapshot: StoreIncomingSnapshot, batch: StoreIncomingBatch): Promise<StorePushResult>; /** * Compacts block's history by merging batches until the given sequence number. * * @param id Block ID. * @param to Sequence number until which the start of the block history * has to be compacted. * @param advance Callback which performs batch merging. */ compact?(id: string, to: number, advance: Advance): Promise<void>; /** * Retrieve an existing block. * * @param id Block ID. * @returns Block data, or `undefined` if the block does not exist. */ get(id: string): Promise<StoreGetResult | undefined>; /** * Retrieve a snapshot at a given sequence number. * * @param id Block ID. * @returns Snapshot and a list of batches to apply to the snapshot to get * to the state at the given sequence number. */ getSnapshot(id: string, seq: number): Promise<{ snapshot: StoreSnapshot; batches: StoreBatch[]; }>; /** * Retrieve the existence of a block. * * @param id Block ID. */ exists(id: string): Promise<boolean>; /** * Retrieve the sequence number of a block. * * @param id Block ID. * @returns Block sequence number, or `undefined` if the block does not exist. */ seq(id: string): Promise<number | undefined>; /** * Retrieve the history of batches for a block. * * @param id Block ID. * @param min Minimum sequence number. * @param max Maximum sequence number. * @returns List of batches. */ scan(id: string, min: number, max: number): Promise<StoreBatch[]>; /** * Remove a block. * * @param id Block ID. * @returns `true` if the block was removed, `false` if the block did not exist. */ remove(id: string): Promise<boolean>; /** * Remove all blocks that have not been accessed since the given timestamp. * * @param ts Timestamp in milliseconds. */ removeAccessedBefore(ts: number, limit: number): Promise<void>; /** * Remove a number of oldest blocks, measured by last update time. * * @param x Number of oldest blocks to remove. */ removeOldest(x: number): Promise<void>; /** * Retrieve statistics about the store. * * @returns Number of blocks and batches. */ stats(): { blocks: number; batches: number; }; stop?(): Promise<void>; } export interface StoreCreateResult { block: StoreBlock; batch?: StoreBatch; } export interface StorePushResult { snapshot: StoreSnapshot; batch: StoreBatch; } export interface StoreGetResult { block: StoreBlock; } export type Advance = (start: StoreSnapshot['blob'], batches: AsyncIterable<StoreBatch>) => Promise<StoreSnapshot['blob']>;