j-templates 8.0.14 → 8.0.16
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 +1 -1
- package/Store/Diff/diffTree.js +27 -6
- package/package.json +1 -1
package/Store/Diff/diffTree.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export interface IDiffTreeConstructor {
|
|
|
39
39
|
* positionally in the same order, so each parameter can be typed at the call site instead of
|
|
40
40
|
* cast out of a generic read.
|
|
41
41
|
*/
|
|
42
|
-
export type DiffTreeProjectionFunc = (...values: any[]) => any;
|
|
42
|
+
export type DiffTreeProjectionFunc = (keys: string[], ...values: any[]) => any;
|
|
43
43
|
/**
|
|
44
44
|
* A projection's declaration: the dot-separated paths it reads (a plain tree path, an
|
|
45
45
|
* entity's key, or another projection's `$projection_<id>` key for chaining) and the
|
package/Store/Diff/diffTree.js
CHANGED
|
@@ -160,7 +160,14 @@ function BuildProjectionOrder(projections) {
|
|
|
160
160
|
throw new Error(`DiffTree projection "${id}" is not defined`);
|
|
161
161
|
state.set(id, "visiting");
|
|
162
162
|
for (let x = 0; x < def.reads.length; x++) {
|
|
163
|
-
const
|
|
163
|
+
const read = def.reads[x];
|
|
164
|
+
const root = read.split(".", 1)[0];
|
|
165
|
+
if (root.endsWith("*") && x !== def.reads.length - 1)
|
|
166
|
+
throw `Wildcard reads only supported as the final read: ${root}`;
|
|
167
|
+
if (root.endsWith("*") && root.includes("."))
|
|
168
|
+
throw `Wildcard reads do not support dot nesting: ${root}`;
|
|
169
|
+
if (root.startsWith(PROJECTION_PREFIX) && read.endsWith("*"))
|
|
170
|
+
throw `Projection keys do not support wildcard reads: ${root}`;
|
|
164
171
|
if (root.startsWith(PROJECTION_PREFIX))
|
|
165
172
|
Visit(root.slice(PROJECTION_PREFIX.length), stack.concat(id));
|
|
166
173
|
}
|
|
@@ -203,17 +210,31 @@ function RunProjections(source, keyFunc, projections, memo) {
|
|
|
203
210
|
const diffResult = [];
|
|
204
211
|
for (let x = 0; x < projections.length; x++) {
|
|
205
212
|
const { id, reads, projection } = projections[x];
|
|
206
|
-
const values =
|
|
213
|
+
const values = [];
|
|
214
|
+
const keys = [];
|
|
207
215
|
let allPathsExist = true;
|
|
208
|
-
|
|
209
|
-
|
|
216
|
+
let y = 0;
|
|
217
|
+
for (; allPathsExist && y < reads.length && !reads[y].endsWith("*"); y++) {
|
|
218
|
+
const read = reads[y];
|
|
219
|
+
const [value, found] = GetPathValue(source, read);
|
|
210
220
|
allPathsExist = found;
|
|
211
|
-
|
|
221
|
+
keys.push(read);
|
|
222
|
+
values.push((found && CreateSnapshot(source, keyFunc, value)) || value);
|
|
223
|
+
}
|
|
224
|
+
if (y < reads.length && reads[y].endsWith("*")) {
|
|
225
|
+
const prefix = reads[y].slice(0, reads[y].length - 1);
|
|
226
|
+
const matchedKeys = Object.keys(source).filter(key => key.startsWith(prefix));
|
|
227
|
+
for (let z = 0; z < matchedKeys.length; z++) {
|
|
228
|
+
const [value, found] = GetPathValue(source, matchedKeys[z]);
|
|
229
|
+
allPathsExist = allPathsExist && found;
|
|
230
|
+
keys.push(matchedKeys[z]);
|
|
231
|
+
values.push((found && CreateSnapshot(source, keyFunc, value)) || value);
|
|
232
|
+
}
|
|
212
233
|
}
|
|
213
234
|
if (allPathsExist) {
|
|
214
235
|
const priorValues = memo.get(id);
|
|
215
236
|
if (!ArraysEqual(priorValues, values)) {
|
|
216
|
-
const result = projection(...values);
|
|
237
|
+
const result = projection(keys, ...values);
|
|
217
238
|
memo.set(id, values);
|
|
218
239
|
// The same diff-and-apply UpdateSource uses for any other write, so a keyed entity
|
|
219
240
|
// embedded in a projection's result is flattened to its own root like any other write,
|