spice-js 2.6.75 → 2.6.77
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/build/models/SpiceModel.js +98 -27
- package/package.json +1 -1
- package/src/models/SpiceModel.js +78 -12
|
@@ -36,7 +36,8 @@ var SDate = require("sonover-date"),
|
|
|
36
36
|
_skip_cache = Symbol(),
|
|
37
37
|
_serializers = Symbol(),
|
|
38
38
|
_level = Symbol(),
|
|
39
|
-
_mapping_dept = Symbol()
|
|
39
|
+
_mapping_dept = Symbol(),
|
|
40
|
+
_mapping_dept_exempt = Symbol(); //const _type = Symbol("type");
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
var that;
|
|
@@ -59,21 +60,22 @@ class SpiceModel {
|
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
try {
|
|
62
|
-
var _args2, _args2$args,
|
|
63
|
+
var _args2, _args2$args, _args3, _args3$args, _args$args, _args4, _args4$args, _args5, _args5$args, _args6, _args6$args;
|
|
63
64
|
|
|
64
65
|
var dbtype = spice.config.database.connections[args.connection].type || "couchbase";
|
|
65
66
|
|
|
66
67
|
var Database = require("spice-" + dbtype);
|
|
67
68
|
|
|
68
|
-
this[_mapping_dept] = ((_args2 = args) == null ? void 0 : (_args2$args = _args2.args) == null ? void 0 : _args2$args.mapping_dept) ||
|
|
69
|
+
this[_mapping_dept] = ((_args2 = args) == null ? void 0 : (_args2$args = _args2.args) == null ? void 0 : _args2$args.mapping_dept) || 2;
|
|
70
|
+
this[_mapping_dept_exempt] = ((_args3 = args) == null ? void 0 : (_args3$args = _args3.args) == null ? void 0 : _args3$args.mapping_dept_exempt) || [];
|
|
69
71
|
this.type = "";
|
|
70
72
|
this.collection = args.connection;
|
|
71
73
|
this[_args] = args.args;
|
|
72
74
|
this[_external_modifier_loaded] = false;
|
|
73
75
|
this[_disable_lifecycle_events] = ((_args$args = args.args) == null ? void 0 : _args$args.disable_lifecycle_events) || false;
|
|
74
|
-
this[_ctx] = (
|
|
75
|
-
this[_skip_cache] = ((
|
|
76
|
-
this[_level] = ((
|
|
76
|
+
this[_ctx] = (_args4 = args) == null ? void 0 : (_args4$args = _args4.args) == null ? void 0 : _args4$args.ctx;
|
|
77
|
+
this[_skip_cache] = ((_args5 = args) == null ? void 0 : (_args5$args = _args5.args) == null ? void 0 : _args5$args.skip_cache) || false;
|
|
78
|
+
this[_level] = ((_args6 = args) == null ? void 0 : (_args6$args = _args6.args) == null ? void 0 : _args6$args._level) || 0;
|
|
77
79
|
this[_hooks] = {
|
|
78
80
|
create: {
|
|
79
81
|
before: [],
|
|
@@ -576,6 +578,7 @@ class SpiceModel {
|
|
|
576
578
|
function () {
|
|
577
579
|
var _ref2 = _asyncToGenerator(function* () {
|
|
578
580
|
if (args.mapping_dept) _this4[_mapping_dept] = args.mapping_dept;
|
|
581
|
+
if (args.mapping_dept_exempt) _this4[_mapping_dept_exempt] = args.mapping_dept_exempt;
|
|
579
582
|
|
|
580
583
|
if (!args) {
|
|
581
584
|
args = {};
|
|
@@ -668,10 +671,10 @@ class SpiceModel {
|
|
|
668
671
|
|
|
669
672
|
try {
|
|
670
673
|
if (p) {
|
|
671
|
-
var
|
|
674
|
+
var _args7;
|
|
672
675
|
|
|
673
676
|
return yield p.track(_this4.type + ".get", doGet, {
|
|
674
|
-
id: (
|
|
677
|
+
id: (_args7 = args) == null ? void 0 : _args7.id
|
|
675
678
|
});
|
|
676
679
|
}
|
|
677
680
|
|
|
@@ -1316,11 +1319,12 @@ class SpiceModel {
|
|
|
1316
1319
|
/*#__PURE__*/
|
|
1317
1320
|
function () {
|
|
1318
1321
|
var _ref12 = _asyncToGenerator(function* () {
|
|
1319
|
-
var
|
|
1322
|
+
var _args8, _args9, _args10;
|
|
1320
1323
|
|
|
1321
|
-
if (args.mapping_dept) _this12[_mapping_dept] = args.mapping_dept;
|
|
1324
|
+
if (args.mapping_dept) _this12[_mapping_dept] = args.mapping_dept;
|
|
1325
|
+
if (args.mapping_dept_exempt) _this12[_mapping_dept_exempt] = args.mapping_dept_exempt; // Find alias tokens from query/columns/sort
|
|
1322
1326
|
|
|
1323
|
-
var nestings = [..._this12.extractNestings(((
|
|
1327
|
+
var nestings = [..._this12.extractNestings(((_args8 = args) == null ? void 0 : _args8.query) || "", _this12.type), ..._this12.extractNestings(((_args9 = args) == null ? void 0 : _args9.columns) || "", _this12.type), ..._this12.extractNestings(((_args10 = args) == null ? void 0 : _args10.sort) || "", _this12.type)]; // Decide which aliases we can join: only when map.type===MODEL AND reference is a STRING keyspace.
|
|
1324
1328
|
|
|
1325
1329
|
var mappedNestings = _.compact(_.uniq(nestings).map(alias => {
|
|
1326
1330
|
var prop = _this12.props[alias];
|
|
@@ -1417,11 +1421,11 @@ class SpiceModel {
|
|
|
1417
1421
|
|
|
1418
1422
|
try {
|
|
1419
1423
|
if (p) {
|
|
1420
|
-
var
|
|
1424
|
+
var _args11, _args12;
|
|
1421
1425
|
|
|
1422
1426
|
return yield p.track(_this12.type + ".list", doList, {
|
|
1423
|
-
limit: (
|
|
1424
|
-
offset: (
|
|
1427
|
+
limit: (_args11 = args) == null ? void 0 : _args11.limit,
|
|
1428
|
+
offset: (_args12 = args) == null ? void 0 : _args12.offset
|
|
1425
1429
|
});
|
|
1426
1430
|
}
|
|
1427
1431
|
|
|
@@ -1589,9 +1593,9 @@ class SpiceModel {
|
|
|
1589
1593
|
data = Array.of(data);
|
|
1590
1594
|
}
|
|
1591
1595
|
|
|
1592
|
-
_this15[
|
|
1596
|
+
var isExempt = _this15[_mapping_dept_exempt].includes(source_property);
|
|
1593
1597
|
|
|
1594
|
-
if (_this15[_level] + 1 < _this15[_mapping_dept]) {
|
|
1598
|
+
if (isExempt || _this15[_level] + 1 < _this15[_mapping_dept]) {
|
|
1595
1599
|
var classes = _.compact(_.isArray(Class) ? Class : [Class]);
|
|
1596
1600
|
|
|
1597
1601
|
var ids = [];
|
|
@@ -1606,7 +1610,8 @@ class SpiceModel {
|
|
|
1606
1610
|
return new obj(_extends({}, _this15[_args], {
|
|
1607
1611
|
skip_cache: _this15[_skip_cache],
|
|
1608
1612
|
_level: _this15[_level] + 1,
|
|
1609
|
-
mapping_dept: _this15[_mapping_dept]
|
|
1613
|
+
mapping_dept: _this15[_mapping_dept],
|
|
1614
|
+
mapping_dept_exempt: _this15[_mapping_dept_exempt]
|
|
1610
1615
|
})).getMulti({
|
|
1611
1616
|
skip_hooks: true,
|
|
1612
1617
|
ids: ids
|
|
@@ -1640,7 +1645,9 @@ class SpiceModel {
|
|
|
1640
1645
|
data = Array.of(data);
|
|
1641
1646
|
}
|
|
1642
1647
|
|
|
1643
|
-
|
|
1648
|
+
var isExempt = _this16[_mapping_dept_exempt].includes(source_property);
|
|
1649
|
+
|
|
1650
|
+
if (isExempt || _this16[_level] + 1 < _this16[_mapping_dept]) {
|
|
1644
1651
|
var ids = [];
|
|
1645
1652
|
|
|
1646
1653
|
_.each(data, result => {
|
|
@@ -1665,7 +1672,8 @@ class SpiceModel {
|
|
|
1665
1672
|
return new obj(_extends({}, _this16[_args], {
|
|
1666
1673
|
skip_cache: _this16[_skip_cache],
|
|
1667
1674
|
_level: _this16[_level] + 1,
|
|
1668
|
-
mapping_dept: _this16[_mapping_dept]
|
|
1675
|
+
mapping_dept: _this16[_mapping_dept],
|
|
1676
|
+
mapping_dept_exempt: _this16[_mapping_dept_exempt]
|
|
1669
1677
|
})).getMulti({
|
|
1670
1678
|
skip_hooks: true,
|
|
1671
1679
|
ids: ids
|
|
@@ -1870,21 +1878,84 @@ class SpiceModel {
|
|
|
1870
1878
|
var requestedColumns = _this18.parseRequestedColumns(args == null ? void 0 : args.columns); // Cache the modifiers lookup for the specified type.
|
|
1871
1879
|
|
|
1872
1880
|
|
|
1873
|
-
var modifiers = ((_this18$_serializers = _this18[_serializers]) == null ? void 0 : (_this18$_serializers$ = _this18$_serializers[type]) == null ? void 0 : _this18$_serializers$.modifiers) || [];
|
|
1881
|
+
var modifiers = ((_this18$_serializers = _this18[_serializers]) == null ? void 0 : (_this18$_serializers$ = _this18$_serializers[type]) == null ? void 0 : _this18$_serializers$.modifiers) || []; // ⚡ OPTIMIZED: Separate field-specific modifiers (can run in parallel) from generic ones (serial)
|
|
1882
|
+
|
|
1883
|
+
var fieldModifiers = [];
|
|
1884
|
+
var genericModifiers = [];
|
|
1874
1885
|
|
|
1875
1886
|
for (var modifier of modifiers) {
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1887
|
+
// Skip field-specific modifiers if columns specified and field not requested
|
|
1888
|
+
if (requestedColumns && modifier.field && !requestedColumns.has(modifier.field)) {
|
|
1889
|
+
continue;
|
|
1890
|
+
} // Field modifiers have a .field property and .execute function - they can run in parallel
|
|
1891
|
+
|
|
1892
|
+
|
|
1893
|
+
if (modifier.field && typeof modifier.execute === "function") {
|
|
1894
|
+
fieldModifiers.push(modifier);
|
|
1895
|
+
} else {
|
|
1896
|
+
genericModifiers.push(modifier);
|
|
1897
|
+
}
|
|
1898
|
+
} // Run generic modifiers serially first (they may transform the data structure)
|
|
1881
1899
|
|
|
1882
1900
|
|
|
1883
|
-
|
|
1901
|
+
for (var _modifier of genericModifiers) {
|
|
1902
|
+
try {
|
|
1903
|
+
var executeFn = typeof _modifier === "function" ? _modifier : _modifier.execute;
|
|
1884
1904
|
data = yield executeFn(data, old_data, _this18[_ctx], _this18.type);
|
|
1885
1905
|
} catch (error) {
|
|
1886
|
-
console.error("Modifier error in do_serialize:", error.stack);
|
|
1906
|
+
console.error("Modifier error in do_serialize (generic):", error.stack);
|
|
1887
1907
|
}
|
|
1908
|
+
} // ⚡ OPTIMIZED: Run field-specific modifiers in PARALLEL - each populates a different field
|
|
1909
|
+
|
|
1910
|
+
|
|
1911
|
+
if (fieldModifiers.length > 0) {
|
|
1912
|
+
var _originalIsArray = Array.isArray(data);
|
|
1913
|
+
|
|
1914
|
+
var dataArray = _originalIsArray ? data : [data]; // Run all field modifiers in parallel
|
|
1915
|
+
|
|
1916
|
+
var fieldResults = yield Promise.allSettled(fieldModifiers.map(
|
|
1917
|
+
/*#__PURE__*/
|
|
1918
|
+
function () {
|
|
1919
|
+
var _ref17 = _asyncToGenerator(function* (modifier) {
|
|
1920
|
+
try {
|
|
1921
|
+
// Each modifier gets a copy of data and returns its field mappings
|
|
1922
|
+
var result = yield modifier.execute(_originalIsArray ? [...dataArray] : dataArray[0], old_data, _this18[_ctx], _this18.type);
|
|
1923
|
+
return {
|
|
1924
|
+
field: modifier.field,
|
|
1925
|
+
result
|
|
1926
|
+
};
|
|
1927
|
+
} catch (error) {
|
|
1928
|
+
console.error("Modifier error for field " + modifier.field + ":", error.stack);
|
|
1929
|
+
return {
|
|
1930
|
+
field: modifier.field,
|
|
1931
|
+
result: null,
|
|
1932
|
+
error
|
|
1933
|
+
};
|
|
1934
|
+
}
|
|
1935
|
+
});
|
|
1936
|
+
|
|
1937
|
+
return function (_x3) {
|
|
1938
|
+
return _ref17.apply(this, arguments);
|
|
1939
|
+
};
|
|
1940
|
+
}())); // Merge results - each field modifier added its field to the data items
|
|
1941
|
+
|
|
1942
|
+
for (var outcome of fieldResults) {
|
|
1943
|
+
if (outcome.status === "fulfilled" && outcome.value.result) {
|
|
1944
|
+
var {
|
|
1945
|
+
field,
|
|
1946
|
+
result
|
|
1947
|
+
} = outcome.value;
|
|
1948
|
+
var resultArray = Array.isArray(result) ? result : [result]; // Copy the mapped field from each result item to the corresponding data item
|
|
1949
|
+
|
|
1950
|
+
for (var i = 0; i < dataArray.length && i < resultArray.length; i++) {
|
|
1951
|
+
if (resultArray[i] && resultArray[i][field] !== undefined) {
|
|
1952
|
+
dataArray[i][field] = resultArray[i][field];
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
data = _originalIsArray ? dataArray : dataArray[0];
|
|
1888
1959
|
} // Ensure data is always an array for consistent processing.
|
|
1889
1960
|
|
|
1890
1961
|
|
package/package.json
CHANGED
package/src/models/SpiceModel.js
CHANGED
|
@@ -52,7 +52,7 @@ export default class SpiceModel {
|
|
|
52
52
|
var dbtype =
|
|
53
53
|
spice.config.database.connections[args.connection].type || "couchbase";
|
|
54
54
|
let Database = require(`spice-${dbtype}`);
|
|
55
|
-
this[_mapping_dept] = args?.args?.mapping_dept ||
|
|
55
|
+
this[_mapping_dept] = args?.args?.mapping_dept || 2;
|
|
56
56
|
this[_mapping_dept_exempt] = args?.args?.mapping_dept_exempt || [];
|
|
57
57
|
this.type = "";
|
|
58
58
|
this.collection = args.connection;
|
|
@@ -1673,26 +1673,92 @@ export default class SpiceModel {
|
|
|
1673
1673
|
|
|
1674
1674
|
// Cache the modifiers lookup for the specified type.
|
|
1675
1675
|
const modifiers = this[_serializers]?.[type]?.modifiers || [];
|
|
1676
|
+
|
|
1677
|
+
// ⚡ OPTIMIZED: Separate field-specific modifiers (can run in parallel) from generic ones (serial)
|
|
1678
|
+
const fieldModifiers = [];
|
|
1679
|
+
const genericModifiers = [];
|
|
1680
|
+
|
|
1676
1681
|
for (const modifier of modifiers) {
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1682
|
+
// Skip field-specific modifiers if columns specified and field not requested
|
|
1683
|
+
if (
|
|
1684
|
+
requestedColumns &&
|
|
1685
|
+
modifier.field &&
|
|
1686
|
+
!requestedColumns.has(modifier.field)
|
|
1687
|
+
) {
|
|
1688
|
+
continue;
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
// Field modifiers have a .field property and .execute function - they can run in parallel
|
|
1692
|
+
if (modifier.field && typeof modifier.execute === "function") {
|
|
1693
|
+
fieldModifiers.push(modifier);
|
|
1694
|
+
} else {
|
|
1695
|
+
genericModifiers.push(modifier);
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1686
1698
|
|
|
1687
|
-
|
|
1699
|
+
// Run generic modifiers serially first (they may transform the data structure)
|
|
1700
|
+
for (const modifier of genericModifiers) {
|
|
1701
|
+
try {
|
|
1688
1702
|
const executeFn =
|
|
1689
1703
|
typeof modifier === "function" ? modifier : modifier.execute;
|
|
1690
1704
|
data = await executeFn(data, old_data, this[_ctx], this.type);
|
|
1691
1705
|
} catch (error) {
|
|
1692
|
-
console.error(
|
|
1706
|
+
console.error(
|
|
1707
|
+
"Modifier error in do_serialize (generic):",
|
|
1708
|
+
error.stack
|
|
1709
|
+
);
|
|
1693
1710
|
}
|
|
1694
1711
|
}
|
|
1695
1712
|
|
|
1713
|
+
// ⚡ OPTIMIZED: Run field-specific modifiers in PARALLEL - each populates a different field
|
|
1714
|
+
if (fieldModifiers.length > 0) {
|
|
1715
|
+
const originalIsArray = Array.isArray(data);
|
|
1716
|
+
const dataArray = originalIsArray ? data : [data];
|
|
1717
|
+
|
|
1718
|
+
// Run all field modifiers in parallel
|
|
1719
|
+
const fieldResults = await Promise.allSettled(
|
|
1720
|
+
fieldModifiers.map(async (modifier) => {
|
|
1721
|
+
try {
|
|
1722
|
+
// Each modifier gets a copy of data and returns its field mappings
|
|
1723
|
+
const result = await modifier.execute(
|
|
1724
|
+
originalIsArray ? [...dataArray] : dataArray[0],
|
|
1725
|
+
old_data,
|
|
1726
|
+
this[_ctx],
|
|
1727
|
+
this.type
|
|
1728
|
+
);
|
|
1729
|
+
return { field: modifier.field, result };
|
|
1730
|
+
} catch (error) {
|
|
1731
|
+
console.error(
|
|
1732
|
+
`Modifier error for field ${modifier.field}:`,
|
|
1733
|
+
error.stack
|
|
1734
|
+
);
|
|
1735
|
+
return { field: modifier.field, result: null, error };
|
|
1736
|
+
}
|
|
1737
|
+
})
|
|
1738
|
+
);
|
|
1739
|
+
|
|
1740
|
+
// Merge results - each field modifier added its field to the data items
|
|
1741
|
+
for (const outcome of fieldResults) {
|
|
1742
|
+
if (outcome.status === "fulfilled" && outcome.value.result) {
|
|
1743
|
+
const { field, result } = outcome.value;
|
|
1744
|
+
const resultArray = Array.isArray(result) ? result : [result];
|
|
1745
|
+
|
|
1746
|
+
// Copy the mapped field from each result item to the corresponding data item
|
|
1747
|
+
for (
|
|
1748
|
+
let i = 0;
|
|
1749
|
+
i < dataArray.length && i < resultArray.length;
|
|
1750
|
+
i++
|
|
1751
|
+
) {
|
|
1752
|
+
if (resultArray[i] && resultArray[i][field] !== undefined) {
|
|
1753
|
+
dataArray[i][field] = resultArray[i][field];
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
data = originalIsArray ? dataArray : dataArray[0];
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1696
1762
|
// Ensure data is always an array for consistent processing.
|
|
1697
1763
|
const originalIsArray = Array.isArray(data);
|
|
1698
1764
|
if (!originalIsArray) {
|