UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

202 lines (201 loc) 8.07 kB
import { FanOut } from 'thingies/lib/fanout'; import { VecNode, ConNode, ObjNode, ArrNode, BinNode, StrNode, ValNode } from '../../nodes'; import { type ApiPath, ArrApi, BinApi, ConApi, type NodeApi, ObjApi, StrApi, VecApi, ValApi } from './nodes'; import type { Patch } from '../../../json-crdt-patch/Patch'; import { PatchBuilder } from '../../../json-crdt-patch/PatchBuilder'; import type { SyncStore } from '../../../util/events/sync-store'; import { MergeFanOut, MicrotaskBufferFanOut } from './fanout'; import { ExtNode } from '../../extensions/ExtNode'; import type { Model } from '../Model'; import type { JsonNode, JsonNodeView } from '../../nodes'; /** * Local changes API for a JSON CRDT model. This class is the main entry point * for executing local user actions on a JSON CRDT document. * * @category Local API */ export declare class ModelApi<N extends JsonNode = JsonNode> implements SyncStore<JsonNodeView<N>> { readonly model: Model<N>; /** * Patch builder for the local changes. */ builder: PatchBuilder; /** * Index of the next operation in builder's patch to be committed locally. * * @ignore */ next: number; /** Emitted before the model is reset, using the `.reset()` method. */ readonly onBeforeReset: FanOut<void>; /** Emitted after the model is reset, using the `.reset()` method. */ readonly onReset: FanOut<void>; /** Emitted before a patch is applied using `model.applyPatch()`. */ readonly onBeforePatch: FanOut<Patch>; /** Emitted after a patch is applied using `model.applyPatch()`. */ readonly onPatch: FanOut<Patch>; /** Emitted before local changes through `model.api` are applied. */ readonly onBeforeLocalChange: FanOut<number>; /** Emitted after local changes through `model.api` are applied. */ readonly onLocalChange: FanOut<number>; /** * Emitted after local changes through `model.api` are applied. Same as * `.onLocalChange`, but this event buffered withing a microtask. */ readonly onLocalChanges: MicrotaskBufferFanOut<number>; /** Emitted before a transaction is started. */ readonly onBeforeTransaction: FanOut<void>; /** Emitted after transaction completes. */ readonly onTransaction: FanOut<void>; /** Emitted when the model changes. Combines `onReset`, `onPatch` and `onLocalChange`. */ readonly onChange: MergeFanOut<number | Patch | undefined>; /** Emitted when the model changes. Same as `.onChange`, but this event is emitted once per microtask. */ readonly onChanges: MicrotaskBufferFanOut<number | Patch | undefined>; /** Emitted when the `model.api` builder change buffer is flushed. */ readonly onFlush: FanOut<Patch>; /** * @param model Model instance on which the API operates. */ constructor(model: Model<N>); /** * Returns a local change API for the given node. If an instance already * exists, returns the existing instance. */ wrap(node: ValNode): ValApi; wrap(node: StrNode<any>): StrApi; wrap(node: BinNode): BinApi; wrap(node: ArrNode): ArrApi; wrap(node: ObjNode): ObjApi; wrap(node: ConNode): ConApi; wrap(node: VecNode): VecApi; wrap(node: JsonNode): NodeApi; wrap(node: ExtNode<any, any>): NodeApi; /** * Local changes API for the root node. */ get r(): ValApi<import("../../nodes").RootNode<N>>; /** @ignore */ get node(): import("./types").JsonNodeApi<N>; /** * Traverses the model starting from the root node and returns a local * changes API for a node at the given path. * * @param path Path at which to locate a node. * @returns A local changes API for a node at the given path. */ in(path?: ApiPath): ValApi<ValNode<any>>; /** * Locates a JSON CRDT node, throws an error if the node doesn't exist. * * @param path Path at which to locate a node. * @returns A JSON CRDT node. */ find(path?: ApiPath): JsonNode<unknown>; /** * Locates a `con` node and returns a local changes API for it. If the node * doesn't exist or the node at the path is not a `con` node, throws an error. * * @todo Rename to `con`. * * @param path Path at which to locate a node. * @returns A local changes API for a `con` node. */ con(path?: ApiPath): ConApi<ConNode<any>>; /** * Locates a `val` node and returns a local changes API for it. If the node * doesn't exist or the node at the path is not a `val` node, throws an error. * * @param path Path at which to locate a node. * @returns A local changes API for a `val` node. */ val(path?: ApiPath): ValApi<ValNode<any>>; /** * Locates a `vec` node and returns a local changes API for it. If the node * doesn't exist or the node at the path is not a `vec` node, throws an error. * * @param path Path at which to locate a node. * @returns A local changes API for a `vec` node. */ vec(path?: ApiPath): VecApi<VecNode<any>>; /** * Locates an `obj` node and returns a local changes API for it. If the node * doesn't exist or the node at the path is not an `obj` node, throws an error. * * @param path Path at which to locate a node. * @returns A local changes API for an `obj` node. */ obj(path?: ApiPath): ObjApi<ObjNode<any>>; /** * Locates a `str` node and returns a local changes API for it. If the node * doesn't exist or the node at the path is not a `str` node, throws an error. * * @param path Path at which to locate a node. * @returns A local changes API for a `str` node. */ str(path?: ApiPath): StrApi; /** * Locates a `bin` node and returns a local changes API for it. If the node * doesn't exist or the node at the path is not a `bin` node, throws an error. * * @param path Path at which to locate a node. * @returns A local changes API for a `bin` node. */ bin(path?: ApiPath): BinApi; /** * Locates an `arr` node and returns a local changes API for it. If the node * doesn't exist or the node at the path is not an `arr` node, throws an error. * * @param path Path at which to locate a node. * @returns A local changes API for an `arr` node. */ arr(path?: ApiPath): ArrApi<ArrNode<any>>; /** * Given a JSON/CBOR value, constructs CRDT nodes recursively out of it and * sets the root node of the model to the constructed nodes. * * @param json JSON/CBOR value to set as the view of the model. * @returns Reference to itself. */ root(json: unknown): this; /** * Apply locally any operations from the `.builder`, which haven't been * applied yet. */ apply(): void; /** * Advance patch pointer to the end without applying the operations. With the * idea that they have already been applied locally. * * You need to manually call `this.onBeforeLocalChange.emit(this.next)` before * calling this method. * * @ignore */ advance(): void; /** * Returns the view of the model. * * @returns JSON/CBOR of the model. */ view(): Readonly<JsonNodeView<N>>; private inTx; transaction(callback: () => void): void; /** * Flushes the builder and returns a patch. * * @returns A JSON CRDT patch. * @todo Make this return undefined if there are no operations in the builder. */ flush(): Patch; stopAutoFlush?: () => void; /** * Begins to automatically flush buffered operations into patches, grouping * operations by microtasks or by transactions. To capture the patch, listen * to the `.onFlush` event. * * @returns Callback to stop auto flushing. */ autoFlush(drainNow?: boolean): () => void; readonly subscribe: (callback: () => void) => import("thingies/lib/fanout").FanOutUnsubscribe; readonly getSnapshot: () => JsonNodeView<N>; }