@forestadmin/datasource-customizer 1.5.0 → 1.5.2
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.
|
@@ -7,30 +7,32 @@ const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
|
7
7
|
const deduplication_1 = __importDefault(require("../utils/deduplication"));
|
|
8
8
|
const flattener_1 = require("../utils/flattener");
|
|
9
9
|
async function computeField(ctx, computed, paths, promises) {
|
|
10
|
-
return (0, deduplication_1.default)((0, flattener_1.unflatten)(await Promise.all(promises),
|
|
10
|
+
return (0, deduplication_1.default)((0, flattener_1.unflatten)(await Promise.all(promises), paths), async (uniquePartials) => computed.getValues(uniquePartials, ctx));
|
|
11
11
|
}
|
|
12
12
|
function queueField(ctx, collection, newPath, paths, promises) {
|
|
13
13
|
// Skip double computations (we're not checking before adding to queue).
|
|
14
14
|
if (!paths.includes(newPath)) {
|
|
15
15
|
const computed = collection.getComputed(newPath);
|
|
16
|
-
const
|
|
16
|
+
const computedDependencies = (0, flattener_1.withNullMarkers)(computed.dependencies);
|
|
17
|
+
const nestedDependencies = new datasource_toolkit_1.Projection(...computedDependencies).nest(newPath.includes(':') ? newPath.substring(0, newPath.lastIndexOf(':')) : null);
|
|
17
18
|
// Queue dependencies (so that computed can await them).
|
|
18
19
|
nestedDependencies.forEach(path => queueField(ctx, collection, path, paths, promises));
|
|
19
20
|
// Queue computed
|
|
20
21
|
const dependencyValues = nestedDependencies.map(path => promises[paths.indexOf(path)]);
|
|
21
22
|
paths.push(newPath);
|
|
22
|
-
promises.push(computeField(ctx, computed,
|
|
23
|
+
promises.push(computeField(ctx, computed, computedDependencies, dependencyValues));
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
async function computeFromRecords(ctx, collection, recordsProjection, desiredProjection, records) {
|
|
26
27
|
// Format data for easy computation (one cell per path, with all values).
|
|
27
|
-
const paths =
|
|
28
|
+
const paths = (0, flattener_1.withNullMarkers)(recordsProjection);
|
|
28
29
|
const promises = (0, flattener_1.flatten)(records, paths).map(values => Promise.resolve(values));
|
|
29
30
|
// Queue all computations, and perform them all at once
|
|
30
31
|
desiredProjection.forEach(path => queueField(ctx, collection, path, paths, promises));
|
|
31
32
|
const values = await Promise.all(promises);
|
|
32
33
|
// Quick reproject and unflatten.
|
|
33
|
-
|
|
34
|
+
const finalProjection = (0, flattener_1.withNullMarkers)(desiredProjection);
|
|
35
|
+
return (0, flattener_1.unflatten)(finalProjection.map(path => values[paths.indexOf(path)]), finalProjection);
|
|
34
36
|
}
|
|
35
37
|
exports.default = computeFromRecords;
|
|
36
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
38
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcHV0ZS1maWVsZHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZGVjb3JhdG9ycy9jb21wdXRlZC9oZWxwZXJzL2NvbXB1dGUtZmllbGRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsd0VBQXlFO0FBS3pFLDJFQUEyRDtBQUMzRCxrREFBeUU7QUFFekUsS0FBSyxVQUFVLFlBQVksQ0FDekIsR0FBbUMsRUFDbkMsUUFBNEIsRUFDNUIsS0FBZSxFQUNmLFFBQThCO0lBRTlCLE9BQU8sSUFBQSx1QkFBcUIsRUFDMUIsSUFBQSxxQkFBUyxFQUFDLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxLQUFLLENBQUMsRUFDN0MsS0FBSyxFQUFDLGNBQWMsRUFBQyxFQUFFLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsR0FBRyxDQUFDLENBQ2hFLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxVQUFVLENBQ2pCLEdBQW1DLEVBQ25DLFVBQThCLEVBQzlCLE9BQWUsRUFDZixLQUFlLEVBQ2YsUUFBOEI7SUFFOUIsd0VBQXdFO0lBQ3hFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQzVCLE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDakQsTUFBTSxvQkFBb0IsR0FBRyxJQUFBLDJCQUFlLEVBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3BFLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSwrQkFBVSxDQUFDLEdBQUcsb0JBQW9CLENBQUMsQ0FBQyxJQUFJLENBQ3JFLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUM5RSxDQUFDO1FBRUYsd0RBQXdEO1FBQ3hELGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUV2RixpQkFBaUI7UUFDakIsTUFBTSxnQkFBZ0IsR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFdkYsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNwQixRQUFRLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsUUFBUSxFQUFFLG9CQUFvQixFQUFFLGdCQUFnQixDQUFDLENBQUMsQ0FBQztLQUNwRjtBQUNILENBQUM7QUFFYyxLQUFLLFVBQVUsa0JBQWtCLENBQzlDLEdBQW1DLEVBQ25DLFVBQThCLEVBQzlCLGlCQUE2QixFQUM3QixpQkFBNkIsRUFDN0IsT0FBcUI7SUFFckIseUVBQXlFO0lBQ3pFLE1BQU0sS0FBSyxHQUFHLElBQUEsMkJBQWUsRUFBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ2pELE1BQU0sUUFBUSxHQUFHLElBQUEsbUJBQU8sRUFBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBRWhGLHVEQUF1RDtJQUN2RCxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDdEYsTUFBTSxNQUFNLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRTNDLGlDQUFpQztJQUNqQyxNQUFNLGVBQWUsR0FBRyxJQUFBLDJCQUFlLEVBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUUzRCxPQUFPLElBQUEscUJBQVMsRUFDZCxlQUFlLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUN4RCxlQUFlLENBQ2hCLENBQUM7QUFDSixDQUFDO0FBdEJELHFDQXNCQyJ9
|
|
@@ -1,6 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* To compute the fields in parallel, it is much easier to represent the records as a group of
|
|
3
|
+
* arrays, one array per field.
|
|
4
|
+
*
|
|
5
|
+
* The issue with this transformation is that it is not a bijective function.
|
|
6
|
+
*
|
|
7
|
+
* When we flatten:
|
|
8
|
+
* - { title: 'Foundation', author: { country: null } }
|
|
9
|
+
*
|
|
10
|
+
* After flattening/unflattening, we don't know if the original record was:
|
|
11
|
+
* - { title: 'Foundation', author: { country: null } }
|
|
12
|
+
* - { title: 'Foundation', author: null }
|
|
13
|
+
*
|
|
14
|
+
* This is why we add a special marker to the projection, to keep track of null values.
|
|
15
|
+
*/
|
|
16
|
+
export declare function withNullMarkers(projection: string[]): string[];
|
|
17
|
+
export declare function unflatten(flatList: unknown[][], projection: string[]): unknown[];
|
|
18
|
+
export declare function flatten(records: unknown[], paths: string[]): unknown[][];
|
|
6
19
|
//# sourceMappingURL=flattener.d.ts.map
|
|
@@ -1,35 +1,73 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* To compute the fields in parallel, it is much easier to represent the records as a group of
|
|
4
|
+
* arrays, one array per field.
|
|
5
|
+
*
|
|
6
|
+
* The issue with this transformation is that it is not a bijective function.
|
|
7
|
+
*
|
|
8
|
+
* When we flatten:
|
|
9
|
+
* - { title: 'Foundation', author: { country: null } }
|
|
10
|
+
*
|
|
11
|
+
* After flattening/unflattening, we don't know if the original record was:
|
|
12
|
+
* - { title: 'Foundation', author: { country: null } }
|
|
13
|
+
* - { title: 'Foundation', author: null }
|
|
14
|
+
*
|
|
15
|
+
* This is why we add a special marker to the projection, to keep track of null values.
|
|
16
|
+
*/
|
|
2
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.flatten = exports.unflatten = void 0;
|
|
4
|
-
const
|
|
18
|
+
exports.flatten = exports.unflatten = exports.withNullMarkers = void 0;
|
|
19
|
+
const markerName = '__nullMarker';
|
|
20
|
+
function withNullMarkers(projection) {
|
|
21
|
+
const set = new Set(projection);
|
|
22
|
+
for (const path of projection) {
|
|
23
|
+
const parts = path.split(':');
|
|
24
|
+
for (let i = 1; i < parts.length; i += 1)
|
|
25
|
+
set.add(`${parts.slice(0, i).join(':')}:${markerName}`);
|
|
26
|
+
}
|
|
27
|
+
return [...set];
|
|
28
|
+
}
|
|
29
|
+
exports.withNullMarkers = withNullMarkers;
|
|
5
30
|
function unflatten(flatList, projection) {
|
|
6
31
|
const numRecords = flatList[0]?.length ?? 0;
|
|
7
32
|
const records = [];
|
|
8
|
-
for (let
|
|
9
|
-
records[
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
33
|
+
for (let recordIndex = 0; recordIndex < numRecords; recordIndex += 1) {
|
|
34
|
+
records[recordIndex] = {};
|
|
35
|
+
for (const [pathIndex, path] of projection.entries()) {
|
|
36
|
+
// When a marker is found, the parent is null.
|
|
37
|
+
const parts = path.split(':').filter(part => part !== markerName);
|
|
38
|
+
const value = flatList[pathIndex][recordIndex];
|
|
39
|
+
// Ignore undefined values.
|
|
40
|
+
if (value === undefined)
|
|
41
|
+
continue; // eslint-disable-line no-continue
|
|
42
|
+
// Set all others (including null)
|
|
43
|
+
let record = records[recordIndex];
|
|
44
|
+
for (let partIndex = 0; partIndex < parts.length; partIndex += 1) {
|
|
45
|
+
const part = parts[partIndex];
|
|
46
|
+
if (partIndex === parts.length - 1)
|
|
47
|
+
record[part] = value;
|
|
48
|
+
else if (!record[part])
|
|
49
|
+
record[part] = {};
|
|
50
|
+
record = record[part];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
24
53
|
}
|
|
25
|
-
|
|
26
|
-
return records.map(r => {
|
|
27
|
-
return Object.values(r).some(v => v !== null) ? r : null;
|
|
28
|
-
});
|
|
54
|
+
return records;
|
|
29
55
|
}
|
|
30
56
|
exports.unflatten = unflatten;
|
|
31
|
-
function flatten(records,
|
|
32
|
-
return
|
|
57
|
+
function flatten(records, paths) {
|
|
58
|
+
return paths.map(field => {
|
|
59
|
+
const parts = field.split(':');
|
|
60
|
+
return records.map(record => {
|
|
61
|
+
let value = record;
|
|
62
|
+
for (let i = 0; i < parts.length - 1; i += 1) {
|
|
63
|
+
value = value?.[parts[i]];
|
|
64
|
+
}
|
|
65
|
+
// for markers, the value tells us which fields are null so that we can set them.
|
|
66
|
+
if (parts[parts.length - 1] === markerName)
|
|
67
|
+
return value === null ? null : undefined;
|
|
68
|
+
return value?.[parts[parts.length - 1]];
|
|
69
|
+
});
|
|
70
|
+
});
|
|
33
71
|
}
|
|
34
72
|
exports.flatten = flatten;
|
|
35
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
73
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxhdHRlbmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RlY29yYXRvcnMvY29tcHV0ZWQvdXRpbHMvZmxhdHRlbmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7R0FjRzs7O0FBRUgsTUFBTSxVQUFVLEdBQUcsY0FBYyxDQUFDO0FBRWxDLFNBQWdCLGVBQWUsQ0FBQyxVQUFvQjtJQUNsRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUVoQyxLQUFLLE1BQU0sSUFBSSxJQUFJLFVBQVUsRUFBRTtRQUM3QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzlCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQ3RDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksVUFBVSxFQUFFLENBQUMsQ0FBQztLQUMzRDtJQUVELE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQ2xCLENBQUM7QUFWRCwwQ0FVQztBQUVELFNBQWdCLFNBQVMsQ0FBQyxRQUFxQixFQUFFLFVBQW9CO0lBQ25FLE1BQU0sVUFBVSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLElBQUksQ0FBQyxDQUFDO0lBQzVDLE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQztJQUVuQixLQUFLLElBQUksV0FBVyxHQUFHLENBQUMsRUFBRSxXQUFXLEdBQUcsVUFBVSxFQUFFLFdBQVcsSUFBSSxDQUFDLEVBQUU7UUFDcEUsT0FBTyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUUxQixLQUFLLE1BQU0sQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ3BELDhDQUE4QztZQUM5QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksS0FBSyxVQUFVLENBQUMsQ0FBQztZQUNsRSxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUM7WUFFL0MsMkJBQTJCO1lBQzNCLElBQUksS0FBSyxLQUFLLFNBQVM7Z0JBQUUsU0FBUyxDQUFDLGtDQUFrQztZQUVyRSxrQ0FBa0M7WUFDbEMsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBRWxDLEtBQUssSUFBSSxTQUFTLEdBQUcsQ0FBQyxFQUFFLFNBQVMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLFNBQVMsSUFBSSxDQUFDLEVBQUU7Z0JBQ2hFLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFFOUIsSUFBSSxTQUFTLEtBQUssS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDO29CQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUM7cUJBQ3BELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO29CQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7Z0JBRTFDLE1BQU0sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDdkI7U0FDRjtLQUNGO0lBRUQsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQztBQTlCRCw4QkE4QkM7QUFFRCxTQUFnQixPQUFPLENBQUMsT0FBa0IsRUFBRSxLQUFlO0lBQ3pELE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUN2QixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRS9CLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUMxQixJQUFJLEtBQUssR0FBRyxNQUFNLENBQUM7WUFFbkIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQzVDLEtBQUssR0FBRyxLQUFLLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUMzQjtZQUVELGlGQUFpRjtZQUNqRixJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLFVBQVU7Z0JBQUUsT0FBTyxLQUFLLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUVyRixPQUFPLEtBQUssRUFBRSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFqQkQsMEJBaUJDIn0=
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forestadmin/datasource-customizer",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"license": "GPL-3.0",
|
|
6
6
|
"publishConfig": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@types/uuid": "^8.3.4"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@forestadmin/datasource-toolkit": "1.1.
|
|
31
|
+
"@forestadmin/datasource-toolkit": "1.1.2",
|
|
32
32
|
"luxon": "^2.3.0",
|
|
33
33
|
"object-hash": "^3.0.0",
|
|
34
34
|
"uuid": "^8.3.2"
|