@routier/core 0.6.0 → 0.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/dist/assertions/index.cjs +19 -8
- package/dist/assertions/index.cjs.map +1 -1
- package/dist/assertions/index.d.ts +5 -1
- package/dist/assertions/index.js +21 -9
- package/dist/assertions/index.js.map +1 -1
- package/dist/collections/MemoryDataCollection.d.ts +10 -0
- package/dist/collections/index.cjs +29 -4
- package/dist/collections/index.cjs.map +1 -1
- package/dist/collections/index.js +29 -4
- package/dist/collections/index.js.map +1 -1
- package/dist/expressions/callSource.d.ts +41 -0
- package/dist/expressions/evaluate.d.ts +3 -0
- package/dist/expressions/fold.d.ts +7 -0
- package/dist/expressions/index.cjs +1754 -233
- package/dist/expressions/index.cjs.map +1 -1
- package/dist/expressions/index.d.ts +2 -0
- package/dist/expressions/index.js +1765 -234
- package/dist/expressions/index.js.map +1 -1
- package/dist/expressions/types.d.ts +45 -26
- package/dist/expressions/utils.d.ts +19 -1
- package/dist/index.cjs +2415 -364
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2755 -684
- package/dist/index.js.map +1 -1
- package/dist/performance/index.cjs +6 -4
- package/dist/performance/index.cjs.map +1 -1
- package/dist/performance/index.js +6 -4
- package/dist/performance/index.js.map +1 -1
- package/dist/pipeline/index.cjs +6 -4
- package/dist/pipeline/index.cjs.map +1 -1
- package/dist/pipeline/index.js +6 -4
- package/dist/pipeline/index.js.map +1 -1
- package/dist/plugins/index.cjs +2309 -316
- package/dist/plugins/index.cjs.map +1 -1
- package/dist/plugins/index.js +2313 -311
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/query/QueryOptionsCollection.d.ts +38 -10
- package/dist/plugins/query/describeFilter.d.ts +83 -0
- package/dist/plugins/query/explain.d.ts +71 -9
- package/dist/plugins/query/index.d.ts +1 -0
- package/dist/plugins/query/join.d.ts +4 -1
- package/dist/plugins/query/types.d.ts +36 -4
- package/dist/schema/PropertyInfo.d.ts +0 -1
- package/dist/schema/index.cjs +7 -14
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.js +7 -14
- package/dist/schema/index.js.map +1 -1
- package/dist/utilities/index.cjs +242 -49
- package/dist/utilities/index.cjs.map +1 -1
- package/dist/utilities/index.js +242 -49
- package/dist/utilities/index.js.map +1 -1
- package/package.json +1 -1
package/dist/utilities/index.cjs
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
var __webpack_modules__ = ({
|
|
4
4
|
126(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
5
5
|
__webpack_require__.d(__webpack_exports__, {
|
|
6
|
-
|
|
6
|
+
isComparatorExpression: () => (isComparatorExpression),
|
|
7
|
+
isPropertyExpression: () => (isPropertyExpression),
|
|
8
|
+
isValueExpression: () => (isValueExpression)
|
|
7
9
|
});
|
|
8
10
|
|
|
9
11
|
|
|
@@ -75,6 +77,11 @@ function isObjectWithType(value) {
|
|
|
75
77
|
*/ function isValueExpression(value) {
|
|
76
78
|
return isObjectWithType(value) && value.type === "value";
|
|
77
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Type guard: narrows `value` to `CallExpression` when it is an object with `type === "call"`.
|
|
82
|
+
*/ function isCallExpression(value) {
|
|
83
|
+
return isObjectWithType(value) && value.type === "call";
|
|
84
|
+
}
|
|
78
85
|
/**
|
|
79
86
|
* Type guard: narrows `value` to `EmptyExpression` when it is an object with `type === "empty"`.
|
|
80
87
|
*/ function isEmptyExpression(value) {
|
|
@@ -90,8 +97,42 @@ function isObjectWithType(value) {
|
|
|
90
97
|
},
|
|
91
98
|
63(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
92
99
|
__webpack_require__.d(__webpack_exports__, {
|
|
93
|
-
|
|
100
|
+
jJ: () => (forEach)
|
|
94
101
|
});
|
|
102
|
+
/**
|
|
103
|
+
* Separates an operand from the calls applied to it.
|
|
104
|
+
*
|
|
105
|
+
* `null` when there is no operand beneath the calls. Every consumer needs this to decide whether a
|
|
106
|
+
* comparator side is a property or a value, so it lives here rather than in each translator.
|
|
107
|
+
*/ function peelCalls(expression) {
|
|
108
|
+
const calls = [];
|
|
109
|
+
let current = expression;
|
|
110
|
+
while(current != null && current.type === "call"){
|
|
111
|
+
calls.unshift(current);
|
|
112
|
+
current = current.expression;
|
|
113
|
+
}
|
|
114
|
+
return current == null ? null : {
|
|
115
|
+
operand: current,
|
|
116
|
+
calls
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function childrenOf(expression) {
|
|
120
|
+
if (expression.type === "call") {
|
|
121
|
+
const call = expression;
|
|
122
|
+
return [
|
|
123
|
+
call.expression,
|
|
124
|
+
...call.arguments ?? []
|
|
125
|
+
].filter((child)=>child != null);
|
|
126
|
+
}
|
|
127
|
+
const children = [];
|
|
128
|
+
if (expression.left != null) {
|
|
129
|
+
children.push(expression.left);
|
|
130
|
+
}
|
|
131
|
+
if (expression.right != null) {
|
|
132
|
+
children.push(expression.right);
|
|
133
|
+
}
|
|
134
|
+
return children;
|
|
135
|
+
}
|
|
95
136
|
/**
|
|
96
137
|
* Extracts all properties referenced in an expression
|
|
97
138
|
* @param expression The expression to analyze
|
|
@@ -103,12 +144,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
103
144
|
if (expr.type === "property") {
|
|
104
145
|
properties.push(expr.property);
|
|
105
146
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
traverse(expr.left);
|
|
109
|
-
}
|
|
110
|
-
if (expr.right) {
|
|
111
|
-
traverse(expr.right);
|
|
147
|
+
for (const child of childrenOf(expr)){
|
|
148
|
+
traverse(child);
|
|
112
149
|
}
|
|
113
150
|
}
|
|
114
151
|
traverse(expression);
|
|
@@ -121,14 +158,8 @@ function forEach(expression, callback) {
|
|
|
121
158
|
if (!callback(expr)) {
|
|
122
159
|
return false;
|
|
123
160
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (!traverse(expr.left)) {
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
if (expr.right) {
|
|
131
|
-
if (!traverse(expr.right)) {
|
|
161
|
+
for (const child of childrenOf(expr)){
|
|
162
|
+
if (!traverse(child)) {
|
|
132
163
|
return false;
|
|
133
164
|
}
|
|
134
165
|
}
|
|
@@ -144,32 +175,62 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
144
175
|
H: () => (QueryOptionsCollection)
|
|
145
176
|
});
|
|
146
177
|
/* import */ var _assertions__rspack_import_1 = __webpack_require__(126);
|
|
147
|
-
/* import */ var
|
|
178
|
+
/* import */ var _expressions_utils__rspack_import_2 = __webpack_require__(63);
|
|
179
|
+
/* import */ var _schema_types__rspack_import_0 = __webpack_require__(537);
|
|
180
|
+
/* import */ var _utilities__rspack_import_3 = __webpack_require__(581);
|
|
148
181
|
|
|
149
182
|
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
/** What a schema type is called in JavaScript, where one exists. A value of any other type cannot equal it. */ const JAVASCRIPT_TYPE_OF = {
|
|
186
|
+
[_schema_types__rspack_import_0/* .SchemaTypes.Number */.L.Number]: "number",
|
|
187
|
+
[_schema_types__rspack_import_0/* .SchemaTypes.String */.L.String]: "string",
|
|
188
|
+
[_schema_types__rspack_import_0/* .SchemaTypes.Boolean */.L.Boolean]: "boolean",
|
|
189
|
+
[_schema_types__rspack_import_0/* .SchemaTypes.Date */.L.Date]: "object"
|
|
190
|
+
};
|
|
191
|
+
const mismatchedSide = (property, value)=>{
|
|
192
|
+
if (property == null || value == null || !(0,_assertions__rspack_import_1.isPropertyExpression)(property) || !(0,_assertions__rspack_import_1.isValueExpression)(value)) {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
const expected = JAVASCRIPT_TYPE_OF[property.property.type];
|
|
196
|
+
if (expected == null || value.value == null || typeof value.value === expected) {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
property,
|
|
201
|
+
value,
|
|
202
|
+
expected
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
/** A strict comparison whose answer is the same for every row, because the types cannot be equal. */ const comparesTypesThatCannotMatch = (expression)=>{
|
|
206
|
+
if (!(0,_assertions__rspack_import_1.isComparatorExpression)(expression) || expression.strict !== true) {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
if (expression.comparator !== "equals") {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
return mismatchedSide(expression.left, expression.right) != null || mismatchedSide(expression.right, expression.left) != null;
|
|
213
|
+
};
|
|
214
|
+
/** `JSON.stringify` throws on a BigInt, and this runs inside the guard that exists to catch one. */ const describeLiteral = (value)=>typeof value === "string" ? `"${value}"` : String(value);
|
|
215
|
+
const mismatchWarning = (expression)=>{
|
|
216
|
+
const side = mismatchedSide(expression.left, expression.right) ?? mismatchedSide(expression.right, expression.left);
|
|
217
|
+
const outcome = expression.negated ? "every row matches" : "no row matches";
|
|
218
|
+
return `Routier: '${side.property.property.getAssignmentPath()}' is a ${side.expected}, and this filter ` + `compares it against ${describeLiteral(side.value.value)}, which is a ${typeof side.value.value}. ` + `A strict comparison between them is the same answer for every row, so ${outcome} and the filter ` + `runs in memory. https://routier.dev/guides/strict-comparison-types`;
|
|
219
|
+
};
|
|
150
220
|
class QueryOptionsCollection {
|
|
151
221
|
options = new Map();
|
|
152
222
|
nextExecutionTarget = "database";
|
|
153
223
|
nextExecutionReason = null;
|
|
154
224
|
nextIndex = 0;
|
|
155
225
|
enumeratedItems = [];
|
|
226
|
+
dirty = true;
|
|
227
|
+
/** The collection a `splitAt`/`split` half came from. A capability report belongs to it. */ origin = null;
|
|
156
228
|
/** Cuts over to memory execution, keeping the first cause. See `MemoryExecutionReason`. */ cutOverToMemory(reason) {
|
|
157
229
|
this.nextExecutionTarget = "memory";
|
|
158
230
|
if (this.nextExecutionReason == null) {
|
|
159
231
|
this.nextExecutionReason = reason;
|
|
160
232
|
}
|
|
161
233
|
}
|
|
162
|
-
/**
|
|
163
|
-
* True when `split()` or `splitAt()` produced this collection.
|
|
164
|
-
*
|
|
165
|
-
* Those rebuild each half by re-adding its options, which re-derives execution targets
|
|
166
|
-
* without the options that caused them — a post-join filter alone in the memory half
|
|
167
|
-
* derives back to `"database"`. Anything reading `target` as a report of where work runs
|
|
168
|
-
* has to reject a derived collection; see `explainQuery`.
|
|
169
|
-
*/ derived = false;
|
|
170
|
-
get isDerived() {
|
|
171
|
-
return this.derived;
|
|
172
|
-
}
|
|
173
234
|
get items() {
|
|
174
235
|
return this.options;
|
|
175
236
|
}
|
|
@@ -204,7 +265,7 @@ class QueryOptionsCollection {
|
|
|
204
265
|
if (filterValue.expression.type === "not-parsable") {
|
|
205
266
|
this.cutOverToMemory("not-parsable");
|
|
206
267
|
} else {
|
|
207
|
-
(0,
|
|
268
|
+
(0,_expressions_utils__rspack_import_2/* .forEach */.jJ)(filterValue.expression, (expression)=>{
|
|
208
269
|
if ((0,_assertions__rspack_import_1.isPropertyExpression)(expression) && expression.property.isUnmapped) {
|
|
209
270
|
// Cut over to memory execution, unmapped properties are not in the database and
|
|
210
271
|
// cannot be queried
|
|
@@ -219,6 +280,11 @@ class QueryOptionsCollection {
|
|
|
219
280
|
this.cutOverToMemory("renamed-property");
|
|
220
281
|
return false;
|
|
221
282
|
}
|
|
283
|
+
if (comparesTypesThatCannotMatch(expression)) {
|
|
284
|
+
_utilities__rspack_import_3/* .logger.warn */.vF.warn(mismatchWarning(expression));
|
|
285
|
+
this.cutOverToMemory("predicate-error");
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
222
288
|
return true;
|
|
223
289
|
});
|
|
224
290
|
}
|
|
@@ -247,6 +313,11 @@ class QueryOptionsCollection {
|
|
|
247
313
|
this.cutOverToMemory("renamed-property");
|
|
248
314
|
}
|
|
249
315
|
}
|
|
316
|
+
if ((name === "filter" || name === "sort") && (this.options.has("skip") || this.options.has("take"))) {
|
|
317
|
+
// SQL emits WHERE before LIMIT and Mongo's find() filters before skipping, so an option
|
|
318
|
+
// written after a window can only see the windowed rows if it runs after it.
|
|
319
|
+
this.cutOverToMemory("after-window");
|
|
320
|
+
}
|
|
250
321
|
if (name === "join") {
|
|
251
322
|
const joinValue = value;
|
|
252
323
|
// A join whose two sides live on different plugins cannot be sent to EITHER of
|
|
@@ -259,18 +330,24 @@ class QueryOptionsCollection {
|
|
|
259
330
|
this.cutOverToMemory("cross-plugin-join");
|
|
260
331
|
}
|
|
261
332
|
}
|
|
333
|
+
// `executed` is the plan, not a record: nothing has run when an option is added. Every
|
|
334
|
+
// consumer reads it after the plugin returned, so the optimistic window is never observed.
|
|
262
335
|
const item = {
|
|
263
336
|
index: this.nextIndex,
|
|
264
|
-
option: {
|
|
337
|
+
option: this.nextExecutionTarget === "database" ? {
|
|
338
|
+
name,
|
|
339
|
+
value,
|
|
340
|
+
target: "database",
|
|
341
|
+
reason: "executed"
|
|
342
|
+
} : {
|
|
265
343
|
name,
|
|
266
|
-
target: this.nextExecutionTarget,
|
|
267
344
|
value,
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
345
|
+
target: "memory",
|
|
346
|
+
reason: this.nextExecutionReason ?? "not-parsable"
|
|
271
347
|
}
|
|
272
348
|
};
|
|
273
349
|
this.nextIndex++;
|
|
350
|
+
this.dirty = true;
|
|
274
351
|
const found = this.options.get(name);
|
|
275
352
|
this.options.set(name, [
|
|
276
353
|
...found ?? [],
|
|
@@ -315,8 +392,6 @@ class QueryOptionsCollection {
|
|
|
315
392
|
const sortedItems = this.enumeratedItems.toSorted((a, b)=>a.index - b.index);
|
|
316
393
|
const before = new QueryOptionsCollection();
|
|
317
394
|
const after = new QueryOptionsCollection();
|
|
318
|
-
before.derived = true;
|
|
319
|
-
after.derived = true;
|
|
320
395
|
let at = null;
|
|
321
396
|
for(let i = 0, length = sortedItems.length; i < length; i++){
|
|
322
397
|
const { option } = sortedItems[i];
|
|
@@ -325,8 +400,10 @@ class QueryOptionsCollection {
|
|
|
325
400
|
continue;
|
|
326
401
|
}
|
|
327
402
|
const destination = at == null ? before : after;
|
|
328
|
-
destination.
|
|
403
|
+
destination.adopt(sortedItems[i]);
|
|
329
404
|
}
|
|
405
|
+
before.origin = this.origin ?? this;
|
|
406
|
+
after.origin = this.origin ?? this;
|
|
330
407
|
return {
|
|
331
408
|
before,
|
|
332
409
|
at,
|
|
@@ -358,23 +435,99 @@ class QueryOptionsCollection {
|
|
|
358
435
|
this.nextExecutionReason = nextExecutionReason;
|
|
359
436
|
this.nextIndex = nextIndex;
|
|
360
437
|
this.enumeratedItems = [];
|
|
438
|
+
// Clearing the list is not enough now that staleness is a flag rather than a count:
|
|
439
|
+
// without this, `resolveEnumeration` believes the empty list is current and every read
|
|
440
|
+
// of the collection sees no options at all.
|
|
441
|
+
this.dirty = true;
|
|
361
442
|
};
|
|
362
443
|
}
|
|
444
|
+
/** Takes an item as it stands — same object, same index, same target and reason. */ adopt(item) {
|
|
445
|
+
const found = this.options.get(item.option.name);
|
|
446
|
+
this.options.set(item.option.name, [
|
|
447
|
+
...found ?? [],
|
|
448
|
+
item
|
|
449
|
+
]);
|
|
450
|
+
this.nextIndex = Math.max(this.nextIndex, item.index + 1);
|
|
451
|
+
this.dirty = true;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* A plugin reporting that its engine cannot express one option.
|
|
455
|
+
*
|
|
456
|
+
* Core marks the rest of the database phase `not-reached`, because the database has to stop
|
|
457
|
+
* there — a window applied in front of a filter that was not applied returns the wrong rows.
|
|
458
|
+
* Passing the cascade through core is what makes it impossible for a plugin to mark a
|
|
459
|
+
* non-contiguous cut.
|
|
460
|
+
*
|
|
461
|
+
* A report names a culprit and never un-names one, so reports commute.
|
|
462
|
+
*
|
|
463
|
+
* The option is not moved to the memory arm. It stays where it was planned, which is what keeps
|
|
464
|
+
* a redirect distinguishable from something core sent to memory in the first place.
|
|
465
|
+
*/ reportMissingCapability(item) {
|
|
466
|
+
this.report(item, "missing-capability");
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* A plugin reporting that its engine would answer one option differently from JavaScript.
|
|
470
|
+
*
|
|
471
|
+
* Same cascade as `reportMissingCapability`, and a separate reason because the caller can act on
|
|
472
|
+
* one and not the other. See `DatabaseExecutionReason`.
|
|
473
|
+
*/ reportEngineDivergence(item) {
|
|
474
|
+
this.report(item, "engine-divergence");
|
|
475
|
+
}
|
|
476
|
+
report(item, reason) {
|
|
477
|
+
// A half can only see its own slice, and the database has to stop for the whole dispatch.
|
|
478
|
+
if (this.origin != null) {
|
|
479
|
+
this.origin.report(item, reason);
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
this.resolveEnumeration();
|
|
483
|
+
for (const candidate of this.enumeratedItems){
|
|
484
|
+
if (candidate.option.target !== "database" || candidate.index < item.index) {
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
if (candidate.index === item.index) {
|
|
488
|
+
candidate.option.reason = reason;
|
|
489
|
+
continue;
|
|
490
|
+
}
|
|
491
|
+
if (candidate.option.reason === "executed") {
|
|
492
|
+
candidate.option.reason = "not-reached";
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Forgets what any previous dispatch reported.
|
|
498
|
+
*
|
|
499
|
+
* Capability is answered per dispatch, so a report is only an answer for the execution that
|
|
500
|
+
* produced it. The items are shared with any snapshot, so a report mutated in place otherwise
|
|
501
|
+
* survives a restore and a second terminal on the same queryable replays options the plugin
|
|
502
|
+
* did run — a `skip` applied twice, over rows already windowed.
|
|
503
|
+
*/ forgetReports() {
|
|
504
|
+
this.resolveEnumeration();
|
|
505
|
+
for (const item of this.enumeratedItems){
|
|
506
|
+
if (item.option.target === "database") {
|
|
507
|
+
item.option.reason = "executed";
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
/** The options the database did not run, in the order they were written. */ notExecuted() {
|
|
512
|
+
this.resolveEnumeration();
|
|
513
|
+
return this.enumeratedItems.filter((item)=>item.option.target === "database" && item.option.reason !== "executed").toSorted((a, b)=>a.index - b.index);
|
|
514
|
+
}
|
|
363
515
|
split() {
|
|
364
516
|
this.resolveEnumeration();
|
|
365
517
|
const sortedItems = this.enumeratedItems.toSorted((a, b)=>a.index - b.index);
|
|
366
518
|
const memoryQueryOptionsCollection = new QueryOptionsCollection();
|
|
367
519
|
const databaseQueryOptionsCollection = new QueryOptionsCollection();
|
|
368
|
-
memoryQueryOptionsCollection.derived = true;
|
|
369
|
-
databaseQueryOptionsCollection.derived = true;
|
|
370
520
|
for(let i = 0, length = sortedItems.length; i < length; i++){
|
|
371
521
|
const sortedItem = sortedItems[i];
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
522
|
+
const half = sortedItem.option.target === "database" ? databaseQueryOptionsCollection : memoryQueryOptionsCollection;
|
|
523
|
+
// The ITEM, not its name and value. Re-adding would re-derive target and reason from a
|
|
524
|
+
// fresh cascade, and a memory option re-added alone comes back out as `database` with no
|
|
525
|
+
// reason at all. Sharing it also means a plugin's report on the database half is the
|
|
526
|
+
// same object the explanation reads.
|
|
527
|
+
half.adopt(sortedItem);
|
|
377
528
|
}
|
|
529
|
+
memoryQueryOptionsCollection.origin = this.origin ?? this;
|
|
530
|
+
databaseQueryOptionsCollection.origin = this.origin ?? this;
|
|
378
531
|
return {
|
|
379
532
|
memory: memoryQueryOptionsCollection,
|
|
380
533
|
database: databaseQueryOptionsCollection
|
|
@@ -420,8 +573,11 @@ class QueryOptionsCollection {
|
|
|
420
573
|
].flat().toSorted((a, b)=>a.index - b.index);
|
|
421
574
|
}
|
|
422
575
|
resolveEnumeration() {
|
|
423
|
-
|
|
576
|
+
// A flag, not a count: adopting leaves gaps in the indexes, so `length !== nextIndex` is
|
|
577
|
+
// true forever on a half and the enumeration rebuilds on every read.
|
|
578
|
+
if (this.dirty === true) {
|
|
424
579
|
this.enumeratedItems = this.getEnumeration();
|
|
580
|
+
this.dirty = false;
|
|
425
581
|
}
|
|
426
582
|
}
|
|
427
583
|
forEach(iterator) {
|
|
@@ -433,6 +589,41 @@ class QueryOptionsCollection {
|
|
|
433
589
|
}
|
|
434
590
|
|
|
435
591
|
|
|
592
|
+
},
|
|
593
|
+
537(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
594
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
595
|
+
L: () => (SchemaTypes)
|
|
596
|
+
});
|
|
597
|
+
var SchemaTypes = /*#__PURE__*/ function(SchemaTypes) {
|
|
598
|
+
SchemaTypes["Array"] = "Array";
|
|
599
|
+
SchemaTypes["Boolean"] = "Boolean";
|
|
600
|
+
SchemaTypes["Date"] = "Date";
|
|
601
|
+
SchemaTypes["Number"] = "Number";
|
|
602
|
+
SchemaTypes["Object"] = "Object";
|
|
603
|
+
SchemaTypes["String"] = "String";
|
|
604
|
+
SchemaTypes["Definition"] = "Definition";
|
|
605
|
+
SchemaTypes["Function"] = "Function";
|
|
606
|
+
SchemaTypes["Computed"] = "Computed";
|
|
607
|
+
/**
|
|
608
|
+
* Content in, reference out. The only type whose write shape differs from its stored
|
|
609
|
+
* shape, and a leaf on purpose — see `SchemaFile`.
|
|
610
|
+
*/ SchemaTypes["File"] = "File";
|
|
611
|
+
/**
|
|
612
|
+
* A fixed-length list of numbers, carrying its dimension count — see `SchemaVector`.
|
|
613
|
+
*
|
|
614
|
+
* Value-shaped exactly like `s.array(s.number())`, which is why every array codegen
|
|
615
|
+
* handler accepts it. It is a distinct type only so a backend can recognise it and store
|
|
616
|
+
* it natively; nothing else needs to tell the two apart.
|
|
617
|
+
*/ SchemaTypes["Vector"] = "Vector";
|
|
618
|
+
return SchemaTypes;
|
|
619
|
+
}({});
|
|
620
|
+
var HashType = /*#__PURE__*/ (/* unused pure expression or super */ null && (function(HashType) {
|
|
621
|
+
HashType["Ids"] = "Ids";
|
|
622
|
+
HashType["Object"] = "Object";
|
|
623
|
+
return HashType;
|
|
624
|
+
}({})));
|
|
625
|
+
|
|
626
|
+
|
|
436
627
|
},
|
|
437
628
|
76(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
438
629
|
__webpack_require__.d(__webpack_exports__, {
|
|
@@ -529,12 +720,14 @@ const isLogLevel = (value)=>typeof value === 'string' && LOG_LEVELS.includes(val
|
|
|
529
720
|
const debug = process.env.DEBUG;
|
|
530
721
|
if (debug === 'routier' || debug === '*') return 'debug';
|
|
531
722
|
const env = "production"?.toLowerCase();
|
|
532
|
-
// `test` is deliberately absent. It used to be here, which meant no test suite anywhere
|
|
533
|
-
// could run Routier quietly. Opt in with DEBUG=routier or ROUTIER_LOG_LEVEL when a test
|
|
534
|
-
// needs the output.
|
|
535
723
|
if (env === 'dev' || env === 'development') return 'debug';
|
|
536
724
|
}
|
|
537
|
-
|
|
725
|
+
// Warnings are on unless something turns them off.
|
|
726
|
+
//
|
|
727
|
+
// Routier warns when a query returns correct rows a slower way than it could, or when a filter
|
|
728
|
+
// compares types that can never match. Both are the caller's to act on, and a default of
|
|
729
|
+
// `silent` meant the only people who ever saw them were the ones who already knew to look.
|
|
730
|
+
return 'warn';
|
|
538
731
|
};
|
|
539
732
|
let level = resolveLevel();
|
|
540
733
|
let rank = RANK[level];
|