reptree 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/OpId.ts","../src/operations.ts","../src/VertexState.ts","../src/TreeState.ts","../src/uuid.ts","../src/Vertex.ts","../src/RepTree.ts"],"sourcesContent":["export class OpId {\n constructor(\n readonly counter: number,\n readonly peerId: string\n ) { }\n\n static compare(opIdA: OpId | string, opIdB: OpId | string): number {\n if (!(opIdA instanceof OpId)) {\n const parsedA = OpId.tryParseStr(opIdA);\n if (!parsedA) throw new Error(`Invalid OpId string: ${opIdA}`);\n opIdA = parsedA;\n }\n if (!(opIdB instanceof OpId)) {\n const parsedB = OpId.tryParseStr(opIdB);\n if (!parsedB) throw new Error(`Invalid OpId string: ${opIdB}`);\n opIdB = parsedB;\n }\n\n const counterA = opIdA.counter;\n const counterB = opIdB.counter;\n\n if (counterA > counterB) {\n return 1;\n } else if (counterA < counterB) {\n return -1;\n } else {\n return opIdA.peerId.localeCompare(opIdB.peerId);\n }\n }\n\n static equals(opIdA: OpId | string | null, opIdB: OpId | string | null): boolean {\n if (opIdA === opIdB) {\n return true;\n } else if (!opIdA || !opIdB) {\n return false;\n }\n\n return OpId.compare(opIdA, opIdB) === 0;\n }\n\n static tryParseStr(opIdStr: string): OpId {\n const parts = opIdStr.split('@');\n\n if (parts.length !== 2) {\n throw new Error(`Invalid OpId string: ${opIdStr}`);\n }\n\n return new OpId(parseInt(parts[0], 10), parts[1]);\n }\n \n isGreaterThan(opId: OpId | string): boolean {\n return OpId.compare(this, opId) === 1;\n }\n\n toString(): string {\n return `${this.counter}@${this.peerId}`;\n }\n}\n","import { OpId } from \"./OpId\";\nimport { type VertexPropertyType } from \"./treeTypes\";\n\nexport interface MoveVertex {\n id: OpId;\n targetId: string;\n parentId: string | null;\n}\n\nexport interface SetVertexProperty {\n id: OpId;\n targetId: string;\n key: string;\n value: VertexPropertyType;\n transient: boolean;\n}\n\nexport type VertexOperation = MoveVertex | SetVertexProperty;\n\nexport function isMoveVertexOp(op: VertexOperation): op is MoveVertex {\n return 'parentId' in op;\n}\n\nexport function isSetPropertyOp(op: VertexOperation): op is SetVertexProperty {\n return 'key' in op;\n}\n\nexport function newMoveVertexOp(clock: number, peerId: string, targetId: string, parentId: string | null): MoveVertex {\n return { id: new OpId(clock, peerId), targetId, parentId };\n}\n\nexport function newSetVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyType): SetVertexProperty {\n return { id: new OpId(clock, peerId), targetId, key, value, transient: false };\n}\n\nexport function newSetTransientVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyType): SetVertexProperty {\n return { id: new OpId(clock, peerId), targetId, key, value, transient: true };\n}","import type { TreeVertexId, TreeVertexProperty, VertexPropertyType } from \"./treeTypes\";\n\nexport class VertexState {\n readonly id: string;\n parentId: TreeVertexId | null;\n private properties: TreeVertexProperty[];\n private transientProperties: TreeVertexProperty[];\n children: string[];\n\n constructor(id: string, parentId: TreeVertexId | null) {\n this.id = id;\n this.parentId = parentId;\n this.properties = [];\n this.transientProperties = [];\n this.children = [];\n }\n\n setProperty(key: string, value: any): void {\n const existingPropIndex = this.properties.findIndex(p => p.key === key);\n if (existingPropIndex !== -1) {\n if (value !== undefined) {\n // Update existing property\n this.properties[existingPropIndex] = { key, value };\n } else {\n // Remove existing property\n this.removeProperty(key);\n }\n } else {\n if (value !== undefined) {\n // Add new property\n this.properties.push({ key, value });\n }\n }\n }\n\n setTransientProperty(key: string, value: any): void {\n const existingPropIndex = this.transientProperties.findIndex(p => p.key === key);\n if (existingPropIndex !== -1) {\n if (value !== undefined) {\n // Update existing property\n this.transientProperties[existingPropIndex] = { key, value };\n } else {\n // Remove existing property\n this.removeTransientProperty(key);\n }\n } else {\n if (value !== undefined) {\n // Add new property\n this.transientProperties.push({ key, value });\n }\n }\n }\n\n getProperty(key: string, includingTransient: boolean = true): VertexPropertyType | undefined {\n if (includingTransient) {\n const transientProp = this.transientProperties.find(p => p.key === key);\n if (transientProp) {\n return transientProp.value;\n }\n }\n\n return this.properties.find(p => p.key === key)?.value;\n }\n\n getAllProperties(includingTransient: boolean = true): ReadonlyArray<TreeVertexProperty> {\n if (!includingTransient) {\n return this.properties;\n }\n\n const result: TreeVertexProperty[] = [];\n const seenKeys = new Set<string>();\n\n // Add transient properties first\n for (const prop of this.transientProperties) {\n result.push(prop);\n seenKeys.add(prop.key);\n }\n\n // Add permanent properties that don't have a transient override\n for (const prop of this.properties) {\n if (!seenKeys.has(prop.key)) {\n result.push(prop);\n }\n }\n\n return result;\n }\n\n removeProperty(key: string): void {\n this.properties = this.properties.filter(p => p.key !== key);\n }\n\n removeTransientProperty(key: string): void {\n this.transientProperties = this.transientProperties.filter(p => p.key !== key);\n }\n}\n","import type { TreeVertexId, VertexChangeEvent, VertexPropertyChangeEvent, VertexChildrenChangeEvent, VertexMoveEvent } from \"./treeTypes\";\nimport { VertexState } from \"./VertexState\";\n\nexport class TreeState {\n private vertices: Map<TreeVertexId, VertexState>;\n private changeCallbacks: Map<TreeVertexId, Set<(events: VertexChangeEvent[]) => void>> = new Map();\n private globalChangeCallbacks: Set<(events: VertexChangeEvent[]) => void> = new Set();\n\n private batchTickInterval: NodeJS.Timeout;\n private batchedEvents: Map<TreeVertexId, VertexChangeEvent[]> = new Map();\n\n constructor() {\n this.vertices = new Map();\n\n this.batchTickInterval = setInterval(() => {\n this.processBatchedEvents();\n }, 33.3);\n }\n\n dispose() {\n clearInterval(this.batchTickInterval);\n }\n\n private processBatchedEvents() {\n for (const [vertexId, events] of this.batchedEvents) {\n // Get last property events per key and last move/children events\n let lastMoveEvent: VertexMoveEvent | null = null;\n let lastChildrenEvent: VertexChildrenChangeEvent | null = null;\n const propertyEventsByKey = new Map<string, VertexPropertyChangeEvent>();\n\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i];\n if (!lastMoveEvent && event.type === 'move') lastMoveEvent = event as VertexMoveEvent;\n if (!lastChildrenEvent && event.type === 'children') lastChildrenEvent = event as VertexChildrenChangeEvent;\n if (event.type === 'property') {\n const propertyEvent = event as VertexPropertyChangeEvent;\n if (!propertyEventsByKey.has(propertyEvent.key)) {\n propertyEventsByKey.set(propertyEvent.key, propertyEvent);\n }\n }\n }\n\n // Combine all events with move and children events first\n const filteredEvents = [\n ...(lastMoveEvent ? [lastMoveEvent] : []),\n ...(lastChildrenEvent ? [lastChildrenEvent] : []),\n ...propertyEventsByKey.values()\n ];\n\n this.globalChangeCallbacks.forEach(listener => listener(filteredEvents));\n this.changeCallbacks.get(vertexId)?.forEach(listener => listener(filteredEvents));\n }\n\n this.batchedEvents.clear();\n }\n\n getAllVertices(): ReadonlyArray<VertexState> {\n return Array.from(this.vertices.values());\n }\n\n getVertex(id: string): VertexState | undefined {\n return this.vertices.get(id);\n }\n\n getChildrenIds(vertexId: TreeVertexId): string[] {\n return this.getVertex(vertexId)?.children ?? [];\n }\n\n getChildren(vertexId: TreeVertexId): VertexState[] {\n return this.getChildrenIds(vertexId)\n .map(id => {\n const vertex = this.vertices.get(id);\n return vertex ? vertex : undefined;\n })\n .filter(vertex => vertex !== undefined)\n .sort((a, b) => {\n const aDate = a.getProperty('_c') as string;\n const bDate = b.getProperty('_c') as string;\n if (!aDate) return -1;\n if (!bDate) return 1;\n return new Date(aDate).getTime() - new Date(bDate).getTime();\n }) as VertexState[];\n }\n\n moveVertex(vertexId: TreeVertexId, newParentId: TreeVertexId | null): VertexState {\n let vertex = this.getVertex(vertexId);\n // Undefined if the vertex is new\n const prevParentId = vertex ? vertex.parentId : undefined;\n if (!vertex) {\n vertex = new VertexState(vertexId, newParentId);\n this.vertices.set(vertexId, vertex);\n }\n\n if (prevParentId === newParentId) {\n return vertex;\n }\n\n vertex.parentId = newParentId;\n\n let childrenInNewParent: string[] | null = null;\n let childrenInOldParent: string[] | null = null;\n\n // Update children arrays in vertices\n if (prevParentId) {\n const oldParentVertex = this.getVertex(prevParentId);\n if (oldParentVertex) {\n oldParentVertex.children = oldParentVertex.children.filter(child => child !== vertexId);\n childrenInOldParent = oldParentVertex.children;\n } else {\n console.error(`Old parent vertex not found for ${prevParentId}`);\n }\n }\n\n if (newParentId !== null) {\n const newParentVertex = this.vertices.get(newParentId);\n if (newParentVertex) {\n newParentVertex.children.push(vertexId);\n childrenInNewParent = newParentVertex.children;\n } else {\n console.error(`New parent vertex not found for ${newParentId}`);\n }\n }\n\n // We notify the listeners in the end so that they have the final state of the tree\n\n this.notifyChange({\n type: 'move',\n vertexId: vertexId,\n oldParentId: prevParentId,\n newParentId,\n } as VertexMoveEvent);\n\n if (childrenInNewParent !== null && newParentId !== null) {\n this.notifyChange({\n type: 'children',\n vertexId: newParentId,\n children: childrenInNewParent.map(id => this.vertices.get(id)!),\n } as VertexChildrenChangeEvent);\n }\n\n if (childrenInOldParent !== null && prevParentId) {\n this.notifyChange({\n type: 'children',\n vertexId: prevParentId,\n children: childrenInOldParent.map(id => this.vertices.get(id)!),\n } as VertexChildrenChangeEvent);\n }\n\n return vertex;\n }\n\n setProperty(vertexId: string, key: string, value: any) {\n const vertex = this.getVertex(vertexId);\n if (!vertex) {\n throw new Error(`Vertex ${vertexId} not found`);\n }\n\n vertex.setProperty(key, value);\n\n this.notifyChange({\n type: 'property',\n vertexId: vertexId,\n key,\n value,\n } as VertexPropertyChangeEvent);\n\n if (vertex.parentId !== null) {\n this.notifyChange({\n type: 'children',\n vertexId: vertex.parentId,\n children: [vertex], // @TODO: shoulld I set all children or rename this property?\n } as VertexChildrenChangeEvent);\n }\n }\n\n setTransientProperty(vertexId: string, key: string, value: any) {\n const vertex = this.getVertex(vertexId);\n if (vertex) {\n vertex.setTransientProperty(key, value);\n }\n\n // @TODO: add info that it's a transient property\n this.notifyChange({\n type: 'property',\n vertexId: vertexId,\n key,\n value,\n } as VertexPropertyChangeEvent);\n }\n\n addChangeCallback(vertexId: TreeVertexId, listener: (events: VertexChangeEvent[]) => void) {\n if (!this.changeCallbacks.has(vertexId)) {\n this.changeCallbacks.set(vertexId, new Set());\n }\n this.changeCallbacks.get(vertexId)!.add(listener);\n }\n\n removeChangeCallback(vertexId: TreeVertexId, listener: (events: VertexChangeEvent[]) => void) {\n this.changeCallbacks.get(vertexId)?.delete(listener);\n }\n\n addGlobalChangeCallback(listener: (events: VertexChangeEvent[]) => void) {\n this.globalChangeCallbacks.add(listener);\n }\n\n removeGlobalChangeCallback(listener: (events: VertexChangeEvent[]) => void) {\n this.globalChangeCallbacks.delete(listener);\n }\n\n private notifyChange(event: VertexChangeEvent) {\n let events = this.batchedEvents.get(event.vertexId);\n if (!events) {\n events = [];\n this.batchedEvents.set(event.vertexId, events);\n }\n\n events.push(event);\n\n // @TODO: have immediate events\n //this.globalChangeCallbacks.forEach(listener => listener(event));\n //this.changeCallbacks.get(event.vertexId)?.forEach(listener => listener(event));\n }\n\n printTree(vertexId: TreeVertexId, indent: string = \"\", isLast: boolean = true): string {\n const prefix = indent + (isLast ? \"└── \" : \"├── \");\n let result = prefix + vertexId + \"\\n\";\n\n let vertexName: string | null = null;\n\n if (vertexId !== null) {\n const vertex = this.getVertex(vertexId);\n if (vertex) {\n for (const prop of vertex.getAllProperties()) {\n if (prop.key === \"_n\") {\n vertexName = prop.value as string;\n //continue;\n }\n\n const propPrefix = indent + (isLast ? \" \" : \"│ \") + \"• \";\n result += `${propPrefix}${prop.key}: ${JSON.stringify(prop.value)}\\n`;\n }\n }\n }\n\n const children = this.getChildrenIds(vertexId);\n for (let i = 0; i < children.length; i++) {\n const childId = children[i];\n const isLastChild = i === children.length - 1;\n result += this.printTree(childId, indent + (isLast ? \" \" : \"│ \"), isLastChild);\n }\n\n return result;\n }\n}","const removeDashes = (guid: string) => guid.replace(/-/g, '');\n\nexport default function uuid(): string {\n return removeDashes(crypto.randomUUID());\n}","import type { VertexState } from \"./VertexState\";\nimport type { RepTree } from \"./RepTree\";\nimport type { TreeVertexProperty, VertexChangeEvent, VertexPropertyType } from \"./treeTypes\";\n\n/**\n * A wrapper class for VertexState that provides a more convenient API\n * for working with vertices in a RepTree.\n */\nexport class Vertex {\n constructor(\n private tree: RepTree,\n private state: VertexState\n ) { }\n\n get id(): string {\n return this.state.id;\n }\n\n get name(): string | undefined {\n return this.getProperty('_n') as string | undefined;\n }\n\n set name(name: string) {\n this.tree.setVertexProperty(this.id, '_n', name);\n }\n\n get createdAt(): Date {\n const createdAt = this.getProperty('_c') as string;\n if (!createdAt) {\n return new Date(0);\n }\n return new Date(createdAt);\n }\n\n get path(): string {\n //return this.tree.getVertexPath(this.id);\n throw new Error('Not implemented');\n }\n\n get parentId(): string | null {\n return this.state.parentId;\n }\n\n get parent(): Vertex | undefined {\n if (!this.parentId) {\n return undefined;\n }\n\n return this.tree.getVertex(this.parentId);\n }\n\n get children(): Vertex[] {\n return this.tree.getChildren(this.id);\n }\n\n get childrenIds(): string[] {\n return this.tree.getChildrenIds(this.id);\n }\n\n getAsTypedObject<T>(): T {\n return this.getProperties() as T;\n }\n\n getChildrenAsTypedArray<T>(): T[] {\n return this.children.map(v => v.getAsTypedObject<T>());\n }\n\n newChild(props?: Record<string, VertexPropertyType> | object | null): Vertex {\n const typedProps = props as Record<string, VertexPropertyType> | null;\n return this.tree.newVertex(this.id, typedProps);\n }\n\n newNamedChild(name: string, props?: Record<string, VertexPropertyType> | object | null): Vertex {\n const typedProps = props as Record<string, VertexPropertyType> | null;\n return this.tree.newNamedVertex(this.id, name, typedProps);\n }\n\n setProperty(key: string, value: VertexPropertyType): void {\n // First check if the property is already set (not including transient properties)\n const existingValue = this.getProperty(key, false);\n if (existingValue === value) {\n return;\n }\n\n this.tree.setVertexProperty(this.id, key, value);\n }\n\n setTransientProperty(key: string, value: VertexPropertyType): void {\n // First check if the property is already set\n const existingValue = this.getProperty(key);\n if (existingValue === value) {\n return;\n }\n\n this.tree.setTransientVertexProperty(this.id, key, value);\n }\n\n setProperties(props: Record<string, VertexPropertyType> | object): void {\n for (const [key, value] of Object.entries(props)) {\n this.setProperty(key, value);\n }\n }\n\n getProperty(key: string, includingTransient: boolean = true): VertexPropertyType | undefined {\n return this.tree.getVertexProperty(this.id, key, includingTransient);\n }\n\n getProperties(): Record<string, VertexPropertyType> {\n const props: Record<string, VertexPropertyType> = {};\n this.tree.getVertexProperties(this.id).forEach(p => {\n props[p.key] = p.value;\n });\n return props;\n }\n\n findAllChildrenWithProperty(key: string, value: VertexPropertyType): Vertex[] {\n return this.children.filter(c => c.getProperty(key) === value);\n }\n\n findFirstChildVertexWithProperty(key: string, value: VertexPropertyType): Vertex | undefined {\n return this.children.find(c => c.getProperty(key) === value);\n }\n\n findFirstTypedChildWithProperty<T>(key: string, value: VertexPropertyType): T | undefined {\n return this.findFirstChildVertexWithProperty(key, value)?.getAsTypedObject<T>();\n }\n\n findAllTypedChildrenWithProperty<T>(key: string, value: VertexPropertyType): T[] {\n return this.findAllChildrenWithProperty(key, value).map(c => c.getAsTypedObject<T>());\n }\n\n observe(listener: (events: VertexChangeEvent[]) => void): () => void {\n const unobserve = this.tree.observe(this.id, listener);\n return () => unobserve();\n }\n\n observeChildren(listener: (children: Vertex[]) => void): () => void {\n const unobserve = this.tree.observe(this.id, (events: VertexChangeEvent[]) => {\n if (events.some(e => e.type === 'children')) {\n listener(this.children);\n }\n });\n return () => unobserve();\n }\n\n observeChildrenAsTypedArray<T>(listener: (children: T[]) => void): () => void {\n return this.observeChildren((children) => {\n listener(children.map(c => c.getProperties() as unknown as T));\n });\n }\n\n delete(): void {\n this.tree.deleteVertex(this.id);\n }\n\n moveTo(parent: Vertex): void {\n this.tree.moveVertex(this.id, parent.id);\n }\n} ","import { newMoveVertexOp, type MoveVertex, type SetVertexProperty, isMoveVertexOp, isSetPropertyOp, type VertexOperation, newSetVertexPropertyOp, newSetTransientVertexPropertyOp } from \"./operations\";\nimport type { VertexPropertyType, TreeVertexProperty, VertexChangeEvent, TreeVertexId, VertexMoveEvent, OpIdRange } from \"./treeTypes\"; // Added OpIdRange\nimport { VertexState } from \"./VertexState\";\nimport { TreeState } from \"./TreeState\";\nimport { OpId } from \"./OpId\";\nimport uuid from \"./uuid\";\nimport { Vertex } from './Vertex';\n\ntype PropertyKeyAtVertexId = `${string}@${TreeVertexId}`;\n\n/**\n * Helper function to subtract one set of ranges from another.\n * Returns the ranges in A that are not in B.\n * Assumes ranges in both A and B are sorted and non-overlapping.\n */\nfunction subtractRanges(rangesA: number[][], rangesB: number[][]): number[][] {\n if (rangesB.length === 0) return rangesA.map(r => [...r]); // Return a copy\n if (rangesA.length === 0) return []; // If A is empty, nothing to subtract\n \n const result: number[][] = [];\n let indexB = 0;\n \n for (const rangeA of rangesA) {\n let currentStart = rangeA[0];\n const endA = rangeA[1];\n \n // Iterate through ranges in B that could potentially overlap with rangeA\n while (indexB < rangesB.length && rangesB[indexB][1] < currentStart) {\n // Skip ranges in B that are entirely before the current start\n indexB++;\n }\n\n while (indexB < rangesB.length && rangesB[indexB][0] <= endA) {\n const startB = rangesB[indexB][0];\n const endB = rangesB[indexB][1];\n\n // If there's a gap before this range in B starts\n if (currentStart < startB) {\n // Add the portion of rangeA before the overlap\n result.push([currentStart, Math.min(endA, startB - 1)]);\n }\n \n // Move current start past this range in B\n currentStart = Math.max(currentStart, endB + 1);\n \n // If we've gone past the end of rangeA, break inner loop\n if (currentStart > endA) break;\n\n // If the current rangeB ends after rangeA, we don't need to check further ranges in B for this rangeA\n if (endB >= endA) break;\n\n // Only advance indexB if the current rangeB is fully processed relative to currentStart\n // Advance indexB if the end of the current B range is before the new currentStart\n if (endB < currentStart) { \n indexB++;\n }\n // If the start of the current B range is greater than or equal to currentStart, \n // it means this B range has been processed for the current segment of A, so move to the next B range.\n else if (startB >= currentStart) {\n indexB++;\n }\n }\n \n // If there's a remaining part of rangeA after processing overlaps with B\n if (currentStart <= endA) {\n result.push([currentStart, endA]);\n }\n }\n \n return result;\n}\n\n\n/**\n * RepTree is a tree data structure for storing vertices with properties.\n * It uses 2 conflict-free replicated data types (CRDTs) to manage seamless replication between peers.\n * A move tree CRDT is used for the tree structure (https://martin.kleppmann.com/papers/move-op.pdf).\n * A last writer wins (LWW) CRDT is used for properties.\n */\nexport class RepTree {\n private static NULL_VERTEX_ID = '0';\n private static DEFAULT_MAX_DEPTH = 100000;\n\n readonly peerId: string;\n readonly rootVertexId: string;\n\n private lamportClock = 0;\n private state: TreeState;\n private moveOps: MoveVertex[] = [];\n private setPropertyOps: SetVertexProperty[] = [];\n private propertiesAndTheirOpIds: Map<PropertyKeyAtVertexId, OpId> = new Map();\n private transientPropertiesAndTheirOpIds: Map<PropertyKeyAtVertexId, OpId> = new Map();\n private localOps: VertexOperation[] = [];\n private pendingMovesWithMissingParent: Map<string, MoveVertex[]> = new Map();\n private pendingPropertiesWithMissingVertex: Map<string, SetVertexProperty[]> = new Map();\n private knownOps: Set<string> = new Set();\n private parentIdBeforeMove: Map<OpId, string | null | undefined> = new Map();\n private opAppliedCallbacks: ((op: VertexOperation) => void)[] = [];\n private maxDepth = RepTree.DEFAULT_MAX_DEPTH;\n\n // State vector tracking operations from each peer\n private stateVector: Record<string, number[][]> = {};\n\n /**\n * @param peerId - The peer ID of the current client\n * @param ops - The operations to replicate an existing tree, if null - a new tree will be created\n */\n constructor(peerId: string, ops: ReadonlyArray<VertexOperation> | null = null) {\n this.peerId = peerId;\n this.state = new TreeState();\n\n if (ops != null && ops.length > 0) {\n // Find a move op that has a parentId as null\n let rootMoveOp: MoveVertex | undefined;\n for (let i = 0; i < ops.length; i++) {\n if (isMoveVertexOp(ops[i]) && (ops[i] as MoveVertex).parentId === null) {\n rootMoveOp = ops[i] as MoveVertex;\n break;\n }\n }\n if (rootMoveOp) {\n this.rootVertexId = rootMoveOp.targetId;\n } else {\n throw new Error('The operations has to contain a move operation with a parentId as null to set the root vertex');\n }\n\n this.applyOps(ops);\n\n // @TODO: perhaps don't do it here. Handle it in validation.\n this.ensureNullVertex();\n\n // @TODO: validate the tree structure, throw an exception if it's invalid\n } else {\n // The root is our only vertex that will have a null parentId\n this.rootVertexId = this.newVertexInternalWithUUID(null);\n\n this.ensureNullVertex();\n }\n }\n\n getMoveOps(): ReadonlyArray<MoveVertex> {\n return this.moveOps;\n }\n\n getAllOps(): ReadonlyArray<VertexOperation> {\n return [...this.moveOps, ...this.setPropertyOps];\n }\n\n getVertex(vertexId: string): Vertex | undefined {\n const vertex = this.state.getVertex(vertexId);\n return vertex ? new Vertex(this, vertex) : undefined;\n }\n\n get rootVertex(): Vertex {\n const rootVertex = this.state.getVertex(this.rootVertexId);\n if (!rootVertex) {\n throw new Error(\"Root vertex not found\");\n }\n\n return new Vertex(this, rootVertex);\n }\n\n getAllVertices(): ReadonlyArray<Vertex> {\n return this.state.getAllVertices().map(v => new Vertex(this, v));\n }\n\n getParent(vertexId: string): Vertex | undefined {\n const parentId = this.state.getVertex(vertexId)?.parentId;\n const parent = parentId ? this.state.getVertex(parentId) : undefined;\n return parent ? new Vertex(this, parent) : undefined;\n }\n\n getChildren(vertexId: string): Vertex[] {\n return this.state.getChildren(vertexId).map(v => new Vertex(this, v));\n }\n\n getChildrenIds(vertexId: string): string[] {\n return this.state.getChildrenIds(vertexId);\n }\n\n getAncestors(vertexId: string): Vertex[] {\n const ancestors: Vertex[] = [];\n let currentVertex = this.state.getVertex(vertexId);\n\n while (currentVertex && currentVertex.parentId) {\n const parentVertex = this.state.getVertex(currentVertex.parentId);\n if (parentVertex) {\n ancestors.push(new Vertex(this, parentVertex));\n currentVertex = parentVertex;\n } else {\n break;\n }\n }\n\n return ancestors;\n }\n\n getVertexProperty(vertexId: string, key: string, includingTransient: boolean = true): VertexPropertyType | undefined {\n const vertex = this.state.getVertex(vertexId);\n if (!vertex) {\n return undefined;\n }\n\n return vertex.getProperty(key, includingTransient);\n }\n\n getVertexProperties(vertexId: string): Readonly<TreeVertexProperty[]> {\n const vertex = this.state.getVertex(vertexId);\n if (!vertex) {\n return [];\n }\n\n return vertex.getAllProperties();\n }\n\n popLocalOps(): VertexOperation[] {\n const ops = this.localOps;\n this.localOps = [];\n return ops;\n }\n\n setMaxDepth(maxDepth: number) {\n this.maxDepth = maxDepth;\n }\n\n newVertex(parentId: string, props: Record<string, VertexPropertyType> | object | null = null): Vertex {\n const typedProps = props as Record<string, VertexPropertyType> | null;\n const vertexId = this.newVertexInternalWithUUID(parentId);\n if (typedProps) {\n this.setVertexProperties(vertexId, typedProps);\n }\n\n const vertex = this.state.getVertex(vertexId);\n if (!vertex) {\n throw new Error('Failed to create vertex');\n }\n return new Vertex(this, vertex);\n }\n\n newNamedVertex(parentId: string, name: string, props: Record<string, VertexPropertyType> | object | null = null): Vertex {\n const typedProps = props as Record<string, VertexPropertyType> | null;\n const vertexId = this.newVertexInternalWithUUID(parentId);\n if (typedProps) {\n this.setVertexProperties(vertexId, typedProps);\n }\n this.setVertexProperty(vertexId, '_n', name);\n\n const vertex = this.state.getVertex(vertexId);\n if (!vertex) {\n throw new Error('Failed to create named vertex');\n }\n return new Vertex(this, vertex);\n }\n\n moveVertex(vertexId: string, parentId: string) {\n this.lamportClock++;\n const op = newMoveVertexOp(this.lamportClock, this.peerId, vertexId, parentId);\n this.localOps.push(op);\n this.applyMove(op);\n }\n\n deleteVertex(vertexId: string) {\n this.moveVertex(vertexId, RepTree.NULL_VERTEX_ID);\n }\n\n setTransientVertexProperty(vertexId: string, key: string, value: VertexPropertyType) {\n this.lamportClock++;\n const op = newSetTransientVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);\n this.localOps.push(op);\n this.applyProperty(op);\n }\n\n setVertexProperty(vertexId: string, key: string, value: VertexPropertyType) {\n this.lamportClock++;\n const op = newSetVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);\n this.localOps.push(op);\n this.applyProperty(op);\n }\n\n setVertexProperties(vertexId: string, props: Record<string, VertexPropertyType> | object) {\n const typedProps = props as Record<string, VertexPropertyType>;\n for (const [key, value] of Object.entries(typedProps)) {\n this.setVertexProperty(vertexId, key, value);\n }\n }\n\n getVertexByPath(path: string): Vertex | undefined {\n // Let's remove '/' at the start and at the end of the path\n path = path.replace(/^\\/+/, '');\n path = path.replace(/\\/+$/, '');\n\n const pathParts = path.split('/');\n\n const root = this.state.getVertex(this.rootVertexId);\n if (!root) {\n throw new Error('The root vertex is not found');\n }\n\n const vertex = this.getVertexByPathArray(new Vertex(this, root), pathParts);\n return vertex;\n }\n\n private getVertexByPathArray(vertex: Vertex, path: string[]): Vertex | undefined {\n if (path.length === 0) {\n return vertex ?? undefined;\n }\n\n const targetName = path[0];\n // Now, search recursively by name '_n' in children until the path is empty or not found.\n const children = this.getChildren(vertex.id);\n for (const child of children) {\n if (child.getProperty('_n') === targetName) {\n return this.getVertexByPathArray(child, path.slice(1));\n }\n }\n\n return undefined;\n }\n\n printTree() {\n return this.state.printTree(this.rootVertexId);\n }\n\n merge(ops: ReadonlyArray<VertexOperation>) {\n /*\n if (ops.length > 100) {\n this.applyOpsOptimizedForLotsOfMoves(ops);\n } else {\n this.applyOps(ops);\n }\n */\n\n this.applyOps(ops);\n }\n\n /** Applies operations in an optimized way, sorting move ops by OpId to avoid undo-do-redo cycles */\n private applyOpsOptimizedForLotsOfMoves(ops: ReadonlyArray<VertexOperation>) {\n const newMoveOps = ops.filter(op => isMoveVertexOp(op) && !this.knownOps.has(op.id.toString()));\n if (newMoveOps.length > 0) {\n // Get an array of all move ops (without already applied ones)\n const allMoveOps = [...this.moveOps, ...newMoveOps] as MoveVertex[];\n // The main point of this optimization is to apply the moves without undo-do-redo cycles (the conflict resolution algorithm).\n // That is why we sort by OpId.\n allMoveOps.sort((a, b) => OpId.compare(a.id, b.id));\n for (let i = 0, len = allMoveOps.length; i < len; i++) {\n const op = allMoveOps[i];\n this.applyMove(op);\n }\n }\n\n // Get an array of all property ops (without already applied ones)\n const propertyOps = ops.filter(op => isSetPropertyOp(op) && !this.knownOps.has(op.id.toString())) as SetVertexProperty[];\n for (let i = 0, len = propertyOps.length; i < len; i++) {\n const op = propertyOps[i];\n this.applyProperty(op);\n }\n }\n\n compareStructure(other: RepTree): boolean {\n return RepTree.compareVertices(this.rootVertexId, this, other);\n }\n\n compareMoveOps(other: RepTree): boolean {\n const movesA = this.moveOps;\n const movesB = other.getMoveOps();\n\n if (movesA.length !== movesB.length) {\n return false;\n }\n\n for (let i = 0; i < movesA.length; i++) {\n if (!OpId.equals(movesA[i].id, movesB[i].id)) {\n return false;\n }\n }\n\n return true;\n }\n\n /** Checks if the given `ancestorId` is an ancestor of `childId` in the tree */\n isAncestor(childId: string, ancestorId: string | null): boolean {\n let targetId = childId;\n let vertex: VertexState | undefined;\n let depth = 0;\n\n while (vertex = this.state.getVertex(targetId)) {\n if (vertex.parentId === ancestorId) return true;\n if (!vertex.parentId) return false;\n\n if (depth > this.maxDepth) {\n console.error(`isAncestor: max depth of ${this.maxDepth} reached. Perhaps, we have an infinite loop here.`);\n return true;\n }\n\n targetId = vertex.parentId;\n depth++;\n }\n\n return false;\n }\n\n observeVertex(vertexId: string, callback: (updatedVertex: Vertex) => void): () => void {\n const vertex = this.getVertex(vertexId);\n if (vertex) {\n callback(vertex);\n }\n\n const unsubscribe = this.observe(vertexId, (_) => { \n const vertex = this.getVertex(vertexId);\n if (vertex) {\n callback(vertex);\n }\n });\n\n return () => {\n unsubscribe();\n };\n }\n\n observeVertexMove(callback: (movedVertex: Vertex, isNew: boolean) => void): () => void {\n const listener = (events: VertexChangeEvent[]) => {\n const moveEvent = events.find(e => e.type === 'move') as VertexMoveEvent | undefined;\n if (moveEvent) {\n const vertex = this.getVertex(moveEvent.vertexId);\n if (vertex) {\n callback(vertex, moveEvent.oldParentId === undefined);\n }\n }\n };\n\n this.state.addGlobalChangeCallback(listener);\n\n return () => this.state.removeGlobalChangeCallback(listener);\n }\n\n observe(vertexId: string, callback: (events: VertexChangeEvent[]) => void): () => void {\n this.state.addChangeCallback(vertexId, callback);\n return () => this.state.removeChangeCallback(vertexId, callback);\n }\n\n observeOpApplied(callback: (op: VertexOperation) => void): () => void {\n this.opAppliedCallbacks.push(callback);\n return () => this.opAppliedCallbacks = this.opAppliedCallbacks.filter(l => l !== callback);\n }\n\n static compareVertices(vertexId: string, treeA: RepTree, treeB: RepTree): boolean {\n const childrenA = treeA.state.getChildrenIds(vertexId);\n const childrenB = treeB.state.getChildrenIds(vertexId);\n\n if (childrenA.length !== childrenB.length) {\n return false;\n }\n\n // Compare properties of the current vertex\n if (vertexId !== null) {\n const propertiesA = treeA.getVertexProperties(vertexId);\n const propertiesB = treeB.getVertexProperties(vertexId);\n\n if (propertiesA.length !== propertiesB.length) {\n return false;\n }\n\n for (const propA of propertiesA) {\n const propB = propertiesB.find(p => p.key === propA.key);\n if (!propB || propA.value !== propB.value) {\n return false;\n }\n }\n }\n\n // Compare children and their properties recursively\n for (const childId of childrenA) {\n if (!childrenB.includes(childId)) {\n return false;\n }\n\n if (!RepTree.compareVertices(childId, treeA, treeB)) {\n return false;\n }\n }\n\n return true;\n }\n\n private newVertexInternal(vertexId: string, parentId: string | null): string {\n this.lamportClock++;\n // To create a vertex - we move a vertex with a fresh id under the parent.\n // No need to have a separate \"create vertex\" operation.\n const op = newMoveVertexOp(this.lamportClock, this.peerId, vertexId, parentId);\n this.localOps.push(op);\n this.applyMove(op);\n\n // Set the creation date\n this.setVertexProperty(vertexId, '_c', new Date().toISOString());\n\n return vertexId;\n }\n\n private newVertexInternalWithUUID(parentId: string | null): string {\n const vertexId = uuid();\n return this.newVertexInternal(vertexId, parentId);\n }\n\n private ensureNullVertex() {\n const vertexId = RepTree.NULL_VERTEX_ID;\n\n // Check if the null vertex already exists\n if (this.state.getVertex(vertexId)) {\n return;\n }\n\n this.newVertexInternal(vertexId, null);\n }\n\n /** Updates the lamport clock with the counter value of the operation */\n private updateLamportClock(operation: VertexOperation): void {\n // This is how Lamport clock updates with a foreign operation that has a greater counter value.\n if (operation.id.counter > this.lamportClock) {\n this.lamportClock = operation.id.counter;\n }\n }\n\n private applyPendingMovesForParent(parentId: string) {\n // If a parent doesn't exist, we can't apply pending moves yet.\n if (!this.state.getVertex(parentId)) {\n return;\n }\n\n const pendingMoves = this.pendingMovesWithMissingParent.get(parentId);\n if (!pendingMoves) {\n return;\n }\n\n this.pendingMovesWithMissingParent.delete(parentId);\n\n for (const pendingOp of pendingMoves) {\n this.applyMove(pendingOp);\n }\n }\n\n private applyMove(op: MoveVertex) {\n // Check if a parent (unless we're dealing with the root vertex) exists for the move operation.\n // If it doesn't exist, stash the move op for later\n if (op.parentId !== null && !this.state.getVertex(op.parentId)) {\n if (!this.pendingMovesWithMissingParent.has(op.parentId)) {\n this.pendingMovesWithMissingParent.set(op.parentId, []);\n }\n this.pendingMovesWithMissingParent.get(op.parentId)!.push(op);\n return;\n }\n\n this.updateLamportClock(op);\n\n const lastOp = this.moveOps.length > 0 ? this.moveOps[this.moveOps.length - 1] : null;\n\n // If it's the most recent move operation - just try to move it. No conflict resolution is needed.\n if (lastOp === null || op.id.isGreaterThan(lastOp.id)) {\n this.moveOps.push(op);\n this.reportOpAsApplied(op);\n this.tryToMove(op);\n }\n\n // Here comes the core of the 'THE REPLICATED TREE ALGORITHM'.\n // From https://martin.kleppmann.com/papers/move-op.pdf\n // We undo all moves that are newer (based on the Lamport clock) than the target move, do the move, and then redo the moves we just undid.\n // The algorithm ensures that all replicas converge to the same tree after applying all operations.\n // The replicas are basically forced to apply the moves in the same order (by undo-do-redo).\n // So if a conflict or a cycle is introduced by some of the peers - the algorithm will resolve it.\n // tryToMove function has the logic to detect cycles and will ignore the move if it creates a cycle. \n else {\n let targetIndex = this.moveOps.length;\n for (let i = this.moveOps.length - 1; i >= 0; i--) {\n const moveOp = this.moveOps[i];\n targetIndex = i;\n if (op.id.isGreaterThan(moveOp.id)) {\n break;\n }\n else {\n this.undoMove(moveOp);\n }\n }\n\n // Insert the op at the correct position\n this.moveOps.splice(targetIndex + 1, 0, op);\n this.reportOpAsApplied(op);\n this.tryToMove(op);\n\n // Redo all of the operations after the operation that we applied\n for (let i = targetIndex + 2; i < this.moveOps.length; i++) {\n this.tryToMove(this.moveOps[i]);\n }\n }\n\n // After applying the move, check if it unblocks any pending moves\n // We use targetId here because this vertex might now be a parent for pending operations\n this.applyPendingMovesForParent(op.targetId);\n }\n\n private setPropertyAndItsOpId(op: SetVertexProperty) {\n this.propertiesAndTheirOpIds.set(`${op.key}@${op.targetId}`, op.id);\n this.state.setProperty(op.targetId, op.key, op.value);\n this.reportOpAsApplied(op);\n }\n\n private setTransientPropertyAndItsOpId(op: SetVertexProperty) {\n this.transientPropertiesAndTheirOpIds.set(`${op.key}@${op.targetId}`, op.id);\n this.state.setTransientProperty(op.targetId, op.key, op.value);\n this.reportOpAsApplied(op);\n }\n\n private applyProperty(op: SetVertexProperty) {\n const targetVertex = this.state.getVertex(op.targetId);\n if (!targetVertex) {\n // No need to handle transient properties if the vertex doesn't exist\n if (op.transient) {\n return;\n }\n\n // If the vertex doesn't exist, we will wait for the move operation to appear that will create the vertex\n // so we can apply the property then.\n if (!this.pendingPropertiesWithMissingVertex.has(op.targetId)) {\n this.pendingPropertiesWithMissingVertex.set(op.targetId, []);\n }\n this.pendingPropertiesWithMissingVertex.get(op.targetId)!.push(op);\n return;\n }\n\n this.updateLamportClock(op);\n\n const prevTransientOpId = this.transientPropertiesAndTheirOpIds.get(`${op.key}@${op.targetId}`);\n\n const prevProp = targetVertex.getProperty(op.key);\n const prevOpId = this.propertiesAndTheirOpIds.get(`${op.key}@${op.targetId}`);\n\n if (!op.transient) {\n this.setPropertyOps.push(op);\n\n // Apply the property if it's not already applied or if the current op is newer\n // This is the last writer wins approach that ensures the same state between replicas.\n if (!prevProp || !prevOpId || op.id.isGreaterThan(prevOpId)) {\n this.setPropertyAndItsOpId(op);\n } else {\n // We add it to set of known ops to avoid adding them to `setPropertyOps` multiple times \n // if we ever receive the same op from another peer.\n this.knownOps.add(op.id.toString());\n }\n\n // Remove the transient property if the current op is greater\n if (prevTransientOpId && op.id.isGreaterThan(prevTransientOpId)) {\n this.transientPropertiesAndTheirOpIds.delete(`${op.key}@${op.targetId}`);\n targetVertex.removeTransientProperty(op.key);\n }\n } else {\n if (!prevTransientOpId || op.id.isGreaterThan(prevTransientOpId)) {\n this.setTransientPropertyAndItsOpId(op);\n }\n }\n }\n\n private applyOps(ops: ReadonlyArray<VertexOperation>) {\n for (const op of ops) {\n // We skip the operation if we already know about it.\n // This is to avoid processing the same operation multiple times.\n if (this.knownOps.has(op.id.toString())) {\n continue;\n }\n\n if (isMoveVertexOp(op)) {\n this.applyMove(op);\n } else if (isSetPropertyOp(op)) {\n this.applyProperty(op);\n }\n }\n }\n\n private reportOpAsApplied(op: VertexOperation) {\n this.knownOps.add(op.id.toString());\n this.updateStateVector(op); // Call the method correctly\n for (const callback of this.opAppliedCallbacks) {\n callback(op);\n }\n }\n\n private tryToMove(op: MoveVertex) {\n let targetVertex = this.state.getVertex(op.targetId);\n\n if (targetVertex) {\n // We cache the parentId before the move operation.\n // We will use it to undo the move according to the move op algorithm.\n this.parentIdBeforeMove.set(op.id, targetVertex.parentId);\n }\n\n // If trying to move the target vertex under itself - do nothing\n if (op.targetId === op.parentId) return;\n\n // If we try to move the vertex (op.targetId) under one of its descendants (op.parentId) - do nothing\n if (op.parentId && this.isAncestor(op.parentId, op.targetId)) return;\n\n this.state.moveVertex(op.targetId, op.parentId);\n\n // If the vertex didn't exist before the move - see if it has pending properties\n // and apply them.\n if (!targetVertex) {\n const pendingProperties = this.pendingPropertiesWithMissingVertex.get(op.targetId) || [];\n this.pendingPropertiesWithMissingVertex.delete(op.targetId);\n for (const prop of pendingProperties) {\n this.setPropertyAndItsOpId(prop);\n }\n }\n }\n\n private undoMove(op: MoveVertex) {\n const targetVertex = this.state.getVertex(op.targetId);\n if (!targetVertex) {\n console.error(`An attempt to undo move operation ${op.id.toString()} failed because the target vertex ${op.targetId} not found`);\n return;\n }\n\n const prevParentId = this.parentIdBeforeMove.get(op.id);\n if (prevParentId === undefined) {\n return;\n }\n\n this.state.moveVertex(op.targetId, prevParentId);\n }\n\n // --- Range-Based State Vector Methods --- \n\n /**\n * Updates the state vector with a newly applied operation.\n * Assumes ranges are sorted and non-overlapping.\n * \n * @param op The operation that was just applied\n */\n private updateStateVector(op: VertexOperation): void {\n const peerId = op.id.peerId;\n const counter = op.id.counter;\n \n // Initialize ranges array for this peer if it doesn't exist\n if (!this.stateVector[peerId]) {\n this.stateVector[peerId] = [];\n }\n \n const ranges = this.stateVector[peerId];\n \n // Case 1: No ranges yet\n if (ranges.length === 0) {\n ranges.push([counter, counter]);\n return;\n }\n \n let rangeExtendedOrMerged = false;\n let insertIndex = -1;\n\n for (let i = 0; i < ranges.length; i++) {\n const range = ranges[i];\n \n // If counter is already in a range, do nothing\n if (counter >= range[0] && counter <= range[1]) {\n rangeExtendedOrMerged = true;\n break;\n }\n \n // If counter is one less than range start, extend range start\n if (counter === range[0] - 1) {\n range[0] = counter;\n rangeExtendedOrMerged = true;\n // Check if this range now merges with the previous range\n if (i > 0 && range[0] === ranges[i - 1][1] + 1) {\n ranges[i - 1][1] = range[1]; // Merge into previous\n ranges.splice(i, 1); // Remove current\n }\n break;\n }\n \n // If counter is one more than range end, extend range end\n if (counter === range[1] + 1) {\n range[1] = counter;\n rangeExtendedOrMerged = true;\n // Check if this range now merges with the next range\n if (i < ranges.length - 1 && range[1] + 1 === ranges[i + 1][0]) {\n range[1] = ranges[i + 1][1]; // Merge next into current\n ranges.splice(i + 1, 1); // Remove next\n }\n break;\n }\n\n // Keep track of where to insert if no extension/merge happens\n if (counter < range[0] && insertIndex === -1) {\n insertIndex = i;\n }\n }\n \n // If we couldn't extend or merge any range, add a new one\n if (!rangeExtendedOrMerged) {\n if (insertIndex === -1) {\n // If counter is greater than all existing ranges, add to the end\n insertIndex = ranges.length;\n }\n ranges.splice(insertIndex, 0, [counter, counter]);\n // After inserting, check if the new range merges with neighbors\n // Merge with previous range if possible\n if (insertIndex > 0 && ranges[insertIndex][0] === ranges[insertIndex - 1][1] + 1) {\n ranges[insertIndex - 1][1] = ranges[insertIndex][1];\n ranges.splice(insertIndex, 1);\n insertIndex--; // Adjust index after merging\n }\n // Merge with next range if possible (use adjusted insertIndex)\n if (insertIndex < ranges.length - 1 && ranges[insertIndex][1] + 1 === ranges[insertIndex + 1][0]) {\n ranges[insertIndex][1] = ranges[insertIndex + 1][1];\n ranges.splice(insertIndex + 1, 1);\n }\n }\n }\n\n /**\n * Returns the current state vector.\n * Returns a readonly reference to the internal state vector.\n */\n getStateVector(): Readonly<Record<string, number[][]>> {\n return this.stateVector;\n }\n\n /**\n * Calculates which operation ranges we have that the other peer is missing\n * by comparing state vectors.\n * \n * @param theirStateVector The state vector from another peer\n * @returns Array of operation ID ranges that we have but they don't\n */\n private diffStateVectors(theirStateVector: Record<string, number[][]>): OpIdRange[] {\n const missingRanges: OpIdRange[] = [];\n \n // Check what we have that they don't have\n for (const [peerId, ourRanges] of Object.entries(this.stateVector)) {\n const theirRanges = theirStateVector[peerId] || [];\n \n // Calculate ranges we have that they don't\n const missing = subtractRanges(ourRanges, theirRanges);\n \n // Convert to OpIdRange format\n for (const [start, end] of missing) {\n // Ensure the range is valid (start <= end)\n if (start <= end) {\n missingRanges.push({\n peerId,\n start,\n end\n });\n }\n }\n }\n \n return missingRanges;\n }\n\n /**\n * Determines which operations are needed to synchronize \n * with the provided state vector.\n * \n * @param theirStateVector The state vector from another peer\n * @returns Operations that should be sent to the other peer, sorted by OpId.\n */\n getMissingOps(theirStateVector: Record<string, number[][]>): VertexOperation[] {\n // First, identify the missing operation ranges by comparing state vectors\n const missingRanges = this.diffStateVectors(theirStateVector);\n \n // Then, retrieve only the operations that fall within those ranges\n const missingOps: VertexOperation[] = [];\n // Combine moveOps and setPropertyOps for checking\n const allOps = [...this.moveOps, ...this.setPropertyOps]; \n \n // Only check operations that might be in the missing ranges\n for (const op of allOps) {\n for (const range of missingRanges) {\n if (op.id.peerId === range.peerId && \n op.id.counter >= range.start && \n op.id.counter <= range.end) {\n missingOps.push(op);\n break; // Move to the next op once found in a missing range\n }\n }\n }\n \n // Sort the missing ops by OpId before returning, ensuring causal order\n missingOps.sort((a, b) => OpId.compare(a.id, b.id));\n\n return missingOps;\n }\n}\n\n"],"mappings":"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","names":["vertex"]}
1
+ {"version":3,"sources":["../src/OpId.ts","../src/operations.ts","../src/VertexState.ts","../src/TreeState.ts","../src/uuid.ts","../src/Vertex.ts","../src/StateVector.ts","../src/RepTree.ts"],"sourcesContent":["export class OpId {\n constructor(\n readonly counter: number,\n readonly peerId: string\n ) { }\n\n static compare(opIdA: OpId | string, opIdB: OpId | string): number {\n if (!(opIdA instanceof OpId)) {\n const parsedA = OpId.tryParseStr(opIdA);\n if (!parsedA) throw new Error(`Invalid OpId string: ${opIdA}`);\n opIdA = parsedA;\n }\n if (!(opIdB instanceof OpId)) {\n const parsedB = OpId.tryParseStr(opIdB);\n if (!parsedB) throw new Error(`Invalid OpId string: ${opIdB}`);\n opIdB = parsedB;\n }\n\n const counterA = opIdA.counter;\n const counterB = opIdB.counter;\n\n if (counterA > counterB) {\n return 1;\n } else if (counterA < counterB) {\n return -1;\n } else {\n return opIdA.peerId.localeCompare(opIdB.peerId);\n }\n }\n\n static equals(opIdA: OpId | string | null, opIdB: OpId | string | null): boolean {\n if (opIdA === opIdB) {\n return true;\n } else if (!opIdA || !opIdB) {\n return false;\n }\n\n return OpId.compare(opIdA, opIdB) === 0;\n }\n\n static tryParseStr(opIdStr: string): OpId {\n const parts = opIdStr.split('@');\n\n if (parts.length !== 2) {\n throw new Error(`Invalid OpId string: ${opIdStr}`);\n }\n\n return new OpId(parseInt(parts[0], 10), parts[1]);\n }\n \n isGreaterThan(opId: OpId | string): boolean {\n return OpId.compare(this, opId) === 1;\n }\n\n toString(): string {\n return `${this.counter}@${this.peerId}`;\n }\n}\n","import { OpId } from \"./OpId\";\nimport { type VertexPropertyType } from \"./treeTypes\";\n\nexport interface MoveVertex {\n id: OpId;\n targetId: string;\n parentId: string | null;\n}\n\nexport interface SetVertexProperty {\n id: OpId;\n targetId: string;\n key: string;\n value: VertexPropertyType;\n transient: boolean;\n}\n\nexport type VertexOperation = MoveVertex | SetVertexProperty;\n\nexport function isMoveVertexOp(op: VertexOperation): op is MoveVertex {\n return 'parentId' in op;\n}\n\nexport function isSetPropertyOp(op: VertexOperation): op is SetVertexProperty {\n return 'key' in op;\n}\n\nexport function newMoveVertexOp(clock: number, peerId: string, targetId: string, parentId: string | null): MoveVertex {\n return { id: new OpId(clock, peerId), targetId, parentId };\n}\n\nexport function newSetVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyType): SetVertexProperty {\n return { id: new OpId(clock, peerId), targetId, key, value, transient: false };\n}\n\nexport function newSetTransientVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyType): SetVertexProperty {\n return { id: new OpId(clock, peerId), targetId, key, value, transient: true };\n}","import type { TreeVertexId, TreeVertexProperty, VertexPropertyType } from \"./treeTypes\";\n\nexport class VertexState {\n readonly id: string;\n parentId: TreeVertexId | null;\n private properties: TreeVertexProperty[];\n private transientProperties: TreeVertexProperty[];\n children: string[];\n\n constructor(id: string, parentId: TreeVertexId | null) {\n this.id = id;\n this.parentId = parentId;\n this.properties = [];\n this.transientProperties = [];\n this.children = [];\n }\n\n setProperty(key: string, value: any): void {\n const existingPropIndex = this.properties.findIndex(p => p.key === key);\n if (existingPropIndex !== -1) {\n if (value !== undefined) {\n // Update existing property\n this.properties[existingPropIndex] = { key, value };\n } else {\n // Remove existing property\n this.removeProperty(key);\n }\n } else {\n if (value !== undefined) {\n // Add new property\n this.properties.push({ key, value });\n }\n }\n }\n\n setTransientProperty(key: string, value: any): void {\n const existingPropIndex = this.transientProperties.findIndex(p => p.key === key);\n if (existingPropIndex !== -1) {\n if (value !== undefined) {\n // Update existing property\n this.transientProperties[existingPropIndex] = { key, value };\n } else {\n // Remove existing property\n this.removeTransientProperty(key);\n }\n } else {\n if (value !== undefined) {\n // Add new property\n this.transientProperties.push({ key, value });\n }\n }\n }\n\n getProperty(key: string, includingTransient: boolean = true): VertexPropertyType | undefined {\n if (includingTransient) {\n const transientProp = this.transientProperties.find(p => p.key === key);\n if (transientProp) {\n return transientProp.value;\n }\n }\n\n return this.properties.find(p => p.key === key)?.value;\n }\n\n getAllProperties(includingTransient: boolean = true): ReadonlyArray<TreeVertexProperty> {\n if (!includingTransient) {\n return this.properties;\n }\n\n const result: TreeVertexProperty[] = [];\n const seenKeys = new Set<string>();\n\n // Add transient properties first\n for (const prop of this.transientProperties) {\n result.push(prop);\n seenKeys.add(prop.key);\n }\n\n // Add permanent properties that don't have a transient override\n for (const prop of this.properties) {\n if (!seenKeys.has(prop.key)) {\n result.push(prop);\n }\n }\n\n return result;\n }\n\n removeProperty(key: string): void {\n this.properties = this.properties.filter(p => p.key !== key);\n }\n\n removeTransientProperty(key: string): void {\n this.transientProperties = this.transientProperties.filter(p => p.key !== key);\n }\n}\n","import type { TreeVertexId, VertexChangeEvent, VertexPropertyChangeEvent, VertexChildrenChangeEvent, VertexMoveEvent } from \"./treeTypes\";\nimport { VertexState } from \"./VertexState\";\n\nexport class TreeState {\n private vertices: Map<TreeVertexId, VertexState>;\n private changeCallbacks: Map<TreeVertexId, Set<(events: VertexChangeEvent[]) => void>> = new Map();\n private globalChangeCallbacks: Set<(events: VertexChangeEvent[]) => void> = new Set();\n\n private batchTickInterval: NodeJS.Timeout;\n private batchedEvents: Map<TreeVertexId, VertexChangeEvent[]> = new Map();\n\n constructor() {\n this.vertices = new Map();\n\n this.batchTickInterval = setInterval(() => {\n this.processBatchedEvents();\n }, 33.3);\n }\n\n dispose() {\n clearInterval(this.batchTickInterval);\n }\n\n private processBatchedEvents() {\n for (const [vertexId, events] of this.batchedEvents) {\n // Get last property events per key and last move/children events\n let lastMoveEvent: VertexMoveEvent | null = null;\n let lastChildrenEvent: VertexChildrenChangeEvent | null = null;\n const propertyEventsByKey = new Map<string, VertexPropertyChangeEvent>();\n\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i];\n if (!lastMoveEvent && event.type === 'move') lastMoveEvent = event as VertexMoveEvent;\n if (!lastChildrenEvent && event.type === 'children') lastChildrenEvent = event as VertexChildrenChangeEvent;\n if (event.type === 'property') {\n const propertyEvent = event as VertexPropertyChangeEvent;\n if (!propertyEventsByKey.has(propertyEvent.key)) {\n propertyEventsByKey.set(propertyEvent.key, propertyEvent);\n }\n }\n }\n\n // Combine all events with move and children events first\n const filteredEvents = [\n ...(lastMoveEvent ? [lastMoveEvent] : []),\n ...(lastChildrenEvent ? [lastChildrenEvent] : []),\n ...propertyEventsByKey.values()\n ];\n\n this.globalChangeCallbacks.forEach(listener => listener(filteredEvents));\n this.changeCallbacks.get(vertexId)?.forEach(listener => listener(filteredEvents));\n }\n\n this.batchedEvents.clear();\n }\n\n getAllVertices(): ReadonlyArray<VertexState> {\n return Array.from(this.vertices.values());\n }\n\n getVertex(id: string): VertexState | undefined {\n return this.vertices.get(id);\n }\n\n getChildrenIds(vertexId: TreeVertexId): string[] {\n return this.getVertex(vertexId)?.children ?? [];\n }\n\n getChildren(vertexId: TreeVertexId): VertexState[] {\n return this.getChildrenIds(vertexId)\n .map(id => {\n const vertex = this.vertices.get(id);\n return vertex ? vertex : undefined;\n })\n .filter(vertex => vertex !== undefined)\n .sort((a, b) => {\n const aDate = a.getProperty('_c') as string;\n const bDate = b.getProperty('_c') as string;\n if (!aDate) return -1;\n if (!bDate) return 1;\n return new Date(aDate).getTime() - new Date(bDate).getTime();\n }) as VertexState[];\n }\n\n moveVertex(vertexId: TreeVertexId, newParentId: TreeVertexId | null): VertexState {\n let vertex = this.getVertex(vertexId);\n // Undefined if the vertex is new\n const prevParentId = vertex ? vertex.parentId : undefined;\n if (!vertex) {\n vertex = new VertexState(vertexId, newParentId);\n this.vertices.set(vertexId, vertex);\n }\n\n if (prevParentId === newParentId) {\n return vertex;\n }\n\n vertex.parentId = newParentId;\n\n let childrenInNewParent: string[] | null = null;\n let childrenInOldParent: string[] | null = null;\n\n // Update children arrays in vertices\n if (prevParentId) {\n const oldParentVertex = this.getVertex(prevParentId);\n if (oldParentVertex) {\n oldParentVertex.children = oldParentVertex.children.filter(child => child !== vertexId);\n childrenInOldParent = oldParentVertex.children;\n } else {\n console.error(`Old parent vertex not found for ${prevParentId}`);\n }\n }\n\n if (newParentId !== null) {\n const newParentVertex = this.vertices.get(newParentId);\n if (newParentVertex) {\n newParentVertex.children.push(vertexId);\n childrenInNewParent = newParentVertex.children;\n } else {\n console.error(`New parent vertex not found for ${newParentId}`);\n }\n }\n\n // We notify the listeners in the end so that they have the final state of the tree\n\n this.notifyChange({\n type: 'move',\n vertexId: vertexId,\n oldParentId: prevParentId,\n newParentId,\n } as VertexMoveEvent);\n\n if (childrenInNewParent !== null && newParentId !== null) {\n this.notifyChange({\n type: 'children',\n vertexId: newParentId,\n children: childrenInNewParent.map(id => this.vertices.get(id)!),\n } as VertexChildrenChangeEvent);\n }\n\n if (childrenInOldParent !== null && prevParentId) {\n this.notifyChange({\n type: 'children',\n vertexId: prevParentId,\n children: childrenInOldParent.map(id => this.vertices.get(id)!),\n } as VertexChildrenChangeEvent);\n }\n\n return vertex;\n }\n\n setProperty(vertexId: string, key: string, value: any) {\n const vertex = this.getVertex(vertexId);\n if (!vertex) {\n throw new Error(`Vertex ${vertexId} not found`);\n }\n\n vertex.setProperty(key, value);\n\n this.notifyChange({\n type: 'property',\n vertexId: vertexId,\n key,\n value,\n } as VertexPropertyChangeEvent);\n\n if (vertex.parentId !== null) {\n this.notifyChange({\n type: 'children',\n vertexId: vertex.parentId,\n children: [vertex], // @TODO: shoulld I set all children or rename this property?\n } as VertexChildrenChangeEvent);\n }\n }\n\n setTransientProperty(vertexId: string, key: string, value: any) {\n const vertex = this.getVertex(vertexId);\n if (vertex) {\n vertex.setTransientProperty(key, value);\n }\n\n // @TODO: add info that it's a transient property\n this.notifyChange({\n type: 'property',\n vertexId: vertexId,\n key,\n value,\n } as VertexPropertyChangeEvent);\n }\n\n addChangeCallback(vertexId: TreeVertexId, listener: (events: VertexChangeEvent[]) => void) {\n if (!this.changeCallbacks.has(vertexId)) {\n this.changeCallbacks.set(vertexId, new Set());\n }\n this.changeCallbacks.get(vertexId)!.add(listener);\n }\n\n removeChangeCallback(vertexId: TreeVertexId, listener: (events: VertexChangeEvent[]) => void) {\n this.changeCallbacks.get(vertexId)?.delete(listener);\n }\n\n addGlobalChangeCallback(listener: (events: VertexChangeEvent[]) => void) {\n this.globalChangeCallbacks.add(listener);\n }\n\n removeGlobalChangeCallback(listener: (events: VertexChangeEvent[]) => void) {\n this.globalChangeCallbacks.delete(listener);\n }\n\n private notifyChange(event: VertexChangeEvent) {\n let events = this.batchedEvents.get(event.vertexId);\n if (!events) {\n events = [];\n this.batchedEvents.set(event.vertexId, events);\n }\n\n events.push(event);\n\n // @TODO: have immediate events\n //this.globalChangeCallbacks.forEach(listener => listener(event));\n //this.changeCallbacks.get(event.vertexId)?.forEach(listener => listener(event));\n }\n\n printTree(vertexId: TreeVertexId, indent: string = \"\", isLast: boolean = true): string {\n const prefix = indent + (isLast ? \"└── \" : \"├── \");\n let result = prefix + vertexId + \"\\n\";\n\n let vertexName: string | null = null;\n\n if (vertexId !== null) {\n const vertex = this.getVertex(vertexId);\n if (vertex) {\n for (const prop of vertex.getAllProperties()) {\n if (prop.key === \"_n\") {\n vertexName = prop.value as string;\n //continue;\n }\n\n const propPrefix = indent + (isLast ? \" \" : \"│ \") + \"• \";\n result += `${propPrefix}${prop.key}: ${JSON.stringify(prop.value)}\\n`;\n }\n }\n }\n\n const children = this.getChildrenIds(vertexId);\n for (let i = 0; i < children.length; i++) {\n const childId = children[i];\n const isLastChild = i === children.length - 1;\n result += this.printTree(childId, indent + (isLast ? \" \" : \"│ \"), isLastChild);\n }\n\n return result;\n }\n}","const removeDashes = (guid: string) => guid.replace(/-/g, '');\n\nexport default function uuid(): string {\n return removeDashes(crypto.randomUUID());\n}","import type { VertexState } from \"./VertexState\";\nimport type { RepTree } from \"./RepTree\";\nimport type { TreeVertexProperty, VertexChangeEvent, VertexPropertyType } from \"./treeTypes\";\n\n/**\n * A wrapper class for VertexState that provides a more convenient API\n * for working with vertices in a RepTree.\n */\nexport class Vertex {\n constructor(\n private tree: RepTree,\n private state: VertexState\n ) { }\n\n get id(): string {\n return this.state.id;\n }\n\n get name(): string | undefined {\n return this.getProperty('_n') as string | undefined;\n }\n\n set name(name: string) {\n this.tree.setVertexProperty(this.id, '_n', name);\n }\n\n get createdAt(): Date {\n const createdAt = this.getProperty('_c') as string;\n if (!createdAt) {\n return new Date(0);\n }\n return new Date(createdAt);\n }\n\n get path(): string {\n //return this.tree.getVertexPath(this.id);\n throw new Error('Not implemented');\n }\n\n get parentId(): string | null {\n return this.state.parentId;\n }\n\n get parent(): Vertex | undefined {\n if (!this.parentId) {\n return undefined;\n }\n\n return this.tree.getVertex(this.parentId);\n }\n\n get children(): Vertex[] {\n return this.tree.getChildren(this.id);\n }\n\n get childrenIds(): string[] {\n return this.tree.getChildrenIds(this.id);\n }\n\n getAsTypedObject<T>(): T {\n return this.getProperties() as T;\n }\n\n getChildrenAsTypedArray<T>(): T[] {\n return this.children.map(v => v.getAsTypedObject<T>());\n }\n\n newChild(props?: Record<string, VertexPropertyType> | object | null): Vertex {\n const typedProps = props as Record<string, VertexPropertyType> | null;\n return this.tree.newVertex(this.id, typedProps);\n }\n\n newNamedChild(name: string, props?: Record<string, VertexPropertyType> | object | null): Vertex {\n const typedProps = props as Record<string, VertexPropertyType> | null;\n return this.tree.newNamedVertex(this.id, name, typedProps);\n }\n\n setProperty(key: string, value: VertexPropertyType): void {\n // First check if the property is already set (not including transient properties)\n const existingValue = this.getProperty(key, false);\n if (existingValue === value) {\n return;\n }\n\n this.tree.setVertexProperty(this.id, key, value);\n }\n\n setTransientProperty(key: string, value: VertexPropertyType): void {\n // First check if the property is already set\n const existingValue = this.getProperty(key);\n if (existingValue === value) {\n return;\n }\n\n this.tree.setTransientVertexProperty(this.id, key, value);\n }\n\n setProperties(props: Record<string, VertexPropertyType> | object): void {\n for (const [key, value] of Object.entries(props)) {\n this.setProperty(key, value);\n }\n }\n\n getProperty(key: string, includingTransient: boolean = true): VertexPropertyType | undefined {\n return this.tree.getVertexProperty(this.id, key, includingTransient);\n }\n\n getProperties(): Record<string, VertexPropertyType> {\n const props: Record<string, VertexPropertyType> = {};\n this.tree.getVertexProperties(this.id).forEach(p => {\n props[p.key] = p.value;\n });\n return props;\n }\n\n findAllChildrenWithProperty(key: string, value: VertexPropertyType): Vertex[] {\n return this.children.filter(c => c.getProperty(key) === value);\n }\n\n findFirstChildVertexWithProperty(key: string, value: VertexPropertyType): Vertex | undefined {\n return this.children.find(c => c.getProperty(key) === value);\n }\n\n findFirstTypedChildWithProperty<T>(key: string, value: VertexPropertyType): T | undefined {\n return this.findFirstChildVertexWithProperty(key, value)?.getAsTypedObject<T>();\n }\n\n findAllTypedChildrenWithProperty<T>(key: string, value: VertexPropertyType): T[] {\n return this.findAllChildrenWithProperty(key, value).map(c => c.getAsTypedObject<T>());\n }\n\n observe(listener: (events: VertexChangeEvent[]) => void): () => void {\n const unobserve = this.tree.observe(this.id, listener);\n return () => unobserve();\n }\n\n observeChildren(listener: (children: Vertex[]) => void): () => void {\n const unobserve = this.tree.observe(this.id, (events: VertexChangeEvent[]) => {\n if (events.some(e => e.type === 'children')) {\n listener(this.children);\n }\n });\n return () => unobserve();\n }\n\n observeChildrenAsTypedArray<T>(listener: (children: T[]) => void): () => void {\n return this.observeChildren((children) => {\n listener(children.map(c => c.getProperties() as unknown as T));\n });\n }\n\n delete(): void {\n this.tree.deleteVertex(this.id);\n }\n\n moveTo(parent: Vertex): void {\n this.tree.moveVertex(this.id, parent.id);\n }\n} ","import { OpId } from \"./OpId\";\nimport type { OpIdRange } from \"./treeTypes\";\nimport type { VertexOperation } from \"./operations\";\n\n/**\n * Helper function to subtract one set of ranges from another.\n * Returns the ranges in A that are not in B.\n * Assumes ranges in both A and B are sorted and non-overlapping.\n */\nexport function subtractRanges(rangesA: number[][], rangesB: number[][]): number[][] {\n if (rangesB.length === 0) return rangesA.map(r => [...r]); // Return a copy\n if (rangesA.length === 0) return []; // If A is empty, nothing to subtract\n\n const result: number[][] = [];\n let indexB = 0;\n\n for (const rangeA of rangesA) {\n let currentStart = rangeA[0];\n const endA = rangeA[1];\n\n // Iterate through ranges in B that could potentially overlap with rangeA\n while (indexB < rangesB.length && rangesB[indexB][1] < currentStart) {\n // Skip ranges in B that are entirely before the current start\n indexB++;\n }\n\n while (indexB < rangesB.length && rangesB[indexB][0] <= endA) {\n const startB = rangesB[indexB][0];\n const endB = rangesB[indexB][1];\n\n // If there's a gap before this range in B starts\n if (currentStart < startB) {\n // Add the portion of rangeA before the overlap\n result.push([currentStart, Math.min(endA, startB - 1)]);\n }\n\n // Move current start past this range in B\n currentStart = Math.max(currentStart, endB + 1);\n\n // If we've gone past the end of rangeA, break inner loop\n if (currentStart > endA) break;\n\n // If the current rangeB ends after rangeA, we don't need to check further ranges in B for this rangeA\n if (endB >= endA) break;\n\n // Only advance indexB if the current rangeB is fully processed relative to currentStart\n if (endB < currentStart) {\n indexB++;\n } else if (startB >= currentStart) {\n indexB++;\n }\n }\n\n // If there's a remaining part of rangeA after processing overlaps with B\n if (currentStart <= endA) {\n result.push([currentStart, endA]);\n }\n }\n\n return result;\n}\n\n/**\n * StateVector tracks operations that have been applied using a range-based representation.\n * It's used for synchronization between peers to determine which operations need to be sent.\n */\nexport class StateVector {\n private ranges: Record<string, number[][]> = {};\n\n /**\n * Creates a new StateVector.\n * @param initialState Optional initial state to copy from\n */\n constructor(initialState: Record<string, number[][]> = {}) {\n // Create a deep copy of the initial state\n for (const [peerId, peerRanges] of Object.entries(initialState)) {\n this.ranges[peerId] = peerRanges.map(range => [...range]);\n }\n }\n\n /**\n * Updates the state vector with a newly applied operation.\n * Assumes ranges are sorted and non-overlapping.\n * \n * @param peerId The peer ID of the operation\n * @param counter The counter value of the operation\n */\n update(peerId: string, counter: number): void {\n // Initialize ranges array for this peer if it doesn't exist\n if (!this.ranges[peerId]) {\n this.ranges[peerId] = [];\n }\n\n const ranges = this.ranges[peerId];\n\n // Case 1: No ranges yet\n if (ranges.length === 0) {\n ranges.push([counter, counter]);\n return;\n }\n\n let rangeExtendedOrMerged = false;\n let insertIndex = -1;\n\n for (let i = 0; i < ranges.length; i++) {\n const range = ranges[i];\n\n // If counter is already in a range, do nothing\n if (counter >= range[0] && counter <= range[1]) {\n rangeExtendedOrMerged = true;\n break;\n }\n\n // If counter is one less than range start, extend range start\n if (counter === range[0] - 1) {\n range[0] = counter;\n rangeExtendedOrMerged = true;\n // Check if this range now merges with the previous range\n if (i > 0 && range[0] === ranges[i - 1][1] + 1) {\n ranges[i - 1][1] = range[1]; // Merge into previous\n ranges.splice(i, 1); // Remove current\n }\n break;\n }\n\n // If counter is one more than range end, extend range end\n if (counter === range[1] + 1) {\n range[1] = counter;\n rangeExtendedOrMerged = true;\n // Check if this range now merges with the next range\n if (i < ranges.length - 1 && range[1] + 1 === ranges[i + 1][0]) {\n range[1] = ranges[i + 1][1]; // Merge next into current\n ranges.splice(i + 1, 1); // Remove next\n }\n break;\n }\n\n // Keep track of where to insert if no extension/merge happens\n if (counter < range[0] && insertIndex === -1) {\n insertIndex = i;\n }\n }\n\n // If we couldn't extend or merge any range, add a new one\n if (!rangeExtendedOrMerged) {\n if (insertIndex === -1) {\n // If counter is greater than all existing ranges, add to the end\n insertIndex = ranges.length;\n }\n ranges.splice(insertIndex, 0, [counter, counter]);\n // After inserting, check if the new range merges with neighbors\n // Merge with previous range if possible\n if (insertIndex > 0 && ranges[insertIndex][0] === ranges[insertIndex - 1][1] + 1) {\n ranges[insertIndex - 1][1] = ranges[insertIndex][1];\n ranges.splice(insertIndex, 1);\n insertIndex--; // Adjust index after merging\n }\n // Merge with next range if possible (use adjusted insertIndex)\n if (insertIndex < ranges.length - 1 && ranges[insertIndex][1] + 1 === ranges[insertIndex + 1][0]) {\n ranges[insertIndex][1] = ranges[insertIndex + 1][1];\n ranges.splice(insertIndex + 1, 1);\n }\n }\n }\n\n /**\n * Updates the state vector with a newly applied operation.\n * \n * @param op The operation that was just applied\n */\n updateFromOp(op: VertexOperation): void {\n this.update(op.id.peerId, op.id.counter);\n }\n\n /**\n * Returns the current state vector.\n * Returns a readonly reference to the internal state.\n */\n getState(): Readonly<Record<string, number[][]>> {\n return this.ranges;\n }\n\n /**\n * Calculates which operation ranges we have that the other state vector is missing\n * by comparing state vectors.\n * \n * @param other The other state vector to compare against\n * @returns Array of operation ID ranges that we have but they don't\n */\n diff(other: StateVector): OpIdRange[] {\n const missingRanges: OpIdRange[] = [];\n const theirState = other.getState();\n\n // Check what we have that they don't have\n for (const [peerId, ourRanges] of Object.entries(this.ranges)) {\n const theirRanges = theirState[peerId] || [];\n\n // Calculate ranges we have that they don't\n const missing = subtractRanges(ourRanges, theirRanges);\n\n // Convert to OpIdRange format\n for (const [start, end] of missing) {\n // Ensure the range is valid (start <= end)\n if (start <= end) {\n missingRanges.push({\n peerId,\n start,\n end\n });\n }\n }\n }\n\n return missingRanges;\n }\n\n /**\n * Checks if the state vector contains the given operation ID\n * \n * @param opId The operation ID to check\n * @returns true if the operation is in the state vector, false otherwise\n */\n contains(opId: OpId): boolean {\n const peerId = opId.peerId;\n const counter = opId.counter;\n\n if (!this.ranges[peerId]) {\n return false;\n }\n\n for (const [start, end] of this.ranges[peerId]) {\n if (counter >= start && counter <= end) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Creates a copy of this state vector\n */\n clone(): StateVector {\n return new StateVector(this.ranges);\n }\n\n /**\n * Builds a state vector from an array of operations\n * @param operations The operations to build the state vector from\n * @returns A new StateVector instance\n */\n static fromOperations(operations: ReadonlyArray<VertexOperation>): StateVector {\n const stateVector = new StateVector();\n for (const op of operations) {\n stateVector.updateFromOp(op);\n }\n return stateVector;\n }\n} ","import { newMoveVertexOp, type MoveVertex, type SetVertexProperty, isMoveVertexOp, isSetPropertyOp, type VertexOperation, newSetVertexPropertyOp, newSetTransientVertexPropertyOp } from \"./operations\";\nimport type { VertexPropertyType, TreeVertexProperty, VertexChangeEvent, TreeVertexId, VertexMoveEvent, OpIdRange } from \"./treeTypes\"; // Added OpIdRange\nimport { VertexState } from \"./VertexState\";\nimport { TreeState } from \"./TreeState\";\nimport { OpId } from \"./OpId\";\nimport uuid from \"./uuid\";\nimport { Vertex } from './Vertex';\nimport { StateVector } from './StateVector';\n\ntype PropertyKeyAtVertexId = `${string}@${TreeVertexId}`;\n\n/**\n * RepTree is a tree data structure for storing vertices with properties.\n * It uses 2 conflict-free replicated data types (CRDTs) to manage seamless replication between peers.\n * A move tree CRDT is used for the tree structure (https://martin.kleppmann.com/papers/move-op.pdf).\n * A last writer wins (LWW) CRDT is used for properties.\n */\nexport class RepTree {\n private static NULL_VERTEX_ID = '0';\n private static DEFAULT_MAX_DEPTH = 100000;\n\n readonly peerId: string;\n private rootVertexId: string | undefined;\n\n private lamportClock = 0;\n private state: TreeState;\n private moveOps: MoveVertex[] = [];\n private setPropertyOps: SetVertexProperty[] = [];\n private propertiesAndTheirOpIds: Map<PropertyKeyAtVertexId, OpId> = new Map();\n private transientPropertiesAndTheirOpIds: Map<PropertyKeyAtVertexId, OpId> = new Map();\n private localOps: VertexOperation[] = [];\n private pendingMovesWithMissingParent: Map<string, MoveVertex[]> = new Map();\n private pendingPropertiesWithMissingVertex: Map<string, SetVertexProperty[]> = new Map();\n private knownOps: Set<string> = new Set();\n private parentIdBeforeMove: Map<OpId, string | null | undefined> = new Map();\n private opAppliedCallbacks: ((op: VertexOperation) => void)[] = [];\n private maxDepth = RepTree.DEFAULT_MAX_DEPTH;\n\n // State vector tracking operations from each peer\n private stateVector: StateVector;\n private _stateVectorEnabled: boolean = true;\n\n /**\n * @param peerId - The peer ID of the current client\n * @param ops - The operations to replicate an existing tree, if null - a new tree will be created\n */\n constructor(peerId: string, ops: ReadonlyArray<VertexOperation> | null = null) {\n this.peerId = peerId;\n this.state = new TreeState();\n\n // Initialize state vector (enabled by default)\n this.stateVector = new StateVector();\n\n if (ops != null && ops.length > 0) {\n this.applyOps(ops);\n\n const root = this.root;\n if (!root) {\n throw new Error('There has to be a root vertex in the operations');\n }\n\n // @TODO: validate the tree structure, throw an exception if it's invalid\n } else {\n this.ensureNullVertex();\n }\n }\n\n get root(): Vertex | undefined {\n if (!this.rootVertexId) {\n const vertices = this.state.getAllVertices();\n for (const vertex of vertices) {\n if (vertex.parentId === null && vertex.id !== RepTree.NULL_VERTEX_ID) {\n this.rootVertexId = vertex.id;\n return new Vertex(this, vertex);\n }\n }\n\n return undefined;\n }\n\n const rootVertex = this.state.getVertex(this.rootVertexId);\n if (!rootVertex) {\n throw new Error(\"Root vertex not found\");\n }\n\n return new Vertex(this, rootVertex);\n }\n\n getMoveOps(): ReadonlyArray<MoveVertex> {\n return this.moveOps;\n }\n\n getAllOps(): ReadonlyArray<VertexOperation> {\n return [...this.moveOps, ...this.setPropertyOps];\n }\n\n getVertex(vertexId: string): Vertex | undefined {\n const vertex = this.state.getVertex(vertexId);\n return vertex ? new Vertex(this, vertex) : undefined;\n }\n\n getAllVertices(): ReadonlyArray<Vertex> {\n return this.state.getAllVertices().map(v => new Vertex(this, v));\n }\n\n getParent(vertexId: string): Vertex | undefined {\n const parentId = this.state.getVertex(vertexId)?.parentId;\n const parent = parentId ? this.state.getVertex(parentId) : undefined;\n return parent ? new Vertex(this, parent) : undefined;\n }\n\n getChildren(vertexId: string): Vertex[] {\n return this.state.getChildren(vertexId).map(v => new Vertex(this, v));\n }\n\n getChildrenIds(vertexId: string): string[] {\n return this.state.getChildrenIds(vertexId);\n }\n\n getAncestors(vertexId: string): Vertex[] {\n const ancestors: Vertex[] = [];\n let currentVertex = this.state.getVertex(vertexId);\n\n while (currentVertex && currentVertex.parentId) {\n const parentVertex = this.state.getVertex(currentVertex.parentId);\n if (parentVertex) {\n ancestors.push(new Vertex(this, parentVertex));\n currentVertex = parentVertex;\n } else {\n break;\n }\n }\n\n return ancestors;\n }\n\n getVertexProperty(vertexId: string, key: string, includingTransient: boolean = true): VertexPropertyType | undefined {\n const vertex = this.state.getVertex(vertexId);\n if (!vertex) {\n return undefined;\n }\n\n return vertex.getProperty(key, includingTransient);\n }\n\n getVertexProperties(vertexId: string): Readonly<TreeVertexProperty[]> {\n const vertex = this.state.getVertex(vertexId);\n if (!vertex) {\n return [];\n }\n\n return vertex.getAllProperties();\n }\n\n popLocalOps(): VertexOperation[] {\n const ops = this.localOps;\n this.localOps = [];\n return ops;\n }\n\n setMaxDepth(maxDepth: number) {\n this.maxDepth = maxDepth;\n }\n\n createRoot(): Vertex {\n if (this.rootVertexId) {\n throw new Error('Root vertex already exists');\n }\n\n this.rootVertexId = this.newVertexInternalWithUUID(null);\n\n const rootVertex = this.state.getVertex(this.rootVertexId);\n if (!rootVertex) {\n throw new Error(\"Root vertex not found\");\n }\n\n return new Vertex(this, rootVertex);\n }\n newVertex(parentId: string, props: Record<string, VertexPropertyType> | object | null = null): Vertex {\n const typedProps = props as Record<string, VertexPropertyType> | null;\n const vertexId = this.newVertexInternalWithUUID(parentId);\n if (typedProps) {\n this.setVertexProperties(vertexId, typedProps);\n }\n\n const vertex = this.state.getVertex(vertexId);\n if (!vertex) {\n throw new Error('Failed to create vertex');\n }\n return new Vertex(this, vertex);\n }\n\n newNamedVertex(parentId: string, name: string, props: Record<string, VertexPropertyType> | object | null = null): Vertex {\n const typedProps = props as Record<string, VertexPropertyType> | null;\n const vertexId = this.newVertexInternalWithUUID(parentId);\n if (typedProps) {\n this.setVertexProperties(vertexId, typedProps);\n }\n this.setVertexProperty(vertexId, '_n', name);\n\n const vertex = this.state.getVertex(vertexId);\n if (!vertex) {\n throw new Error('Failed to create named vertex');\n }\n return new Vertex(this, vertex);\n }\n\n moveVertex(vertexId: string, parentId: string) {\n this.lamportClock++;\n const op = newMoveVertexOp(this.lamportClock, this.peerId, vertexId, parentId);\n this.localOps.push(op);\n this.applyMove(op);\n }\n\n deleteVertex(vertexId: string) {\n this.moveVertex(vertexId, RepTree.NULL_VERTEX_ID);\n }\n\n setTransientVertexProperty(vertexId: string, key: string, value: VertexPropertyType) {\n this.lamportClock++;\n const op = newSetTransientVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);\n this.localOps.push(op);\n this.applyProperty(op);\n }\n\n setVertexProperty(vertexId: string, key: string, value: VertexPropertyType) {\n this.lamportClock++;\n const op = newSetVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);\n this.localOps.push(op);\n this.applyProperty(op);\n }\n\n setVertexProperties(vertexId: string, props: Record<string, VertexPropertyType> | object) {\n const typedProps = props as Record<string, VertexPropertyType>;\n for (const [key, value] of Object.entries(typedProps)) {\n this.setVertexProperty(vertexId, key, value);\n }\n }\n\n getVertexByPath(path: string): Vertex | undefined {\n // Let's remove '/' at the start and at the end of the path\n path = path.replace(/^\\/+/, '');\n path = path.replace(/\\/+$/, '');\n\n const pathParts = path.split('/');\n\n if (!this.rootVertexId) {\n return undefined;\n }\n\n const root = this.state.getVertex(this.rootVertexId);\n if (!root) {\n throw new Error('The root vertex is not found');\n }\n\n const vertex = this.getVertexByPathArray(new Vertex(this, root), pathParts);\n return vertex;\n }\n\n private getVertexByPathArray(vertex: Vertex, path: string[]): Vertex | undefined {\n if (path.length === 0) {\n return vertex ?? undefined;\n }\n\n const targetName = path[0];\n // Now, search recursively by name '_n' in children until the path is empty or not found.\n const children = this.getChildren(vertex.id);\n for (const child of children) {\n if (child.getProperty('_n') === targetName) {\n return this.getVertexByPathArray(child, path.slice(1));\n }\n }\n\n return undefined;\n }\n\n printTree() {\n if (!this.rootVertexId) {\n return '';\n }\n\n return this.state.printTree(this.rootVertexId);\n }\n\n merge(ops: ReadonlyArray<VertexOperation>) {\n /*\n if (ops.length > 100) {\n this.applyOpsOptimizedForLotsOfMoves(ops);\n } else {\n this.applyOps(ops);\n }\n */\n\n this.applyOps(ops);\n }\n\n /** Applies operations in an optimized way, sorting move ops by OpId to avoid undo-do-redo cycles */\n private applyOpsOptimizedForLotsOfMoves(ops: ReadonlyArray<VertexOperation>) {\n const newMoveOps = ops.filter(op => isMoveVertexOp(op) && !this.knownOps.has(op.id.toString()));\n if (newMoveOps.length > 0) {\n // Get an array of all move ops (without already applied ones)\n const allMoveOps = [...this.moveOps, ...newMoveOps] as MoveVertex[];\n // The main point of this optimization is to apply the moves without undo-do-redo cycles (the conflict resolution algorithm).\n // That is why we sort by OpId.\n allMoveOps.sort((a, b) => OpId.compare(a.id, b.id));\n for (let i = 0, len = allMoveOps.length; i < len; i++) {\n const op = allMoveOps[i];\n this.applyMove(op);\n }\n }\n\n // Get an array of all property ops (without already applied ones)\n const propertyOps = ops.filter(op => isSetPropertyOp(op) && !this.knownOps.has(op.id.toString())) as SetVertexProperty[];\n for (let i = 0, len = propertyOps.length; i < len; i++) {\n const op = propertyOps[i];\n this.applyProperty(op);\n }\n }\n\n compareStructure(other: RepTree): boolean {\n if (this.root?.id !== other.root?.id) {\n return false;\n }\n\n if (!this.rootVertexId) {\n return true;\n }\n\n return RepTree.compareVertices(this.rootVertexId, this, other);\n }\n\n compareMoveOps(other: RepTree): boolean {\n const movesA = this.moveOps;\n const movesB = other.getMoveOps();\n\n if (movesA.length !== movesB.length) {\n return false;\n }\n\n for (let i = 0; i < movesA.length; i++) {\n if (!OpId.equals(movesA[i].id, movesB[i].id)) {\n return false;\n }\n }\n\n return true;\n }\n\n /** Checks if the given `ancestorId` is an ancestor of `childId` in the tree */\n isAncestor(childId: string, ancestorId: string | null): boolean {\n let targetId = childId;\n let vertex: VertexState | undefined;\n let depth = 0;\n\n while (vertex = this.state.getVertex(targetId)) {\n if (vertex.parentId === ancestorId) return true;\n if (!vertex.parentId) return false;\n\n if (depth > this.maxDepth) {\n console.error(`isAncestor: max depth of ${this.maxDepth} reached. Perhaps, we have an infinite loop here.`);\n return true;\n }\n\n targetId = vertex.parentId;\n depth++;\n }\n\n return false;\n }\n\n observeVertex(vertexId: string, callback: (updatedVertex: Vertex) => void): () => void {\n const vertex = this.getVertex(vertexId);\n if (vertex) {\n callback(vertex);\n }\n\n const unsubscribe = this.observe(vertexId, (_) => {\n const vertex = this.getVertex(vertexId);\n if (vertex) {\n callback(vertex);\n }\n });\n\n return () => {\n unsubscribe();\n };\n }\n\n observeVertexMove(callback: (movedVertex: Vertex, isNew: boolean) => void): () => void {\n const listener = (events: VertexChangeEvent[]) => {\n const moveEvent = events.find(e => e.type === 'move') as VertexMoveEvent | undefined;\n if (moveEvent) {\n const vertex = this.getVertex(moveEvent.vertexId);\n if (vertex) {\n callback(vertex, moveEvent.oldParentId === undefined);\n }\n }\n };\n\n this.state.addGlobalChangeCallback(listener);\n\n return () => this.state.removeGlobalChangeCallback(listener);\n }\n\n observe(vertexId: string, callback: (events: VertexChangeEvent[]) => void): () => void {\n this.state.addChangeCallback(vertexId, callback);\n return () => this.state.removeChangeCallback(vertexId, callback);\n }\n\n observeOpApplied(callback: (op: VertexOperation) => void): () => void {\n this.opAppliedCallbacks.push(callback);\n return () => this.opAppliedCallbacks = this.opAppliedCallbacks.filter(l => l !== callback);\n }\n\n static compareVertices(vertexId: string, treeA: RepTree, treeB: RepTree): boolean {\n const childrenA = treeA.state.getChildrenIds(vertexId);\n const childrenB = treeB.state.getChildrenIds(vertexId);\n\n if (childrenA.length !== childrenB.length) {\n return false;\n }\n\n // Compare properties of the current vertex\n if (vertexId !== null) {\n const propertiesA = treeA.getVertexProperties(vertexId);\n const propertiesB = treeB.getVertexProperties(vertexId);\n\n if (propertiesA.length !== propertiesB.length) {\n return false;\n }\n\n for (const propA of propertiesA) {\n const propB = propertiesB.find(p => p.key === propA.key);\n if (!propB || propA.value !== propB.value) {\n return false;\n }\n }\n }\n\n // Compare children and their properties recursively\n for (const childId of childrenA) {\n if (!childrenB.includes(childId)) {\n return false;\n }\n\n if (!RepTree.compareVertices(childId, treeA, treeB)) {\n return false;\n }\n }\n\n return true;\n }\n\n private newVertexInternal(vertexId: string, parentId: string | null): string {\n this.lamportClock++;\n // To create a vertex - we move a vertex with a fresh id under the parent.\n // No need to have a separate \"create vertex\" operation.\n const op = newMoveVertexOp(this.lamportClock, this.peerId, vertexId, parentId);\n this.localOps.push(op);\n this.applyMove(op);\n\n // Set the creation date\n this.setVertexProperty(vertexId, '_c', new Date().toISOString());\n\n return vertexId;\n }\n\n private newVertexInternalWithUUID(parentId: string | null): string {\n const vertexId = uuid();\n return this.newVertexInternal(vertexId, parentId);\n }\n\n private ensureNullVertex() {\n const vertexId = RepTree.NULL_VERTEX_ID;\n\n // Check if the null vertex already exists\n if (this.state.getVertex(vertexId)) {\n return;\n }\n\n this.newVertexInternal(vertexId, null);\n }\n\n /** Updates the lamport clock with the counter value of the operation */\n private updateLamportClock(operation: VertexOperation): void {\n // This is how Lamport clock updates with a foreign operation that has a greater counter value.\n if (operation.id.counter > this.lamportClock) {\n this.lamportClock = operation.id.counter;\n }\n }\n\n private applyPendingMovesForParent(parentId: string) {\n // If a parent doesn't exist, we can't apply pending moves yet.\n if (!this.state.getVertex(parentId)) {\n return;\n }\n\n const pendingMoves = this.pendingMovesWithMissingParent.get(parentId);\n if (!pendingMoves) {\n return;\n }\n\n this.pendingMovesWithMissingParent.delete(parentId);\n\n for (const pendingOp of pendingMoves) {\n this.applyMove(pendingOp);\n }\n }\n\n private applyMove(op: MoveVertex) {\n // Check if a parent (unless we're dealing with the root vertex) exists for the move operation.\n // If it doesn't exist, stash the move op for later\n if (op.parentId !== null && !this.state.getVertex(op.parentId)) {\n if (!this.pendingMovesWithMissingParent.has(op.parentId)) {\n this.pendingMovesWithMissingParent.set(op.parentId, []);\n }\n this.pendingMovesWithMissingParent.get(op.parentId)!.push(op);\n return;\n }\n\n this.updateLamportClock(op);\n\n const lastOp = this.moveOps.length > 0 ? this.moveOps[this.moveOps.length - 1] : null;\n\n // If it's the most recent move operation - just try to move it. No conflict resolution is needed.\n if (lastOp === null || op.id.isGreaterThan(lastOp.id)) {\n this.moveOps.push(op);\n this.reportOpAsApplied(op);\n this.tryToMove(op);\n }\n\n // Here comes the core of the 'THE REPLICATED TREE ALGORITHM'.\n // From https://martin.kleppmann.com/papers/move-op.pdf\n // We undo all moves that are newer (based on the Lamport clock) than the target move, do the move, and then redo the moves we just undid.\n // The algorithm ensures that all replicas converge to the same tree after applying all operations.\n // The replicas are basically forced to apply the moves in the same order (by undo-do-redo).\n // So if a conflict or a cycle is introduced by some of the peers - the algorithm will resolve it.\n // tryToMove function has the logic to detect cycles and will ignore the move if it creates a cycle. \n else {\n let targetIndex = this.moveOps.length;\n for (let i = this.moveOps.length - 1; i >= 0; i--) {\n const moveOp = this.moveOps[i];\n targetIndex = i;\n if (op.id.isGreaterThan(moveOp.id)) {\n break;\n }\n else {\n this.undoMove(moveOp);\n }\n }\n\n // Insert the op at the correct position\n this.moveOps.splice(targetIndex + 1, 0, op);\n this.reportOpAsApplied(op);\n this.tryToMove(op);\n\n // Redo all of the operations after the operation that we applied\n for (let i = targetIndex + 2; i < this.moveOps.length; i++) {\n this.tryToMove(this.moveOps[i]);\n }\n }\n\n // After applying the move, check if it unblocks any pending moves\n // We use targetId here because this vertex might now be a parent for pending operations\n this.applyPendingMovesForParent(op.targetId);\n }\n\n private setPropertyAndItsOpId(op: SetVertexProperty) {\n this.propertiesAndTheirOpIds.set(`${op.key}@${op.targetId}`, op.id);\n this.state.setProperty(op.targetId, op.key, op.value);\n this.reportOpAsApplied(op);\n }\n\n private setTransientPropertyAndItsOpId(op: SetVertexProperty) {\n this.transientPropertiesAndTheirOpIds.set(`${op.key}@${op.targetId}`, op.id);\n this.state.setTransientProperty(op.targetId, op.key, op.value);\n this.reportOpAsApplied(op);\n }\n\n private applyProperty(op: SetVertexProperty) {\n const targetVertex = this.state.getVertex(op.targetId);\n if (!targetVertex) {\n // No need to handle transient properties if the vertex doesn't exist\n if (op.transient) {\n return;\n }\n\n // If the vertex doesn't exist, we will wait for the move operation to appear that will create the vertex\n // so we can apply the property then.\n if (!this.pendingPropertiesWithMissingVertex.has(op.targetId)) {\n this.pendingPropertiesWithMissingVertex.set(op.targetId, []);\n }\n this.pendingPropertiesWithMissingVertex.get(op.targetId)!.push(op);\n return;\n }\n\n this.updateLamportClock(op);\n\n const prevTransientOpId = this.transientPropertiesAndTheirOpIds.get(`${op.key}@${op.targetId}`);\n\n const prevProp = targetVertex.getProperty(op.key);\n const prevOpId = this.propertiesAndTheirOpIds.get(`${op.key}@${op.targetId}`);\n\n if (!op.transient) {\n this.setPropertyOps.push(op);\n\n // Apply the property if it's not already applied or if the current op is newer\n // This is the last writer wins approach that ensures the same state between replicas.\n if (!prevProp || !prevOpId || op.id.isGreaterThan(prevOpId)) {\n this.setPropertyAndItsOpId(op);\n } else {\n // We add it to set of known ops to avoid adding them to `setPropertyOps` multiple times \n // if we ever receive the same op from another peer.\n this.knownOps.add(op.id.toString());\n }\n\n // Remove the transient property if the current op is greater\n if (prevTransientOpId && op.id.isGreaterThan(prevTransientOpId)) {\n this.transientPropertiesAndTheirOpIds.delete(`${op.key}@${op.targetId}`);\n targetVertex.removeTransientProperty(op.key);\n }\n } else {\n if (!prevTransientOpId || op.id.isGreaterThan(prevTransientOpId)) {\n this.setTransientPropertyAndItsOpId(op);\n }\n }\n }\n\n private applyOps(ops: ReadonlyArray<VertexOperation>) {\n for (const op of ops) {\n // We skip the operation if we already know about it.\n // This is to avoid processing the same operation multiple times.\n if (this.knownOps.has(op.id.toString())) {\n continue;\n }\n\n if (isMoveVertexOp(op)) {\n this.applyMove(op);\n } else if (isSetPropertyOp(op)) {\n this.applyProperty(op);\n }\n }\n }\n\n private reportOpAsApplied(op: VertexOperation) {\n this.knownOps.add(op.id.toString());\n\n if (this._stateVectorEnabled) {\n this.stateVector.updateFromOp(op);\n }\n\n for (const callback of this.opAppliedCallbacks) {\n callback(op);\n }\n }\n\n private tryToMove(op: MoveVertex) {\n let targetVertex = this.state.getVertex(op.targetId);\n\n if (targetVertex) {\n // We cache the parentId before the move operation.\n // We will use it to undo the move according to the move op algorithm.\n this.parentIdBeforeMove.set(op.id, targetVertex.parentId);\n }\n\n // If trying to move the target vertex under itself - do nothing\n if (op.targetId === op.parentId) return;\n\n // If we try to move the vertex (op.targetId) under one of its descendants (op.parentId) - do nothing\n if (op.parentId && this.isAncestor(op.parentId, op.targetId)) return;\n\n this.state.moveVertex(op.targetId, op.parentId);\n\n // If the vertex didn't exist before the move - see if it has pending properties\n // and apply them.\n if (!targetVertex) {\n const pendingProperties = this.pendingPropertiesWithMissingVertex.get(op.targetId) || [];\n this.pendingPropertiesWithMissingVertex.delete(op.targetId);\n for (const prop of pendingProperties) {\n this.setPropertyAndItsOpId(prop);\n }\n }\n }\n\n private undoMove(op: MoveVertex) {\n const targetVertex = this.state.getVertex(op.targetId);\n if (!targetVertex) {\n console.error(`An attempt to undo move operation ${op.id.toString()} failed because the target vertex ${op.targetId} not found`);\n return;\n }\n\n const prevParentId = this.parentIdBeforeMove.get(op.id);\n if (prevParentId === undefined) {\n return;\n }\n\n this.state.moveVertex(op.targetId, prevParentId);\n }\n\n // --- Range-Based State Vector Methods --- \n\n /**\n * Returns the current state vector.\n * Returns a readonly reference to the internal state vector.\n */\n getStateVector(): Readonly<Record<string, number[][]>> | null {\n if (!this._stateVectorEnabled) {\n return null;\n }\n return this.stateVector.getState();\n }\n\n /**\n * Determines which operations are needed to synchronize \n * with the provided state vector.\n * \n * @param theirStateVector The state vector from another peer\n * @returns Operations that should be sent to the other peer, sorted by OpId.\n */\n getMissingOps(theirStateVector: Record<string, number[][]>): VertexOperation[] {\n // If state vector is disabled, fallback to sending all ops\n if (!this._stateVectorEnabled) {\n return [...this.moveOps, ...this.setPropertyOps];\n }\n\n // Create a StateVector instance from their state vector\n const otherStateVector = new StateVector(theirStateVector);\n\n // Get the missing ranges\n const missingRanges = this.stateVector.diff(otherStateVector);\n\n // Then, retrieve only the operations that fall within those ranges\n const missingOps: VertexOperation[] = [];\n // Combine moveOps and setPropertyOps for checking\n const allOps = [...this.moveOps, ...this.setPropertyOps];\n\n // Only check operations that might be in the missing ranges\n for (const op of allOps) {\n for (const range of missingRanges) {\n if (op.id.peerId === range.peerId &&\n op.id.counter >= range.start &&\n op.id.counter <= range.end) {\n missingOps.push(op);\n break; // Move to the next op once found in a missing range\n }\n }\n }\n\n // Sort the missing ops by OpId before returning, ensuring causal order\n missingOps.sort((a, b) => OpId.compare(a.id, b.id));\n\n return missingOps;\n }\n\n /**\n * Gets or sets whether state vector tracking is enabled\n */\n get stateVectorEnabled(): boolean {\n return this._stateVectorEnabled;\n }\n\n /**\n * Sets the state vector enabled status\n * When enabled, rebuilds the state vector from existing operations if needed\n */\n set stateVectorEnabled(value: boolean) {\n if (value === this._stateVectorEnabled) return;\n\n if (value) {\n // Enable state vector and rebuild from existing operations\n this._stateVectorEnabled = true;\n this.stateVector = StateVector.fromOperations([...this.moveOps, ...this.setPropertyOps]);\n } else {\n // Disable state vector and clear it to save memory\n this._stateVectorEnabled = false;\n this.stateVector = new StateVector();\n }\n }\n}\n\n"],"mappings":"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","names":["vertex"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reptree",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "A tree data structure using CRDTs for seamless replication between peers",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",