UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

136 lines (135 loc) 3.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ObjNode = void 0; const printTree_1 = require("tree-dump/lib/printTree"); const clock_1 = require("../../../json-crdt-patch/clock"); /** * Represents a `obj` JSON CRDT node, which is a Last-write-wins (LWW) object. * It is a map of string keys to LWW registers. The value of each register is * a reference to another JSON CRDT node. * * @category CRDT Node */ class ObjNode { constructor( /** * @ignore */ doc, id) { this.doc = doc; this.id = id; /** * @ignore */ this.keys = new Map(); /** * @ignore */ this._tick = 0; /** * @ignore */ this._view = {}; /** * @ignore */ this.api = undefined; } /** * Retrieves a JSON CRDT node at the given key. * * @param key A key of the object. * @returns JSON CRDT node at the given key, if any. */ get(key) { const id = this.keys.get(key); if (!id) return undefined; return this.doc.index.get(id); } /** * Rewrites object key. * * @param key Object key to set. * @param id ID of the contents of the key. * @returns Returns old entry ID, if any. * @ignore */ put(key, id) { const currentId = this.keys.get(key); if (currentId && (0, clock_1.compare)(currentId, id) >= 0) return; this.keys.set(key, id); return currentId; } /** * Iterate over all key-value pairs in the object. * * @param callback Callback to call for each key-value pair. */ nodes(callback) { const index = this.doc.index; this.keys.forEach((id, key) => callback(index.get(id), key)); } // ----------------------------------------------------------------- JsonNode /** * @ignore */ children(callback) { const index = this.doc.index; this.keys.forEach((id, key) => callback(index.get(id))); } /** * @ignore */ child() { return undefined; } /** * @ignore */ container() { return this; } /** * @ignore */ view() { const doc = this.doc; const tick = doc.clock.time + doc.tick; const _view = this._view; if (this._tick === tick) return _view; const view = {}; const index = doc.index; let useCache = true; this.keys.forEach((id, key) => { const valueNode = index.get(id); if (!valueNode) { useCache = false; return; } const value = valueNode.view(); if (value !== undefined) { if (_view[key] !== value) useCache = false; view[key] = value; } else if (_view[key] !== undefined) useCache = false; }); return useCache ? _view : ((this._tick = tick), (this._view = view)); } name() { return 'obj'; } // ---------------------------------------------------------------- Printable toString(tab = '') { const header = this.name() + ' ' + (0, clock_1.printTs)(this.id); return (header + (0, printTree_1.printTree)(tab, [...this.keys.entries()] .filter(([, id]) => !!this.doc.index.get(id)) .map(([key, id]) => (tab) => JSON.stringify(key) + (0, printTree_1.printTree)(tab + ' ', [(tab) => this.doc.index.get(id).toString(tab)])))); } } exports.ObjNode = ObjNode;