spice-js 2.7.29 → 2.7.31
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/index.js +3 -1
- package/build/models/SpiceModel.js +306 -81
- package/package.json +1 -1
- package/src/index.js +3 -1
- package/src/models/SpiceModel.js +277 -26
- package/tests/__mocks__/globalMocks.js +3 -1
- package/tests/fixtures/testData.js +3 -1
- package/tests/helpers/modelFactory.js +7 -1
- package/tests/jest-env.js +3 -1
- package/tests/models/SpiceModel.mapping-depth.test.js +320 -0
|
@@ -7,9 +7,9 @@ var _ResourceLifecycleTriggered = _interopRequireDefault(require("../events/even
|
|
|
7
7
|
var _Security = require("../utility/Security");
|
|
8
8
|
var _fix = require("../utility/fix");
|
|
9
9
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) { ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } } return n; }, _extends.apply(null, arguments); }
|
|
10
11
|
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
11
12
|
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
12
|
-
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) { ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } } return n; }, _extends.apply(null, arguments); }
|
|
13
13
|
var co = require("co");
|
|
14
14
|
var regeneratorRuntime = require("regenerator-runtime");
|
|
15
15
|
var SDate = require("sonover-date"),
|
|
@@ -27,11 +27,76 @@ var SDate = require("sonover-date"),
|
|
|
27
27
|
_serializers = Symbol(),
|
|
28
28
|
_level = Symbol(),
|
|
29
29
|
_mapping_dept = Symbol(),
|
|
30
|
+
_mapping_dept_scalar = Symbol(),
|
|
31
|
+
_mapping_dept_array = Symbol(),
|
|
32
|
+
_mapping_concurrency = Symbol(),
|
|
33
|
+
_skip_mapped_serialization = Symbol(),
|
|
30
34
|
_mapping_dept_exempt = Symbol(),
|
|
31
35
|
_current_path = Symbol();
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
var GLOBAL_MAPPING_CONCURRENCY = Math.max(1, Number(process.env.SPICE_MAPPING_GLOBAL_CONCURRENCY) || 32);
|
|
37
|
+
var activeGlobalMappings = 0;
|
|
38
|
+
var globalMappingWaiters = [];
|
|
39
|
+
function normalizeConcurrency(value, fallback) {
|
|
40
|
+
if (fallback === void 0) {
|
|
41
|
+
fallback = 1;
|
|
42
|
+
}
|
|
43
|
+
var parsed = Number(value);
|
|
44
|
+
return Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : fallback;
|
|
45
|
+
}
|
|
46
|
+
function acquireGlobalMappingSlot() {
|
|
47
|
+
return _acquireGlobalMappingSlot.apply(this, arguments);
|
|
48
|
+
}
|
|
49
|
+
function _acquireGlobalMappingSlot() {
|
|
50
|
+
_acquireGlobalMappingSlot = _asyncToGenerator(function* () {
|
|
51
|
+
var queuedAt = process.hrtime.bigint();
|
|
52
|
+
if (activeGlobalMappings < GLOBAL_MAPPING_CONCURRENCY) {
|
|
53
|
+
activeGlobalMappings += 1;
|
|
54
|
+
} else {
|
|
55
|
+
yield new Promise(resolve => globalMappingWaiters.push(resolve));
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
active: activeGlobalMappings,
|
|
59
|
+
waitMs: Number(process.hrtime.bigint() - queuedAt) / 1e6,
|
|
60
|
+
release() {
|
|
61
|
+
var next = globalMappingWaiters.shift();
|
|
62
|
+
if (next) {
|
|
63
|
+
next();
|
|
64
|
+
} else {
|
|
65
|
+
activeGlobalMappings -= 1;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
return _acquireGlobalMappingSlot.apply(this, arguments);
|
|
71
|
+
}
|
|
72
|
+
function runWithConcurrency(_x, _x2, _x3) {
|
|
73
|
+
return _runWithConcurrency.apply(this, arguments);
|
|
74
|
+
} //const _type = Symbol("type");
|
|
75
|
+
function _runWithConcurrency() {
|
|
76
|
+
_runWithConcurrency = _asyncToGenerator(function* (items, concurrency, worker) {
|
|
77
|
+
var results = new Array(items.length);
|
|
78
|
+
var nextIndex = 0;
|
|
79
|
+
function runWorker() {
|
|
80
|
+
return _runWorker.apply(this, arguments);
|
|
81
|
+
}
|
|
82
|
+
function _runWorker() {
|
|
83
|
+
_runWorker = _asyncToGenerator(function* () {
|
|
84
|
+
while (nextIndex < items.length) {
|
|
85
|
+
var index = nextIndex;
|
|
86
|
+
nextIndex += 1;
|
|
87
|
+
results[index] = yield worker(items[index], index);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
return _runWorker.apply(this, arguments);
|
|
91
|
+
}
|
|
92
|
+
var workerCount = Math.min(concurrency, items.length);
|
|
93
|
+
yield Promise.all(Array.from({
|
|
94
|
+
length: workerCount
|
|
95
|
+
}, () => runWorker()));
|
|
96
|
+
return results;
|
|
97
|
+
});
|
|
98
|
+
return _runWithConcurrency.apply(this, arguments);
|
|
99
|
+
}
|
|
35
100
|
var that;
|
|
36
101
|
if (!Promise.allSettled) {
|
|
37
102
|
Promise.allSettled = promises => Promise.all(promises.map((promise, i) => promise.then(value => ({
|
|
@@ -48,21 +113,29 @@ class SpiceModel {
|
|
|
48
113
|
args = {};
|
|
49
114
|
}
|
|
50
115
|
try {
|
|
51
|
-
var _args2,
|
|
116
|
+
var _args2, _modelArgs$ctx, _modelArgs$ctx$state, _ref, _ref2, _modelArgs$mapping_de, _ref3, _ref4, _modelArgs$mapping_de2, _modelArgs$mapping_co, _ref5, _modelArgs$skip_mappe, _args$args, _args3, _args3$args, _args4, _args4$args, _args5, _args5$args, _args6, _args6$args, _args7, _args7$args;
|
|
117
|
+
var modelArgs = ((_args2 = args) == null ? void 0 : _args2.args) || {};
|
|
118
|
+
var requestProfile = (modelArgs == null ? void 0 : (_modelArgs$ctx = modelArgs.ctx) == null ? void 0 : (_modelArgs$ctx$state = _modelArgs$ctx.state) == null ? void 0 : _modelArgs$ctx$state.read_profile) || {};
|
|
119
|
+
var defaultMappingDept = process.env.MAPPING_DEPT || 3;
|
|
120
|
+
var legacyMappingDept = modelArgs.mapping_dept !== undefined && modelArgs.mapping_dept !== null ? modelArgs.mapping_dept : undefined;
|
|
52
121
|
var dbtype = spice.config.database.connections[args.connection].type || "couchbase";
|
|
53
122
|
var Database = require("spice-" + dbtype);
|
|
54
|
-
this[_mapping_dept] =
|
|
55
|
-
this[
|
|
123
|
+
this[_mapping_dept] = legacyMappingDept != null ? legacyMappingDept : defaultMappingDept;
|
|
124
|
+
this[_mapping_dept_scalar] = (_ref = (_ref2 = (_modelArgs$mapping_de = modelArgs.mapping_dept_scalar) != null ? _modelArgs$mapping_de : legacyMappingDept) != null ? _ref2 : requestProfile.mapping_dept_scalar) != null ? _ref : defaultMappingDept;
|
|
125
|
+
this[_mapping_dept_array] = (_ref3 = (_ref4 = (_modelArgs$mapping_de2 = modelArgs.mapping_dept_array) != null ? _modelArgs$mapping_de2 : legacyMappingDept) != null ? _ref4 : requestProfile.mapping_dept_array) != null ? _ref3 : defaultMappingDept;
|
|
126
|
+
this[_mapping_concurrency] = normalizeConcurrency((_modelArgs$mapping_co = modelArgs.mapping_concurrency) != null ? _modelArgs$mapping_co : requestProfile.mapping_concurrency);
|
|
127
|
+
this[_skip_mapped_serialization] = (_ref5 = (_modelArgs$skip_mappe = modelArgs.skip_mapped_serialization) != null ? _modelArgs$skip_mappe : requestProfile.skip_mapped_serialization) != null ? _ref5 : false;
|
|
128
|
+
this[_mapping_dept_exempt] = modelArgs.mapping_dept_exempt || [];
|
|
56
129
|
this.type = "";
|
|
57
130
|
this.collection = args.connection;
|
|
58
131
|
this[_args] = args.args;
|
|
59
132
|
this[_external_modifier_loaded] = false;
|
|
60
133
|
this[_disable_lifecycle_events] = ((_args$args = args.args) == null ? void 0 : _args$args.disable_lifecycle_events) || false;
|
|
61
|
-
this[_ctx] = (
|
|
62
|
-
this[_skip_cache] = ((
|
|
63
|
-
this[_level] = ((
|
|
64
|
-
this[_current_path] = ((
|
|
65
|
-
this[_columns] = ((
|
|
134
|
+
this[_ctx] = (_args3 = args) == null ? void 0 : (_args3$args = _args3.args) == null ? void 0 : _args3$args.ctx;
|
|
135
|
+
this[_skip_cache] = ((_args4 = args) == null ? void 0 : (_args4$args = _args4.args) == null ? void 0 : _args4$args.skip_cache) || false;
|
|
136
|
+
this[_level] = ((_args5 = args) == null ? void 0 : (_args5$args = _args5.args) == null ? void 0 : _args5$args._level) || 0;
|
|
137
|
+
this[_current_path] = ((_args6 = args) == null ? void 0 : (_args6$args = _args6.args) == null ? void 0 : _args6$args._current_path) || "";
|
|
138
|
+
this[_columns] = ((_args7 = args) == null ? void 0 : (_args7$args = _args7.args) == null ? void 0 : _args7$args._columns) || "";
|
|
66
139
|
this[_hooks] = {
|
|
67
140
|
create: {
|
|
68
141
|
before: [],
|
|
@@ -209,6 +282,32 @@ class SpiceModel {
|
|
|
209
282
|
}
|
|
210
283
|
// }
|
|
211
284
|
}
|
|
285
|
+
applyMappingDepthArgs(args) {
|
|
286
|
+
if (args === void 0) {
|
|
287
|
+
args = {};
|
|
288
|
+
}
|
|
289
|
+
var hasLegacyDepth = args.mapping_dept !== undefined && args.mapping_dept !== null;
|
|
290
|
+
if (hasLegacyDepth) {
|
|
291
|
+
this[_mapping_dept] = args.mapping_dept;
|
|
292
|
+
this[_mapping_dept_scalar] = args.mapping_dept;
|
|
293
|
+
this[_mapping_dept_array] = args.mapping_dept;
|
|
294
|
+
}
|
|
295
|
+
if (args.mapping_dept_scalar !== undefined && args.mapping_dept_scalar !== null) {
|
|
296
|
+
this[_mapping_dept_scalar] = args.mapping_dept_scalar;
|
|
297
|
+
}
|
|
298
|
+
if (args.mapping_dept_array !== undefined && args.mapping_dept_array !== null) {
|
|
299
|
+
this[_mapping_dept_array] = args.mapping_dept_array;
|
|
300
|
+
}
|
|
301
|
+
if (args.skip_mapped_serialization !== undefined) {
|
|
302
|
+
this[_skip_mapped_serialization] = args.skip_mapped_serialization;
|
|
303
|
+
}
|
|
304
|
+
if (args.mapping_concurrency !== undefined) {
|
|
305
|
+
this[_mapping_concurrency] = normalizeConcurrency(args.mapping_concurrency, this[_mapping_concurrency]);
|
|
306
|
+
}
|
|
307
|
+
if (args.mapping_dept_exempt) {
|
|
308
|
+
this[_mapping_dept_exempt] = args.mapping_dept_exempt;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
212
311
|
get database() {
|
|
213
312
|
return this[_database];
|
|
214
313
|
}
|
|
@@ -250,13 +349,13 @@ class SpiceModel {
|
|
|
250
349
|
return [];
|
|
251
350
|
})();
|
|
252
351
|
}
|
|
253
|
-
createValidationString(
|
|
352
|
+
createValidationString(_ref6) {
|
|
254
353
|
var {
|
|
255
354
|
property_name,
|
|
256
355
|
props,
|
|
257
356
|
operation,
|
|
258
357
|
complete
|
|
259
|
-
} =
|
|
358
|
+
} = _ref6;
|
|
260
359
|
var operationExempt = {
|
|
261
360
|
PUT: ["required", "unique"]
|
|
262
361
|
};
|
|
@@ -487,14 +586,13 @@ class SpiceModel {
|
|
|
487
586
|
// Profiling: use track() for proper async context forking
|
|
488
587
|
var p = (_this4$_ctx = _this4[_ctx]) == null ? void 0 : _this4$_ctx.profiler;
|
|
489
588
|
var doGet = /*#__PURE__*/function () {
|
|
490
|
-
var
|
|
491
|
-
if (args.mapping_dept) _this4[_mapping_dept] = args.mapping_dept;
|
|
492
|
-
if (args.mapping_dept_exempt) _this4[_mapping_dept_exempt] = args.mapping_dept_exempt;
|
|
589
|
+
var _ref7 = _asyncToGenerator(function* () {
|
|
493
590
|
if (!args) {
|
|
494
591
|
args = {};
|
|
495
592
|
}
|
|
593
|
+
_this4.applyMappingDepthArgs(args);
|
|
496
594
|
if (_.isString(args.id)) {
|
|
497
|
-
var
|
|
595
|
+
var _args8, _results, _results2, _results3, _results4, _results5, _results6;
|
|
498
596
|
if (args.skip_hooks !== true) {
|
|
499
597
|
yield _this4.run_hook(args, "get", "before");
|
|
500
598
|
}
|
|
@@ -514,7 +612,7 @@ class SpiceModel {
|
|
|
514
612
|
var originalColumns = args.columns;
|
|
515
613
|
|
|
516
614
|
// Extract nestings from columns if specified
|
|
517
|
-
var nestings = _this4.extractNestings(((
|
|
615
|
+
var nestings = _this4.extractNestings(((_args8 = args) == null ? void 0 : _args8.columns) || "", _this4.type);
|
|
518
616
|
|
|
519
617
|
// Build join metadata and prepare columns
|
|
520
618
|
_this4.buildJoinMetadata(nestings, args);
|
|
@@ -597,14 +695,14 @@ class SpiceModel {
|
|
|
597
695
|
}
|
|
598
696
|
});
|
|
599
697
|
return function doGet() {
|
|
600
|
-
return
|
|
698
|
+
return _ref7.apply(this, arguments);
|
|
601
699
|
};
|
|
602
700
|
}();
|
|
603
701
|
try {
|
|
604
702
|
if (p) {
|
|
605
|
-
var
|
|
703
|
+
var _args9;
|
|
606
704
|
return yield p.track(_this4.type + ".get", doGet, {
|
|
607
|
-
id: (
|
|
705
|
+
id: (_args9 = args) == null ? void 0 : _args9.id
|
|
608
706
|
});
|
|
609
707
|
}
|
|
610
708
|
return yield doGet();
|
|
@@ -632,14 +730,15 @@ class SpiceModel {
|
|
|
632
730
|
// ⚡ Profiling: use track() for proper async context forking
|
|
633
731
|
var p = (_this6$_ctx = _this6[_ctx]) == null ? void 0 : _this6$_ctx.profiler;
|
|
634
732
|
var doGetMulti = /*#__PURE__*/function () {
|
|
635
|
-
var
|
|
733
|
+
var _ref0 = _asyncToGenerator(function* () {
|
|
636
734
|
if (!args) {
|
|
637
735
|
args = {};
|
|
638
736
|
}
|
|
737
|
+
_this6.applyMappingDepthArgs(args);
|
|
639
738
|
if (args.skip_hooks != true) {
|
|
640
739
|
yield _this6.run_hook(_this6, "list", "before");
|
|
641
740
|
}
|
|
642
|
-
_.
|
|
741
|
+
args.ids = _.uniq(_.filter(args.ids || [], id => _.isString(id) && id.length > 0));
|
|
643
742
|
var key = "multi-get::" + _this6.type + "::" + _.join(args.ids, "|") + ":" + args.columns;
|
|
644
743
|
var results = [];
|
|
645
744
|
if (args.ids.length > 0) {
|
|
@@ -673,14 +772,14 @@ class SpiceModel {
|
|
|
673
772
|
return results;
|
|
674
773
|
});
|
|
675
774
|
return function doGetMulti() {
|
|
676
|
-
return
|
|
775
|
+
return _ref0.apply(this, arguments);
|
|
677
776
|
};
|
|
678
777
|
}();
|
|
679
778
|
try {
|
|
680
779
|
if (p) {
|
|
681
|
-
var
|
|
780
|
+
var _args0, _args0$ids;
|
|
682
781
|
return yield p.track(_this6.type + ".getMulti", doGetMulti, {
|
|
683
|
-
ids_count: ((
|
|
782
|
+
ids_count: ((_args0 = args) == null ? void 0 : (_args0$ids = _args0.ids) == null ? void 0 : _args0$ids.length) || 0
|
|
684
783
|
});
|
|
685
784
|
}
|
|
686
785
|
return yield doGetMulti();
|
|
@@ -729,7 +828,7 @@ class SpiceModel {
|
|
|
729
828
|
// Profiling: use track() for proper async context forking
|
|
730
829
|
var p = (_this8$_ctx = _this8[_ctx]) == null ? void 0 : _this8$_ctx.profiler;
|
|
731
830
|
var doUpdate = /*#__PURE__*/function () {
|
|
732
|
-
var
|
|
831
|
+
var _ref1 = _asyncToGenerator(function* () {
|
|
733
832
|
_this8.updated_at = new SDate().now();
|
|
734
833
|
var results = yield _this8.database.get(args.id);
|
|
735
834
|
var item_exist = yield _this8.exist(results);
|
|
@@ -773,7 +872,7 @@ class SpiceModel {
|
|
|
773
872
|
});
|
|
774
873
|
});
|
|
775
874
|
return function doUpdate() {
|
|
776
|
-
return
|
|
875
|
+
return _ref1.apply(this, arguments);
|
|
777
876
|
};
|
|
778
877
|
}();
|
|
779
878
|
try {
|
|
@@ -799,7 +898,7 @@ class SpiceModel {
|
|
|
799
898
|
// Profiling: use track() for proper async context forking
|
|
800
899
|
var p = (_this9$_ctx = _this9[_ctx]) == null ? void 0 : _this9$_ctx.profiler;
|
|
801
900
|
var doCreate = /*#__PURE__*/function () {
|
|
802
|
-
var
|
|
901
|
+
var _ref11 = _asyncToGenerator(function* () {
|
|
803
902
|
var form;
|
|
804
903
|
_this9.created_at = new SDate().now();
|
|
805
904
|
args = _.defaults(args, {
|
|
@@ -845,7 +944,7 @@ class SpiceModel {
|
|
|
845
944
|
});
|
|
846
945
|
});
|
|
847
946
|
return function doCreate() {
|
|
848
|
-
return
|
|
947
|
+
return _ref11.apply(this, arguments);
|
|
849
948
|
};
|
|
850
949
|
}();
|
|
851
950
|
try {
|
|
@@ -883,7 +982,7 @@ class SpiceModel {
|
|
|
883
982
|
// Profiling: use track() for proper async context forking
|
|
884
983
|
var p = (_this1$_ctx = _this1[_ctx]) == null ? void 0 : _this1$_ctx.profiler;
|
|
885
984
|
var doDelete = /*#__PURE__*/function () {
|
|
886
|
-
var
|
|
985
|
+
var _ref13 = _asyncToGenerator(function* () {
|
|
887
986
|
var item_exist = yield _this1.exist(args.id);
|
|
888
987
|
if (!item_exist) {
|
|
889
988
|
throw new Error(_this1.type + " does not exist.");
|
|
@@ -894,7 +993,7 @@ class SpiceModel {
|
|
|
894
993
|
}
|
|
895
994
|
var delete_response = {};
|
|
896
995
|
var dbOperation = /*#__PURE__*/function () {
|
|
897
|
-
var
|
|
996
|
+
var _ref14 = _asyncToGenerator(function* () {
|
|
898
997
|
if (args.hard) {
|
|
899
998
|
delete_response = yield _this1.database.delete(args.id);
|
|
900
999
|
_this1.setMonitor();
|
|
@@ -905,7 +1004,7 @@ class SpiceModel {
|
|
|
905
1004
|
}
|
|
906
1005
|
});
|
|
907
1006
|
return function dbOperation() {
|
|
908
|
-
return
|
|
1007
|
+
return _ref14.apply(this, arguments);
|
|
909
1008
|
};
|
|
910
1009
|
}();
|
|
911
1010
|
if (p) {
|
|
@@ -921,7 +1020,7 @@ class SpiceModel {
|
|
|
921
1020
|
return {};
|
|
922
1021
|
});
|
|
923
1022
|
return function doDelete() {
|
|
924
|
-
return
|
|
1023
|
+
return _ref13.apply(this, arguments);
|
|
925
1024
|
};
|
|
926
1025
|
}();
|
|
927
1026
|
try {
|
|
@@ -1111,12 +1210,12 @@ class SpiceModel {
|
|
|
1111
1210
|
}
|
|
1112
1211
|
createJoinSection(mappedNestings) {
|
|
1113
1212
|
if (!mappedNestings || mappedNestings.length === 0) return "";
|
|
1114
|
-
return mappedNestings.map(
|
|
1213
|
+
return mappedNestings.map(_ref15 => {
|
|
1115
1214
|
var {
|
|
1116
1215
|
alias,
|
|
1117
1216
|
reference,
|
|
1118
1217
|
is_array
|
|
1119
|
-
} =
|
|
1218
|
+
} = _ref15;
|
|
1120
1219
|
var keyspace = (0, _fix.fixCollection)(reference);
|
|
1121
1220
|
if (is_array === true) {
|
|
1122
1221
|
return "LEFT NEST `" + keyspace + "` AS `" + alias + "` ON KEYS `" + this.type + "`.`" + alias + "`";
|
|
@@ -1261,10 +1360,9 @@ class SpiceModel {
|
|
|
1261
1360
|
// Profiling: use track() for proper async context forking
|
|
1262
1361
|
var p = (_this10$_ctx = _this10[_ctx]) == null ? void 0 : _this10$_ctx.profiler;
|
|
1263
1362
|
var doList = /*#__PURE__*/function () {
|
|
1264
|
-
var
|
|
1265
|
-
var
|
|
1266
|
-
|
|
1267
|
-
if (args.mapping_dept_exempt) _this10[_mapping_dept_exempt] = args.mapping_dept_exempt;
|
|
1363
|
+
var _ref16 = _asyncToGenerator(function* () {
|
|
1364
|
+
var _args1, _args10;
|
|
1365
|
+
_this10.applyMappingDepthArgs(args);
|
|
1268
1366
|
|
|
1269
1367
|
// Filter out id, meta().id, and any column ending with .id (e.g., dependents.id)
|
|
1270
1368
|
if (args.columns) {
|
|
@@ -1278,9 +1376,9 @@ class SpiceModel {
|
|
|
1278
1376
|
var originalColumns = args.columns;
|
|
1279
1377
|
|
|
1280
1378
|
// Find alias tokens from query/columns/sort
|
|
1281
|
-
var nestings = [..._this10.extractNestings(((
|
|
1379
|
+
var nestings = [..._this10.extractNestings(((_args1 = args) == null ? void 0 : _args1.query) || "", _this10.type),
|
|
1282
1380
|
//...this.extractNestings(args?.columns || "", this.type),
|
|
1283
|
-
..._this10.extractNestings(((
|
|
1381
|
+
..._this10.extractNestings(((_args10 = args) == null ? void 0 : _args10.sort) || "", _this10.type)];
|
|
1284
1382
|
|
|
1285
1383
|
// Build join metadata and prepare columns
|
|
1286
1384
|
var {
|
|
@@ -1341,15 +1439,15 @@ class SpiceModel {
|
|
|
1341
1439
|
return results;
|
|
1342
1440
|
});
|
|
1343
1441
|
return function doList() {
|
|
1344
|
-
return
|
|
1442
|
+
return _ref16.apply(this, arguments);
|
|
1345
1443
|
};
|
|
1346
1444
|
}();
|
|
1347
1445
|
try {
|
|
1348
1446
|
if (p) {
|
|
1349
|
-
var
|
|
1447
|
+
var _args11, _args12;
|
|
1350
1448
|
return yield p.track(_this10.type + ".list", doList, {
|
|
1351
|
-
limit: (
|
|
1352
|
-
offset: (
|
|
1449
|
+
limit: (_args11 = args) == null ? void 0 : _args11.limit,
|
|
1450
|
+
offset: (_args12 = args) == null ? void 0 : _args12.offset
|
|
1353
1451
|
});
|
|
1354
1452
|
}
|
|
1355
1453
|
return yield doList();
|
|
@@ -1395,8 +1493,9 @@ class SpiceModel {
|
|
|
1395
1493
|
// Profiling: use track() for proper async context forking
|
|
1396
1494
|
var p = (_this11$_ctx = _this11[_ctx]) == null ? void 0 : _this11$_ctx.profiler;
|
|
1397
1495
|
var doFetch = /*#__PURE__*/function () {
|
|
1398
|
-
var
|
|
1496
|
+
var _ref17 = _asyncToGenerator(function* () {
|
|
1399
1497
|
if (args.is_custom_query === "true" && args.ids.length > 0) {
|
|
1498
|
+
console.log("Fetching results from database", _this11.type, args, query, mappedNestings);
|
|
1400
1499
|
return yield _this11.database.query(query);
|
|
1401
1500
|
} else if (args.is_full_text === "true") {
|
|
1402
1501
|
return yield _this11.database.full_text_search(_this11.type, query || "", args.limit, args.offset, args._join);
|
|
@@ -1407,7 +1506,7 @@ class SpiceModel {
|
|
|
1407
1506
|
}
|
|
1408
1507
|
});
|
|
1409
1508
|
return function doFetch() {
|
|
1410
|
-
return
|
|
1509
|
+
return _ref17.apply(this, arguments);
|
|
1411
1510
|
};
|
|
1412
1511
|
}();
|
|
1413
1512
|
if (p) {
|
|
@@ -1416,12 +1515,12 @@ class SpiceModel {
|
|
|
1416
1515
|
return yield doFetch();
|
|
1417
1516
|
})();
|
|
1418
1517
|
}
|
|
1419
|
-
addHook(
|
|
1518
|
+
addHook(_ref18) {
|
|
1420
1519
|
var {
|
|
1421
1520
|
operation,
|
|
1422
1521
|
when,
|
|
1423
1522
|
execute
|
|
1424
|
-
} =
|
|
1523
|
+
} = _ref18;
|
|
1425
1524
|
this[_hooks][operation][when].push(execute);
|
|
1426
1525
|
}
|
|
1427
1526
|
run_hook(data, op, when, old_data) {
|
|
@@ -1519,7 +1618,8 @@ class SpiceModel {
|
|
|
1519
1618
|
data = Array.of(data);
|
|
1520
1619
|
}
|
|
1521
1620
|
var isExempt = _this13.isFieldExempt(source_property);
|
|
1522
|
-
|
|
1621
|
+
var activeMappingDept = type === "read" ? _this13[_mapping_dept_scalar] : _this13[_mapping_dept];
|
|
1622
|
+
if (isExempt || _this13[_level] + 1 < activeMappingDept) {
|
|
1523
1623
|
var classes = _.compact(_.isArray(Class) ? Class : [Class]);
|
|
1524
1624
|
var ids = [];
|
|
1525
1625
|
_.each(data, result => {
|
|
@@ -1543,12 +1643,16 @@ class SpiceModel {
|
|
|
1543
1643
|
|
|
1544
1644
|
// ⚡ Wrap in profiler track() to ensure proper async context for child operations
|
|
1545
1645
|
var fetchRelated = /*#__PURE__*/function () {
|
|
1546
|
-
var
|
|
1646
|
+
var _ref19 = _asyncToGenerator(function* () {
|
|
1547
1647
|
return yield Promise.allSettled(_.map(classes, obj => {
|
|
1548
1648
|
var objInstance = new obj(_extends({}, _this13[_args], {
|
|
1549
1649
|
skip_cache: _this13[_skip_cache],
|
|
1550
1650
|
_level: _this13[_level] + 1,
|
|
1551
1651
|
mapping_dept: _this13[_mapping_dept],
|
|
1652
|
+
mapping_dept_scalar: _this13[_mapping_dept_scalar],
|
|
1653
|
+
mapping_dept_array: _this13[_mapping_dept_array],
|
|
1654
|
+
mapping_concurrency: _this13[_mapping_concurrency],
|
|
1655
|
+
skip_mapped_serialization: _this13[_skip_mapped_serialization],
|
|
1552
1656
|
mapping_dept_exempt: _this13[_mapping_dept_exempt],
|
|
1553
1657
|
_columns: columnArray.join(","),
|
|
1554
1658
|
_current_path: childPath
|
|
@@ -1556,12 +1660,13 @@ class SpiceModel {
|
|
|
1556
1660
|
return objInstance.getMulti({
|
|
1557
1661
|
skip_hooks: true,
|
|
1558
1662
|
ids: ids,
|
|
1559
|
-
columns: columnArray
|
|
1663
|
+
columns: columnArray,
|
|
1664
|
+
skip_read_serialize: _this13[_skip_mapped_serialization]
|
|
1560
1665
|
});
|
|
1561
1666
|
}));
|
|
1562
1667
|
});
|
|
1563
1668
|
return function fetchRelated() {
|
|
1564
|
-
return
|
|
1669
|
+
return _ref19.apply(this, arguments);
|
|
1565
1670
|
};
|
|
1566
1671
|
}();
|
|
1567
1672
|
var returned_all;
|
|
@@ -1628,7 +1733,8 @@ class SpiceModel {
|
|
|
1628
1733
|
data = Array.of(data);
|
|
1629
1734
|
}
|
|
1630
1735
|
var isExempt = _this14.isFieldExempt(source_property);
|
|
1631
|
-
|
|
1736
|
+
var activeMappingDept = type === "read" ? _this14[_mapping_dept_array] : _this14[_mapping_dept];
|
|
1737
|
+
if (isExempt || _this14[_level] + 1 < activeMappingDept) {
|
|
1632
1738
|
var ids = [];
|
|
1633
1739
|
_.each(data, result => {
|
|
1634
1740
|
var value = result[source_property];
|
|
@@ -1661,24 +1767,29 @@ class SpiceModel {
|
|
|
1661
1767
|
|
|
1662
1768
|
// ⚡ Wrap in profiler track() to ensure proper async context for child operations
|
|
1663
1769
|
var fetchRelated = /*#__PURE__*/function () {
|
|
1664
|
-
var
|
|
1770
|
+
var _ref20 = _asyncToGenerator(function* () {
|
|
1665
1771
|
return yield Promise.allSettled(_.map(classes, obj => {
|
|
1666
1772
|
return new obj(_extends({}, _this14[_args], {
|
|
1667
1773
|
skip_cache: _this14[_skip_cache],
|
|
1668
1774
|
_level: _this14[_level] + 1,
|
|
1669
1775
|
mapping_dept: _this14[_mapping_dept],
|
|
1776
|
+
mapping_dept_scalar: _this14[_mapping_dept_scalar],
|
|
1777
|
+
mapping_dept_array: _this14[_mapping_dept_array],
|
|
1778
|
+
mapping_concurrency: _this14[_mapping_concurrency],
|
|
1779
|
+
skip_mapped_serialization: _this14[_skip_mapped_serialization],
|
|
1670
1780
|
mapping_dept_exempt: _this14[_mapping_dept_exempt],
|
|
1671
1781
|
_columns: columnArray.join(","),
|
|
1672
1782
|
_current_path: childPath
|
|
1673
1783
|
})).getMulti({
|
|
1674
1784
|
skip_hooks: true,
|
|
1675
1785
|
ids: ids,
|
|
1676
|
-
columns: columnArray
|
|
1786
|
+
columns: columnArray,
|
|
1787
|
+
skip_read_serialize: _this14[_skip_mapped_serialization]
|
|
1677
1788
|
});
|
|
1678
1789
|
}));
|
|
1679
1790
|
});
|
|
1680
1791
|
return function fetchRelated() {
|
|
1681
|
-
return
|
|
1792
|
+
return _ref20.apply(this, arguments);
|
|
1682
1793
|
};
|
|
1683
1794
|
}();
|
|
1684
1795
|
var returned_all;
|
|
@@ -1726,12 +1837,22 @@ class SpiceModel {
|
|
|
1726
1837
|
return original_is_array ? data : data[0];
|
|
1727
1838
|
})();
|
|
1728
1839
|
}
|
|
1729
|
-
addModifier(
|
|
1840
|
+
addModifier(_ref21) {
|
|
1730
1841
|
var {
|
|
1731
1842
|
when,
|
|
1732
|
-
execute
|
|
1733
|
-
|
|
1843
|
+
execute,
|
|
1844
|
+
kind,
|
|
1845
|
+
source_property,
|
|
1846
|
+
store_property
|
|
1847
|
+
} = _ref21;
|
|
1734
1848
|
if (this[_serializers][when]) {
|
|
1849
|
+
if (kind) {
|
|
1850
|
+
execute.spiceModifier = {
|
|
1851
|
+
kind,
|
|
1852
|
+
source_property,
|
|
1853
|
+
store_property
|
|
1854
|
+
};
|
|
1855
|
+
}
|
|
1735
1856
|
this[_serializers][when]["modifiers"].push(execute);
|
|
1736
1857
|
}
|
|
1737
1858
|
}
|
|
@@ -1799,15 +1920,18 @@ class SpiceModel {
|
|
|
1799
1920
|
{
|
|
1800
1921
|
_this15.addModifier({
|
|
1801
1922
|
when: properties[i].map.when || "read",
|
|
1923
|
+
kind: "relationship_map",
|
|
1924
|
+
source_property: i,
|
|
1925
|
+
store_property: properties[i].map.destination || i,
|
|
1802
1926
|
execute: function () {
|
|
1803
|
-
var _execute = _asyncToGenerator(function* (data, old_data, ctx, type, args, mapping_dept, level, columns) {
|
|
1927
|
+
var _execute = _asyncToGenerator(function* (data, old_data, ctx, type, args, mapping_dept, level, columns, serializationType) {
|
|
1804
1928
|
// Skip if columns are specified but this field isn't included
|
|
1805
1929
|
if (!_this15.isFieldInColumns(i, columns)) {
|
|
1806
1930
|
return data;
|
|
1807
1931
|
}
|
|
1808
|
-
return yield _this15.mapToObject(data, _.isString(properties[i].map.reference) ? spice.models[properties[i].map.reference] : properties[i].map.reference, i, properties[i].map.destination || i, properties[i], args,
|
|
1932
|
+
return yield _this15.mapToObject(data, _.isString(properties[i].map.reference) ? spice.models[properties[i].map.reference] : properties[i].map.reference, i, properties[i].map.destination || i, properties[i], args, serializationType, mapping_dept, level, columns);
|
|
1809
1933
|
});
|
|
1810
|
-
function execute(
|
|
1934
|
+
function execute(_x4, _x5, _x6, _x7, _x8, _x9, _x0, _x1, _x10) {
|
|
1811
1935
|
return _execute.apply(this, arguments);
|
|
1812
1936
|
}
|
|
1813
1937
|
return execute;
|
|
@@ -1820,15 +1944,18 @@ class SpiceModel {
|
|
|
1820
1944
|
{
|
|
1821
1945
|
_this15.addModifier({
|
|
1822
1946
|
when: properties[i].map.when || "read",
|
|
1947
|
+
kind: "relationship_map",
|
|
1948
|
+
source_property: i,
|
|
1949
|
+
store_property: properties[i].map.destination || i,
|
|
1823
1950
|
execute: function () {
|
|
1824
|
-
var _execute2 = _asyncToGenerator(function* (data, old_data, ctx, type, args, mapping_dept, level, columns) {
|
|
1951
|
+
var _execute2 = _asyncToGenerator(function* (data, old_data, ctx, type, args, mapping_dept, level, columns, serializationType) {
|
|
1825
1952
|
// Skip if columns are specified but this field isn't included
|
|
1826
1953
|
if (!_this15.isFieldInColumns(i, columns)) {
|
|
1827
1954
|
return data;
|
|
1828
1955
|
}
|
|
1829
|
-
return yield _this15.mapToObjectArray(data, _.isString(properties[i].map.reference) ? spice.models[properties[i].map.reference] : properties[i].map.reference, i, properties[i].map.destination || i, properties[i], args,
|
|
1956
|
+
return yield _this15.mapToObjectArray(data, _.isString(properties[i].map.reference) ? spice.models[properties[i].map.reference] : properties[i].map.reference, i, properties[i].map.destination || i, properties[i], args, serializationType, mapping_dept, level, columns);
|
|
1830
1957
|
});
|
|
1831
|
-
function execute(
|
|
1958
|
+
function execute(_x11, _x12, _x13, _x14, _x15, _x16, _x17, _x18, _x19) {
|
|
1832
1959
|
return _execute2.apply(this, arguments);
|
|
1833
1960
|
}
|
|
1834
1961
|
return execute;
|
|
@@ -1860,7 +1987,7 @@ class SpiceModel {
|
|
|
1860
1987
|
// Profiling: use track() for proper async context forking
|
|
1861
1988
|
var p = (_this16$_ctx = _this16[_ctx]) == null ? void 0 : _this16$_ctx.profiler;
|
|
1862
1989
|
var doSerialize = /*#__PURE__*/function () {
|
|
1863
|
-
var
|
|
1990
|
+
var _ref22 = _asyncToGenerator(function* () {
|
|
1864
1991
|
var _this16$_serializers, _this16$_serializers$;
|
|
1865
1992
|
// Early exit if serialization should not run.
|
|
1866
1993
|
if (!_this16.shouldSerializerRun(args, type)) {
|
|
@@ -1875,19 +2002,117 @@ class SpiceModel {
|
|
|
1875
2002
|
|
|
1876
2003
|
// Cache the modifiers lookup for the specified type.
|
|
1877
2004
|
var modifiers = ((_this16$_serializers = _this16[_serializers]) == null ? void 0 : (_this16$_serializers$ = _this16$_serializers[type]) == null ? void 0 : _this16$_serializers$.modifiers) || [];
|
|
1878
|
-
|
|
1879
|
-
var
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
2005
|
+
var invokeModifier = /*#__PURE__*/function () {
|
|
2006
|
+
var _ref23 = _asyncToGenerator(function* (modifier, index, inputData) {
|
|
2007
|
+
try {
|
|
2008
|
+
var result = yield modifier(inputData, old_data, _this16[_ctx], _this16.type, args, _this16[_mapping_dept], _this16[_level], _this16[_columns], type);
|
|
2009
|
+
if (result !== undefined) {
|
|
2010
|
+
return {
|
|
2011
|
+
hasValue: true,
|
|
2012
|
+
value: result
|
|
2013
|
+
};
|
|
2014
|
+
}
|
|
2015
|
+
console.warn("Modifier #" + index + " for type=" + _this16.type + " returned undefined, keeping previous data");
|
|
2016
|
+
} catch (error) {
|
|
2017
|
+
console.error("Modifier error in do_serialize (type=" + _this16.type + ", modifier #" + index + "):", error instanceof Error ? error.stack : "Non-Error thrown: " + JSON.stringify(error));
|
|
1887
2018
|
}
|
|
1888
|
-
|
|
1889
|
-
|
|
2019
|
+
return {
|
|
2020
|
+
hasValue: false
|
|
2021
|
+
};
|
|
2022
|
+
});
|
|
2023
|
+
return function invokeModifier(_x20, _x21, _x22) {
|
|
2024
|
+
return _ref23.apply(this, arguments);
|
|
2025
|
+
};
|
|
2026
|
+
}();
|
|
2027
|
+
var modifierIndex = 0;
|
|
2028
|
+
var _loop2 = function* _loop2() {
|
|
2029
|
+
var _modifier$spiceModifi;
|
|
2030
|
+
var modifier = modifiers[modifierIndex];
|
|
2031
|
+
var canRunRelationshipMapsConcurrently = type === "read" && _this16[_level] === 0 && _this16[_mapping_concurrency] > 1 && (modifier == null ? void 0 : (_modifier$spiceModifi = modifier.spiceModifier) == null ? void 0 : _modifier$spiceModifi.kind) === "relationship_map";
|
|
2032
|
+
if (!canRunRelationshipMapsConcurrently) {
|
|
2033
|
+
var result = yield invokeModifier(modifier, modifierIndex, data);
|
|
2034
|
+
if (result.hasValue) data = result.value;
|
|
2035
|
+
modifierIndex += 1;
|
|
2036
|
+
return "continue";
|
|
2037
|
+
}
|
|
2038
|
+
var group = [];
|
|
2039
|
+
var destinations = new Set();
|
|
2040
|
+
while (modifierIndex < modifiers.length) {
|
|
2041
|
+
var candidate = modifiers[modifierIndex];
|
|
2042
|
+
var metadata = candidate == null ? void 0 : candidate.spiceModifier;
|
|
2043
|
+
if ((metadata == null ? void 0 : metadata.kind) !== "relationship_map") break;
|
|
2044
|
+
if (metadata.store_property && destinations.has(metadata.store_property)) {
|
|
2045
|
+
break;
|
|
2046
|
+
}
|
|
2047
|
+
if (metadata.store_property) {
|
|
2048
|
+
destinations.add(metadata.store_property);
|
|
2049
|
+
}
|
|
2050
|
+
group.push({
|
|
2051
|
+
modifier: candidate,
|
|
2052
|
+
index: modifierIndex,
|
|
2053
|
+
metadata
|
|
2054
|
+
});
|
|
2055
|
+
modifierIndex += 1;
|
|
1890
2056
|
}
|
|
2057
|
+
var groupQueuedAt = process.hrtime.bigint();
|
|
2058
|
+
var activeRequestMappings = 0;
|
|
2059
|
+
var executeGroup = /*#__PURE__*/function () {
|
|
2060
|
+
var _ref24 = _asyncToGenerator(function* () {
|
|
2061
|
+
return yield runWithConcurrency(group, _this16[_mapping_concurrency], /*#__PURE__*/function () {
|
|
2062
|
+
var _ref25 = _asyncToGenerator(function* (entry) {
|
|
2063
|
+
var requestQueueWaitMs = Number(process.hrtime.bigint() - groupQueuedAt) / 1e6;
|
|
2064
|
+
var globalSlot = yield acquireGlobalMappingSlot();
|
|
2065
|
+
activeRequestMappings += 1;
|
|
2066
|
+
var profileMetadata = {
|
|
2067
|
+
source_property: entry.metadata.source_property,
|
|
2068
|
+
store_property: entry.metadata.store_property,
|
|
2069
|
+
request_queue_wait_ms: Math.round(requestQueueWaitMs * 100) / 100,
|
|
2070
|
+
global_queue_wait_ms: Math.round(globalSlot.waitMs * 100) / 100,
|
|
2071
|
+
active_request_mappings: activeRequestMappings,
|
|
2072
|
+
request_limit: _this16[_mapping_concurrency],
|
|
2073
|
+
active_global_mappings: globalSlot.active,
|
|
2074
|
+
global_limit: GLOBAL_MAPPING_CONCURRENCY
|
|
2075
|
+
};
|
|
2076
|
+
try {
|
|
2077
|
+
var execute = /*#__PURE__*/function () {
|
|
2078
|
+
var _ref26 = _asyncToGenerator(function* () {
|
|
2079
|
+
return yield invokeModifier(entry.modifier, entry.index, data);
|
|
2080
|
+
});
|
|
2081
|
+
return function execute() {
|
|
2082
|
+
return _ref26.apply(this, arguments);
|
|
2083
|
+
};
|
|
2084
|
+
}();
|
|
2085
|
+
if (p) {
|
|
2086
|
+
return yield p.track(_this16.type + ".map.concurrent." + entry.metadata.source_property, execute, profileMetadata);
|
|
2087
|
+
}
|
|
2088
|
+
return yield execute();
|
|
2089
|
+
} finally {
|
|
2090
|
+
activeRequestMappings -= 1;
|
|
2091
|
+
globalSlot.release();
|
|
2092
|
+
}
|
|
2093
|
+
});
|
|
2094
|
+
return function (_x23) {
|
|
2095
|
+
return _ref25.apply(this, arguments);
|
|
2096
|
+
};
|
|
2097
|
+
}());
|
|
2098
|
+
});
|
|
2099
|
+
return function executeGroup() {
|
|
2100
|
+
return _ref24.apply(this, arguments);
|
|
2101
|
+
};
|
|
2102
|
+
}();
|
|
2103
|
+
var groupMetadata = {
|
|
2104
|
+
map_count: group.length,
|
|
2105
|
+
request_limit: _this16[_mapping_concurrency],
|
|
2106
|
+
global_limit: GLOBAL_MAPPING_CONCURRENCY
|
|
2107
|
+
};
|
|
2108
|
+
var groupResults = p ? yield p.track(_this16.type + ".map.concurrent", executeGroup, groupMetadata) : yield executeGroup();
|
|
2109
|
+
for (var _result of groupResults) {
|
|
2110
|
+
if (_result == null ? void 0 : _result.hasValue) data = _result.value;
|
|
2111
|
+
}
|
|
2112
|
+
};
|
|
2113
|
+
while (modifierIndex < modifiers.length) {
|
|
2114
|
+
var _ret = yield* _loop2();
|
|
2115
|
+
if (_ret === "continue") continue;
|
|
1891
2116
|
}
|
|
1892
2117
|
|
|
1893
2118
|
// Ensure data is always an array for consistent processing.
|
|
@@ -1928,7 +2153,7 @@ class SpiceModel {
|
|
|
1928
2153
|
return originalIsArray ? data : data[0];
|
|
1929
2154
|
});
|
|
1930
2155
|
return function doSerialize() {
|
|
1931
|
-
return
|
|
2156
|
+
return _ref22.apply(this, arguments);
|
|
1932
2157
|
};
|
|
1933
2158
|
}();
|
|
1934
2159
|
try {
|