UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

90 lines 2.9 kB
import { s } from '../../../json-crdt-patch'; import { ConApi, ObjApi, VecApi } from '../../../json-crdt/model'; /** * Represents a single nested tag in a slice type. For example, in a slice type * like `['<blockquote>', 0, {author: 'Alice'}, ['<p>', 0, {indent: 2}]]`, there * is a tag for the blockquote and a tag for the paragraph. Each tag can * contain a discriminant and data. */ export class NestedTag { type; index; constructor(type, index) { this.type = type; this.index = index; } /** * Enforces current tag at `index` to be a "vec" node, which contains * a tag, a discriminant and an object with data. */ asVec() { const arr = this.type.asArr(); const typeLen = arr.length(); let index = this.index; if (typeof index !== 'number' || index > typeLen - 1) index = typeLen - 1; const vec = arr.get(index); if (vec instanceof VecApi) return vec; const tag = vec instanceof ConApi ? vec.view() : 0; arr.upd(index, s.vec(s.con(tag))); return arr.get(index); } /** * Returns the tag name at the current index, which is either a string or a number. * If the tag is not set, it returns `0`. * * @returns The tag value. */ name() { const vec = this.asVec(); const tag = vec.select(0)?.view(); return typeof tag === 'string' || typeof tag === 'number' ? tag : 0; } /** * Sets the tag name at the current index. If the tag is not a string or a number, * it will be converted to a string. * * @param tag - The tag value to set. */ setName(tag) { const vec = this.asVec(); vec.set([[0, s.con(tag)]]); } /** * Returns the discriminant of the tag at the current index. * If the discriminant is not set, it returns `0`. * * @returns The discriminant value. */ discriminant() { const disciminant = this.asVec().select(1)?.view() || 0; return typeof disciminant === 'number' ? disciminant : 0; } /** * Sets the discriminant of the tag at the current index. * * @param value - The discriminant value to set. */ setDiscriminant(value) { const vec = this.asVec(); vec.set([[1, s.con(value)]]); } /** * Returns the data object of the tag at the current index. * If the data is not set, it returns an empty object. Enforces the * data to be a {@link ObjApi} node, use this API to manipulate the data * object. * * @returns The data object. */ data() { const vec = this.asVec(); const data = vec.select(2); if (data instanceof ObjApi) return data; vec.set([[2, s.obj({})]]); return vec.get(2); } } //# sourceMappingURL=NestedTag.js.map