meridian-sdk 1.2.0 → 1.3.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +1 -0
  3. package/dist/agents.d.ts +143 -8
  4. package/dist/agents.d.ts.map +1 -1
  5. package/dist/agents.js +141 -14
  6. package/dist/agents.js.map +1 -1
  7. package/dist/client.d.ts +35 -2
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +45 -3
  10. package/dist/client.js.map +1 -1
  11. package/dist/conflict/types.d.ts +54 -0
  12. package/dist/conflict/types.d.ts.map +1 -0
  13. package/dist/conflict/types.js +9 -0
  14. package/dist/conflict/types.js.map +1 -0
  15. package/dist/crdt/rga.d.ts +20 -4
  16. package/dist/crdt/rga.d.ts.map +1 -1
  17. package/dist/crdt/rga.js +42 -6
  18. package/dist/crdt/rga.js.map +1 -1
  19. package/dist/crdt/tree.d.ts +128 -0
  20. package/dist/crdt/tree.d.ts.map +1 -0
  21. package/dist/crdt/tree.js +304 -0
  22. package/dist/crdt/tree.js.map +1 -0
  23. package/dist/index.d.ts +13 -4
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +10 -3
  26. package/dist/index.js.map +1 -1
  27. package/dist/schema.d.ts +63 -3
  28. package/dist/schema.d.ts.map +1 -1
  29. package/dist/schema.js +18 -1
  30. package/dist/schema.js.map +1 -1
  31. package/dist/sync/delta.d.ts +35 -0
  32. package/dist/sync/delta.d.ts.map +1 -1
  33. package/dist/sync/delta.js +4 -0
  34. package/dist/sync/delta.js.map +1 -1
  35. package/dist/undo/UndoManager.d.ts +74 -0
  36. package/dist/undo/UndoManager.d.ts.map +1 -0
  37. package/dist/undo/UndoManager.js +318 -0
  38. package/dist/undo/UndoManager.js.map +1 -0
  39. package/dist/undo/types.d.ts +63 -0
  40. package/dist/undo/types.d.ts.map +1 -0
  41. package/dist/undo/types.js +9 -0
  42. package/dist/undo/types.js.map +1 -0
  43. package/dist/utils/fractional.d.ts +78 -0
  44. package/dist/utils/fractional.d.ts.map +1 -0
  45. package/dist/utils/fractional.js +159 -0
  46. package/dist/utils/fractional.js.map +1 -0
  47. package/dist/validation/index.d.ts +107 -0
  48. package/dist/validation/index.d.ts.map +1 -0
  49. package/dist/validation/index.js +123 -0
  50. package/dist/validation/index.js.map +1 -0
  51. package/package.json +1 -1
  52. package/src/agents.ts +224 -15
  53. package/src/client.ts +52 -3
  54. package/src/conflict/types.ts +60 -0
  55. package/src/crdt/rga.ts +46 -7
  56. package/src/crdt/tree.ts +367 -0
  57. package/src/index.ts +31 -1
  58. package/src/schema.ts +24 -1
  59. package/src/sync/delta.ts +30 -1
  60. package/src/undo/UndoManager.ts +369 -0
  61. package/src/undo/types.ts +74 -0
  62. package/src/utils/fractional.ts +166 -0
  63. package/src/validation/index.ts +137 -0
  64. package/test/conflict.test.ts +242 -0
  65. package/test/fractional.test.ts +127 -0
  66. package/test/undo.test.ts +272 -0
  67. package/test/validation.test.ts +137 -0
