reptree 0.1.1 → 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/README.md +42 -14
- package/dist/index.cjs +369 -94
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -18
- package/dist/index.d.ts +103 -18
- package/dist/index.js +368 -94
- package/dist/index.js.map +1 -1
- package/package.json +12 -5
package/dist/index.d.ts
CHANGED
|
@@ -49,6 +49,14 @@ type VertexChildrenChangeEvent = VertexChangeEvent & {
|
|
|
49
49
|
type: 'children';
|
|
50
50
|
children: VertexState[];
|
|
51
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* Type definition for operation ID range used in state vectors
|
|
54
|
+
*/
|
|
55
|
+
interface OpIdRange {
|
|
56
|
+
peerId: string;
|
|
57
|
+
start: number;
|
|
58
|
+
end: number;
|
|
59
|
+
}
|
|
52
60
|
|
|
53
61
|
interface MoveVertex {
|
|
54
62
|
id: OpId;
|
|
@@ -106,11 +114,6 @@ declare class Vertex {
|
|
|
106
114
|
moveTo(parent: Vertex): void;
|
|
107
115
|
}
|
|
108
116
|
|
|
109
|
-
/**
|
|
110
|
-
* MIT License
|
|
111
|
-
* Copyright (c) 2024 Dmitry Kury (d@dkury.com)
|
|
112
|
-
*/
|
|
113
|
-
|
|
114
117
|
/**
|
|
115
118
|
* RepTree is a tree data structure for storing vertices with properties.
|
|
116
119
|
* It uses 2 conflict-free replicated data types (CRDTs) to manage seamless replication between peers.
|
|
@@ -118,10 +121,10 @@ declare class Vertex {
|
|
|
118
121
|
* A last writer wins (LWW) CRDT is used for properties.
|
|
119
122
|
*/
|
|
120
123
|
declare class RepTree {
|
|
121
|
-
private static
|
|
124
|
+
private static NULL_VERTEX_ID;
|
|
122
125
|
private static DEFAULT_MAX_DEPTH;
|
|
123
126
|
readonly peerId: string;
|
|
124
|
-
|
|
127
|
+
private rootVertexId;
|
|
125
128
|
private lamportClock;
|
|
126
129
|
private state;
|
|
127
130
|
private moveOps;
|
|
@@ -131,19 +134,21 @@ declare class RepTree {
|
|
|
131
134
|
private localOps;
|
|
132
135
|
private pendingMovesWithMissingParent;
|
|
133
136
|
private pendingPropertiesWithMissingVertex;
|
|
134
|
-
private
|
|
137
|
+
private knownOps;
|
|
135
138
|
private parentIdBeforeMove;
|
|
136
139
|
private opAppliedCallbacks;
|
|
137
140
|
private maxDepth;
|
|
141
|
+
private stateVector;
|
|
142
|
+
private _stateVectorEnabled;
|
|
138
143
|
/**
|
|
139
144
|
* @param peerId - The peer ID of the current client
|
|
140
145
|
* @param ops - The operations to replicate an existing tree, if null - a new tree will be created
|
|
141
146
|
*/
|
|
142
147
|
constructor(peerId: string, ops?: ReadonlyArray<VertexOperation> | null);
|
|
148
|
+
get root(): Vertex | undefined;
|
|
143
149
|
getMoveOps(): ReadonlyArray<MoveVertex>;
|
|
144
150
|
getAllOps(): ReadonlyArray<VertexOperation>;
|
|
145
151
|
getVertex(vertexId: string): Vertex | undefined;
|
|
146
|
-
get rootVertex(): Vertex;
|
|
147
152
|
getAllVertices(): ReadonlyArray<Vertex>;
|
|
148
153
|
getParent(vertexId: string): Vertex | undefined;
|
|
149
154
|
getChildren(vertexId: string): Vertex[];
|
|
@@ -153,6 +158,7 @@ declare class RepTree {
|
|
|
153
158
|
getVertexProperties(vertexId: string): Readonly<TreeVertexProperty[]>;
|
|
154
159
|
popLocalOps(): VertexOperation[];
|
|
155
160
|
setMaxDepth(maxDepth: number): void;
|
|
161
|
+
createRoot(): Vertex;
|
|
156
162
|
newVertex(parentId: string, props?: Record<string, VertexPropertyType> | object | null): Vertex;
|
|
157
163
|
newNamedVertex(parentId: string, name: string, props?: Record<string, VertexPropertyType> | object | null): Vertex;
|
|
158
164
|
moveVertex(vertexId: string, parentId: string): void;
|
|
@@ -164,6 +170,8 @@ declare class RepTree {
|
|
|
164
170
|
private getVertexByPathArray;
|
|
165
171
|
printTree(): string;
|
|
166
172
|
merge(ops: ReadonlyArray<VertexOperation>): void;
|
|
173
|
+
/** Applies operations in an optimized way, sorting move ops by OpId to avoid undo-do-redo cycles */
|
|
174
|
+
private applyOpsOptimizedForLotsOfMoves;
|
|
167
175
|
compareStructure(other: RepTree): boolean;
|
|
168
176
|
compareMoveOps(other: RepTree): boolean;
|
|
169
177
|
/** Checks if the given `ancestorId` is an ancestor of `childId` in the tree */
|
|
@@ -175,20 +183,40 @@ declare class RepTree {
|
|
|
175
183
|
static compareVertices(vertexId: string, treeA: RepTree, treeB: RepTree): boolean;
|
|
176
184
|
private newVertexInternal;
|
|
177
185
|
private newVertexInternalWithUUID;
|
|
178
|
-
private
|
|
186
|
+
private ensureNullVertex;
|
|
179
187
|
/** Updates the lamport clock with the counter value of the operation */
|
|
180
188
|
private updateLamportClock;
|
|
181
|
-
private applyMove;
|
|
182
|
-
private reportOpAsApplied;
|
|
183
|
-
private applyOps;
|
|
184
|
-
/** Applies operations in an optimized way, sorting move ops by OpId to avoid undo-do-redo cycles */
|
|
185
|
-
private applyOpsOptimizedForLotsOfMoves;
|
|
186
189
|
private applyPendingMovesForParent;
|
|
187
|
-
private
|
|
188
|
-
private undoMove;
|
|
190
|
+
private applyMove;
|
|
189
191
|
private setPropertyAndItsOpId;
|
|
190
192
|
private setTransientPropertyAndItsOpId;
|
|
191
193
|
private applyProperty;
|
|
194
|
+
private applyOps;
|
|
195
|
+
private reportOpAsApplied;
|
|
196
|
+
private tryToMove;
|
|
197
|
+
private undoMove;
|
|
198
|
+
/**
|
|
199
|
+
* Returns the current state vector.
|
|
200
|
+
* Returns a readonly reference to the internal state vector.
|
|
201
|
+
*/
|
|
202
|
+
getStateVector(): Readonly<Record<string, number[][]>> | null;
|
|
203
|
+
/**
|
|
204
|
+
* Determines which operations are needed to synchronize
|
|
205
|
+
* with the provided state vector.
|
|
206
|
+
*
|
|
207
|
+
* @param theirStateVector The state vector from another peer
|
|
208
|
+
* @returns Operations that should be sent to the other peer, sorted by OpId.
|
|
209
|
+
*/
|
|
210
|
+
getMissingOps(theirStateVector: Record<string, number[][]>): VertexOperation[];
|
|
211
|
+
/**
|
|
212
|
+
* Gets or sets whether state vector tracking is enabled
|
|
213
|
+
*/
|
|
214
|
+
get stateVectorEnabled(): boolean;
|
|
215
|
+
/**
|
|
216
|
+
* Sets the state vector enabled status
|
|
217
|
+
* When enabled, rebuilds the state vector from existing operations if needed
|
|
218
|
+
*/
|
|
219
|
+
set stateVectorEnabled(value: boolean);
|
|
192
220
|
}
|
|
193
221
|
|
|
194
222
|
declare class TreeState {
|
|
@@ -215,6 +243,63 @@ declare class TreeState {
|
|
|
215
243
|
printTree(vertexId: TreeVertexId, indent?: string, isLast?: boolean): string;
|
|
216
244
|
}
|
|
217
245
|
|
|
246
|
+
/**
|
|
247
|
+
* StateVector tracks operations that have been applied using a range-based representation.
|
|
248
|
+
* It's used for synchronization between peers to determine which operations need to be sent.
|
|
249
|
+
*/
|
|
250
|
+
declare class StateVector {
|
|
251
|
+
private ranges;
|
|
252
|
+
/**
|
|
253
|
+
* Creates a new StateVector.
|
|
254
|
+
* @param initialState Optional initial state to copy from
|
|
255
|
+
*/
|
|
256
|
+
constructor(initialState?: Record<string, number[][]>);
|
|
257
|
+
/**
|
|
258
|
+
* Updates the state vector with a newly applied operation.
|
|
259
|
+
* Assumes ranges are sorted and non-overlapping.
|
|
260
|
+
*
|
|
261
|
+
* @param peerId The peer ID of the operation
|
|
262
|
+
* @param counter The counter value of the operation
|
|
263
|
+
*/
|
|
264
|
+
update(peerId: string, counter: number): void;
|
|
265
|
+
/**
|
|
266
|
+
* Updates the state vector with a newly applied operation.
|
|
267
|
+
*
|
|
268
|
+
* @param op The operation that was just applied
|
|
269
|
+
*/
|
|
270
|
+
updateFromOp(op: VertexOperation): void;
|
|
271
|
+
/**
|
|
272
|
+
* Returns the current state vector.
|
|
273
|
+
* Returns a readonly reference to the internal state.
|
|
274
|
+
*/
|
|
275
|
+
getState(): Readonly<Record<string, number[][]>>;
|
|
276
|
+
/**
|
|
277
|
+
* Calculates which operation ranges we have that the other state vector is missing
|
|
278
|
+
* by comparing state vectors.
|
|
279
|
+
*
|
|
280
|
+
* @param other The other state vector to compare against
|
|
281
|
+
* @returns Array of operation ID ranges that we have but they don't
|
|
282
|
+
*/
|
|
283
|
+
diff(other: StateVector): OpIdRange[];
|
|
284
|
+
/**
|
|
285
|
+
* Checks if the state vector contains the given operation ID
|
|
286
|
+
*
|
|
287
|
+
* @param opId The operation ID to check
|
|
288
|
+
* @returns true if the operation is in the state vector, false otherwise
|
|
289
|
+
*/
|
|
290
|
+
contains(opId: OpId): boolean;
|
|
291
|
+
/**
|
|
292
|
+
* Creates a copy of this state vector
|
|
293
|
+
*/
|
|
294
|
+
clone(): StateVector;
|
|
295
|
+
/**
|
|
296
|
+
* Builds a state vector from an array of operations
|
|
297
|
+
* @param operations The operations to build the state vector from
|
|
298
|
+
* @returns A new StateVector instance
|
|
299
|
+
*/
|
|
300
|
+
static fromOperations(operations: ReadonlyArray<VertexOperation>): StateVector;
|
|
301
|
+
}
|
|
302
|
+
|
|
218
303
|
declare function uuid(): string;
|
|
219
304
|
|
|
220
|
-
export { type MoveVertex, OpId, RepTree, type SetVertexProperty, TreeState, type TreeVertexId, type TreeVertexProperty, Vertex, type VertexChangeEvent, type VertexChildrenChangeEvent, type VertexMoveEvent, type VertexOperation, type VertexPropertyChangeEvent, type VertexPropertyType, VertexState, isMoveVertexOp, isSetPropertyOp, newMoveVertexOp, newSetTransientVertexPropertyOp, newSetVertexPropertyOp, uuid };
|
|
305
|
+
export { type MoveVertex, OpId, type OpIdRange, RepTree, type SetVertexProperty, StateVector, TreeState, type TreeVertexId, type TreeVertexProperty, Vertex, type VertexChangeEvent, type VertexChildrenChangeEvent, type VertexMoveEvent, type VertexOperation, type VertexPropertyChangeEvent, type VertexPropertyType, VertexState, isMoveVertexOp, isSetPropertyOp, newMoveVertexOp, newSetTransientVertexPropertyOp, newSetVertexPropertyOp, uuid };
|