UNPKG

marshall-y-slate

Version:
97 lines (80 loc) 2.22 kB
import { Path } from 'slate'; import invariant from 'tiny-invariant'; import * as Y from 'yjs'; import { SharedType, SyncElement, SyncNode } from '../model'; import { toSlateDoc } from '../utils/convert'; const isTree = (node: SyncNode): boolean => !!SyncNode.getChildren(node); /** * Returns the SyncNode referenced by the path * * @param doc * @param path */ export function getTarget(doc: SharedType, path: Path): SyncNode { function iterate(current: SyncNode, idx: number) { const children = SyncNode.getChildren(current); if (!isTree(current) || !children?.get(idx)) { throw new TypeError( `path ${path.toString()} does not match doc ${JSON.stringify( toSlateDoc(doc) )}` ); } return children.get(idx); } return path.reduce<SyncNode>(iterate, doc); } function getParentPath(path: Path, level = 1): [number, Path] { if (level > path.length) { throw new TypeError('requested ancestor is higher than root'); } return [path[path.length - level], path.slice(0, path.length - level)]; } export function getParent( doc: SharedType, path: Path, level = 1 ): [SyncNode, number] { const [idx, parentPath] = getParentPath(path, level); const parent = getTarget(doc, parentPath); invariant(parent, 'Parent node should exists'); return [parent, idx]; } /** * Returns the position of the sync item inside inside it's parent array. * * @param item */ export function getArrayPosition(item: Y.Item): number { let i = 0; let c = (item.parent as Y.Array<SyncElement>)._start; while (c !== item && c !== null) { if (!c.deleted) { i += 1; } c = c.right; } return i; } /** * Returns the document path of a sync item * * @param node */ export function getSyncNodePath(node: SyncNode): Path { if (!node) { return []; } const { parent } = node; if (!parent) { return []; } if (parent instanceof Y.Array) { invariant(node._item, 'Parent should be associated with a item'); return [...getSyncNodePath(parent), getArrayPosition(node._item)]; } if (parent instanceof Y.Map) { return getSyncNodePath(parent); } throw new Error(`Unknown parent type ${parent}`); }