reptree 0.1.0
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/README.md +52 -0
- package/dist/index.cjs +979 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +220 -0
- package/dist/index.d.ts +220 -0
- package/dist/index.js +942 -0
- package/dist/index.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +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} ","/**\n * MIT License\n * Copyright (c) 2024 Dmitry Kury (d@dkury.com)\n */\n\nimport { newMoveVertexOp, type MoveVertex, type SetVertexProperty, isMoveVertexOp, isSetPropertyOp, type VertexOperation, newSetVertexPropertyOp, newSetTransientVertexPropertyOp } from \"./operations\";\nimport type { VertexPropertyType, TreeVertexProperty, VertexChangeEvent, TreeVertexId, VertexMoveEvent } from \"./treeTypes\";\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 * 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 TRASH_VERTEX_ID = 't';\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 appliedOps: 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 /**\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.ensureTrashVertex();\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.ensureTrashVertex();\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.TRASH_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 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 ensureTrashVertex() {\n const vertexId = RepTree.TRASH_VERTEX_ID;\n\n // Check if the trash 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 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 reportOpAsApplied(op: VertexOperation) {\n this.appliedOps.add(op.id.toString());\n for (const callback of this.opAppliedCallbacks) {\n callback(op);\n }\n }\n\n private applyOps(ops: ReadonlyArray<VertexOperation>) {\n for (const op of ops) {\n if (this.appliedOps.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 /** 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.appliedOps.has(op.id.toString()));\n if (newMoveOps.length > 0) {\n // Clear the vertices\n\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.appliedOps.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 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 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 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 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 }\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}"],"mappings":"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","names":["vertex"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "reptree",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A tree data structure using CRDTs for seamless replication between peers",
|
|
5
|
+
"main": "dist/index.cjs",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsup",
|
|
22
|
+
"dev": "tsup --watch",
|
|
23
|
+
"test": "npm run test:dist",
|
|
24
|
+
"test:src": "node --loader ts-node/esm tests/test-runner.ts",
|
|
25
|
+
"test:dist": "npm run build && node --loader ts-node/esm tests/test-runner.ts",
|
|
26
|
+
"example": "npm run build && node --loader ts-node/esm examples/basic-usage.ts",
|
|
27
|
+
"prepublishOnly": "npm run build"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"crdt",
|
|
31
|
+
"tree",
|
|
32
|
+
"data-structure",
|
|
33
|
+
"replication"
|
|
34
|
+
],
|
|
35
|
+
"author": "Dmitry Kury (d@dkury.com)",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/mitkury/reptree.git"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/mitkury/reptree#readme",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/mitkury/reptree/issues"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"ts-node": "^10.9.1",
|
|
47
|
+
"tsup": "^8.0.1",
|
|
48
|
+
"typescript": "^5.2.2"
|
|
49
|
+
}
|
|
50
|
+
}
|