@dabble/patches 0.8.19 → 0.8.20
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.
|
@@ -3,6 +3,7 @@ import { getTypes } from "./ops/index.js";
|
|
|
3
3
|
import { runWithObject } from "./state.js";
|
|
4
4
|
import { exit } from "./utils/exit.js";
|
|
5
5
|
import { getType } from "./utils/getType.js";
|
|
6
|
+
import { isSoftOp, pathExistsInState } from "./utils/softWrites.js";
|
|
6
7
|
function applyPatch(object, patches, opts = {}, custom) {
|
|
7
8
|
if (patches.length === 0) {
|
|
8
9
|
return object;
|
|
@@ -14,6 +15,9 @@ function applyPatch(object, patches, opts = {}, custom) {
|
|
|
14
15
|
return runWithObject(object, types, patches.length > 1, (state) => {
|
|
15
16
|
for (let i = 0, imax = patches.length; i < imax; i++) {
|
|
16
17
|
const patch = patches[i];
|
|
18
|
+
if (isSoftOp(patch) && pathExistsInState(state.root[""], patch.path)) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
17
21
|
const handler = getType(state, patch)?.apply;
|
|
18
22
|
const error = handler ? handler(state, "" + patch.path, patch.from || patch.value) : `[op:${patch.op}] unknown`;
|
|
19
23
|
if (error) {
|
|
@@ -8,7 +8,7 @@ export { isAdd, mapAndFilterOps, transformRemove, updateRemovedOps } from './ops
|
|
|
8
8
|
export { getArrayIndex, getArrayPrefixAndIndex, getIndexAndEnd, getPrefix, getPrefixAndProp, getProp, getPropAfter, isArrayPath } from './paths.js';
|
|
9
9
|
export { EMPTY, EMPTY_ARRAY, getValue, pluck, pluckWithShallowCopy } from './pluck.js';
|
|
10
10
|
export { shallowCopy } from './shallowCopy.js';
|
|
11
|
-
export { filterSoftWritesAgainstState, isEmptyContainer, updateSoftWrites } from './softWrites.js';
|
|
11
|
+
export { filterSoftWritesAgainstState, isEmptyContainer, isSoftOp, pathExistsInState, updateSoftWrites } from './softWrites.js';
|
|
12
12
|
export { toArrayIndex } from './toArrayIndex.js';
|
|
13
13
|
export { toKeys } from './toKeys.js';
|
|
14
14
|
export { updateArrayIndexes } from './updateArrayIndexes.js';
|
|
@@ -7,10 +7,17 @@ declare function isEmptyContainer(value: any): boolean;
|
|
|
7
7
|
* for any value that already exists.
|
|
8
8
|
*/
|
|
9
9
|
declare function updateSoftWrites(overPath: string, ops: JSONPatchOp[], originalValue: any): JSONPatchOp[];
|
|
10
|
+
/**
|
|
11
|
+
* Returns true when an op carries soft semantics — either an explicit
|
|
12
|
+
* `soft: true` flag, or an empty-container `add` (treated as initialization
|
|
13
|
+
* by convention). Mirrors the check used by the LWW consolidation algorithm.
|
|
14
|
+
*/
|
|
15
|
+
declare function isSoftOp(op: JSONPatchOp): boolean;
|
|
10
16
|
/**
|
|
11
17
|
* Filters out soft writes that would overwrite existing data in state.
|
|
12
18
|
* Used when baseRev: 0 is jumped forward, bypassing normal transformation.
|
|
13
19
|
*/
|
|
14
20
|
declare function filterSoftWritesAgainstState(ops: JSONPatchOp[], state: any): JSONPatchOp[];
|
|
21
|
+
declare function pathExistsInState(state: any, path: string): boolean;
|
|
15
22
|
|
|
16
|
-
export { filterSoftWritesAgainstState, isEmptyContainer, updateSoftWrites };
|
|
23
|
+
export { filterSoftWritesAgainstState, isEmptyContainer, isSoftOp, pathExistsInState, updateSoftWrites };
|
|
@@ -16,10 +16,12 @@ function updateSoftWrites(overPath, ops, originalValue) {
|
|
|
16
16
|
return op;
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
+
function isSoftOp(op) {
|
|
20
|
+
return op.soft === true || op.op === "add" && isEmptyContainer(op.value);
|
|
21
|
+
}
|
|
19
22
|
function filterSoftWritesAgainstState(ops, state) {
|
|
20
23
|
return ops.filter((op) => {
|
|
21
|
-
|
|
22
|
-
if (!isSoft) return true;
|
|
24
|
+
if (!isSoftOp(op)) return true;
|
|
23
25
|
return !pathExistsInState(state, op.path);
|
|
24
26
|
});
|
|
25
27
|
}
|
|
@@ -37,5 +39,7 @@ function pathExistsInState(state, path) {
|
|
|
37
39
|
export {
|
|
38
40
|
filterSoftWritesAgainstState,
|
|
39
41
|
isEmptyContainer,
|
|
42
|
+
isSoftOp,
|
|
43
|
+
pathExistsInState,
|
|
40
44
|
updateSoftWrites
|
|
41
45
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dabble/patches",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.20",
|
|
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": {
|