@dabble/patches 0.9.5 → 0.9.6
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.
|
@@ -86,6 +86,9 @@ declare class JSONPatch {
|
|
|
86
86
|
bit(path: PathLike, index: number, on: boolean): this;
|
|
87
87
|
/**
|
|
88
88
|
* Applies a delta to a text document.
|
|
89
|
+
*
|
|
90
|
+
* `value` is stored as a bare `Op[]` array (the canonical `@txt` shape).
|
|
91
|
+
* Accepts a `Delta` instance, a serialized `{ ops }` form, or the array directly.
|
|
89
92
|
*/
|
|
90
93
|
text(path: PathLike, value: Delta | Delta['ops']): this;
|
|
91
94
|
/**
|
|
@@ -22,6 +22,7 @@ import { applyPatch } from "./applyPatch.js";
|
|
|
22
22
|
import { composePatch } from "./composePatch.js";
|
|
23
23
|
import { invertPatch } from "./invertPatch.js";
|
|
24
24
|
import { bitmask } from "./ops/bitmask.js";
|
|
25
|
+
import { toOps } from "./ops/text.js";
|
|
25
26
|
import { transformPatch } from "./transformPatch.js";
|
|
26
27
|
class JSONPatch {
|
|
27
28
|
ops;
|
|
@@ -120,16 +121,14 @@ class JSONPatch {
|
|
|
120
121
|
}
|
|
121
122
|
/**
|
|
122
123
|
* Applies a delta to a text document.
|
|
124
|
+
*
|
|
125
|
+
* `value` is stored as a bare `Op[]` array (the canonical `@txt` shape).
|
|
126
|
+
* Accepts a `Delta` instance, a serialized `{ ops }` form, or the array directly.
|
|
123
127
|
*/
|
|
124
128
|
text(path, value) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
value = new Delta(value.ops);
|
|
129
|
-
} else if (!(value instanceof Delta)) {
|
|
130
|
-
throw new Error("Invalid Delta");
|
|
131
|
-
}
|
|
132
|
-
return this.op("@txt", path, value);
|
|
129
|
+
const ops = toOps(value);
|
|
130
|
+
if (!ops) throw new Error("Invalid Delta");
|
|
131
|
+
return this.op("@txt", path, ops);
|
|
133
132
|
}
|
|
134
133
|
/**
|
|
135
134
|
* Creates a patch from an object partial, updating each field. Set a field to undefined to delete it.
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
import { Op } from '@dabble/delta';
|
|
1
2
|
import { JSONPatchOpHandler } from '../types.js';
|
|
2
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Normalize a `@txt` op's `value` to a bare `Op[]` array.
|
|
6
|
+
*
|
|
7
|
+
* The canonical form is an array of Delta ops, but historically `JSONPatch.text()`,
|
|
8
|
+
* `text.compose()`, and `text.invert()` produced `Delta` instances. Those serialize
|
|
9
|
+
* via `JSON.stringify` to `{ ops: [...] }`, so any rehydrated op may land in either
|
|
10
|
+
* shape. Accept all three; return `null` if the input isn't a recognizable Delta.
|
|
11
|
+
*/
|
|
12
|
+
declare function toOps(value: unknown): Op[] | null;
|
|
3
13
|
declare const text: JSONPatchOpHandler;
|
|
4
14
|
|
|
5
|
-
export { text };
|
|
15
|
+
export { text, toOps };
|
|
@@ -4,13 +4,21 @@ import { replace } from "../ops/replace.js";
|
|
|
4
4
|
import { get } from "../utils/get.js";
|
|
5
5
|
import { log } from "../utils/log.js";
|
|
6
6
|
import { updateRemovedOps } from "../utils/ops.js";
|
|
7
|
+
function toOps(value) {
|
|
8
|
+
if (Array.isArray(value)) return value;
|
|
9
|
+
if (value && typeof value === "object" && Array.isArray(value.ops)) {
|
|
10
|
+
return value.ops;
|
|
11
|
+
}
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
7
14
|
const text = {
|
|
8
15
|
like: "replace",
|
|
9
16
|
apply(state, path, value) {
|
|
10
|
-
const
|
|
11
|
-
if (!
|
|
17
|
+
const ops = toOps(value);
|
|
18
|
+
if (!ops) {
|
|
12
19
|
return "Invalid delta";
|
|
13
20
|
}
|
|
21
|
+
const delta = new Delta(ops);
|
|
14
22
|
const existingData = get(state, path);
|
|
15
23
|
let doc;
|
|
16
24
|
if (Array.isArray(existingData)) {
|
|
@@ -29,22 +37,24 @@ const text = {
|
|
|
29
37
|
},
|
|
30
38
|
transform(state, thisOp, otherOps) {
|
|
31
39
|
log("Transforming ", otherOps, ' against "@txt"', thisOp);
|
|
40
|
+
const thisOps = toOps(thisOp.value);
|
|
32
41
|
return updateRemovedOps(state, thisOp.path, otherOps, false, true, thisOp.op, (op) => {
|
|
33
42
|
if (op.path !== thisOp.path) return null;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
43
|
+
const otherOpsArr = toOps(op.value);
|
|
44
|
+
if (!thisOps || !otherOpsArr) return null;
|
|
45
|
+
const thisDelta = new Delta(thisOps);
|
|
46
|
+
let otherDelta = new Delta(otherOpsArr);
|
|
37
47
|
otherDelta = thisDelta.transform(otherDelta, true);
|
|
38
48
|
return { ...op, value: otherDelta.ops };
|
|
39
49
|
});
|
|
40
50
|
},
|
|
41
51
|
invert(state, { path, value }, oldValue, changedObj) {
|
|
42
52
|
if (path.endsWith("/-")) path = path.replace("-", changedObj.length);
|
|
43
|
-
const delta = new Delta(value);
|
|
44
|
-
return oldValue === void 0 ? { op: "remove", path } : { op: "@txt", path, value: delta.invert(oldValue) };
|
|
53
|
+
const delta = new Delta(toOps(value) ?? []);
|
|
54
|
+
return oldValue === void 0 ? { op: "remove", path } : { op: "@txt", path, value: delta.invert(oldValue).ops };
|
|
45
55
|
},
|
|
46
56
|
compose(state, delta1, delta2) {
|
|
47
|
-
return new Delta(delta1).compose(new Delta(delta2));
|
|
57
|
+
return new Delta(toOps(delta1) ?? []).compose(new Delta(toOps(delta2) ?? [])).ops;
|
|
48
58
|
}
|
|
49
59
|
};
|
|
50
60
|
function fixBadDeltaDoc(delta) {
|
|
@@ -72,5 +82,6 @@ function fixBadDeltaDoc(delta) {
|
|
|
72
82
|
return newDelta;
|
|
73
83
|
}
|
|
74
84
|
export {
|
|
75
|
-
text
|
|
85
|
+
text,
|
|
86
|
+
toOps
|
|
76
87
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dabble/patches",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.6",
|
|
4
4
|
"description": "Immutable JSON Patch implementation based on RFC 6902 supporting operational transformation and last-writer-wins",
|
|
5
5
|
"author": "Jacob Wright <jacwright@gmail.com>",
|
|
6
6
|
"bugs": {
|