json-patch-to-crdt 0.0.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/LICENSE.md +21 -0
- package/README.md +416 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +33 -0
- package/dist/index.mjs +3 -0
- package/dist/internals.d.mts +25 -0
- package/dist/internals.d.ts +25 -0
- package/dist/internals.js +51 -0
- package/dist/internals.mjs +3 -0
- package/dist/merge-B1BFMhJJ.js +1723 -0
- package/dist/merge-BpAUNaPe.d.mts +419 -0
- package/dist/merge-DikOFBWc.mjs +1435 -0
- package/dist/merge-QmPXxE6_.d.ts +419 -0
- package/package.json +58 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Samuel Laycock
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
# json-patch-to-crdt
|
|
2
|
+
|
|
3
|
+
Convert JSON Patch (RFC 6902) operations into a CRDT-friendly data structure and back to JSON.
|
|
4
|
+
|
|
5
|
+
This package is for applications that need to:
|
|
6
|
+
|
|
7
|
+
- Apply JSON Patch operations locally.
|
|
8
|
+
- Maintain a CRDT-compatible document model for sync.
|
|
9
|
+
- Merge divergent document states from multiple peers.
|
|
10
|
+
- Serialize and restore CRDT state safely.
|
|
11
|
+
- Generate JSON Patch deltas using explicit base snapshots.
|
|
12
|
+
|
|
13
|
+
It models JSON with:
|
|
14
|
+
|
|
15
|
+
- LWW registers for primitives.
|
|
16
|
+
- An RGA sequence for arrays.
|
|
17
|
+
- A map with delete-wins semantics for objects.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bun add json-patch-to-crdt
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install json-patch-to-crdt
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Runtime Requirements
|
|
30
|
+
|
|
31
|
+
- Node.js `>= 18` (for package consumers).
|
|
32
|
+
- TypeScript `^5` when type-checking in your project.
|
|
33
|
+
- Bun is optional (used for this repo's own build/test scripts).
|
|
34
|
+
|
|
35
|
+
## Quick Start (Recommended API)
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { applyPatch, createState, toJson, type JsonPatchOp } from "json-patch-to-crdt";
|
|
39
|
+
|
|
40
|
+
const state = createState({ list: ["a", "b"], meta: { ok: true } }, { actor: "A" });
|
|
41
|
+
|
|
42
|
+
const patch: JsonPatchOp[] = [
|
|
43
|
+
{ op: "add", path: "/list/-", value: "c" },
|
|
44
|
+
{ op: "replace", path: "/meta/ok", value: false },
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const next = applyPatch(state, patch);
|
|
49
|
+
console.log(toJson(next));
|
|
50
|
+
} catch (err) {
|
|
51
|
+
// PatchError has a `.code` you can inspect if needed.
|
|
52
|
+
throw err;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Multi-Peer Sync
|
|
57
|
+
|
|
58
|
+
Two peers can start from a shared state, apply patches independently, and merge:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import {
|
|
62
|
+
applyPatch,
|
|
63
|
+
cloneDoc,
|
|
64
|
+
createClock,
|
|
65
|
+
createState,
|
|
66
|
+
mergeState,
|
|
67
|
+
toJson,
|
|
68
|
+
type CrdtState,
|
|
69
|
+
} from "json-patch-to-crdt";
|
|
70
|
+
|
|
71
|
+
// Both peers start from the same origin state.
|
|
72
|
+
const origin = createState({ count: 0, items: ["a"] }, { actor: "origin" });
|
|
73
|
+
|
|
74
|
+
// Each peer gets a clone of the document with its own clock.
|
|
75
|
+
const peerA: CrdtState = {
|
|
76
|
+
doc: cloneDoc(origin.doc),
|
|
77
|
+
clock: createClock("A", origin.clock.ctr),
|
|
78
|
+
};
|
|
79
|
+
const peerB: CrdtState = {
|
|
80
|
+
doc: cloneDoc(origin.doc),
|
|
81
|
+
clock: createClock("B", origin.clock.ctr),
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// Peers diverge with independent edits.
|
|
85
|
+
const a1 = applyPatch(peerA, [
|
|
86
|
+
{ op: "replace", path: "/count", value: 1 },
|
|
87
|
+
{ op: "add", path: "/items/-", value: "b" },
|
|
88
|
+
]);
|
|
89
|
+
|
|
90
|
+
const b1 = applyPatch(peerB, [
|
|
91
|
+
{ op: "replace", path: "/count", value: 2 },
|
|
92
|
+
{ op: "add", path: "/items/-", value: "c" },
|
|
93
|
+
]);
|
|
94
|
+
|
|
95
|
+
// Each peer merges while preserving its own actor identity.
|
|
96
|
+
const mergedAtA = mergeState(a1, b1, { actor: "A" });
|
|
97
|
+
const mergedAtB = mergeState(b1, a1, { actor: "B" });
|
|
98
|
+
|
|
99
|
+
console.log(toJson(mergedAtA));
|
|
100
|
+
// { count: 2, items: ["a", "c", "b"] }
|
|
101
|
+
// (both appends preserved; sibling order follows dot ordering)
|
|
102
|
+
|
|
103
|
+
// Both peers can continue editing safely.
|
|
104
|
+
const a2 = applyPatch(mergedAtA, [{ op: "replace", path: "/count", value: 3 }]);
|
|
105
|
+
const b2 = applyPatch(mergedAtB, [{ op: "add", path: "/items/-", value: "d" }]);
|
|
106
|
+
|
|
107
|
+
// Merge again to converge.
|
|
108
|
+
const converged = mergeState(a2, b2, { actor: "A" });
|
|
109
|
+
console.log(toJson(converged));
|
|
110
|
+
// { count: 3, items: ["a", "c", "b", "d"] }
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Concepts
|
|
114
|
+
|
|
115
|
+
- **Doc**: CRDT document node graph.
|
|
116
|
+
- **State**: `{ doc, clock }`, where `clock` yields new dots.
|
|
117
|
+
- **Base snapshot**: explicit JSON or CRDT doc used to interpret array indices and compute deltas.
|
|
118
|
+
|
|
119
|
+
## Ordered Event Log Server Pattern
|
|
120
|
+
|
|
121
|
+
If your service contract is "JSON Patch in / JSON Patch out", and your backend keeps CRDT metadata internally:
|
|
122
|
+
|
|
123
|
+
- Keep one authoritative CRDT head per document.
|
|
124
|
+
- Keep a version vector keyed by actor ID.
|
|
125
|
+
- On each incoming JSON Patch, call `applyPatchAsActor(headDoc, vv, actor, patch, { base })`.
|
|
126
|
+
- Append the accepted event to your ordered log.
|
|
127
|
+
- For downstream clients, emit `crdtToJsonPatch(clientBaseDoc, currentHeadDoc)`.
|
|
128
|
+
|
|
129
|
+
Minimal shape:
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
import {
|
|
133
|
+
applyPatchAsActor,
|
|
134
|
+
PatchError,
|
|
135
|
+
crdtToJsonPatch,
|
|
136
|
+
createState,
|
|
137
|
+
type Doc,
|
|
138
|
+
type JsonPatchOp,
|
|
139
|
+
type VersionVector,
|
|
140
|
+
} from "json-patch-to-crdt";
|
|
141
|
+
|
|
142
|
+
let head: Doc = createState({ list: [] }, { actor: "server" }).doc;
|
|
143
|
+
let vv: VersionVector = {};
|
|
144
|
+
|
|
145
|
+
function applyIncomingPatch(
|
|
146
|
+
actor: string,
|
|
147
|
+
base: Doc,
|
|
148
|
+
patch: JsonPatchOp[],
|
|
149
|
+
): { ok: true; outPatch: JsonPatchOp[] } | { ok: false; code: number; message: string } {
|
|
150
|
+
try {
|
|
151
|
+
const applied = applyPatchAsActor(head, vv, actor, patch, { base });
|
|
152
|
+
head = applied.state.doc;
|
|
153
|
+
vv = applied.vv;
|
|
154
|
+
|
|
155
|
+
// Persist incoming event and/or outPatch in your append-only ordered log.
|
|
156
|
+
const outPatch = crdtToJsonPatch(base, head);
|
|
157
|
+
return { ok: true, outPatch };
|
|
158
|
+
} catch (error) {
|
|
159
|
+
if (error instanceof PatchError) {
|
|
160
|
+
return { ok: false, code: error.code, message: error.message };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
throw error;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
If you prefer a non-throwing low-level compile+apply path, use `jsonPatchToCrdtSafe`.
|
|
169
|
+
|
|
170
|
+
## Patch Semantics
|
|
171
|
+
|
|
172
|
+
- Patches are interpreted relative to a base snapshot.
|
|
173
|
+
- `applyPatch` defaults to a safe snapshot of the current state as its base.
|
|
174
|
+
- You can pass an explicit base doc via `applyPatch(state, patch, { base })`.
|
|
175
|
+
- Patch semantics are configurable: `semantics: "base"` (default) or `"sequential"`.
|
|
176
|
+
- In `sequential` mode with an explicit `base`, operations are interpreted against a rolling base snapshot while being applied step-by-step to the evolving head.
|
|
177
|
+
- Array indexes are mapped to element IDs based on the base snapshot.
|
|
178
|
+
- `"-"` is treated as append for array inserts.
|
|
179
|
+
- Missing arrays in the base snapshot only allow inserts at index `0` or `"-"`; other indexes throw a `PatchError` with code `409`.
|
|
180
|
+
- `test` operations can be evaluated against `head` or `base` using the `testAgainst` option.
|
|
181
|
+
|
|
182
|
+
### Semantics Modes
|
|
183
|
+
|
|
184
|
+
- `semantics: "base"` (default): interprets the full patch relative to one fixed snapshot.
|
|
185
|
+
- `semantics: "sequential"`: applies operations one-by-one against the evolving head (closest to RFC 6902 execution style).
|
|
186
|
+
|
|
187
|
+
#### Which Mode Should You Use?
|
|
188
|
+
|
|
189
|
+
| If you need... | Use |
|
|
190
|
+
| ------------------------------------------------------------------------- | ------------------------- |
|
|
191
|
+
| Deterministic CRDT-style replay against a known snapshot | `semantics: "base"` |
|
|
192
|
+
| JSON Patch behavior that feels closest to RFC 6902 step-by-step execution | `semantics: "sequential"` |
|
|
193
|
+
| Step-by-step replay from an explicit historical base | `semantics: "sequential"` |
|
|
194
|
+
|
|
195
|
+
Example:
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
const baseMode = applyPatch(state, [{ op: "add", path: "/list/0", value: "x" }], {
|
|
199
|
+
semantics: "base",
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
const sequentialMode = applyPatch(state, [{ op: "add", path: "/list/0", value: "x" }], {
|
|
203
|
+
semantics: "sequential",
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Delta Patches (First-Class)
|
|
208
|
+
|
|
209
|
+
If you want a JSON Patch delta, you must provide a base snapshot. This is a first-class API:
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
import { crdtToJsonPatch } from "json-patch-to-crdt";
|
|
213
|
+
|
|
214
|
+
const delta = crdtToJsonPatch(baseDoc, headDoc);
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
You can also diff JSON directly:
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
import { diffJsonPatch } from "json-patch-to-crdt";
|
|
221
|
+
|
|
222
|
+
const delta = diffJsonPatch(baseJson, nextJson);
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
If you need a full-state root `replace` patch (no delta), use `crdtToFullReplace`:
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
import { crdtToFullReplace } from "json-patch-to-crdt";
|
|
229
|
+
|
|
230
|
+
const fullPatch = crdtToFullReplace(doc);
|
|
231
|
+
// [{ op: "replace", path: "", value: { ... } }]
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Array Delta Strategy
|
|
235
|
+
|
|
236
|
+
By default, arrays are diffed with deterministic LCS edits.
|
|
237
|
+
|
|
238
|
+
If you want atomic array replacement, pass `{ arrayStrategy: "atomic" }`:
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
const delta = crdtToJsonPatch(baseDoc, headDoc, { arrayStrategy: "atomic" });
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Notes:
|
|
245
|
+
|
|
246
|
+
- LCS diffs are deterministic but not necessarily minimal.
|
|
247
|
+
- Reorders are expressed as remove/add pairs.
|
|
248
|
+
|
|
249
|
+
## Merging
|
|
250
|
+
|
|
251
|
+
Merge two divergent CRDT documents or states:
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
import { mergeDoc, mergeState } from "json-patch-to-crdt";
|
|
255
|
+
|
|
256
|
+
// Merge documents (low-level):
|
|
257
|
+
const mergedDoc = mergeDoc(docA, docB);
|
|
258
|
+
|
|
259
|
+
// Merge full states (preserve local actor identity):
|
|
260
|
+
const mergedState = mergeState(stateA, stateB, { actor: "A" });
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
By default, merge checks that non-empty arrays share lineage (common element IDs).
|
|
264
|
+
If you intentionally need best-effort merging of unrelated array histories, disable this guard:
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
const mergedDoc = mergeDoc(docA, docB, { requireSharedOrigin: false });
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Resolution rules:
|
|
271
|
+
|
|
272
|
+
- **LWW registers**: the register with the higher dot wins.
|
|
273
|
+
- **Objects**: entries merge key-by-key; delete-wins semantics apply.
|
|
274
|
+
- **RGA arrays**: elements union by ID; tombstones propagate (delete wins).
|
|
275
|
+
- **Kind mismatch**: the node with the higher representative dot wins.
|
|
276
|
+
|
|
277
|
+
`mergeDoc` is commutative (`merge(a, b)` equals `merge(b, a)`) and idempotent.
|
|
278
|
+
For `mergeState`, pass the local actor explicitly (or as the first argument) so each peer keeps a stable actor ID.
|
|
279
|
+
|
|
280
|
+
## Serialization
|
|
281
|
+
|
|
282
|
+
```ts
|
|
283
|
+
import {
|
|
284
|
+
createState,
|
|
285
|
+
serializeState,
|
|
286
|
+
deserializeState,
|
|
287
|
+
applyPatch,
|
|
288
|
+
toJson,
|
|
289
|
+
} from "json-patch-to-crdt";
|
|
290
|
+
|
|
291
|
+
const state = createState({ a: 1 }, { actor: "A" });
|
|
292
|
+
const payload = serializeState(state);
|
|
293
|
+
|
|
294
|
+
const restored = deserializeState(payload);
|
|
295
|
+
const next = applyPatch(restored, [{ op: "replace", path: "/a", value: 2 }]);
|
|
296
|
+
|
|
297
|
+
console.log(toJson(next));
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Supported JSON Patch Ops
|
|
301
|
+
|
|
302
|
+
- `add`, `remove`, `replace`, `move`, `copy`, `test`.
|
|
303
|
+
- `move` and `copy` are compiled to `add` + optional `remove` using the base snapshot.
|
|
304
|
+
- Object operations follow strict parent/target checks (no implicit object path creation).
|
|
305
|
+
|
|
306
|
+
## Error Handling
|
|
307
|
+
|
|
308
|
+
High-level `applyPatch` throws `PatchError` on failure and returns a new state:
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
import { applyPatch, PatchError } from "json-patch-to-crdt";
|
|
312
|
+
|
|
313
|
+
try {
|
|
314
|
+
const next = applyPatch(state, patch);
|
|
315
|
+
} catch (err) {
|
|
316
|
+
if (err instanceof PatchError) {
|
|
317
|
+
console.error(err.code, err.message);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Low-level APIs (`applyIntentsToCrdt`, `jsonPatchToCrdt`) return `{ ok: false, code: 409, message }` for apply-time conflicts.
|
|
323
|
+
Compile-time patch issues (invalid pointers, missing object parents/targets) throw errors unless you use `jsonPatchToCrdtSafe`.
|
|
324
|
+
|
|
325
|
+
## API Summary
|
|
326
|
+
|
|
327
|
+
### State helpers
|
|
328
|
+
|
|
329
|
+
- `createState(initial, { actor, start? })` - Create a new CRDT state from JSON.
|
|
330
|
+
- `applyPatch(state, patch, options?)` - Apply a patch immutably, returning a new state (`semantics: "base"` by default).
|
|
331
|
+
- `applyPatchInPlace(state, patch, options?)` - Apply a patch by mutating state in place (atomic by default, `atomic: false` for legacy behavior).
|
|
332
|
+
- `applyPatchAsActor(doc, vv, actor, patch, options?)` - Apply a patch for a server-tracked actor and return updated `{ state, vv }`.
|
|
333
|
+
- `toJson(docOrState)` - Materialize a JSON value from a doc or state.
|
|
334
|
+
- `PatchError` - Error class thrown for failed patches (code `409`).
|
|
335
|
+
|
|
336
|
+
### Clock helpers
|
|
337
|
+
|
|
338
|
+
- `createClock(actor, start?)` - Create a new clock for dot generation.
|
|
339
|
+
- `cloneClock(clock)` - Clone a clock independently.
|
|
340
|
+
- `nextDotForActor(vv, actor)` - Generate a dot for any actor from a shared version-vector map.
|
|
341
|
+
- `observeDot(vv, dot)` - Record observed dots into that map.
|
|
342
|
+
|
|
343
|
+
### Document helpers
|
|
344
|
+
|
|
345
|
+
- `docFromJson(value, nextDot)` - Create a CRDT doc using fresh dots per node.
|
|
346
|
+
- `cloneDoc(doc)` - Deep-clone a document.
|
|
347
|
+
- `materialize(node)` - Convert a CRDT node to a JSON value.
|
|
348
|
+
|
|
349
|
+
### Merge helpers
|
|
350
|
+
|
|
351
|
+
- `mergeDoc(a, b, options?)` - Merge two CRDT documents (`options.requireSharedOrigin` defaults to `true`).
|
|
352
|
+
- `mergeState(a, b, options?)` - Merge two CRDT states (doc + clock), preserving actor identity (`options.actor`) and optional shared-origin checks.
|
|
353
|
+
|
|
354
|
+
### Patch helpers
|
|
355
|
+
|
|
356
|
+
- `compileJsonPatchToIntent(baseJson, patch)` - Compile JSON Patch to intent operations.
|
|
357
|
+
- `applyIntentsToCrdt(base, head, intents, newDot, evalTestAgainst?, bumpCounterAbove?)` - Apply intents to a document.
|
|
358
|
+
- `jsonPatchToCrdt(base, head, patch, newDot, evalTestAgainst?, bumpCounterAbove?)` - Compile and apply in one step.
|
|
359
|
+
- `jsonPatchToCrdtSafe(base, head, patch, newDot, evalTestAgainst?, bumpCounterAbove?)` - Safe compile+apply wrapper that returns `409` results instead of throwing on compile-time patch issues.
|
|
360
|
+
- `diffJsonPatch(baseJson, nextJson, options?)` - Compute a JSON Patch delta between two JSON values.
|
|
361
|
+
- `crdtToJsonPatch(baseDoc, headDoc, options?)` - Compute a JSON Patch delta between two CRDT docs.
|
|
362
|
+
- `crdtToFullReplace(doc)` - Emit a full-state root `replace` patch.
|
|
363
|
+
|
|
364
|
+
### Serialization
|
|
365
|
+
|
|
366
|
+
- `serializeDoc(doc)` / `deserializeDoc(payload)` - Serialize/restore a document.
|
|
367
|
+
- `serializeState(state)` / `deserializeState(payload)` - Serialize/restore a full state.
|
|
368
|
+
|
|
369
|
+
### Internals (`json-patch-to-crdt/internals`)
|
|
370
|
+
|
|
371
|
+
Low-level helpers are available via a separate entry point for advanced use:
|
|
372
|
+
|
|
373
|
+
```ts
|
|
374
|
+
import { compareDot, rgaInsertAfter, objSet, HEAD } from "json-patch-to-crdt/internals";
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
This includes: `compareDot`, `vvHasDot`, `vvMerge`, `dotToElemId`, `newObj`, `newSeq`, `newReg`, `lwwSet`, `objSet`, `objRemove`, `HEAD`, `rgaInsertAfter`, `rgaDelete`, `rgaLinearizeIds`, `rgaPrevForInsertAtIndex`, `rgaIdAtIndex`, `docFromJsonWithDot`.
|
|
378
|
+
|
|
379
|
+
## Determinism
|
|
380
|
+
|
|
381
|
+
- Object key ordering in deltas is stable (sorted keys).
|
|
382
|
+
- LCS array diffs are deterministic.
|
|
383
|
+
- Repeated runs for identical inputs yield identical patches.
|
|
384
|
+
|
|
385
|
+
## FAQ / Troubleshooting
|
|
386
|
+
|
|
387
|
+
**Why did I get `PatchError` with code `409`?**
|
|
388
|
+
This typically means the patch could not be applied against the base snapshot. Common causes:
|
|
389
|
+
|
|
390
|
+
- Array index out of bounds relative to the base snapshot.
|
|
391
|
+
- `test` op failed (value mismatch).
|
|
392
|
+
- Base array missing for a non-append insert.
|
|
393
|
+
|
|
394
|
+
**How do I avoid `409` for arrays?**
|
|
395
|
+
Always pass a base snapshot that matches the array you are patching. If the array may be missing, only insert at index `0` or `"-"` (append) to allow auto-creation.
|
|
396
|
+
|
|
397
|
+
**How do I get a full-state patch instead of a delta?**
|
|
398
|
+
Use `crdtToFullReplace(doc)` which emits a single root `replace` patch.
|
|
399
|
+
|
|
400
|
+
**Why do array deltas look bigger than expected?**
|
|
401
|
+
LCS diffs are deterministic, not minimal. If you prefer one-op array replacement, use `{ arrayStrategy: "atomic" }`.
|
|
402
|
+
|
|
403
|
+
**Does LCS guarantee the smallest patch?**
|
|
404
|
+
No. It is deterministic and usually compact, but not guaranteed to be minimal.
|
|
405
|
+
|
|
406
|
+
**How do I merge states from two peers?**
|
|
407
|
+
Use `mergeState(local, remote, { actor: localActorId })`. Both peers should start from a shared origin state (same document, different clocks), and each peer should keep its own unique actor ID across merges. See the [Multi-Peer Sync](#multi-peer-sync) example above.
|
|
408
|
+
|
|
409
|
+
**Why can my local counter jump after a merge?**
|
|
410
|
+
Array inserts that target an existing predecessor may need to outrank sibling insert dots for deterministic ordering. The library can fast-forward the local counter in constant time to avoid expensive loops, but the resulting counter value may still jump upward when merging with peers that already have high counters.
|
|
411
|
+
|
|
412
|
+
## Limitations
|
|
413
|
+
|
|
414
|
+
- The array materialization and insert mapping depend on a base snapshot; concurrent inserts resolve by dot order.
|
|
415
|
+
- Under highly skewed peer counters, local counters may jump upward after merges to preserve deterministic insert ordering.
|
|
416
|
+
- Merge requires both peers to have started from the same origin document so that shared elements have matching IDs.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { $ as PatchSemantics, A as createState, B as Dot, C as createClock, D as applyPatch, E as PatchError, F as ApplyResult, G as JsonPrimitive, H as IntentOp, I as Clock, J as MergeDocOptions, K as JsonValue, L as CrdtState, M as ActorId, N as ApplyPatchAsActorResult, O as applyPatchAsActor, P as ApplyPatchOptions, Q as ObjNode, R as DiffOptions, S as cloneClock, T as observeDot, U as JsonPatch, V as ElemId, W as JsonPatchOp, X as Node, Y as MergeStateOptions, Z as ObjEntry, _ as crdtToJsonPatch, a as deserializeState, at as SerializedState, b as jsonPatchToCrdt, c as compileJsonPatchToIntent, d as jsonEquals, f as parseJsonPointer, g as crdtToFullReplace, h as cloneDoc, i as deserializeDoc, it as SerializedNode, j as toJson, k as applyPatchInPlace, l as diffJsonPatch, m as applyIntentsToCrdt, n as mergeState, nt as RgaSeq, o as serializeDoc, ot as VersionVector, p as stringifyJsonPointer, q as LwwReg, r as materialize, rt as SerializedDoc, s as serializeState, t as mergeDoc, tt as RgaElem, u as getAtJson, v as docFromJson, w as nextDotForActor, x as jsonPatchToCrdtSafe, z as Doc } from "./merge-BpAUNaPe.mjs";
|
|
2
|
+
export { type ActorId, type ApplyPatchAsActorResult, type ApplyPatchOptions, type ApplyResult, type Clock, type CrdtState, type DiffOptions, type Doc, type Dot, type ElemId, type IntentOp, type JsonPatch, type JsonPatchOp, type JsonPrimitive, type JsonValue, type LwwReg, type MergeDocOptions, type MergeStateOptions, type Node, type ObjEntry, type ObjNode, PatchError, type PatchSemantics, type RgaElem, type RgaSeq, type SerializedDoc, type SerializedNode, type SerializedState, type VersionVector, applyIntentsToCrdt, applyPatch, applyPatchAsActor, applyPatchInPlace, cloneClock, cloneDoc, compileJsonPatchToIntent, crdtToFullReplace, crdtToJsonPatch, createClock, createState, deserializeDoc, deserializeState, diffJsonPatch, docFromJson, getAtJson, jsonEquals, jsonPatchToCrdt, jsonPatchToCrdtSafe, materialize, mergeDoc, mergeState, nextDotForActor, observeDot, parseJsonPointer, serializeDoc, serializeState, stringifyJsonPointer, toJson };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { $ as PatchSemantics, A as createState, B as Dot, C as createClock, D as applyPatch, E as PatchError, F as ApplyResult, G as JsonPrimitive, H as IntentOp, I as Clock, J as MergeDocOptions, K as JsonValue, L as CrdtState, M as ActorId, N as ApplyPatchAsActorResult, O as applyPatchAsActor, P as ApplyPatchOptions, Q as ObjNode, R as DiffOptions, S as cloneClock, T as observeDot, U as JsonPatch, V as ElemId, W as JsonPatchOp, X as Node, Y as MergeStateOptions, Z as ObjEntry, _ as crdtToJsonPatch, a as deserializeState, at as SerializedState, b as jsonPatchToCrdt, c as compileJsonPatchToIntent, d as jsonEquals, f as parseJsonPointer, g as crdtToFullReplace, h as cloneDoc, i as deserializeDoc, it as SerializedNode, j as toJson, k as applyPatchInPlace, l as diffJsonPatch, m as applyIntentsToCrdt, n as mergeState, nt as RgaSeq, o as serializeDoc, ot as VersionVector, p as stringifyJsonPointer, q as LwwReg, r as materialize, rt as SerializedDoc, s as serializeState, t as mergeDoc, tt as RgaElem, u as getAtJson, v as docFromJson, w as nextDotForActor, x as jsonPatchToCrdtSafe, z as Doc } from "./merge-QmPXxE6_.js";
|
|
2
|
+
export { type ActorId, type ApplyPatchAsActorResult, type ApplyPatchOptions, type ApplyResult, type Clock, type CrdtState, type DiffOptions, type Doc, type Dot, type ElemId, type IntentOp, type JsonPatch, type JsonPatchOp, type JsonPrimitive, type JsonValue, type LwwReg, type MergeDocOptions, type MergeStateOptions, type Node, type ObjEntry, type ObjNode, PatchError, type PatchSemantics, type RgaElem, type RgaSeq, type SerializedDoc, type SerializedNode, type SerializedState, type VersionVector, applyIntentsToCrdt, applyPatch, applyPatchAsActor, applyPatchInPlace, cloneClock, cloneDoc, compileJsonPatchToIntent, crdtToFullReplace, crdtToJsonPatch, createClock, createState, deserializeDoc, deserializeState, diffJsonPatch, docFromJson, getAtJson, jsonEquals, jsonPatchToCrdt, jsonPatchToCrdtSafe, materialize, mergeDoc, mergeState, nextDotForActor, observeDot, parseJsonPointer, serializeDoc, serializeState, stringifyJsonPointer, toJson };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_merge = require('./merge-B1BFMhJJ.js');
|
|
3
|
+
|
|
4
|
+
exports.PatchError = require_merge.PatchError;
|
|
5
|
+
exports.applyIntentsToCrdt = require_merge.applyIntentsToCrdt;
|
|
6
|
+
exports.applyPatch = require_merge.applyPatch;
|
|
7
|
+
exports.applyPatchAsActor = require_merge.applyPatchAsActor;
|
|
8
|
+
exports.applyPatchInPlace = require_merge.applyPatchInPlace;
|
|
9
|
+
exports.cloneClock = require_merge.cloneClock;
|
|
10
|
+
exports.cloneDoc = require_merge.cloneDoc;
|
|
11
|
+
exports.compileJsonPatchToIntent = require_merge.compileJsonPatchToIntent;
|
|
12
|
+
exports.crdtToFullReplace = require_merge.crdtToFullReplace;
|
|
13
|
+
exports.crdtToJsonPatch = require_merge.crdtToJsonPatch;
|
|
14
|
+
exports.createClock = require_merge.createClock;
|
|
15
|
+
exports.createState = require_merge.createState;
|
|
16
|
+
exports.deserializeDoc = require_merge.deserializeDoc;
|
|
17
|
+
exports.deserializeState = require_merge.deserializeState;
|
|
18
|
+
exports.diffJsonPatch = require_merge.diffJsonPatch;
|
|
19
|
+
exports.docFromJson = require_merge.docFromJson;
|
|
20
|
+
exports.getAtJson = require_merge.getAtJson;
|
|
21
|
+
exports.jsonEquals = require_merge.jsonEquals;
|
|
22
|
+
exports.jsonPatchToCrdt = require_merge.jsonPatchToCrdt;
|
|
23
|
+
exports.jsonPatchToCrdtSafe = require_merge.jsonPatchToCrdtSafe;
|
|
24
|
+
exports.materialize = require_merge.materialize;
|
|
25
|
+
exports.mergeDoc = require_merge.mergeDoc;
|
|
26
|
+
exports.mergeState = require_merge.mergeState;
|
|
27
|
+
exports.nextDotForActor = require_merge.nextDotForActor;
|
|
28
|
+
exports.observeDot = require_merge.observeDot;
|
|
29
|
+
exports.parseJsonPointer = require_merge.parseJsonPointer;
|
|
30
|
+
exports.serializeDoc = require_merge.serializeDoc;
|
|
31
|
+
exports.serializeState = require_merge.serializeState;
|
|
32
|
+
exports.stringifyJsonPointer = require_merge.stringifyJsonPointer;
|
|
33
|
+
exports.toJson = require_merge.toJson;
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { C as getAtJson, E as stringifyJsonPointer, G as cloneClock, J as observeDot, K as createClock, P as materialize, S as diffJsonPatch, T as parseJsonPointer, _ as docFromJson, a as serializeDoc, b as jsonPatchToCrdtSafe, c as applyPatch, d as createState, f as toJson, g as crdtToJsonPatch, h as crdtToFullReplace, i as deserializeState, l as applyPatchAsActor, m as cloneDoc, n as mergeState, o as serializeState, p as applyIntentsToCrdt, q as nextDotForActor, r as deserializeDoc, s as PatchError, t as mergeDoc, u as applyPatchInPlace, w as jsonEquals, x as compileJsonPatchToIntent, y as jsonPatchToCrdt } from "./merge-DikOFBWc.mjs";
|
|
2
|
+
|
|
3
|
+
export { PatchError, applyIntentsToCrdt, applyPatch, applyPatchAsActor, applyPatchInPlace, cloneClock, cloneDoc, compileJsonPatchToIntent, crdtToFullReplace, crdtToJsonPatch, createClock, createState, deserializeDoc, deserializeState, diffJsonPatch, docFromJson, getAtJson, jsonEquals, jsonPatchToCrdt, jsonPatchToCrdtSafe, materialize, mergeDoc, mergeState, nextDotForActor, observeDot, parseJsonPointer, serializeDoc, serializeState, stringifyJsonPointer, toJson };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { $ as PatchSemantics, A as createState, B as Dot, C as createClock, D as applyPatch, E as PatchError, F as ApplyResult, G as JsonPrimitive, H as IntentOp, I as Clock, J as MergeDocOptions, K as JsonValue, L as CrdtState, M as ActorId, N as ApplyPatchAsActorResult, O as applyPatchAsActor, P as ApplyPatchOptions, Q as ObjNode, R as DiffOptions, S as cloneClock, T as observeDot, U as JsonPatch, V as ElemId, W as JsonPatchOp, X as Node, Y as MergeStateOptions, Z as ObjEntry, _ as crdtToJsonPatch, a as deserializeState, at as SerializedState, b as jsonPatchToCrdt, c as compileJsonPatchToIntent, d as jsonEquals, et as ROOT_KEY, f as parseJsonPointer, g as crdtToFullReplace, h as cloneDoc, i as deserializeDoc, it as SerializedNode, j as toJson, k as applyPatchInPlace, l as diffJsonPatch, m as applyIntentsToCrdt, n as mergeState, nt as RgaSeq, o as serializeDoc, ot as VersionVector, p as stringifyJsonPointer, q as LwwReg, r as materialize, rt as SerializedDoc, s as serializeState, t as mergeDoc, tt as RgaElem, u as getAtJson, v as docFromJson, w as nextDotForActor, x as jsonPatchToCrdtSafe, y as docFromJsonWithDot, z as Doc } from "./merge-BpAUNaPe.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/dot.d.ts
|
|
4
|
+
declare function compareDot(a: Dot, b: Dot): number;
|
|
5
|
+
declare function vvHasDot(vv: VersionVector, d: Dot): boolean;
|
|
6
|
+
declare function vvMerge(a: VersionVector, b: VersionVector): VersionVector;
|
|
7
|
+
declare function dotToElemId(d: Dot): ElemId;
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/nodes.d.ts
|
|
10
|
+
declare function newObj(): ObjNode;
|
|
11
|
+
declare function newSeq(): RgaSeq;
|
|
12
|
+
declare function newReg(value: JsonValue, dot: Dot): LwwReg;
|
|
13
|
+
declare function lwwSet(reg: LwwReg, value: JsonValue, dot: Dot): void;
|
|
14
|
+
declare function objSet(obj: ObjNode, key: string, node: Node, dot: Dot): void;
|
|
15
|
+
declare function objRemove(obj: ObjNode, key: string, dot: Dot): void;
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/rga.d.ts
|
|
18
|
+
declare const HEAD: ElemId;
|
|
19
|
+
declare function rgaLinearizeIds(seq: RgaSeq): ElemId[];
|
|
20
|
+
declare function rgaInsertAfter(seq: RgaSeq, prev: ElemId, id: ElemId, insDot: Dot, value: Node): void;
|
|
21
|
+
declare function rgaDelete(seq: RgaSeq, id: ElemId): void;
|
|
22
|
+
declare function rgaIdAtIndex(seq: RgaSeq, index: number): ElemId | undefined;
|
|
23
|
+
declare function rgaPrevForInsertAtIndex(seq: RgaSeq, index: number): ElemId;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { ActorId, ApplyPatchAsActorResult, ApplyPatchOptions, ApplyResult, Clock, CrdtState, DiffOptions, Doc, Dot, ElemId, HEAD, IntentOp, JsonPatch, JsonPatchOp, JsonPrimitive, JsonValue, LwwReg, MergeDocOptions, MergeStateOptions, Node, ObjEntry, ObjNode, PatchError, PatchSemantics, ROOT_KEY, RgaElem, RgaSeq, SerializedDoc, SerializedNode, SerializedState, VersionVector, applyIntentsToCrdt, applyPatch, applyPatchAsActor, applyPatchInPlace, cloneClock, cloneDoc, compareDot, compileJsonPatchToIntent, crdtToFullReplace, crdtToJsonPatch, createClock, createState, deserializeDoc, deserializeState, diffJsonPatch, docFromJson, docFromJsonWithDot, dotToElemId, getAtJson, jsonEquals, jsonPatchToCrdt, jsonPatchToCrdtSafe, lwwSet, materialize, mergeDoc, mergeState, newObj, newReg, newSeq, nextDotForActor, objRemove, objSet, observeDot, parseJsonPointer, rgaDelete, rgaIdAtIndex, rgaInsertAfter, rgaLinearizeIds, rgaPrevForInsertAtIndex, serializeDoc, serializeState, stringifyJsonPointer, toJson, vvHasDot, vvMerge };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { $ as PatchSemantics, A as createState, B as Dot, C as createClock, D as applyPatch, E as PatchError, F as ApplyResult, G as JsonPrimitive, H as IntentOp, I as Clock, J as MergeDocOptions, K as JsonValue, L as CrdtState, M as ActorId, N as ApplyPatchAsActorResult, O as applyPatchAsActor, P as ApplyPatchOptions, Q as ObjNode, R as DiffOptions, S as cloneClock, T as observeDot, U as JsonPatch, V as ElemId, W as JsonPatchOp, X as Node, Y as MergeStateOptions, Z as ObjEntry, _ as crdtToJsonPatch, a as deserializeState, at as SerializedState, b as jsonPatchToCrdt, c as compileJsonPatchToIntent, d as jsonEquals, et as ROOT_KEY, f as parseJsonPointer, g as crdtToFullReplace, h as cloneDoc, i as deserializeDoc, it as SerializedNode, j as toJson, k as applyPatchInPlace, l as diffJsonPatch, m as applyIntentsToCrdt, n as mergeState, nt as RgaSeq, o as serializeDoc, ot as VersionVector, p as stringifyJsonPointer, q as LwwReg, r as materialize, rt as SerializedDoc, s as serializeState, t as mergeDoc, tt as RgaElem, u as getAtJson, v as docFromJson, w as nextDotForActor, x as jsonPatchToCrdtSafe, y as docFromJsonWithDot, z as Doc } from "./merge-QmPXxE6_.js";
|
|
2
|
+
|
|
3
|
+
//#region src/dot.d.ts
|
|
4
|
+
declare function compareDot(a: Dot, b: Dot): number;
|
|
5
|
+
declare function vvHasDot(vv: VersionVector, d: Dot): boolean;
|
|
6
|
+
declare function vvMerge(a: VersionVector, b: VersionVector): VersionVector;
|
|
7
|
+
declare function dotToElemId(d: Dot): ElemId;
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/nodes.d.ts
|
|
10
|
+
declare function newObj(): ObjNode;
|
|
11
|
+
declare function newSeq(): RgaSeq;
|
|
12
|
+
declare function newReg(value: JsonValue, dot: Dot): LwwReg;
|
|
13
|
+
declare function lwwSet(reg: LwwReg, value: JsonValue, dot: Dot): void;
|
|
14
|
+
declare function objSet(obj: ObjNode, key: string, node: Node, dot: Dot): void;
|
|
15
|
+
declare function objRemove(obj: ObjNode, key: string, dot: Dot): void;
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/rga.d.ts
|
|
18
|
+
declare const HEAD: ElemId;
|
|
19
|
+
declare function rgaLinearizeIds(seq: RgaSeq): ElemId[];
|
|
20
|
+
declare function rgaInsertAfter(seq: RgaSeq, prev: ElemId, id: ElemId, insDot: Dot, value: Node): void;
|
|
21
|
+
declare function rgaDelete(seq: RgaSeq, id: ElemId): void;
|
|
22
|
+
declare function rgaIdAtIndex(seq: RgaSeq, index: number): ElemId | undefined;
|
|
23
|
+
declare function rgaPrevForInsertAtIndex(seq: RgaSeq, index: number): ElemId;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { ActorId, ApplyPatchAsActorResult, ApplyPatchOptions, ApplyResult, Clock, CrdtState, DiffOptions, Doc, Dot, ElemId, HEAD, IntentOp, JsonPatch, JsonPatchOp, JsonPrimitive, JsonValue, LwwReg, MergeDocOptions, MergeStateOptions, Node, ObjEntry, ObjNode, PatchError, PatchSemantics, ROOT_KEY, RgaElem, RgaSeq, SerializedDoc, SerializedNode, SerializedState, VersionVector, applyIntentsToCrdt, applyPatch, applyPatchAsActor, applyPatchInPlace, cloneClock, cloneDoc, compareDot, compileJsonPatchToIntent, crdtToFullReplace, crdtToJsonPatch, createClock, createState, deserializeDoc, deserializeState, diffJsonPatch, docFromJson, docFromJsonWithDot, dotToElemId, getAtJson, jsonEquals, jsonPatchToCrdt, jsonPatchToCrdtSafe, lwwSet, materialize, mergeDoc, mergeState, newObj, newReg, newSeq, nextDotForActor, objRemove, objSet, observeDot, parseJsonPointer, rgaDelete, rgaIdAtIndex, rgaInsertAfter, rgaLinearizeIds, rgaPrevForInsertAtIndex, serializeDoc, serializeState, stringifyJsonPointer, toJson, vvHasDot, vvMerge };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_merge = require('./merge-B1BFMhJJ.js');
|
|
3
|
+
|
|
4
|
+
exports.HEAD = require_merge.HEAD;
|
|
5
|
+
exports.PatchError = require_merge.PatchError;
|
|
6
|
+
exports.ROOT_KEY = require_merge.ROOT_KEY;
|
|
7
|
+
exports.applyIntentsToCrdt = require_merge.applyIntentsToCrdt;
|
|
8
|
+
exports.applyPatch = require_merge.applyPatch;
|
|
9
|
+
exports.applyPatchAsActor = require_merge.applyPatchAsActor;
|
|
10
|
+
exports.applyPatchInPlace = require_merge.applyPatchInPlace;
|
|
11
|
+
exports.cloneClock = require_merge.cloneClock;
|
|
12
|
+
exports.cloneDoc = require_merge.cloneDoc;
|
|
13
|
+
exports.compareDot = require_merge.compareDot;
|
|
14
|
+
exports.compileJsonPatchToIntent = require_merge.compileJsonPatchToIntent;
|
|
15
|
+
exports.crdtToFullReplace = require_merge.crdtToFullReplace;
|
|
16
|
+
exports.crdtToJsonPatch = require_merge.crdtToJsonPatch;
|
|
17
|
+
exports.createClock = require_merge.createClock;
|
|
18
|
+
exports.createState = require_merge.createState;
|
|
19
|
+
exports.deserializeDoc = require_merge.deserializeDoc;
|
|
20
|
+
exports.deserializeState = require_merge.deserializeState;
|
|
21
|
+
exports.diffJsonPatch = require_merge.diffJsonPatch;
|
|
22
|
+
exports.docFromJson = require_merge.docFromJson;
|
|
23
|
+
exports.docFromJsonWithDot = require_merge.docFromJsonWithDot;
|
|
24
|
+
exports.dotToElemId = require_merge.dotToElemId;
|
|
25
|
+
exports.getAtJson = require_merge.getAtJson;
|
|
26
|
+
exports.jsonEquals = require_merge.jsonEquals;
|
|
27
|
+
exports.jsonPatchToCrdt = require_merge.jsonPatchToCrdt;
|
|
28
|
+
exports.jsonPatchToCrdtSafe = require_merge.jsonPatchToCrdtSafe;
|
|
29
|
+
exports.lwwSet = require_merge.lwwSet;
|
|
30
|
+
exports.materialize = require_merge.materialize;
|
|
31
|
+
exports.mergeDoc = require_merge.mergeDoc;
|
|
32
|
+
exports.mergeState = require_merge.mergeState;
|
|
33
|
+
exports.newObj = require_merge.newObj;
|
|
34
|
+
exports.newReg = require_merge.newReg;
|
|
35
|
+
exports.newSeq = require_merge.newSeq;
|
|
36
|
+
exports.nextDotForActor = require_merge.nextDotForActor;
|
|
37
|
+
exports.objRemove = require_merge.objRemove;
|
|
38
|
+
exports.objSet = require_merge.objSet;
|
|
39
|
+
exports.observeDot = require_merge.observeDot;
|
|
40
|
+
exports.parseJsonPointer = require_merge.parseJsonPointer;
|
|
41
|
+
exports.rgaDelete = require_merge.rgaDelete;
|
|
42
|
+
exports.rgaIdAtIndex = require_merge.rgaIdAtIndex;
|
|
43
|
+
exports.rgaInsertAfter = require_merge.rgaInsertAfter;
|
|
44
|
+
exports.rgaLinearizeIds = require_merge.rgaLinearizeIds;
|
|
45
|
+
exports.rgaPrevForInsertAtIndex = require_merge.rgaPrevForInsertAtIndex;
|
|
46
|
+
exports.serializeDoc = require_merge.serializeDoc;
|
|
47
|
+
exports.serializeState = require_merge.serializeState;
|
|
48
|
+
exports.stringifyJsonPointer = require_merge.stringifyJsonPointer;
|
|
49
|
+
exports.toJson = require_merge.toJson;
|
|
50
|
+
exports.vvHasDot = require_merge.vvHasDot;
|
|
51
|
+
exports.vvMerge = require_merge.vvMerge;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { A as newReg, B as rgaPrevForInsertAtIndex, C as getAtJson, D as ROOT_KEY, E as stringifyJsonPointer, F as HEAD, G as cloneClock, H as dotToElemId, I as rgaDelete, J as observeDot, K as createClock, L as rgaIdAtIndex, M as objRemove, N as objSet, O as lwwSet, P as materialize, R as rgaInsertAfter, S as diffJsonPatch, T as parseJsonPointer, U as vvHasDot, V as compareDot, W as vvMerge, _ as docFromJson, a as serializeDoc, b as jsonPatchToCrdtSafe, c as applyPatch, d as createState, f as toJson, g as crdtToJsonPatch, h as crdtToFullReplace, i as deserializeState, j as newSeq, k as newObj, l as applyPatchAsActor, m as cloneDoc, n as mergeState, o as serializeState, p as applyIntentsToCrdt, q as nextDotForActor, r as deserializeDoc, s as PatchError, t as mergeDoc, u as applyPatchInPlace, v as docFromJsonWithDot, w as jsonEquals, x as compileJsonPatchToIntent, y as jsonPatchToCrdt, z as rgaLinearizeIds } from "./merge-DikOFBWc.mjs";
|
|
2
|
+
|
|
3
|
+
export { HEAD, PatchError, ROOT_KEY, applyIntentsToCrdt, applyPatch, applyPatchAsActor, applyPatchInPlace, cloneClock, cloneDoc, compareDot, compileJsonPatchToIntent, crdtToFullReplace, crdtToJsonPatch, createClock, createState, deserializeDoc, deserializeState, diffJsonPatch, docFromJson, docFromJsonWithDot, dotToElemId, getAtJson, jsonEquals, jsonPatchToCrdt, jsonPatchToCrdtSafe, lwwSet, materialize, mergeDoc, mergeState, newObj, newReg, newSeq, nextDotForActor, objRemove, objSet, observeDot, parseJsonPointer, rgaDelete, rgaIdAtIndex, rgaInsertAfter, rgaLinearizeIds, rgaPrevForInsertAtIndex, serializeDoc, serializeState, stringifyJsonPointer, toJson, vvHasDot, vvMerge };
|