spice-js 2.6.75 → 2.6.76

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.
@@ -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(); //const _type = Symbol("type");
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, _args$args, _args3, _args3$args, _args4, _args4$args, _args5, _args5$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
69
  this[_mapping_dept] = ((_args2 = args) == null ? void 0 : (_args2$args = _args2.args) == null ? void 0 : _args2$args.mapping_dept) || 100;
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] = (_args3 = args) == null ? void 0 : (_args3$args = _args3.args) == null ? void 0 : _args3$args.ctx;
75
- this[_skip_cache] = ((_args4 = args) == null ? void 0 : (_args4$args = _args4.args) == null ? void 0 : _args4$args.skip_cache) || false;
76
- this[_level] = ((_args5 = args) == null ? void 0 : (_args5$args = _args5.args) == null ? void 0 : _args5$args._level) || 0;
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 _args6;
674
+ var _args7;
672
675
 
673
676
  return yield p.track(_this4.type + ".get", doGet, {
674
- id: (_args6 = args) == null ? void 0 : _args6.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 _args7, _args8, _args9;
1322
+ var _args8, _args9, _args10;
1320
1323
 
1321
- if (args.mapping_dept) _this12[_mapping_dept] = args.mapping_dept; // Find alias tokens from query/columns/sort
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(((_args7 = args) == null ? void 0 : _args7.query) || "", _this12.type), ..._this12.extractNestings(((_args8 = args) == null ? void 0 : _args8.columns) || "", _this12.type), ..._this12.extractNestings(((_args9 = args) == null ? void 0 : _args9.sort) || "", _this12.type)]; // Decide which aliases we can join: only when map.type===MODEL AND reference is a STRING keyspace.
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 _args10, _args11;
1424
+ var _args11, _args12;
1421
1425
 
1422
1426
  return yield p.track(_this12.type + ".list", doList, {
1423
- limit: (_args10 = args) == null ? void 0 : _args10.limit,
1424
- offset: (_args11 = args) == null ? void 0 : _args11.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[_mapping_dept];
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
- if (_this16[_level] + 1 < _this16[_mapping_dept]) {
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
- try {
1877
- // OPTIMIZED: Skip field-specific modifiers if columns specified and field not requested
1878
- if (requestedColumns && modifier.field && !requestedColumns.has(modifier.field)) {
1879
- continue; // Skip this modifier - field not in requested columns
1880
- } // Execute modifier (supports both old function format and new object format)
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
- var executeFn = typeof modifier === "function" ? modifier : modifier.execute;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spice-js",
3
- "version": "2.6.75",
3
+ "version": "2.6.76",
4
4
  "description": "spice",
5
5
  "main": "build/index.js",
6
6
  "repository": {
@@ -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
- try {
1678
- // ⚡ OPTIMIZED: Skip field-specific modifiers if columns specified and field not requested
1679
- if (
1680
- requestedColumns &&
1681
- modifier.field &&
1682
- !requestedColumns.has(modifier.field)
1683
- ) {
1684
- continue; // Skip this modifier - field not in requested columns
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
- // Execute modifier (supports both old function format and new object format)
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("Modifier error in do_serialize:", error.stack);
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) {