@@ -0,0 +1,74 @@
1
+ import { RGAHandle } from "../crdt/rga.js";
2
+ import { TreeHandle } from "../crdt/tree.js";
3
+ type SupportedHandle = RGAHandle | TreeHandle;
4
+ /**
5
+ * CRDT-aware per-client undo/redo manager.
6
+ *
7
+ * Wraps an RGAHandle or TreeHandle. Intercept mutating methods via the manager
8
+ * instead of the handle directly to record undo history.
9
+ *
10
+ * Rules:
11
+ * - Undo sends a new valid CrdtOp (never a state rollback).
12
+ * - Only the local client's ops are tracked — remote ops are unaffected.
13
+ * - RGA Delete is NOT recorded (tombstones are final).
14
+ * - Stack is capped at 100 batches; oldest entries are dropped silently.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const manager = new UndoManager(client.rga("doc"));
19
+ * manager.insert(0, "hello");
20
+ * manager.undo(); // sends 5 × RgaOp::Delete
21
+ * ```
22
+ */
23
+ export declare class UndoManager<H extends SupportedHandle> {
24
+ private readonly handle;
25
+ private undoStack;
26
+ private redoStack;
27
+ private readonly stackListeners;
28
+ private openBatch;
29
+ private debounceTimer;
30
+ constructor(handle: H);
31
+ get canUndo(): boolean;
32
+ get canRedo(): boolean;
33
+ /**
34
+ * Subscribe to stack change notifications (fired after any undo/redo/record).
35
+ * @returns Unsubscribe function.
36
+ */
37
+ onStackChange(listener: () => void): () => void;
38
+ /** Begin accumulating entries into a single undo step. */
39
+ startBatch(): void;
40
+ /** Commit the open batch as one entry on the undo stack. No-op if no batch is open. */
41
+ commitBatch(): void;
42
+ /** Discard the open batch without recording anything. */
43
+ cancelBatch(): void;
44
+ undo(): void;
45
+ redo(): void;
46
+ /**
47
+ * Insert text at visible position. Records undo entry with HLC node IDs.
48
+ * Uses 250ms debounce — consecutive inserts within the window form one batch.
49
+ */
50
+ insert(pos: number, text: string, ttlMs?: number): string[];
51
+ /**
52
+ * Delete characters by position. NOT recorded — RGA delete is non-undoable
53
+ * (tombstones are final; content is irrecoverable).
54
+ * clearRedo() is intentional: a destructive untracked op should invalidate
55
+ * any pending redo history, matching ProseMirror/Yjs behaviour.
56
+ */
57
+ delete(pos: number, length: number, ttlMs?: number): void;
58
+ addNode(parentId: string | null, position: string, value: string, ttlMs?: number): string;
59
+ moveNode(nodeId: string, newParentId: string | null, newPosition: string, ttlMs?: number): void;
60
+ updateNode(nodeId: string, value: string, ttlMs?: number): void;
61
+ deleteNode(nodeId: string, ttlMs?: number): void;
62
+ private applyInverse;
63
+ private record;
64
+ /** Record with 250ms debounce — consecutive calls within window share one batch. */
65
+ private recordWithDebounce;
66
+ private pushUndo;
67
+ private clearRedo;
68
+ private notifyStackChange;
69
+ private asRGA;
70
+ private asTree;
71
+ private getCrdtId;
72
+ }
73
+ export {};
74
+ //# sourceMappingURL=UndoManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UndoManager.d.ts","sourceRoot":"","sources":["../../src/undo/UndoManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAc7C,KAAK,eAAe,GAAG,SAAS,GAAG,UAAU,CAAC;AAE9C;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,WAAW,CAAC,CAAC,SAAS,eAAe;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAI;IAC3B,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;IAGxD,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,aAAa,CAA8C;gBAEvD,MAAM,EAAE,CAAC;IAMrB,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;OAGG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAO/C,0DAA0D;IAC1D,UAAU,IAAI,IAAI;IAMlB,uFAAuF;IACvF,WAAW,IAAI,IAAI;IAOnB,yDAAyD;IACzD,WAAW,IAAI,IAAI;IAMnB,IAAI,IAAI,IAAI;IAkBZ,IAAI,IAAI,IAAI;IAsBZ;;;OAGG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAmB3D;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAOzD,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;IAgBzF,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAiB/F,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAgB/D,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAmBhD,OAAO,CAAC,YAAY;IAsEpB,OAAO,CAAC,MAAM;IAQd,oFAAoF;IACpF,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,MAAM;IAOd,OAAO,CAAC,SAAS;CAGlB"}
@@ -0,0 +1,318 @@
1
+ import { RGAHandle } from "../crdt/rga.js";
2
+ import { TreeHandle } from "../crdt/tree.js";
3
+ const MAX_STACK_DEPTH = 100;
4
+ const RGA_DEBOUNCE_MS = 250;
5
+ /**
6
+ * CRDT-aware per-client undo/redo manager.
7
+ *
8
+ * Wraps an RGAHandle or TreeHandle. Intercept mutating methods via the manager
9
+ * instead of the handle directly to record undo history.
10
+ *
11
+ * Rules:
12
+ * - Undo sends a new valid CrdtOp (never a state rollback).
13
+ * - Only the local client's ops are tracked — remote ops are unaffected.
14
+ * - RGA Delete is NOT recorded (tombstones are final).
15
+ * - Stack is capped at 100 batches; oldest entries are dropped silently.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * const manager = new UndoManager(client.rga("doc"));
20
+ * manager.insert(0, "hello");
21
+ * manager.undo(); // sends 5 × RgaOp::Delete
22
+ * ```
23
+ */
24
+ export class UndoManager {
25
+ handle;
26
+ undoStack = [];
27
+ redoStack = [];
28
+ stackListeners = new Set();
29
+ // Batch accumulation
30
+ openBatch = null;
31
+ debounceTimer = null;
32
+ constructor(handle) {
33
+ this.handle = handle;
34
+ }
35
+ // ─── Stack state ────────────────────────────────────────────────────────────
36
+ get canUndo() {
37
+ return this.undoStack.length > 0;
38
+ }
39
+ get canRedo() {
40
+ return this.redoStack.length > 0;
41
+ }
42
+ /**
43
+ * Subscribe to stack change notifications (fired after any undo/redo/record).
44
+ * @returns Unsubscribe function.
45
+ */
46
+ onStackChange(listener) {
47
+ this.stackListeners.add(listener);
48
+ return () => { this.stackListeners.delete(listener); };
49
+ }
50
+ // ─── Manual batching ────────────────────────────────────────────────────────
51
+ /** Begin accumulating entries into a single undo step. */
52
+ startBatch() {
53
+ if (this.openBatch === null) {
54
+ this.openBatch = [];
55
+ }
56
+ }
57
+ /** Commit the open batch as one entry on the undo stack. No-op if no batch is open. */
58
+ commitBatch() {
59
+ if (this.openBatch !== null && this.openBatch.length > 0) {
60
+ this.pushUndo({ entries: this.openBatch });
61
+ }
62
+ this.openBatch = null;
63
+ }
64
+ /** Discard the open batch without recording anything. */
65
+ cancelBatch() {
66
+ this.openBatch = null;
67
+ }
68
+ // ─── Undo / Redo ────────────────────────────────────────────────────────────
69
+ undo() {
70
+ const batch = this.undoStack.pop();
71
+ if (batch === undefined)
72
+ return;
73
+ const inverseEntries = [];
74
+ // Apply inverse ops in reverse entry order.
75
+ for (let i = batch.entries.length - 1; i >= 0; i--) {
76
+ const entry = batch.entries[i];
77
+ const inverse = this.applyInverse(entry);
78
+ if (inverse !== null)
79
+ inverseEntries.unshift(inverse);
80
+ }
81
+ if (inverseEntries.length > 0) {
82
+ this.redoStack.push({ entries: inverseEntries });
83
+ }
84
+ this.notifyStackChange();
85
+ }
86
+ redo() {
87
+ const batch = this.redoStack.pop();
88
+ if (batch === undefined)
89
+ return;
90
+ const inverseEntries = [];
91
+ for (let i = batch.entries.length - 1; i >= 0; i--) {
92
+ const entry = batch.entries[i];
93
+ const inverse = this.applyInverse(entry);
94
+ if (inverse !== null)
95
+ inverseEntries.unshift(inverse);
96
+ }
97
+ if (inverseEntries.length > 0) {
98
+ this.undoStack.push({ entries: inverseEntries });
99
+ if (this.undoStack.length > MAX_STACK_DEPTH) {
100
+ this.undoStack.shift();
101
+ }
102
+ }
103
+ this.notifyStackChange();
104
+ }
105
+ // ─── RGA handle proxy methods ────────────────────────────────────────────────
106
+ /**
107
+ * Insert text at visible position. Records undo entry with HLC node IDs.
108
+ * Uses 250ms debounce — consecutive inserts within the window form one batch.
109
+ */
110
+ insert(pos, text, ttlMs) {
111
+ const handle = this.asRGA();
112
+ const nodeIds = handle.insert(pos, text, ttlMs);
113
+ for (let i = 0; i < nodeIds.length; i++) {
114
+ const entry = {
115
+ kind: "rga_insert",
116
+ crdtId: handle.id,
117
+ nodeId: nodeIds[i],
118
+ pos: pos + i,
119
+ content: text[i],
120
+ };
121
+ this.recordWithDebounce(entry);
122
+ }
123
+ this.clearRedo();
124
+ return nodeIds;
125
+ }
126
+ /**
127
+ * Delete characters by position. NOT recorded — RGA delete is non-undoable
128
+ * (tombstones are final; content is irrecoverable).
129
+ * clearRedo() is intentional: a destructive untracked op should invalidate
130
+ * any pending redo history, matching ProseMirror/Yjs behaviour.
131
+ */
132
+ delete(pos, length, ttlMs) {
133
+ this.asRGA().delete(pos, length, ttlMs);
134
+ this.clearRedo();
135
+ }
136
+ // ─── Tree handle proxy methods ───────────────────────────────────────────────
137
+ addNode(parentId, position, value, ttlMs) {
138
+ const handle = this.asTree();
139
+ const nodeId = handle.addNode(parentId, position, value, ttlMs);
140
+ const entry = {
141
+ kind: "tree_add",
142
+ crdtId: this.getCrdtId(),
143
+ nodeId,
144
+ parentId,
145
+ position,
146
+ value,
147
+ };
148
+ this.record(entry);
149
+ this.clearRedo();
150
+ return nodeId;
151
+ }
152
+ moveNode(nodeId, newParentId, newPosition, ttlMs) {
153
+ const handle = this.asTree();
154
+ const meta = handle.getNodeMeta(nodeId);
155
+ handle.moveNode(nodeId, newParentId, newPosition, ttlMs);
156
+ const entry = {
157
+ kind: "tree_move",
158
+ crdtId: this.getCrdtId(),
159
+ nodeId,
160
+ oldParentId: meta?.parentId ?? null,
161
+ oldPosition: meta?.position ?? "a0",
162
+ newParentId,
163
+ newPosition,
164
+ };
165
+ this.record(entry);
166
+ this.clearRedo();
167
+ }
168
+ updateNode(nodeId, value, ttlMs) {
169
+ const handle = this.asTree();
170
+ const meta = handle.getNodeMeta(nodeId);
171
+ handle.updateNode(nodeId, value, ttlMs);
172
+ const entry = {
173
+ kind: "tree_update",
174
+ crdtId: this.getCrdtId(),
175
+ nodeId,
176
+ previousValue: meta?.value ?? "",
177
+ previousUpdatedAt: meta?.updatedAt ?? nodeId,
178
+ newValue: value,
179
+ };
180
+ this.record(entry);
181
+ this.clearRedo();
182
+ }
183
+ deleteNode(nodeId, ttlMs) {
184
+ const handle = this.asTree();
185
+ const meta = handle.getNodeMeta(nodeId);
186
+ handle.deleteNode(nodeId, ttlMs);
187
+ const entry = {
188
+ kind: "tree_delete",
189
+ crdtId: this.getCrdtId(),
190
+ nodeId,
191
+ parentId: meta?.parentId ?? null,
192
+ position: meta?.position ?? "a0",
193
+ value: meta?.value ?? "",
194
+ updatedAt: meta?.updatedAt ?? nodeId,
195
+ };
196
+ this.record(entry);
197
+ this.clearRedo();
198
+ }
199
+ // ─── Internal ────────────────────────────────────────────────────────────────
200
+ applyInverse(entry) {
201
+ switch (entry.kind) {
202
+ case "rga_insert": {
203
+ this.asRGA().deleteById(entry.nodeId);
204
+ // Inverse of an insert is a delete — not re-recordable as an undo entry.
205
+ return null;
206
+ }
207
+ case "tree_add": {
208
+ this.asTree().deleteNode(entry.nodeId);
209
+ // Inverse: a delete entry (for redo — re-add the node).
210
+ const inverse = {
211
+ kind: "tree_delete",
212
+ crdtId: entry.crdtId,
213
+ nodeId: entry.nodeId,
214
+ parentId: entry.parentId,
215
+ position: entry.position,
216
+ value: entry.value,
217
+ updatedAt: entry.nodeId,
218
+ };
219
+ return inverse;
220
+ }
221
+ case "tree_delete": {
222
+ // Re-add with original state. Gets a new nodeId (tombstone is permanent).
223
+ const newNodeId = this.asTree().addNode(entry.parentId, entry.position, entry.value);
224
+ const inverse = {
225
+ kind: "tree_add",
226
+ crdtId: entry.crdtId,
227
+ nodeId: newNodeId,
228
+ parentId: entry.parentId,
229
+ position: entry.position,
230
+ value: entry.value,
231
+ };
232
+ return inverse;
233
+ }
234
+ case "tree_move": {
235
+ this.asTree().moveNode(entry.nodeId, entry.oldParentId, entry.oldPosition);
236
+ const inverse = {
237
+ kind: "tree_move",
238
+ crdtId: entry.crdtId,
239
+ nodeId: entry.nodeId,
240
+ oldParentId: entry.newParentId,
241
+ oldPosition: entry.newPosition,
242
+ newParentId: entry.oldParentId,
243
+ newPosition: entry.oldPosition,
244
+ };
245
+ return inverse;
246
+ }
247
+ case "tree_update": {
248
+ this.asTree().updateNode(entry.nodeId, entry.previousValue);
249
+ const inverse = {
250
+ kind: "tree_update",
251
+ crdtId: entry.crdtId,
252
+ nodeId: entry.nodeId,
253
+ previousValue: entry.newValue,
254
+ previousUpdatedAt: entry.previousUpdatedAt,
255
+ newValue: entry.previousValue,
256
+ };
257
+ return inverse;
258
+ }
259
+ }
260
+ }
261
+ record(entry) {
262
+ if (this.openBatch !== null) {
263
+ this.openBatch.push(entry);
264
+ }
265
+ else {
266
+ this.pushUndo({ entries: [entry] });
267
+ }
268
+ }
269
+ /** Record with 250ms debounce — consecutive calls within window share one batch. */
270
+ recordWithDebounce(entry) {
271
+ if (this.debounceTimer === null) {
272
+ // Start a new debounce batch.
273
+ this.openBatch = [entry];
274
+ }
275
+ else {
276
+ // Extend the current batch.
277
+ clearTimeout(this.debounceTimer);
278
+ this.openBatch?.push(entry);
279
+ }
280
+ this.debounceTimer = setTimeout(() => {
281
+ this.debounceTimer = null;
282
+ this.commitBatch();
283
+ }, RGA_DEBOUNCE_MS);
284
+ }
285
+ pushUndo(batch) {
286
+ this.undoStack.push(batch);
287
+ if (this.undoStack.length > MAX_STACK_DEPTH) {
288
+ this.undoStack.shift();
289
+ }
290
+ this.notifyStackChange();
291
+ }
292
+ clearRedo() {
293
+ if (this.redoStack.length > 0) {
294
+ this.redoStack = [];
295
+ this.notifyStackChange();
296
+ }
297
+ }
298
+ notifyStackChange() {
299
+ for (const listener of this.stackListeners)
300
+ listener();
301
+ }
302
+ asRGA() {
303
+ if (!(this.handle instanceof RGAHandle)) {
304
+ throw new Error("UndoManager: handle is not an RGAHandle");
305
+ }
306
+ return this.handle;
307
+ }
308
+ asTree() {
309
+ if (!(this.handle instanceof TreeHandle)) {
310
+ throw new Error("UndoManager: handle is not a TreeHandle");
311
+ }
312
+ return this.handle;
313
+ }
314
+ getCrdtId() {
315
+ return this.handle.id;
316
+ }
317
+ }
318
+ //# sourceMappingURL=UndoManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UndoManager.js","sourceRoot":"","sources":["../../src/undo/UndoManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Undo/redo entry types for CRDT-aware per-client history.
3
+ *
4
+ * Each entry stores enough information to produce the inverse operation.
5
+ * RGA Delete is intentionally not recorded — tombstones are final and
6
+ * the content is not recoverable (same semantics as ProseMirror/Yjs).
7
+ */
8
+ export interface RgaInsertEntry {
9
+ readonly kind: "rga_insert";
10
+ readonly crdtId: string;
11
+ /** HLC string "wall_ms:logical:node_id" of the inserted node. Undo = deleteById(nodeId). */
12
+ readonly nodeId: string;
13
+ /** Original visible position — used for redo re-insert. */
14
+ readonly pos: number;
15
+ /** The character that was inserted. */
16
+ readonly content: string;
17
+ }
18
+ export interface TreeAddEntry {
19
+ readonly kind: "tree_add";
20
+ readonly crdtId: string;
21
+ /** Node ID returned by addNode(). Undo = deleteNode(nodeId). */
22
+ readonly nodeId: string;
23
+ /** Stored for redo: re-add with same parent/position/value. */
24
+ readonly parentId: string | null;
25
+ readonly position: string;
26
+ readonly value: string;
27
+ }
28
+ export interface TreeDeleteEntry {
29
+ readonly kind: "tree_delete";
30
+ readonly crdtId: string;
31
+ readonly nodeId: string;
32
+ /** State captured before the delete — used to reconstruct addNode for undo. */
33
+ readonly parentId: string | null;
34
+ readonly position: string;
35
+ readonly value: string;
36
+ readonly updatedAt: string;
37
+ }
38
+ export interface TreeMoveEntry {
39
+ readonly kind: "tree_move";
40
+ readonly crdtId: string;
41
+ readonly nodeId: string;
42
+ readonly oldParentId: string | null;
43
+ readonly oldPosition: string;
44
+ /** Stored for redo. */
45
+ readonly newParentId: string | null;
46
+ readonly newPosition: string;
47
+ }
48
+ export interface TreeUpdateEntry {
49
+ readonly kind: "tree_update";
50
+ readonly crdtId: string;
51
+ readonly nodeId: string;
52
+ /** Captured before the update — used for undo. */
53
+ readonly previousValue: string;
54
+ readonly previousUpdatedAt: string;
55
+ /** Stored for redo. */
56
+ readonly newValue: string;
57
+ }
58
+ export type UndoEntry = RgaInsertEntry | TreeAddEntry | TreeDeleteEntry | TreeMoveEntry | TreeUpdateEntry;
59
+ /** A batch groups one or more entries into a single logical undo step. */
60
+ export interface UndoBatch {
61
+ readonly entries: readonly UndoEntry[];
62
+ }
63
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/undo/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,4FAA4F;IAC5F,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,2DAA2D;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,uBAAuB;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,uBAAuB;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,SAAS,GACjB,cAAc,GACd,YAAY,GACZ,eAAe,GACf,aAAa,GACb,eAAe,CAAC;AAEpB,0EAA0E;AAC1E,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;CACxC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Undo/redo entry types for CRDT-aware per-client history.
3
+ *
4
+ * Each entry stores enough information to produce the inverse operation.
5
+ * RGA Delete is intentionally not recorded — tombstones are final and
6
+ * the content is not recoverable (same semantics as ProseMirror/Yjs).
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/undo/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Fractional indexing helpers for TreeCRDT sibling ordering.
3
+ *
4
+ * Positions are lexicographically ordered strings over the alphabet [a-z0-9].
5
+ * They can be compared with plain string comparison: "a0" < "b0" < "z9".
6
+ *
7
+ * Use these helpers to compute positions when inserting nodes between, before,
8
+ * or after existing siblings — without having to manage the alphabet manually.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { fi } from "meridian-sdk";
13
+ *
14
+ * const first = fi.start(); // "a0"
15
+ * const last = fi.end(); // "z9"
16
+ * const mid = fi.between("a0","z9"); // "m4" (midpoint)
17
+ * const prev = fi.before("a0"); // "V9" (below a0)
18
+ * const next = fi.after("z9"); // "{0" (above z9, still valid)
19
+ * ```
20
+ */
21
+ /**
22
+ * Returns a position string strictly between `a` and `b`.
23
+ *
24
+ * Both `a` and `b` must be valid fractional index strings, and `a < b`
25
+ * lexicographically. Uses BigInt arithmetic to find the exact midpoint,
26
+ * appending an extra character when the gap is too small.
27
+ *
28
+ * @param a - Lower bound (exclusive).
29
+ * @param b - Upper bound (exclusive).
30
+ */
31
+ export declare function between(a: string, b: string): string;
32
+ /**
33
+ * Returns a position string that sorts before `a`.
34
+ *
35
+ * @param a - The reference position.
36
+ */
37
+ export declare function before(a: string): string;
38
+ /**
39
+ * Returns a position string that sorts after `b`.
40
+ *
41
+ * @param b - The reference position.
42
+ */
43
+ export declare function after(b: string): string;
44
+ /**
45
+ * Returns the canonical start position — the lowest recommended initial value.
46
+ */
47
+ export declare function start(): string;
48
+ /**
49
+ * Returns the canonical end position — the highest recommended initial value.
50
+ */
51
+ export declare function end(): string;
52
+ /**
53
+ * Computes an array of `n` evenly-spaced positions between `a` and `b`
54
+ * (exclusive). Useful for bulk-inserting nodes in order.
55
+ *
56
+ * @param a - Lower bound (exclusive).
57
+ * @param b - Upper bound (exclusive).
58
+ * @param n - Number of positions to generate.
59
+ */
60
+ export declare function spread(a: string, b: string, n: number): string[];
61
+ /**
62
+ * Namespace object for convenient import.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * import { fi } from "meridian-sdk";
67
+ * const pos = fi.between("a0", "z9");
68
+ * ```
69
+ */
70
+ export declare const fi: {
71
+ between: typeof between;
72
+ before: typeof before;
73
+ after: typeof after;
74
+ start: typeof start;
75
+ end: typeof end;
76
+ spread: typeof spread;
77
+ };
78
+ //# sourceMappingURL=fractional.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fractional.d.ts","sourceRoot":"","sources":["../../src/utils/fractional.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AA+CH;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAgBpD;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAExC;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvC;AAED;;GAEG;AACH,wBAAgB,KAAK,IAAI,MAAM,CAE9B;AAED;;GAEG;AACH,wBAAgB,GAAG,IAAI,MAAM,CAE5B;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAoBhE;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,EAAE;;;;;;;CAAiD,CAAC"}