j-templates 8.2.0 → 9.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/Store/Diff/diffTree.d.ts +24 -49
- package/Store/Diff/diffTree.js +112 -511
- package/Store/Diff/index.d.ts +1 -0
- package/Store/Diff/index.js +1 -0
- package/Store/Diff/utils/diffTree.types.d.ts +6 -1
- package/Store/Diff/utils/homes.d.ts +46 -0
- package/Store/Diff/utils/homes.js +213 -0
- package/Store/Diff/utils/paths.d.ts +42 -0
- package/Store/Diff/utils/paths.js +87 -0
- package/Store/Diff/utils/projections.d.ts +55 -0
- package/Store/Diff/utils/projections.js +290 -0
- package/Store/Diff/utils/routes.d.ts +27 -0
- package/Store/Diff/utils/routes.js +168 -0
- package/Store/Diff/utils/state.d.ts +56 -0
- package/Store/Diff/utils/state.js +155 -0
- package/Store/Store/store.d.ts +8 -0
- package/Store/Store/store.js +13 -0
- package/Store/Store/storeAsync.js +7 -6
- package/Store/Store/storeSync.js +3 -3
- package/Store/Tree/observableNode.js +18 -15
- package/Store/Tree/snapshot.d.ts +19 -21
- package/Store/Tree/snapshot.js +29 -23
- package/Utils/json.d.ts +166 -26
- package/Utils/json.js +510 -183
- package/package.json +1 -1
- package/Store/Diff/utils/diffTree.utils.d.ts +0 -79
- package/Store/Diff/utils/diffTree.utils.js +0 -398
package/Utils/json.d.ts
CHANGED
|
@@ -3,17 +3,73 @@ export type JsonWrite = {
|
|
|
3
3
|
path: (string | number)[];
|
|
4
4
|
value: unknown;
|
|
5
5
|
};
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
/** Removes the property the path ends with from the object holding it */
|
|
7
|
+
export type JsonDelete = {
|
|
8
|
+
type: "delete";
|
|
8
9
|
path: (string | number)[];
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
};
|
|
11
|
+
/** How an inserted splice item gets its value */
|
|
12
|
+
export declare enum SPLICE_ACTION {
|
|
13
|
+
/** The element at `from` in the array before the splice is applied */
|
|
14
|
+
MOVE = 1,
|
|
15
|
+
/** A new value */
|
|
16
|
+
INSERT = 2
|
|
17
|
+
}
|
|
18
|
+
export type JsonSpliceItem = {
|
|
19
|
+
type: SPLICE_ACTION.MOVE;
|
|
20
|
+
from: number;
|
|
21
|
+
} | {
|
|
22
|
+
type: SPLICE_ACTION.INSERT;
|
|
23
|
+
value: unknown;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* One `Array.prototype.splice` call. Splices are applied in order, so `index` is a position in the
|
|
27
|
+
* array as the splices before it left it. A moved item's `from` is an index in the array before any
|
|
28
|
+
* splice was applied.
|
|
29
|
+
*/
|
|
30
|
+
export type JsonSplice = {
|
|
31
|
+
index: number;
|
|
32
|
+
delete: number;
|
|
33
|
+
insert: JsonSpliceItem[];
|
|
34
|
+
};
|
|
35
|
+
/** The splices that turn the array at `path` into its new value */
|
|
36
|
+
export type JsonSpliceRecord = {
|
|
37
|
+
type: "splice";
|
|
38
|
+
path: (string | number)[];
|
|
39
|
+
splices: JsonSplice[];
|
|
11
40
|
};
|
|
12
41
|
/**
|
|
13
42
|
* Result of a JSON diff operation, containing paths and values that changed.
|
|
14
43
|
* @template T - The type of the JSON value being diffed
|
|
15
44
|
*/
|
|
16
|
-
export type JsonDiffResult<T = unknown> = (
|
|
45
|
+
export type JsonDiffResult<T = unknown> = (JsonWrite | JsonDelete | JsonSpliceRecord)[];
|
|
46
|
+
/**
|
|
47
|
+
* How JsonDiff handles an object or array that changed:
|
|
48
|
+
* - `"diff"`: walk into it. An array is diffed by position.
|
|
49
|
+
* - `"splice"`: arrays only. Diff it as splices that match elements by the diff's identity (see
|
|
50
|
+
* JsonDiffIdentityFunc), without walking into them. Anything else is diffed as `"diff"`.
|
|
51
|
+
* - `"skip"`: record nothing for it.
|
|
52
|
+
* - `"write"`: write the new value as is.
|
|
53
|
+
*/
|
|
54
|
+
export type JsonDiffStrategy = "diff" | "splice" | "skip" | "write";
|
|
55
|
+
/**
|
|
56
|
+
* Chooses how JsonDiff handles a changed object or array, given the new value, the old one (of any
|
|
57
|
+
* type) and the path they're at. Returning undefined means `"diff"`. It isn't called for primitives. `path` is the diff's own, so it
|
|
58
|
+
* must not be kept or changed.
|
|
59
|
+
*/
|
|
60
|
+
export type JsonDiffStrategyFunc = (newValue: any, oldValue: any, path: readonly (string | number)[]) => JsonDiffStrategy | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* What a spliced array's element is compared by: two elements whose identities are === are the same
|
|
63
|
+
* element, so it's matched and never diffed into. It's called for elements of any type, primitives
|
|
64
|
+
* included, but not to compare two elements that are already ===, so it must give the same identity
|
|
65
|
+
* for the same value. When two different elements share an identity, they're treated as the same
|
|
66
|
+
* element; avoiding that is up to the function.
|
|
67
|
+
*/
|
|
68
|
+
export type JsonDiffIdentityFunc = (value: any) => unknown;
|
|
69
|
+
/** The default strategy: every changed object and array is diffed into, arrays by position */
|
|
70
|
+
export declare const JsonDiffDefaultStrategy: JsonDiffStrategyFunc;
|
|
71
|
+
/** The default identity: an element is its own identity, so elements are compared by === */
|
|
72
|
+
export declare const JsonDiffDefaultIdentity: JsonDiffIdentityFunc;
|
|
17
73
|
/**
|
|
18
74
|
* Determines the JSON type of a value.
|
|
19
75
|
* @param value - The value to check
|
|
@@ -38,37 +94,121 @@ export declare function JsonMerge(source: unknown, patch: unknown): unknown;
|
|
|
38
94
|
*/
|
|
39
95
|
export declare function JsonDeepClone<T>(value: T, type?: string): T;
|
|
40
96
|
/**
|
|
41
|
-
* Applies a diff result to a root value in place
|
|
42
|
-
*
|
|
43
|
-
*
|
|
97
|
+
* Applies a diff result to a root value in place, one record at a time in order. A diff doesn't own
|
|
98
|
+
* its values (see JsonDiff), so each value written or inserted is deep-cloned first: the root never
|
|
99
|
+
* shares an object with the diff, the value it was computed from, or another record, unless
|
|
100
|
+
* `clone` says otherwise.
|
|
101
|
+
* - A write assigns its value at its path
|
|
102
|
+
* - A delete removes the property its path ends with
|
|
103
|
+
* - A splice record splices the array at its path in place (see JsonApplySplices)
|
|
104
|
+
* @param root - The value to update; must be an object or array
|
|
105
|
+
* @param diff - The diff result to apply
|
|
44
106
|
* @param assign - Assigns a written value (already cloned) to its parent
|
|
45
|
-
* @param
|
|
46
|
-
*
|
|
107
|
+
* @param remove - Removes a deleted property from its parent
|
|
108
|
+
* @param spliced - Called with each array a splice record changed, after it's changed
|
|
109
|
+
* @param clone - Copies each value before it's written or inserted. A caller that already owns the
|
|
110
|
+
* diff's values can pass one that keeps them, or parts of them, as they are.
|
|
111
|
+
* @throws For a write or delete with an empty path: the root can't be replaced or removed, only
|
|
112
|
+
* changed inside. JsonDiff records one only when the root's JSON type changes.
|
|
47
113
|
*/
|
|
48
|
-
export declare function JsonApplyDiff(root: any, diff: JsonDiffResult, assign?: (parent: any, prop: string | number, value: any) => void): void;
|
|
114
|
+
export declare function JsonApplyDiff(root: any, diff: JsonDiffResult, assign?: (parent: any, prop: string | number, value: any) => void, remove?: (parent: any, prop: string | number) => void, spliced?: (array: unknown[]) => void, clone?: (value: unknown) => unknown): void;
|
|
49
115
|
/**
|
|
50
|
-
* Applies
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* @param
|
|
56
|
-
* @
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
116
|
+
* Applies splices to an array in place, in one pass however many there are: the new contents are
|
|
117
|
+
* built from the old ones, then written back into the same array. A moved item is the old element
|
|
118
|
+
* at its `from`, as is; an inserted item's value is deep-cloned.
|
|
119
|
+
* @param splices - In ascending, non-overlapping order, as JsonDiffArraySplice returns them: each
|
|
120
|
+
* one's index is at or after where the one before it ended
|
|
121
|
+
* @param clone - Copies each inserted value; see JsonApplyDiff
|
|
122
|
+
* @throws When a splice starts before the one before it ended
|
|
123
|
+
*/
|
|
124
|
+
export declare function JsonApplySplices(array: unknown[], splices: readonly JsonSplice[], clone?: (value: unknown) => unknown): void;
|
|
125
|
+
/**
|
|
126
|
+
* Whether two JSON values differ, without recording how: it stops at the first difference and
|
|
127
|
+
* skips any subtree both values share, so it costs no more than walking what differs. An
|
|
128
|
+
* undefined property counts as absent, as in JSON. Arrays are compared by position.
|
|
129
|
+
* @param newValue - The new value
|
|
130
|
+
* @param oldValue - The old value to compare against
|
|
131
|
+
* @returns true when the values differ
|
|
60
132
|
*/
|
|
61
|
-
export declare function
|
|
133
|
+
export declare function JsonHasChanges(newValue: unknown, oldValue: unknown): boolean;
|
|
134
|
+
/**
|
|
135
|
+
* `newValue`, with every part that has no changes from the same place in `oldValue` (as
|
|
136
|
+
* JsonHasChanges compares them) replaced by `oldValue`'s object, so unchanged parts keep their
|
|
137
|
+
* identity. Neither value is changed: a container of `newValue` is copied only when one of its
|
|
138
|
+
* children is replaced, and kept as it is otherwise. Arrays are compared by position.
|
|
139
|
+
*
|
|
140
|
+
* old: { a: { x: 1 }, b: { y: 1 } }
|
|
141
|
+
* new: { a: { x: 1 }, b: { y: 2 } }
|
|
142
|
+
* result: { a: old.a, b: new.b }, a new object
|
|
143
|
+
*
|
|
144
|
+
* @param newValue - The new value
|
|
145
|
+
* @param oldValue - The value whose objects are kept where nothing changed
|
|
146
|
+
* @returns `oldValue` itself when nothing changed, otherwise `newValue` or a copy of it holding
|
|
147
|
+
* `oldValue`'s unchanged parts
|
|
148
|
+
*/
|
|
149
|
+
export declare function JsonMaintainUnchanged<T>(newValue: T, oldValue: unknown): T;
|
|
150
|
+
/** Sets a key as an own property, even `__proto__`, which plain assignment would make the prototype */
|
|
151
|
+
export declare function SetOwnProperty(target: {
|
|
152
|
+
[key: string]: unknown;
|
|
153
|
+
}, key: string, value: unknown): void;
|
|
62
154
|
/**
|
|
63
155
|
* Computes the differences between two JSON values.
|
|
64
|
-
* Returns an array of paths and values that changed from oldValue to newValue. A
|
|
156
|
+
* Returns an array of paths and values that changed from oldValue to newValue. A value is only
|
|
157
|
+
* written whole where its JSON type changes (or a strategy says so); an object or array of the
|
|
158
|
+
* same type is always diffed into, however much of it changed. So the root itself is only ever
|
|
159
|
+
* written when its type changes, and a diff of values of the same type can always be applied
|
|
160
|
+
* in place. A record doesn't
|
|
65
161
|
* own its value: it references `newValue`'s objects, so two records can share one, and
|
|
66
162
|
* JsonApplyDiff clones each value as it's applied.
|
|
67
163
|
* @template T - The type of the JSON values being compared
|
|
68
164
|
* @param newValue - The new value
|
|
69
165
|
* @param oldValue - The old value to compare against
|
|
70
|
-
* @param rootPath - Optional dot-separated string for the base path
|
|
71
|
-
* @param
|
|
166
|
+
* @param rootPath - Optional dot-separated string for the base path
|
|
167
|
+
* @param strategy - Optional choice of how each changed object or array is diffed; without one,
|
|
168
|
+
* everything is diffed by walking into it, arrays by position
|
|
169
|
+
* @param identity - Optional identity a spliced array's elements are compared by; without one,
|
|
170
|
+
* elements are compared by ===. See JsonDiffIdentityFunc
|
|
72
171
|
* @returns Array of change records with path and new value
|
|
73
172
|
*/
|
|
74
|
-
export declare function JsonDiff<T>(newValue: T, oldValue: T, rootPath?: string,
|
|
173
|
+
export declare function JsonDiff<T>(newValue: T, oldValue: T, rootPath?: string, strategy?: JsonDiffStrategyFunc, identity?: JsonDiffIdentityFunc): JsonDiffResult<T>;
|
|
174
|
+
/**
|
|
175
|
+
* Appends the differences between two JSON values to `result`, so several values can be diffed into
|
|
176
|
+
* one result.
|
|
177
|
+
* @param path - The path the values are at
|
|
178
|
+
* @param strategy - See JsonDiff
|
|
179
|
+
* @param identity - See JsonDiff
|
|
180
|
+
* @returns The result
|
|
181
|
+
*/
|
|
182
|
+
export declare function JsonDiffInto<T>(newValue: T, oldValue: T, path: (string | number)[], result: JsonDiffResult<T>, strategy?: JsonDiffStrategyFunc, identity?: JsonDiffIdentityFunc): JsonDiffResult<T>;
|
|
183
|
+
/**
|
|
184
|
+
* The splices that turn `oldValue` into `newValue`, matching elements by identity without walking
|
|
185
|
+
* into them: two elements are the same when their identities are ===. With the default identity,
|
|
186
|
+
* that's the elements themselves. A matched element is never diffed into, even when it isn't === to
|
|
187
|
+
* its match. An identity that repeats is matched in order, and a repeat with no old element left to
|
|
188
|
+
* match is inserted.
|
|
189
|
+
*
|
|
190
|
+
* It works in four stages, followed through this example in the comments below:
|
|
191
|
+
*
|
|
192
|
+
* old: [A, B, C, D, E, F]
|
|
193
|
+
* new: [A, E, B, X, D, F]
|
|
194
|
+
*
|
|
195
|
+
* 1. Trim the elements identical at the start and end (A and F): they can't need a change.
|
|
196
|
+
* 2. Match each remaining new element to the old index holding the same element, or -1.
|
|
197
|
+
* 3. Choose which matched elements stay in place: the longest run of them still in their old
|
|
198
|
+
* order (B, D). Keeping the longest run is what keeps the number of moves as small as possible.
|
|
199
|
+
* 4. Walk both arrays from kept element to kept element. Between two kept elements, delete the
|
|
200
|
+
* old elements that aren't kept (C, E) and insert the new ones that aren't (E as a move, X as
|
|
201
|
+
* a new value).
|
|
202
|
+
*
|
|
203
|
+
* @returns The splices, in the order to apply them; none when the arrays hold the same elements.
|
|
204
|
+
* Applied in order to [A, B, C, D, E, F], with each move read from the array before any splice:
|
|
205
|
+
*
|
|
206
|
+
* splice(1, 0, E) [A, E, B, C, D, E, F]
|
|
207
|
+
* splice(3, 1, X) [A, E, B, X, D, E, F]
|
|
208
|
+
* splice(5, 1) [A, E, B, X, D, F]
|
|
209
|
+
*
|
|
210
|
+
* @param identity - What elements are compared by; see JsonDiffIdentityFunc. Elements that are
|
|
211
|
+
* === are the same element without calling it, and it's called at most a few times for each
|
|
212
|
+
* other element, so it must give the same identity for the same value.
|
|
213
|
+
*/
|
|
214
|
+
export declare function JsonDiffArraySplice(newValue: readonly unknown[], oldValue: readonly unknown[], identity?: JsonDiffIdentityFunc): JsonSplice[];
|