spice-js 2.6.85 → 2.7.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/, ADDED
File without changes
@@ -1947,61 +1947,30 @@ class SpiceModel {
1947
1947
  for (var _modifier of genericModifiers) {
1948
1948
  try {
1949
1949
  var executeFn = typeof _modifier === "function" ? _modifier : _modifier.execute;
1950
- data = yield executeFn(data, old_data, _this18[_ctx], _this18.type);
1950
+ var result = yield executeFn(data, old_data, _this18[_ctx], _this18.type); // Only assign if modifier returned a value to prevent data corruption
1951
+
1952
+ if (result !== undefined) {
1953
+ data = result;
1954
+ }
1951
1955
  } catch (error) {
1952
1956
  console.error("Modifier error in do_serialize (generic):", error.stack);
1953
1957
  }
1954
- } // ⚡ OPTIMIZED: Run field-specific modifiers in PARALLEL - each populates a different field
1958
+ } // Run field-specific modifiers SERIALLY to allow proper deduplication
1959
+ // of nested relation lookups (parallel execution causes duplicate fetches
1960
+ // when related entities have circular references like user fields)
1955
1961
 
1956
1962
 
1957
- if (fieldModifiers.length > 0) {
1958
- var _originalIsArray = Array.isArray(data);
1963
+ for (var _modifier2 of fieldModifiers) {
1964
+ try {
1965
+ var _result = yield _modifier2.execute(data, old_data, _this18[_ctx], _this18.type); // Only assign if modifier returned a value to prevent data corruption
1959
1966
 
1960
- var dataArray = _originalIsArray ? data : [data]; // Run all field modifiers in parallel
1961
1967
 
1962
- var fieldResults = yield Promise.allSettled(fieldModifiers.map(
1963
- /*#__PURE__*/
1964
- function () {
1965
- var _ref17 = _asyncToGenerator(function* (modifier) {
1966
- try {
1967
- // Each modifier gets a copy of data and returns its field mappings
1968
- var result = yield modifier.execute(_originalIsArray ? [...dataArray] : dataArray[0], old_data, _this18[_ctx], _this18.type);
1969
- return {
1970
- field: modifier.field,
1971
- result
1972
- };
1973
- } catch (error) {
1974
- console.error("Modifier error for field " + modifier.field + ":", error.stack);
1975
- return {
1976
- field: modifier.field,
1977
- result: null,
1978
- error
1979
- };
1980
- }
1981
- });
1982
-
1983
- return function (_x3) {
1984
- return _ref17.apply(this, arguments);
1985
- };
1986
- }())); // Merge results - each field modifier added its field to the data items
1987
-
1988
- for (var outcome of fieldResults) {
1989
- if (outcome.status === "fulfilled" && outcome.value.result) {
1990
- var {
1991
- field,
1992
- result
1993
- } = outcome.value;
1994
- var resultArray = Array.isArray(result) ? result : [result]; // Copy the mapped field from each result item to the corresponding data item
1995
-
1996
- for (var i = 0; i < dataArray.length && i < resultArray.length; i++) {
1997
- if (resultArray[i] && resultArray[i][field] !== undefined) {
1998
- dataArray[i][field] = resultArray[i][field];
1999
- }
2000
- }
1968
+ if (_result !== undefined) {
1969
+ data = _result;
2001
1970
  }
1971
+ } catch (error) {
1972
+ console.error("Modifier error for field " + _modifier2.field + ":", error.stack);
2002
1973
  }
2003
-
2004
- data = _originalIsArray ? dataArray : dataArray[0];
2005
1974
  } // Ensure data is always an array for consistent processing.
2006
1975
 
2007
1976
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spice-js",
3
- "version": "2.6.85",
3
+ "version": "2.7.0",
4
4
  "description": "spice",
5
5
  "main": "build/index.js",
6
6
  "repository": {
@@ -1755,7 +1755,11 @@ export default class SpiceModel {
1755
1755
  try {
1756
1756
  const executeFn =
1757
1757
  typeof modifier === "function" ? modifier : modifier.execute;
1758
- data = await executeFn(data, old_data, this[_ctx], this.type);
1758
+ const result = await executeFn(data, old_data, this[_ctx], this.type);
1759
+ // Only assign if modifier returned a value to prevent data corruption
1760
+ if (result !== undefined) {
1761
+ data = result;
1762
+ }
1759
1763
  } catch (error) {
1760
1764
  console.error(
1761
1765
  "Modifier error in do_serialize (generic):",
@@ -1764,53 +1768,27 @@ export default class SpiceModel {
1764
1768
  }
1765
1769
  }
1766
1770
 
1767
- // ⚡ OPTIMIZED: Run field-specific modifiers in PARALLEL - each populates a different field
1768
- if (fieldModifiers.length > 0) {
1769
- const originalIsArray = Array.isArray(data);
1770
- const dataArray = originalIsArray ? data : [data];
1771
-
1772
- // Run all field modifiers in parallel
1773
- const fieldResults = await Promise.allSettled(
1774
- fieldModifiers.map(async (modifier) => {
1775
- try {
1776
- // Each modifier gets a copy of data and returns its field mappings
1777
- const result = await modifier.execute(
1778
- originalIsArray ? [...dataArray] : dataArray[0],
1779
- old_data,
1780
- this[_ctx],
1781
- this.type
1782
- );
1783
- return { field: modifier.field, result };
1784
- } catch (error) {
1785
- console.error(
1786
- `Modifier error for field ${modifier.field}:`,
1787
- error.stack
1788
- );
1789
- return { field: modifier.field, result: null, error };
1790
- }
1791
- })
1792
- );
1793
-
1794
- // Merge results - each field modifier added its field to the data items
1795
- for (const outcome of fieldResults) {
1796
- if (outcome.status === "fulfilled" && outcome.value.result) {
1797
- const { field, result } = outcome.value;
1798
- const resultArray = Array.isArray(result) ? result : [result];
1799
-
1800
- // Copy the mapped field from each result item to the corresponding data item
1801
- for (
1802
- let i = 0;
1803
- i < dataArray.length && i < resultArray.length;
1804
- i++
1805
- ) {
1806
- if (resultArray[i] && resultArray[i][field] !== undefined) {
1807
- dataArray[i][field] = resultArray[i][field];
1808
- }
1809
- }
1771
+ // Run field-specific modifiers SERIALLY to allow proper deduplication
1772
+ // of nested relation lookups (parallel execution causes duplicate fetches
1773
+ // when related entities have circular references like user fields)
1774
+ for (const modifier of fieldModifiers) {
1775
+ try {
1776
+ const result = await modifier.execute(
1777
+ data,
1778
+ old_data,
1779
+ this[_ctx],
1780
+ this.type
1781
+ );
1782
+ // Only assign if modifier returned a value to prevent data corruption
1783
+ if (result !== undefined) {
1784
+ data = result;
1810
1785
  }
1786
+ } catch (error) {
1787
+ console.error(
1788
+ `Modifier error for field ${modifier.field}:`,
1789
+ error.stack
1790
+ );
1811
1791
  }
1812
-
1813
- data = originalIsArray ? dataArray : dataArray[0];
1814
1792
  }
1815
1793
 
1816
1794
  // Ensure data is always an array for consistent processing.