patch-recorder 0.0.0 → 0.1.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/README.md +197 -46
- package/dist/arrays.d.ts.map +1 -1
- package/dist/arrays.js +72 -72
- package/dist/arrays.js.map +1 -1
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -2
- package/dist/index.js.map +1 -1
- package/dist/maps.d.ts.map +1 -1
- package/dist/maps.js +5 -7
- package/dist/maps.js.map +1 -1
- package/dist/optimizer.d.ts.map +1 -1
- package/dist/optimizer.js +109 -55
- package/dist/optimizer.js.map +1 -1
- package/dist/patches.d.ts +1 -1
- package/dist/patches.d.ts.map +1 -1
- package/dist/patches.js +26 -2
- package/dist/patches.js.map +1 -1
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +19 -3
- package/dist/proxy.js.map +1 -1
- package/dist/types.d.ts +37 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +11 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +48 -9
- package/dist/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/arrays.ts +78 -90
- package/src/index.ts +34 -2
- package/src/maps.ts +4 -6
- package/src/optimizer.ts +139 -57
- package/src/patches.ts +32 -4
- package/src/proxy.ts +17 -3
- package/src/types.ts +39 -4
- package/src/utils.ts +62 -10
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,YAAY,CAAC;AACvC,OAAO,EAAC,eAAe,EAAC,MAAM,gBAAgB,CAAC;AAU/C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,aAAa,CAC5B,KAAQ,EACR,MAAiC,EACjC,UAAgC,EAAE;IAElC,MAAM,sBAAsB,GAAG;QAC9B,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;QACxC,qBAAqB,EAAE,OAAO,CAAC,qBAAqB,IAAI,IAAI;KAC5D,CAAC;IAEF,MAAM,aAAa,GAAG;QACrB,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,EAAE;QACZ,OAAO,EAAE;YACR,GAAG,OAAO;YACV,sBAAsB;SACtB;KACD,CAAC;IAEF,eAAe;IACf,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,aAAa,CAAa,CAAC;IAEhE,kBAAkB;IAClB,MAAM,CAAC,KAAK,CAAC,CAAC;IAEd,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,YAAY,CAAC;AACvC,OAAO,EAAC,eAAe,EAAC,MAAM,gBAAgB,CAAC;AAU/C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,aAAa,CAC5B,KAAQ,EACR,MAAiC,EACjC,UAAgC,EAAE;IAElC,MAAM,sBAAsB,GAAG;QAC9B,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;QACxC,qBAAqB,EAAE,OAAO,CAAC,qBAAqB,IAAI,IAAI;KAC5D,CAAC;IAEF,MAAM,aAAa,GAAG;QACrB,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,EAAE;QACZ,OAAO,EAAE;YACR,GAAG,OAAO;YACV,sBAAsB;SACtB;KACD,CAAC;IAEF,eAAe;IACf,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,aAAa,CAAa,CAAC;IAEhE,kBAAkB;IAClB,MAAM,CAAC,KAAK,CAAC,CAAC;IAEd,yCAAyC;IACzC,IAAI,OAAO,CAAC,eAAe,KAAK,KAAK,EAAE,CAAC;QACvC,OAAO,eAAe,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,aAAa,CAAC,OAAwB,CAAC;AAC/C,CAAC;AAGD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,MAAM,CACrB,KAAQ,EACR,MAAiC,EACjC,UAAwD,EAAC,aAAa,EAAE,IAAI,EAAC;IAE7E,oEAAoE;IACpE,MAAM,EAAC,aAAa,EAAE,GAAG,oBAAoB,EAAC,GAAG,OAAO,CAAC;IACzD,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC;IACnE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACzB,CAAC"}
|
package/dist/maps.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maps.d.ts","sourceRoot":"","sources":["../src/maps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,YAAY,CAAC;AAM9C;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EAC5C,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EACd,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACzB,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,GACvB,GAAG,
|
|
1
|
+
{"version":3,"file":"maps.d.ts","sourceRoot":"","sources":["../src/maps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,YAAY,CAAC;AAM9C;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EAC5C,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EACd,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACzB,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,GACvB,GAAG,CAmFL"}
|
package/dist/maps.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createProxy } from './proxy.js';
|
|
2
2
|
import { generateAddPatch, generateDeletePatch, generateReplacePatch } from './patches.js';
|
|
3
|
-
import { cloneIfNeeded
|
|
3
|
+
import { cloneIfNeeded } from './utils.js';
|
|
4
4
|
/**
|
|
5
5
|
* Handle property access on Map objects
|
|
6
6
|
* Wraps mutating methods (set, delete, clear) to generate patches
|
|
@@ -20,8 +20,8 @@ export function handleMapGet(obj, prop, path, state) {
|
|
|
20
20
|
// Generate patch
|
|
21
21
|
const itemPath = [...path, key];
|
|
22
22
|
if (existed) {
|
|
23
|
-
// Key exists - replace
|
|
24
|
-
generateReplacePatch(state, itemPath, cloneIfNeeded(value));
|
|
23
|
+
// Key exists - replace (pass oldValue for getItemId)
|
|
24
|
+
generateReplacePatch(state, itemPath, cloneIfNeeded(value), oldValue);
|
|
25
25
|
}
|
|
26
26
|
else {
|
|
27
27
|
// Key doesn't exist - add
|
|
@@ -56,11 +56,9 @@ export function handleMapGet(obj, prop, path, state) {
|
|
|
56
56
|
if (prop === 'get') {
|
|
57
57
|
return (key) => {
|
|
58
58
|
const value = obj.get(key);
|
|
59
|
-
// If the value is
|
|
59
|
+
// If the value is an object, return a proxy for nested mutation tracking
|
|
60
60
|
if (value != null && typeof value === 'object') {
|
|
61
|
-
|
|
62
|
-
return createProxy(value, [...path, key], state);
|
|
63
|
-
}
|
|
61
|
+
return createProxy(value, [...path, key], state);
|
|
64
62
|
}
|
|
65
63
|
return value;
|
|
66
64
|
};
|
package/dist/maps.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maps.js","sourceRoot":"","sources":["../src/maps.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,WAAW,EAAC,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAC,gBAAgB,EAAE,mBAAmB,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AACzF,OAAO,EAAC,aAAa,
|
|
1
|
+
{"version":3,"file":"maps.js","sourceRoot":"","sources":["../src/maps.ts"],"names":[],"mappings":"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"}
|
package/dist/optimizer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"optimizer.d.ts","sourceRoot":"","sources":["../src/optimizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,YAAY,CAAC;AAExC;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"optimizer.d.ts","sourceRoot":"","sources":["../src/optimizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,YAAY,CAAC;AAExC;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CA8CrE"}
|
package/dist/optimizer.js
CHANGED
|
@@ -15,27 +15,110 @@ export function compressPatches(patches) {
|
|
|
15
15
|
if (!existing) {
|
|
16
16
|
// First operation on this path
|
|
17
17
|
pathMap.set(pathKey, patch);
|
|
18
|
-
continue;
|
|
19
18
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
//
|
|
24
|
-
if (merged !==
|
|
25
|
-
|
|
19
|
+
else {
|
|
20
|
+
// Merge with existing operation based on operation types
|
|
21
|
+
const merged = mergePatches(existing, patch);
|
|
22
|
+
// Check for undefined specifically (null means canceled, which is a valid result)
|
|
23
|
+
if (merged !== undefined) {
|
|
24
|
+
// Update with merged result (or null if they cancel out)
|
|
25
|
+
if (merged !== null) {
|
|
26
|
+
pathMap.set(pathKey, merged);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
// Operations canceled each other out
|
|
30
|
+
pathMap.delete(pathKey);
|
|
31
|
+
}
|
|
26
32
|
}
|
|
27
33
|
else {
|
|
28
|
-
//
|
|
29
|
-
pathMap.
|
|
34
|
+
// Can't merge, keep the new operation
|
|
35
|
+
pathMap.set(pathKey, patch);
|
|
30
36
|
}
|
|
31
37
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
}
|
|
39
|
+
// Convert Map to array for final processing
|
|
40
|
+
let finalPatches = Array.from(pathMap.values());
|
|
41
|
+
// Handle array push + pop cancellation
|
|
42
|
+
// Only cancel when push is at the last index and pop reduces length
|
|
43
|
+
finalPatches = cancelArrayPushPop(finalPatches);
|
|
44
|
+
// Cancel patches that are beyond array bounds after final length update
|
|
45
|
+
finalPatches = cancelOutOfBoundsPatches(finalPatches);
|
|
46
|
+
return finalPatches;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Cancel array push + pop operations
|
|
50
|
+
* Only cancels when push is at the last index and pop reduces length
|
|
51
|
+
*/
|
|
52
|
+
function cancelArrayPushPop(patches) {
|
|
53
|
+
// Group patches by parent array path
|
|
54
|
+
const arrayGroups = new Map();
|
|
55
|
+
for (const patch of patches) {
|
|
56
|
+
if (!Array.isArray(patch.path) || patch.path.length < 2) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const parentPath = patch.path.slice(0, -1);
|
|
60
|
+
const parentKey = JSON.stringify(parentPath);
|
|
61
|
+
if (!arrayGroups.has(parentKey)) {
|
|
62
|
+
arrayGroups.set(parentKey, []);
|
|
63
|
+
}
|
|
64
|
+
arrayGroups.get(parentKey).push(patch);
|
|
65
|
+
}
|
|
66
|
+
const cancelablePatches = new Set();
|
|
67
|
+
for (const [, groupPatches] of arrayGroups.entries()) {
|
|
68
|
+
// Find push patches (add at highest indices)
|
|
69
|
+
const pushPatches = groupPatches
|
|
70
|
+
.filter((p) => p.op === 'add' && typeof p.path[p.path.length - 1] === 'number')
|
|
71
|
+
.sort((a, b) => b.path[b.path.length - 1] - a.path[a.path.length - 1]);
|
|
72
|
+
// Find pop patches (length reduction)
|
|
73
|
+
const popPatches = groupPatches.filter((p) => p.op === 'replace' && p.path[p.path.length - 1] === 'length');
|
|
74
|
+
// Cancel pushes and pops that match (push at highest index, pop reduces length)
|
|
75
|
+
const cancelCount = Math.min(pushPatches.length, popPatches.length);
|
|
76
|
+
for (let i = 0; i < cancelCount; i++) {
|
|
77
|
+
const pushPatch = pushPatches[i];
|
|
78
|
+
const popPatch = popPatches[i];
|
|
79
|
+
// Check if the push index matches the pop target
|
|
80
|
+
const pushIndex = pushPatch.path[pushPatch.path.length - 1];
|
|
81
|
+
const popLength = popPatch.value;
|
|
82
|
+
// If push added at index pushIndex and pop reduced to popLength, they cancel
|
|
83
|
+
// This is a heuristic: push adds at end, pop removes from end
|
|
84
|
+
if (pushIndex >= popLength) {
|
|
85
|
+
cancelablePatches.add(JSON.stringify(pushPatch.path));
|
|
86
|
+
cancelablePatches.add(JSON.stringify(popPatch.path));
|
|
87
|
+
}
|
|
35
88
|
}
|
|
36
89
|
}
|
|
37
|
-
|
|
38
|
-
|
|
90
|
+
return patches.filter((patch) => !cancelablePatches.has(JSON.stringify(patch.path)));
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Cancel patches that are beyond array bounds after final length update
|
|
94
|
+
*/
|
|
95
|
+
function cancelOutOfBoundsPatches(patches) {
|
|
96
|
+
// Find the final length for each array
|
|
97
|
+
const arrayLengths = new Map();
|
|
98
|
+
const canceledPatches = new Set();
|
|
99
|
+
for (const patch of patches) {
|
|
100
|
+
if (Array.isArray(patch.path) &&
|
|
101
|
+
patch.path.length >= 2 &&
|
|
102
|
+
patch.path[patch.path.length - 1] === 'length') {
|
|
103
|
+
const parentPath = JSON.stringify(patch.path.slice(0, -1));
|
|
104
|
+
arrayLengths.set(parentPath, patch.value);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Cancel patches at indices >= final length
|
|
108
|
+
for (const patch of patches) {
|
|
109
|
+
if (!Array.isArray(patch.path) || patch.path.length < 2) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const lastPath = patch.path[patch.path.length - 1];
|
|
113
|
+
const parentPath = JSON.stringify(patch.path.slice(0, -1));
|
|
114
|
+
if (typeof lastPath === 'number' && arrayLengths.has(parentPath)) {
|
|
115
|
+
const length = arrayLengths.get(parentPath);
|
|
116
|
+
if (lastPath >= length) {
|
|
117
|
+
canceledPatches.add(JSON.stringify(patch.path));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return patches.filter((patch) => !canceledPatches.has(JSON.stringify(patch.path)));
|
|
39
122
|
}
|
|
40
123
|
/**
|
|
41
124
|
* Merge two patches on the same path
|
|
@@ -48,19 +131,19 @@ function mergePatches(patch1, patch2) {
|
|
|
48
131
|
if (op1 === op2) {
|
|
49
132
|
// For replace operations, keep the latest value
|
|
50
133
|
if (op1 === 'replace') {
|
|
51
|
-
// Skip if same
|
|
52
|
-
if (
|
|
134
|
+
// Skip if same reference (no-op)
|
|
135
|
+
if (patch1.value === patch2.value) {
|
|
53
136
|
return patch1;
|
|
54
137
|
}
|
|
55
138
|
return patch2;
|
|
56
139
|
}
|
|
57
|
-
// For add operations, if adding
|
|
58
|
-
if (op1 === 'add' &&
|
|
140
|
+
// For add operations, if adding same reference, it's a no-op
|
|
141
|
+
if (op1 === 'add' && patch1.value === patch2.value) {
|
|
59
142
|
return patch1;
|
|
60
143
|
}
|
|
61
|
-
// For remove operations,
|
|
144
|
+
// For remove operations, don't merge (sequential removes should never be merged)
|
|
62
145
|
if (op1 === 'remove') {
|
|
63
|
-
return
|
|
146
|
+
return undefined;
|
|
64
147
|
}
|
|
65
148
|
}
|
|
66
149
|
// Different operations
|
|
@@ -81,43 +164,14 @@ function mergePatches(patch1, patch2) {
|
|
|
81
164
|
return null;
|
|
82
165
|
}
|
|
83
166
|
if (op1 === 'remove' && op2 === 'add') {
|
|
84
|
-
// Remove then add -
|
|
85
|
-
return
|
|
167
|
+
// Remove then add - this is a replace operation
|
|
168
|
+
return {
|
|
169
|
+
op: 'replace',
|
|
170
|
+
path: patch1.path,
|
|
171
|
+
value: patch2.value,
|
|
172
|
+
};
|
|
86
173
|
}
|
|
87
174
|
// Can't merge these operations
|
|
88
175
|
return undefined;
|
|
89
176
|
}
|
|
90
|
-
/**
|
|
91
|
-
* Check if two values are equal (deep comparison)
|
|
92
|
-
*/
|
|
93
|
-
function valuesEqual(val1, val2) {
|
|
94
|
-
if (val1 === val2)
|
|
95
|
-
return true;
|
|
96
|
-
// Handle null/undefined
|
|
97
|
-
if (val1 == null || val2 == null)
|
|
98
|
-
return val1 === val2;
|
|
99
|
-
// Handle arrays
|
|
100
|
-
if (Array.isArray(val1) && Array.isArray(val2)) {
|
|
101
|
-
if (val1.length !== val2.length)
|
|
102
|
-
return false;
|
|
103
|
-
for (let i = 0; i < val1.length; i++) {
|
|
104
|
-
if (!valuesEqual(val1[i], val2[i]))
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
return true;
|
|
108
|
-
}
|
|
109
|
-
// Handle objects
|
|
110
|
-
if (typeof val1 === 'object' && typeof val2 === 'object') {
|
|
111
|
-
const keys1 = Object.keys(val1);
|
|
112
|
-
const keys2 = Object.keys(val2);
|
|
113
|
-
if (keys1.length !== keys2.length)
|
|
114
|
-
return false;
|
|
115
|
-
for (const key of keys1) {
|
|
116
|
-
if (!valuesEqual(val1[key], val2[key]))
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
return false;
|
|
122
|
-
}
|
|
123
177
|
//# sourceMappingURL=optimizer.js.map
|
package/dist/optimizer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"optimizer.js","sourceRoot":"","sources":["../src/optimizer.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAAsB;IACrD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,wDAAwD;IACxD,oEAAoE;IACpE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAe,CAAC;IAEvC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAEtC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,+BAA+B;YAC/B,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"optimizer.js","sourceRoot":"","sources":["../src/optimizer.ts"],"names":[],"mappings":"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"}
|
package/dist/patches.d.ts
CHANGED
|
@@ -14,5 +14,5 @@ export declare function generateAddPatch(state: RecorderState<any>, path: (strin
|
|
|
14
14
|
/**
|
|
15
15
|
* Generate a replace patch for full object/array replacement
|
|
16
16
|
*/
|
|
17
|
-
export declare function generateReplacePatch(state: RecorderState<any>, path: (string | number)[], value: any): void;
|
|
17
|
+
export declare function generateReplacePatch(state: RecorderState<any>, path: (string | number)[], value: any, oldValue?: any): void;
|
|
18
18
|
//# sourceMappingURL=patches.d.ts.map
|
package/dist/patches.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patches.d.ts","sourceRoot":"","sources":["../src/patches.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,YAAY,CAAC;AAI9C;;GAEG;AACH,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,EACzB,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACzB,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"patches.d.ts","sourceRoot":"","sources":["../src/patches.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,YAAY,CAAC;AAI9C;;GAEG;AACH,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,EACzB,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACzB,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,GAAG,QAkBb;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,EACzB,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACzB,QAAQ,EAAE,GAAG,QAiBb;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,QAQhG;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,EACzB,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACzB,KAAK,EAAE,GAAG,EACV,QAAQ,CAAC,EAAE,GAAG,QAkBd"}
|
package/dist/patches.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Operation } from './types.js';
|
|
2
|
-
import { formatPath, cloneIfNeeded } from './utils.js';
|
|
2
|
+
import { formatPath, cloneIfNeeded, findGetItemIdFn } from './utils.js';
|
|
3
3
|
/**
|
|
4
4
|
* Generate a replace patch for property changes
|
|
5
5
|
*/
|
|
@@ -9,6 +9,14 @@ export function generateSetPatch(state, path, oldValue, newValue) {
|
|
|
9
9
|
path: formatPath(path, state.options),
|
|
10
10
|
value: cloneIfNeeded(newValue),
|
|
11
11
|
};
|
|
12
|
+
// Add id if getItemId is configured for this path
|
|
13
|
+
const getItemIdFn = findGetItemIdFn(path, state.options.getItemId);
|
|
14
|
+
if (getItemIdFn && oldValue !== undefined) {
|
|
15
|
+
const id = getItemIdFn(oldValue);
|
|
16
|
+
if (id !== undefined && id !== null) {
|
|
17
|
+
patch.id = id;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
12
20
|
state.patches.push(patch);
|
|
13
21
|
}
|
|
14
22
|
/**
|
|
@@ -19,6 +27,14 @@ export function generateDeletePatch(state, path, oldValue) {
|
|
|
19
27
|
op: Operation.Remove,
|
|
20
28
|
path: formatPath(path, state.options),
|
|
21
29
|
};
|
|
30
|
+
// Add id if getItemId is configured for this path
|
|
31
|
+
const getItemIdFn = findGetItemIdFn(path, state.options.getItemId);
|
|
32
|
+
if (getItemIdFn && oldValue !== undefined) {
|
|
33
|
+
const id = getItemIdFn(oldValue);
|
|
34
|
+
if (id !== undefined && id !== null) {
|
|
35
|
+
patch.id = id;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
22
38
|
state.patches.push(patch);
|
|
23
39
|
}
|
|
24
40
|
/**
|
|
@@ -35,12 +51,20 @@ export function generateAddPatch(state, path, value) {
|
|
|
35
51
|
/**
|
|
36
52
|
* Generate a replace patch for full object/array replacement
|
|
37
53
|
*/
|
|
38
|
-
export function generateReplacePatch(state, path, value) {
|
|
54
|
+
export function generateReplacePatch(state, path, value, oldValue) {
|
|
39
55
|
const patch = {
|
|
40
56
|
op: Operation.Replace,
|
|
41
57
|
path: formatPath(path, state.options),
|
|
42
58
|
value: cloneIfNeeded(value),
|
|
43
59
|
};
|
|
60
|
+
// Add id if getItemId is configured for this path
|
|
61
|
+
const getItemIdFn = findGetItemIdFn(path, state.options.getItemId);
|
|
62
|
+
if (getItemIdFn && oldValue !== undefined) {
|
|
63
|
+
const id = getItemIdFn(oldValue);
|
|
64
|
+
if (id !== undefined && id !== null) {
|
|
65
|
+
patch.id = id;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
44
68
|
state.patches.push(patch);
|
|
45
69
|
}
|
|
46
70
|
//# sourceMappingURL=patches.js.map
|
package/dist/patches.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patches.js","sourceRoot":"","sources":["../src/patches.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,SAAS,EAAC,MAAM,YAAY,CAAC;AACrC,OAAO,EAAC,UAAU,EAAE,aAAa,EAAC,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"patches.js","sourceRoot":"","sources":["../src/patches.ts"],"names":[],"mappings":"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"}
|
package/dist/proxy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,YAAY,CAAC;AAO9C,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAC3C,MAAM,EAAE,CAAC,EACT,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACzB,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,GACvB,CAAC,
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,YAAY,CAAC;AAO9C,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAC3C,MAAM,EAAE,CAAC,EACT,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACzB,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,GACvB,CAAC,CAqKH"}
|
package/dist/proxy.js
CHANGED
|
@@ -49,7 +49,8 @@ export function createProxy(target, path, state) {
|
|
|
49
49
|
const propForPath = typeof prop === 'string' && !isNaN(Number(prop)) ? Number(prop) : prop;
|
|
50
50
|
const propPath = [...path, propForPath];
|
|
51
51
|
// Skip if no actual change (handle undefined as a valid value)
|
|
52
|
-
|
|
52
|
+
// Use Object.is to correctly handle NaN (NaN !== NaN, but Object.is(NaN, NaN) === true)
|
|
53
|
+
if (Object.is(oldValue, value) &&
|
|
53
54
|
(value !== undefined || Object.prototype.hasOwnProperty.call(obj, prop))) {
|
|
54
55
|
return true;
|
|
55
56
|
}
|
|
@@ -65,8 +66,23 @@ export function createProxy(target, path, state) {
|
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
if (currentOriginal && currentOriginal !== undefined && currentOriginal !== null) {
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
// For arrays, check if the index is within the array length (handles sparse arrays correctly)
|
|
70
|
+
if (Array.isArray(currentOriginal)) {
|
|
71
|
+
// Convert prop to number if it's a numeric string
|
|
72
|
+
const index = typeof prop === 'string' && !isNaN(Number(prop)) ? Number(prop) : prop;
|
|
73
|
+
if (typeof index === 'number') {
|
|
74
|
+
originalHasProperty = index >= 0 && index < currentOriginal.length;
|
|
75
|
+
originalValue = currentOriginal[index];
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
originalHasProperty = Object.prototype.hasOwnProperty.call(currentOriginal, prop);
|
|
79
|
+
originalValue = currentOriginal[prop];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
originalHasProperty = Object.prototype.hasOwnProperty.call(currentOriginal, prop);
|
|
84
|
+
originalValue = currentOriginal[prop];
|
|
85
|
+
}
|
|
70
86
|
}
|
|
71
87
|
// Mutate original immediately
|
|
72
88
|
obj[prop] = value;
|
package/dist/proxy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,gBAAgB,EAAE,mBAAmB,EAAE,gBAAgB,EAAC,MAAM,cAAc,CAAC;AACrF,OAAO,EAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAC,MAAM,YAAY,CAAC;AACjD,OAAO,EAAC,cAAc,EAAC,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAC,YAAY,EAAC,MAAM,WAAW,CAAC;AACvC,OAAO,EAAC,YAAY,EAAC,MAAM,WAAW,CAAC;AAEvC,MAAM,UAAU,WAAW,CAC1B,MAAS,EACT,IAAyB,EACzB,KAAyB;IAEzB,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAEhC,MAAM,OAAO,GAAoB;QAChC,GAAG,CAAC,GAAG,EAAE,IAAI;YACZ,uBAAuB;YACvB,IAAI,WAAW,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7C,OAAO,cAAc,CAAC,GAAY,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YACxD,CAAC;YAED,qBAAqB;YACrB,IAAI,SAAS,EAAE,CAAC;gBACf,OAAO,YAAY,CAAC,GAAoB,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YAC9D,CAAC;YAED,qBAAqB;YACrB,IAAI,SAAS,EAAE,CAAC;gBACf,OAAO,YAAY,CAAC,GAAe,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YACzD,CAAC;YAED,yBAAyB;YACzB,MAAM,KAAK,GAAI,GAAW,CAAC,IAAI,CAAC,CAAC;YAEjC,+DAA+D;YAC/D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACjD,OAAO,KAAK,CAAC;YACd,CAAC;YAED,2CAA2C;YAC3C,qDAAqD;YACrD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC1D,OAAO,WAAW,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;QAED,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK;YACnB,uDAAuD;YACvD,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;YAC5E,CAAC;YAED,MAAM,QAAQ,GAAI,GAAW,CAAC,IAAI,CAAC,CAAC;YAEpC,2DAA2D;YAC3D,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACzD,GAAW,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;gBAC3B,OAAO,IAAI,CAAC;YACb,CAAC;YAED,4DAA4D;YAC5D,MAAM,WAAW,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC3F,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAC;YAExC,+DAA+D;YAC/D,IACC,QAAQ,KAAK,
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -14,11 +14,26 @@ export type PatchesOptions = boolean | {
|
|
|
14
14
|
*/
|
|
15
15
|
arrayLengthAssignment?: boolean;
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Function that extracts an ID from an item value
|
|
19
|
+
*/
|
|
20
|
+
export type GetItemIdFunction = (value: any) => string | number | undefined | null;
|
|
21
|
+
/**
|
|
22
|
+
* Recursive configuration for getItemId - can be a function or nested object
|
|
23
|
+
*/
|
|
24
|
+
export type GetItemIdConfig = {
|
|
25
|
+
[key: string]: GetItemIdFunction | GetItemIdConfig;
|
|
26
|
+
};
|
|
17
27
|
export interface IPatch {
|
|
18
28
|
op: PatchOp;
|
|
19
29
|
value?: any;
|
|
30
|
+
/**
|
|
31
|
+
* Optional ID of the item being removed or replaced.
|
|
32
|
+
* Populated when getItemId option is configured for the item's parent path.
|
|
33
|
+
*/
|
|
34
|
+
id?: string | number;
|
|
20
35
|
}
|
|
21
|
-
export type Patch<P extends PatchesOptions =
|
|
36
|
+
export type Patch<P extends PatchesOptions = true> = P extends {
|
|
22
37
|
pathAsArray: false;
|
|
23
38
|
} ? IPatch & {
|
|
24
39
|
path: string;
|
|
@@ -27,7 +42,7 @@ export type Patch<P extends PatchesOptions = any> = P extends {
|
|
|
27
42
|
} : IPatch & {
|
|
28
43
|
path: string | (string | number)[];
|
|
29
44
|
};
|
|
30
|
-
export type Patches<P extends PatchesOptions =
|
|
45
|
+
export type Patches<P extends PatchesOptions = true> = Patch<P>[];
|
|
31
46
|
export type NonPrimitive = object | Array<unknown>;
|
|
32
47
|
export interface RecordPatchesOptions {
|
|
33
48
|
/**
|
|
@@ -39,9 +54,27 @@ export interface RecordPatchesOptions {
|
|
|
39
54
|
*/
|
|
40
55
|
arrayLengthAssignment?: boolean;
|
|
41
56
|
/**
|
|
42
|
-
*
|
|
57
|
+
* Compress patches by merging redundant operations (default: true)
|
|
58
|
+
*/
|
|
59
|
+
compressPatches?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Configuration for extracting item IDs for remove/replace patches.
|
|
62
|
+
* Maps paths to functions that extract IDs from item values.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* recordPatches(state, mutate, {
|
|
67
|
+
* getItemId: {
|
|
68
|
+
* items: (item) => item.id,
|
|
69
|
+
* users: (user) => user.userId,
|
|
70
|
+
* nested: {
|
|
71
|
+
* array: (item) => item._id
|
|
72
|
+
* }
|
|
73
|
+
* }
|
|
74
|
+
* });
|
|
75
|
+
* ```
|
|
43
76
|
*/
|
|
44
|
-
|
|
77
|
+
getItemId?: GetItemIdConfig;
|
|
45
78
|
}
|
|
46
79
|
export type Draft<T> = T;
|
|
47
80
|
export interface RecorderState<T> {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS;;;;CAIZ,CAAC;AAEX,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAEjE,MAAM,MAAM,cAAc,GACvB,OAAO,GACP;IACA;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC;AAEL,MAAM,WAAW,MAAM;IACtB,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS;;;;CAIZ,CAAC;AAEX,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAEjE,MAAM,MAAM,cAAc,GACvB,OAAO,GACP;IACA;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC;AAEL;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;AAEnF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,GAAG,eAAe,CAAC;CACnD,CAAC;AAEF,MAAM,WAAW,MAAM;IACtB,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,cAAc,GAAG,IAAI,IAAI,CAAC,SAAS;IAC9D,WAAW,EAAE,KAAK,CAAC;CACnB,GACE,MAAM,GAAG;IACT,IAAI,EAAE,MAAM,CAAC;CACb,GACA,CAAC,SAAS,IAAI,GAAG,MAAM,GACtB,MAAM,GAAG;IACT,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;CAC1B,GACA,MAAM,GAAG;IACT,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;CACnC,CAAC;AAEL,MAAM,MAAM,OAAO,CAAC,CAAC,SAAS,cAAc,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAElE,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;AAEnD,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;AAEzB,MAAM,WAAW,aAAa,CAAC,CAAC;IAC/B,QAAQ,EAAE,CAAC,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACtB,QAAQ,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC9B,OAAO,EAAE,oBAAoB,GAAG;QAAC,sBAAsB,EAAE,cAAc,CAAA;KAAC,CAAC;CACzE"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PatchesOptions } from './types.js';
|
|
1
|
+
import type { PatchesOptions, GetItemIdConfig, GetItemIdFunction } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Type guard to check if a value is a plain object (not null, not array, not Map/Set)
|
|
4
4
|
*/
|
|
@@ -30,4 +30,14 @@ export declare function isEqual(a: unknown, b: unknown): boolean;
|
|
|
30
30
|
* This is needed for patch values to avoid reference issues
|
|
31
31
|
*/
|
|
32
32
|
export declare function cloneIfNeeded<T>(value: T): T;
|
|
33
|
+
/**
|
|
34
|
+
* Find a getItemId function for a given path.
|
|
35
|
+
* The function is looked up by traversing the getItemId config object
|
|
36
|
+
* using the parent path (all elements except the last one).
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // For path ['items', 3] with config { items: (item) => item.id }
|
|
40
|
+
* // Returns the function (item) => item.id
|
|
41
|
+
*/
|
|
42
|
+
export declare function findGetItemIdFn(path: (string | number)[], getItemIdConfig: GetItemIdConfig | undefined): GetItemIdFunction | undefined;
|
|
33
43
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAC,MAAM,YAAY,CAAC;AAEnF;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzE;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,EAAE,CAE1D;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAEpE;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,CAE3D;AAED;;GAEG;AACH,wBAAgB,UAAU,CACzB,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACzB,OAAO,EAAE;IAAC,sBAAsB,EAAE,cAAc,CAAA;CAAC,GAC/C,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAgB9B;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CA2CvD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAmC5C;AAED;;;;;;;;MAQG;AACH,wBAAgB,eAAe,CAC9B,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACzB,eAAe,EAAE,eAAe,GAAG,SAAS,GAC1C,iBAAiB,GAAG,SAAS,CAwC/B"}
|
package/dist/utils.js
CHANGED
|
@@ -33,15 +33,13 @@ export function formatPath(path, options) {
|
|
|
33
33
|
if (options.internalPatchesOptions &&
|
|
34
34
|
typeof options.internalPatchesOptions === 'object' &&
|
|
35
35
|
options.internalPatchesOptions.pathAsArray === false) {
|
|
36
|
-
// Convert to JSON Pointer string format
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
})
|
|
44
|
-
.join('');
|
|
36
|
+
// Convert to JSON Pointer string format (RFC 6901)
|
|
37
|
+
if (path.length === 0) {
|
|
38
|
+
return '';
|
|
39
|
+
}
|
|
40
|
+
return '/' + path
|
|
41
|
+
.map((part) => String(part).replace(/~/g, '~0').replace(/\//g, '~1'))
|
|
42
|
+
.join('/');
|
|
45
43
|
}
|
|
46
44
|
return path;
|
|
47
45
|
}
|
|
@@ -129,4 +127,45 @@ export function cloneIfNeeded(value) {
|
|
|
129
127
|
}
|
|
130
128
|
return cloned;
|
|
131
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Find a getItemId function for a given path.
|
|
132
|
+
* The function is looked up by traversing the getItemId config object
|
|
133
|
+
* using the parent path (all elements except the last one).
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* // For path ['items', 3] with config { items: (item) => item.id }
|
|
137
|
+
* // Returns the function (item) => item.id
|
|
138
|
+
*/
|
|
139
|
+
export function findGetItemIdFn(path, getItemIdConfig) {
|
|
140
|
+
if (!getItemIdConfig || path.length === 0) {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
// We want to match the parent path (all elements except the last one)
|
|
144
|
+
// For path ['items', 3], we want to find config at 'items'
|
|
145
|
+
// For path ['user', 'settings', 'darkMode'], we want to find config at ['user', 'settings']
|
|
146
|
+
const parentPath = path.slice(0, -1);
|
|
147
|
+
if (parentPath.length === 0) {
|
|
148
|
+
// The path is directly under root (e.g., ['items'])
|
|
149
|
+
// In this case, there's no parent to match against
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
// Navigate the config object using the parent path
|
|
153
|
+
let current = getItemIdConfig;
|
|
154
|
+
for (let i = 0; i < parentPath.length; i++) {
|
|
155
|
+
const key = parentPath[i];
|
|
156
|
+
// Skip numeric indices (array positions) in the path
|
|
157
|
+
if (typeof key === 'number') {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (current === undefined || typeof current !== 'object') {
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
current = current[key];
|
|
164
|
+
}
|
|
165
|
+
// current should now be a function or undefined
|
|
166
|
+
if (typeof current === 'function') {
|
|
167
|
+
return current;
|
|
168
|
+
}
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
132
171
|
//# sourceMappingURL=utils.js.map
|