@routier/core 0.7.0 → 0.8.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/codegen/blocks.d.ts +17 -1
- package/dist/codegen/handlers/types.d.ts +13 -5
- package/dist/codegen/index.cjs +28 -0
- package/dist/codegen/index.cjs.map +1 -1
- package/dist/codegen/index.js +28 -0
- package/dist/codegen/index.js.map +1 -1
- package/dist/collections/MemoryDataCollection.d.ts +2 -4
- package/dist/collections/index.cjs +127 -15
- package/dist/collections/index.cjs.map +1 -1
- package/dist/collections/index.js +127 -15
- package/dist/collections/index.js.map +1 -1
- package/dist/expressions/index.cjs +226 -4
- package/dist/expressions/index.cjs.map +1 -1
- package/dist/expressions/index.js +228 -5
- package/dist/expressions/index.js.map +1 -1
- package/dist/expressions/parser.d.ts +42 -1
- package/dist/index.cjs +753 -345
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +756 -345
- package/dist/index.js.map +1 -1
- package/dist/plugins/EphemeralDataPlugin.d.ts +8 -0
- package/dist/plugins/index.cjs +566 -49
- package/dist/plugins/index.cjs.map +1 -1
- package/dist/plugins/index.js +566 -48
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/query/QueryOptionsCollection.d.ts +15 -5
- package/dist/plugins/query/index.d.ts +1 -0
- package/dist/plugins/query/renames.d.ts +27 -0
- package/dist/plugins/query/types.d.ts +15 -1
- package/dist/plugins/translators/SqlTranslator.d.ts +15 -0
- package/dist/schema/SchemaDefinition.d.ts +8 -0
- package/dist/schema/changeTracker.d.ts +10 -0
- package/dist/schema/index.cjs +291 -274
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +294 -276
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/types.d.ts +8 -7
- package/dist/schema/utils/storageDates.d.ts +25 -0
- package/dist/transfer/index.cjs.map +1 -1
- package/dist/transfer/index.js.map +1 -1
- package/dist/utilities/index.cjs +74 -29
- package/dist/utilities/index.cjs.map +1 -1
- package/dist/utilities/index.js +74 -29
- package/dist/utilities/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/codegen/utils.d.ts +0 -22
package/dist/schema/index.cjs
CHANGED
|
@@ -346,6 +346,14 @@ class FunctionFactoryBuilder extends ContainerBlock {
|
|
|
346
346
|
this._params.push(...params);
|
|
347
347
|
return this;
|
|
348
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* Adds a factory parameter carrying `value` and returns its name, for generated code to
|
|
351
|
+
* refer to. See `CodeBuilder.bind` for why values travel this way.
|
|
352
|
+
*/ bind(value) {
|
|
353
|
+
const parameter = this.createParameter(value);
|
|
354
|
+
this._params.push(parameter);
|
|
355
|
+
return parameter.name;
|
|
356
|
+
}
|
|
349
357
|
return() {
|
|
350
358
|
this._return = true;
|
|
351
359
|
return this;
|
|
@@ -461,6 +469,26 @@ class IfBuilder extends ContainerBlock {
|
|
|
461
469
|
}
|
|
462
470
|
}
|
|
463
471
|
class CodeBuilder extends ContainerBlock {
|
|
472
|
+
_bindings = [];
|
|
473
|
+
/**
|
|
474
|
+
* Makes `value` available to the generated function under the returned name.
|
|
475
|
+
*
|
|
476
|
+
* Generated code must never reach a runtime value by its source name or by pasting its
|
|
477
|
+
* source text: a minifier renames the declaration and cannot see inside the generated
|
|
478
|
+
* string, and pasted source loses the scope it closed over (#40, #46). A binding is passed
|
|
479
|
+
* in as a real value when the function is compiled, so it survives any bundler.
|
|
480
|
+
*/ bind(value, name = `binding${this._bindings.length}`) {
|
|
481
|
+
this._bindings.push({
|
|
482
|
+
name,
|
|
483
|
+
value
|
|
484
|
+
});
|
|
485
|
+
return name;
|
|
486
|
+
}
|
|
487
|
+
getBindings() {
|
|
488
|
+
return [
|
|
489
|
+
...this._bindings
|
|
490
|
+
];
|
|
491
|
+
}
|
|
464
492
|
toString() {
|
|
465
493
|
return this._lines.map((line)=>typeof line === 'string' ? this.indent(line) : line.toString()).join('\n\n');
|
|
466
494
|
}
|
|
@@ -543,6 +571,129 @@ var HashType = /*#__PURE__*/ function(HashType) {
|
|
|
543
571
|
}({});
|
|
544
572
|
|
|
545
573
|
|
|
574
|
+
},
|
|
575
|
+
575(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
576
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
577
|
+
L: () => (hasPrimitiveElements),
|
|
578
|
+
l: () => (isArrayValued)
|
|
579
|
+
});
|
|
580
|
+
/* import */ var _types__rspack_import_0 = __webpack_require__(537);
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Types whose runtime value is a JS array.
|
|
584
|
+
*
|
|
585
|
+
* `Array` and `Vector` are the same thing to every layer that copies, compares, hashes or
|
|
586
|
+
* freezes a value — a vector is a list of numbers and nothing more. They differ only where a
|
|
587
|
+
* backend chooses storage, which is the one place that should ask for `SchemaTypes.Vector` by
|
|
588
|
+
* name.
|
|
589
|
+
*
|
|
590
|
+
* This exists so adding a third array-shaped type is one edit rather than a hunt through
|
|
591
|
+
* twelve handlers. Missing one of those is silent in the worst way: a vector that clones by
|
|
592
|
+
* reference is shared with the change tracker's copy, so overwriting an embedding produces no
|
|
593
|
+
* diff and the save reports nothing to do.
|
|
594
|
+
*/ const ARRAY_VALUED_TYPES = new Set([
|
|
595
|
+
_types__rspack_import_0/* .SchemaTypes.Array */.L.Array,
|
|
596
|
+
_types__rspack_import_0/* .SchemaTypes.Vector */.L.Vector
|
|
597
|
+
]);
|
|
598
|
+
/** True when the property's value is a JS array and needs value rather than reference semantics. */ const isArrayValued = (type)=>ARRAY_VALUED_TYPES.has(type);
|
|
599
|
+
/**
|
|
600
|
+
* True when the property's elements are primitives, so a spread is a sufficient copy.
|
|
601
|
+
*
|
|
602
|
+
* A vector is always numbers, so it never needs the per-element deep copy an array of objects
|
|
603
|
+
* or dates does.
|
|
604
|
+
*/ const PRIMITIVE_ELEMENT_TYPES = new Set([
|
|
605
|
+
_types__rspack_import_0/* .SchemaTypes.String */.L.String,
|
|
606
|
+
_types__rspack_import_0/* .SchemaTypes.Number */.L.Number,
|
|
607
|
+
_types__rspack_import_0/* .SchemaTypes.Boolean */.L.Boolean
|
|
608
|
+
]);
|
|
609
|
+
const hasPrimitiveElements = (type, elementType)=>type === _types__rspack_import_0/* .SchemaTypes.Vector */.L.Vector || PRIMITIVE_ELEMENT_TYPES.has(elementType);
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
},
|
|
613
|
+
894(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
614
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
615
|
+
T: () => (getStorageDateReviver)
|
|
616
|
+
});
|
|
617
|
+
/* import */ var _types__rspack_import_0 = __webpack_require__(537);
|
|
618
|
+
/* import */ var _propertyKind__rspack_import_1 = __webpack_require__(575);
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
const collectDatePaths = (properties, paths)=>{
|
|
622
|
+
for (const property of properties){
|
|
623
|
+
// The stored value belongs to whoever wrote it: a custom serializer, deserializer or
|
|
624
|
+
// transform reads it back, and would be handed a Date it did not expect. Unmapped
|
|
625
|
+
// properties are never stored.
|
|
626
|
+
if (property.valueSerializer != null || property.valueDeserializer != null || property.transform != null || property.isUnmapped) {
|
|
627
|
+
continue;
|
|
628
|
+
}
|
|
629
|
+
if (property.type === _types__rspack_import_0/* .SchemaTypes.Object */.L.Object) {
|
|
630
|
+
collectDatePaths(property.children, paths);
|
|
631
|
+
continue;
|
|
632
|
+
}
|
|
633
|
+
const isArray = (0,_propertyKind__rspack_import_1/* .isArrayValued */.l)(property.type) && property.innerSchema?.type === _types__rspack_import_0/* .SchemaTypes.Date */.L.Date;
|
|
634
|
+
if (property.type !== _types__rspack_import_0/* .SchemaTypes.Date */.L.Date && isArray === false) {
|
|
635
|
+
continue;
|
|
636
|
+
}
|
|
637
|
+
paths.push({
|
|
638
|
+
segments: [
|
|
639
|
+
...property.getParentPathArray({
|
|
640
|
+
useFromPropertyName: true
|
|
641
|
+
}),
|
|
642
|
+
property.getResolvedName()
|
|
643
|
+
],
|
|
644
|
+
isArray
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
const reviveAt = (record, path)=>{
|
|
649
|
+
const { segments } = path;
|
|
650
|
+
let parent = record;
|
|
651
|
+
for(let i = 0, length = segments.length - 1; i < length; i++){
|
|
652
|
+
parent = parent[segments[i]];
|
|
653
|
+
// An absent or null parent holds no date
|
|
654
|
+
if (parent == null || typeof parent !== "object") {
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
const key = segments[segments.length - 1];
|
|
659
|
+
const value = parent[key];
|
|
660
|
+
if (path.isArray === false) {
|
|
661
|
+
if (typeof value === "string") {
|
|
662
|
+
parent[key] = new Date(value);
|
|
663
|
+
}
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
if (Array.isArray(value)) {
|
|
667
|
+
for(let i = 0, length = value.length; i < length; i++){
|
|
668
|
+
if (typeof value[i] === "string") {
|
|
669
|
+
value[i] = new Date(value[i]);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
};
|
|
674
|
+
/** Per schema: `null` for a schema with no dates, so a caller can skip the pass. */ const revivers = new WeakMap();
|
|
675
|
+
/**
|
|
676
|
+
* The reviver for `schema`'s records, or `null` when it declares no dates.
|
|
677
|
+
*
|
|
678
|
+
* Built once per compiled schema. A read revives every row it returns, so the paths are resolved
|
|
679
|
+
* here rather than per row.
|
|
680
|
+
*/ const getStorageDateReviver = (schema)=>{
|
|
681
|
+
const cached = revivers.get(schema);
|
|
682
|
+
if (cached !== undefined) {
|
|
683
|
+
return cached;
|
|
684
|
+
}
|
|
685
|
+
const paths = [];
|
|
686
|
+
collectDatePaths(schema.properties, paths);
|
|
687
|
+
const reviver = paths.length === 0 ? null : (record)=>{
|
|
688
|
+
for(let i = 0, length = paths.length; i < length; i++){
|
|
689
|
+
reviveAt(record, paths[i]);
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
revivers.set(schema, reviver);
|
|
693
|
+
return reviver;
|
|
694
|
+
};
|
|
695
|
+
|
|
696
|
+
|
|
546
697
|
},
|
|
547
698
|
581(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
548
699
|
__webpack_require__.d(__webpack_exports__, {
|
|
@@ -937,6 +1088,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
937
1088
|
SchemaTransform: () => (/* reexport */ SchemaTransform),
|
|
938
1089
|
SchemaComputed: () => (/* reexport */ SchemaComputed),
|
|
939
1090
|
extractTypeInfo: () => (/* reexport */ extractTypeInfo),
|
|
1091
|
+
getStorageDateReviver: () => (/* reexport */ storageDates/* .getStorageDateReviver */.T),
|
|
940
1092
|
SchemaTracked: () => (/* reexport */ SchemaTracked),
|
|
941
1093
|
SchemaFile: () => (/* reexport */ SchemaFile),
|
|
942
1094
|
SchemaNumber: () => (/* reexport */ SchemaNumber),
|
|
@@ -953,12 +1105,12 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
953
1105
|
SchemaArray: () => (/* reexport */ SchemaArray),
|
|
954
1106
|
SchemaKey: () => (/* reexport */ SchemaKey),
|
|
955
1107
|
SchemaOptional: () => (/* reexport */ SchemaOptional),
|
|
956
|
-
hasPrimitiveElements: () => (/* reexport */ hasPrimitiveElements),
|
|
1108
|
+
hasPrimitiveElements: () => (/* reexport */ propertyKind/* .hasPrimitiveElements */.L),
|
|
957
1109
|
SchemaDefault: () => (/* reexport */ SchemaDefault),
|
|
958
1110
|
SchemaIndex: () => (/* reexport */ SchemaIndex),
|
|
959
1111
|
SchemaVector: () => (/* reexport */ SchemaVector),
|
|
960
1112
|
HashType: () => (/* reexport */ types/* .HashType */.$),
|
|
961
|
-
isArrayValued: () => (/* reexport */ isArrayValued),
|
|
1113
|
+
isArrayValued: () => (/* reexport */ propertyKind/* .isArrayValued */.l),
|
|
962
1114
|
SchemaBase: () => (/* reexport */ SchemaBase),
|
|
963
1115
|
createStandardJsonSchemaProps: () => (/* reexport */ createStandardJsonSchemaProps),
|
|
964
1116
|
propertyInfoToJsonSchema: () => (/* reexport */ propertyInfoToJsonSchema),
|
|
@@ -2179,78 +2331,9 @@ class SlotPath {
|
|
|
2179
2331
|
|
|
2180
2332
|
// EXTERNAL MODULE: ./src/errors/SchemaError.ts
|
|
2181
2333
|
var SchemaError = __webpack_require__(131);
|
|
2182
|
-
;// CONCATENATED MODULE: ./src/codegen/utils.ts
|
|
2183
|
-
/**
|
|
2184
|
-
* Counts non-overlapping occurrences of a term in text.
|
|
2185
|
-
*
|
|
2186
|
-
* Behavior:
|
|
2187
|
-
* - Case-sensitive matching
|
|
2188
|
-
* - If the search term is composed entirely of word characters (A–Z, a–z, 0–9, _),
|
|
2189
|
-
* enforce whole-word boundaries so "red" does not match inside "redder".
|
|
2190
|
-
* - If the search term contains any non-word character (e.g. "=>", "()", "::"),
|
|
2191
|
-
* match anywhere without boundary checks (useful for symbols).
|
|
2192
|
-
* - Non-overlapping matches (after a hit, advances by term length)
|
|
2193
|
-
* - Optimized single-character fast path; otherwise uses indexOf loop
|
|
2194
|
-
*
|
|
2195
|
-
* Examples:
|
|
2196
|
-
* - countWordOccurance("red redder red", "red") => 2
|
|
2197
|
-
* - countWordOccurance("()=>{}", "=>") => 1
|
|
2198
|
-
* - countWordOccurance("aaaa", "aa") => 2 (non-overlapping)
|
|
2199
|
-
*
|
|
2200
|
-
* @param text The source text to scan
|
|
2201
|
-
* @param word The term to match (must be non-empty)
|
|
2202
|
-
* @returns The number of occurrences found
|
|
2203
|
-
*/ const countWordOccurance = (text, word)=>{
|
|
2204
|
-
const wl = word.length;
|
|
2205
|
-
const tl = text.length;
|
|
2206
|
-
if (wl === 0 || wl > tl) return 0;
|
|
2207
|
-
// Fast path for single-character words
|
|
2208
|
-
if (wl === 1) {
|
|
2209
|
-
let c = 0;
|
|
2210
|
-
const code = word.charCodeAt(0);
|
|
2211
|
-
for(let i = 0; i < tl; i++)if (text.charCodeAt(i) === code) c++;
|
|
2212
|
-
return c;
|
|
2213
|
-
}
|
|
2214
|
-
let count = 0;
|
|
2215
|
-
let i = 0;
|
|
2216
|
-
function isWordCharCode(c) {
|
|
2217
|
-
return c >= 48 && c <= 57 // 0-9
|
|
2218
|
-
|| c >= 65 && c <= 90 // A-Z
|
|
2219
|
-
|| c >= 97 && c <= 122 // a-z
|
|
2220
|
-
|| c === 95; // _
|
|
2221
|
-
}
|
|
2222
|
-
// Decide whether to enforce word boundaries based on the search term
|
|
2223
|
-
let enforceWordBoundaries = true;
|
|
2224
|
-
for(let k = 0; k < wl; k++){
|
|
2225
|
-
const cc = word.charCodeAt(k);
|
|
2226
|
-
if (!isWordCharCode(cc)) {
|
|
2227
|
-
enforceWordBoundaries = false;
|
|
2228
|
-
break;
|
|
2229
|
-
}
|
|
2230
|
-
}
|
|
2231
|
-
while(true){
|
|
2232
|
-
i = text.indexOf(word, i);
|
|
2233
|
-
if (i === -1) break;
|
|
2234
|
-
if (enforceWordBoundaries) {
|
|
2235
|
-
const left = i - 1;
|
|
2236
|
-
const right = i + wl;
|
|
2237
|
-
const leftOk = left < 0 || !isWordCharCode(text.charCodeAt(left));
|
|
2238
|
-
const rightOk = right >= tl || !isWordCharCode(text.charCodeAt(right));
|
|
2239
|
-
if (leftOk && rightOk) count++;
|
|
2240
|
-
} else {
|
|
2241
|
-
// No boundary enforcement for symbol-containing terms
|
|
2242
|
-
count++;
|
|
2243
|
-
}
|
|
2244
|
-
i += wl; // non-overlapping word matches
|
|
2245
|
-
}
|
|
2246
|
-
return count;
|
|
2247
|
-
};
|
|
2248
|
-
|
|
2249
2334
|
;// CONCATENATED MODULE: ./src/codegen/handlers/types.ts
|
|
2250
2335
|
|
|
2251
2336
|
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
2337
|
/**
|
|
2255
2338
|
* Terminal link for chains that apply only to a subset of properties (keys,
|
|
2256
2339
|
* identities). Returning the builder marks every other property as
|
|
@@ -2426,34 +2509,16 @@ class PropertyInfoHandler {
|
|
|
2426
2509
|
}
|
|
2427
2510
|
enriched.property(`${property.name}: ${entitySelectorPath}`);
|
|
2428
2511
|
}
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
const index = stringifiedFunction.indexOf("=>");
|
|
2440
|
-
body = stringifiedFunction.slice(index + 2, stringifiedFunction.length);
|
|
2441
|
-
}
|
|
2442
|
-
if (body.startsWith("{") === true && body.endsWith("}")) {
|
|
2443
|
-
// Remove brackets, wrapping function will have them
|
|
2444
|
-
builder.appendBody(body.slice(1, body.length - 1));
|
|
2445
|
-
return {
|
|
2446
|
-
builder,
|
|
2447
|
-
parameters
|
|
2448
|
-
};
|
|
2449
|
-
}
|
|
2450
|
-
builder.appendBody(`return ${body};`);
|
|
2451
|
-
return {
|
|
2452
|
-
builder,
|
|
2453
|
-
parameters
|
|
2454
|
-
};
|
|
2455
|
-
}
|
|
2456
|
-
throw new Error("Only arrow functions are allowed in the schema definition: function () {} ---> () => {}");
|
|
2512
|
+
/**
|
|
2513
|
+
* Binds a function the schema author supplied (a default, a computed, a serializer) into
|
|
2514
|
+
* the generated code and returns the expression that calls it with `args`.
|
|
2515
|
+
*
|
|
2516
|
+
* The function is passed in by value rather than pasted in as source text. Pasted source
|
|
2517
|
+
* loses the scope it was written in, so a default that called an imported helper threw, and
|
|
2518
|
+
* it had to be parsed back apart, which only worked for arrows: a bundler that lowers arrows
|
|
2519
|
+
* to `function` expressions, or renames what they refer to, broke every schema (#46).
|
|
2520
|
+
*/ emitBoundCall(target, fn, args) {
|
|
2521
|
+
return `${target.bind(fn)}(${args.join(", ")})`;
|
|
2457
2522
|
}
|
|
2458
2523
|
}
|
|
2459
2524
|
|
|
@@ -2613,28 +2678,21 @@ class EnrichmentPrimitiveHandler extends PropertyInfoHandler {
|
|
|
2613
2678
|
class EnrichmentFunctionHandler extends PropertyInfoHandler {
|
|
2614
2679
|
handle(property, builder) {
|
|
2615
2680
|
if (property.functionBody != null && property.type === types/* .SchemaTypes.Function */.L.Function) {
|
|
2616
|
-
const
|
|
2681
|
+
const factory = builder.get("factory");
|
|
2682
|
+
const args = [
|
|
2617
2683
|
"enriched",
|
|
2618
2684
|
"collectionName"
|
|
2619
2685
|
];
|
|
2620
2686
|
if (property.injected != null) {
|
|
2621
|
-
|
|
2622
|
-
const parameter = factory.createParameter(property.injected);
|
|
2623
|
-
factory.parameters(parameter);
|
|
2624
|
-
parameterNames.push(parameter.name);
|
|
2687
|
+
args.push(factory.bind(property.injected));
|
|
2625
2688
|
}
|
|
2626
|
-
const declarationsSlot = builder.get("factory.function.declarations");
|
|
2627
|
-
// Unwrap the functions to removing currying
|
|
2628
|
-
const defaultFunctionWithParameters = this.toNamedFunction(property.functionBody.toString(), declarationsSlot);
|
|
2629
|
-
defaultFunctionWithParameters.builder.parameters(...parameterNames.map((w, i)=>({
|
|
2630
|
-
name: defaultFunctionWithParameters.parameters[i],
|
|
2631
|
-
callName: w
|
|
2632
|
-
})));
|
|
2633
2689
|
const slot = builder.get("factory.function.assignment");
|
|
2634
2690
|
const enrichedAssignmentPath = property.getAssignmentPath({
|
|
2635
2691
|
parent: "enriched"
|
|
2636
2692
|
});
|
|
2637
|
-
|
|
2693
|
+
// The definition is curried: calling it with the entity returns the function the
|
|
2694
|
+
// property holds
|
|
2695
|
+
slot.assign(enrichedAssignmentPath).value(this.emitBoundCall(factory, property.functionBody, args));
|
|
2638
2696
|
return builder;
|
|
2639
2697
|
}
|
|
2640
2698
|
return super.handle(property, builder);
|
|
@@ -2689,34 +2747,17 @@ class EnrichmentDefaultFunctionHandler extends PropertyInfoHandler {
|
|
|
2689
2747
|
handle(property, builder) {
|
|
2690
2748
|
if (property.defaultValue != null && typeof property.defaultValue === "function") {
|
|
2691
2749
|
this.setEnrichedProperty(property, builder);
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
}
|
|
2699
|
-
const parameter = factory.createParameter(property.injected);
|
|
2700
|
-
factory.parameters(parameter);
|
|
2701
|
-
const defaultFunctionWithParameters = this.toNamedFunction(property.defaultValue.toString(), declarationsSlot);
|
|
2702
|
-
// This is ok, defaults can only inject one parameter anyways
|
|
2703
|
-
defaultFunctionWithParameters.builder.parameters(...defaultFunctionWithParameters.parameters.map((w)=>({
|
|
2704
|
-
name: w,
|
|
2705
|
-
callName: parameter.name
|
|
2706
|
-
})));
|
|
2707
|
-
const ifsSlot = builder.get("factory.function.ifs");
|
|
2708
|
-
const enrichedAssignmentPath = property.getAssignmentPath({
|
|
2709
|
-
parent: "enriched"
|
|
2710
|
-
});
|
|
2711
|
-
ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${defaultFunctionWithParameters.builder.toCallable()}`);
|
|
2712
|
-
return builder;
|
|
2713
|
-
}
|
|
2714
|
-
const defaultFunction = this.toNamedFunction(property.defaultValue.toString(), declarationsSlot);
|
|
2750
|
+
const factory = builder.get("factory");
|
|
2751
|
+
// Defaults take at most one argument: the injected value, when there is one
|
|
2752
|
+
const args = property.injected != null ? [
|
|
2753
|
+
factory.bind(property.injected)
|
|
2754
|
+
] : [];
|
|
2755
|
+
const call = this.emitBoundCall(factory, property.defaultValue, args);
|
|
2715
2756
|
const ifsSlot = builder.get("factory.function.ifs");
|
|
2716
2757
|
const enrichedAssignmentPath = property.getAssignmentPath({
|
|
2717
2758
|
parent: "enriched"
|
|
2718
2759
|
});
|
|
2719
|
-
ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${
|
|
2760
|
+
ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${call}`);
|
|
2720
2761
|
return builder;
|
|
2721
2762
|
}
|
|
2722
2763
|
return super.handle(property, builder);
|
|
@@ -2729,22 +2770,15 @@ class EnrichmentDefaultFunctionHandler extends PropertyInfoHandler {
|
|
|
2729
2770
|
class EnrichmentComputedValueHandler extends PropertyInfoHandler {
|
|
2730
2771
|
handle(property, builder) {
|
|
2731
2772
|
if (property.functionBody != null && property.type === types/* .SchemaTypes.Computed */.L.Computed) {
|
|
2732
|
-
const
|
|
2773
|
+
const factory = builder.get("factory");
|
|
2774
|
+
const args = [
|
|
2733
2775
|
"enriched",
|
|
2734
2776
|
"collectionName"
|
|
2735
2777
|
];
|
|
2736
2778
|
if (property.injected != null) {
|
|
2737
|
-
|
|
2738
|
-
const parameter = factory.createParameter(property.injected);
|
|
2739
|
-
factory.parameters(parameter);
|
|
2740
|
-
parameterNames.push(parameter.name);
|
|
2779
|
+
args.push(factory.bind(property.injected));
|
|
2741
2780
|
}
|
|
2742
|
-
const
|
|
2743
|
-
const defaultFunctionWithParameters = this.toNamedFunction(property.functionBody.toString(), declarationsSlot);
|
|
2744
|
-
defaultFunctionWithParameters.builder.parameters(...parameterNames.map((w, i)=>({
|
|
2745
|
-
name: defaultFunctionWithParameters.parameters[i],
|
|
2746
|
-
callName: w
|
|
2747
|
-
})));
|
|
2781
|
+
const call = this.emitBoundCall(factory, property.functionBody, args);
|
|
2748
2782
|
// Compute-once semantics for computed keys/identities: an existing value is
|
|
2749
2783
|
// carried into the enriched literal and never recomputed — a key must stay
|
|
2750
2784
|
// stable once assigned (content-hash ids would otherwise churn as the
|
|
@@ -2757,44 +2791,15 @@ class EnrichmentComputedValueHandler extends PropertyInfoHandler {
|
|
|
2757
2791
|
const enrichedAssignmentPath = property.getAssignmentPath({
|
|
2758
2792
|
parent: "enriched"
|
|
2759
2793
|
});
|
|
2760
|
-
ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${
|
|
2794
|
+
ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${call}`);
|
|
2761
2795
|
return builder;
|
|
2762
2796
|
}
|
|
2763
2797
|
return super.handle(property, builder);
|
|
2764
2798
|
}
|
|
2765
2799
|
}
|
|
2766
2800
|
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
/**
|
|
2770
|
-
* Types whose runtime value is a JS array.
|
|
2771
|
-
*
|
|
2772
|
-
* `Array` and `Vector` are the same thing to every layer that copies, compares, hashes or
|
|
2773
|
-
* freezes a value — a vector is a list of numbers and nothing more. They differ only where a
|
|
2774
|
-
* backend chooses storage, which is the one place that should ask for `SchemaTypes.Vector` by
|
|
2775
|
-
* name.
|
|
2776
|
-
*
|
|
2777
|
-
* This exists so adding a third array-shaped type is one edit rather than a hunt through
|
|
2778
|
-
* twelve handlers. Missing one of those is silent in the worst way: a vector that clones by
|
|
2779
|
-
* reference is shared with the change tracker's copy, so overwriting an embedding produces no
|
|
2780
|
-
* diff and the save reports nothing to do.
|
|
2781
|
-
*/ const ARRAY_VALUED_TYPES = new Set([
|
|
2782
|
-
types/* .SchemaTypes.Array */.L.Array,
|
|
2783
|
-
types/* .SchemaTypes.Vector */.L.Vector
|
|
2784
|
-
]);
|
|
2785
|
-
/** True when the property's value is a JS array and needs value rather than reference semantics. */ const isArrayValued = (type)=>ARRAY_VALUED_TYPES.has(type);
|
|
2786
|
-
/**
|
|
2787
|
-
* True when the property's elements are primitives, so a spread is a sufficient copy.
|
|
2788
|
-
*
|
|
2789
|
-
* A vector is always numbers, so it never needs the per-element deep copy an array of objects
|
|
2790
|
-
* or dates does.
|
|
2791
|
-
*/ const PRIMITIVE_ELEMENT_TYPES = new Set([
|
|
2792
|
-
types/* .SchemaTypes.String */.L.String,
|
|
2793
|
-
types/* .SchemaTypes.Number */.L.Number,
|
|
2794
|
-
types/* .SchemaTypes.Boolean */.L.Boolean
|
|
2795
|
-
]);
|
|
2796
|
-
const hasPrimitiveElements = (type, elementType)=>type === types/* .SchemaTypes.Vector */.L.Vector || PRIMITIVE_ELEMENT_TYPES.has(elementType);
|
|
2797
|
-
|
|
2801
|
+
// EXTERNAL MODULE: ./src/schema/utils/propertyKind.ts
|
|
2802
|
+
var propertyKind = __webpack_require__(575);
|
|
2798
2803
|
;// CONCATENATED MODULE: ./src/codegen/handlers/enrichment/EnrichmentArrayHandler.ts
|
|
2799
2804
|
|
|
2800
2805
|
|
|
@@ -2804,7 +2809,7 @@ const hasPrimitiveElements = (type, elementType)=>type === types/* .SchemaTypes.
|
|
|
2804
2809
|
* mark the root entity dirty instead of being silently lost on save.
|
|
2805
2810
|
*/ class EnrichmentArrayHandler extends PropertyInfoHandler {
|
|
2806
2811
|
handle(property, builder) {
|
|
2807
|
-
if (isArrayValued(property.type)) {
|
|
2812
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
2808
2813
|
// Place the property in the enriched literal like any other leaf
|
|
2809
2814
|
this.setEnrichedProperty(property, builder);
|
|
2810
2815
|
const enrichedPath = property.getAssignmentPath({
|
|
@@ -2846,13 +2851,10 @@ class MergeDefaultFunctionHandler extends PropertyInfoHandler {
|
|
|
2846
2851
|
// we are changing merge to be more like enrich so we can handle injections
|
|
2847
2852
|
// we may need to change more. Need to move towards factories
|
|
2848
2853
|
if (property.defaultValue != null && typeof property.defaultValue === "function") {
|
|
2849
|
-
const
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
factory.parameters(parameter);
|
|
2854
|
-
defaultFunctionParameters.push(parameter.name);
|
|
2855
|
-
}
|
|
2854
|
+
const factory = builder.get("factory");
|
|
2855
|
+
const args = property.injected != null ? [
|
|
2856
|
+
factory.bind(property.injected)
|
|
2857
|
+
] : [];
|
|
2856
2858
|
// A defaulted property still merges from the source; the default only fills
|
|
2857
2859
|
// the gap when neither side has a value
|
|
2858
2860
|
this.emitMergeCopy(property, builder, {
|
|
@@ -2868,15 +2870,9 @@ class MergeDefaultFunctionHandler extends PropertyInfoHandler {
|
|
|
2868
2870
|
const assignmentPath = property.getAssignmentPath({
|
|
2869
2871
|
parent: "destination"
|
|
2870
2872
|
});
|
|
2871
|
-
const declarationsSlot = builder.get("factory.function.header");
|
|
2872
|
-
const defaultFunctionWithParameters = this.toNamedFunction(property.defaultValue.toString(), declarationsSlot);
|
|
2873
|
-
defaultFunctionWithParameters.builder.parameters(...defaultFunctionParameters.map((w, i)=>({
|
|
2874
|
-
name: defaultFunctionWithParameters.parameters[i],
|
|
2875
|
-
callName: w
|
|
2876
|
-
})));
|
|
2877
2873
|
const defaultIf = ifsSlot.if(`${selectorPath} == null`);
|
|
2878
2874
|
this.emitDestinationAncestorGuards(property, defaultIf);
|
|
2879
|
-
defaultIf.appendBody(`${assignmentPath} = ${
|
|
2875
|
+
defaultIf.appendBody(`${assignmentPath} = ${this.emitBoundCall(factory, property.defaultValue, args)}`);
|
|
2880
2876
|
return builder;
|
|
2881
2877
|
}
|
|
2882
2878
|
return super.handle(property, builder);
|
|
@@ -2917,28 +2913,20 @@ class MergePrimitiveHandler extends PropertyInfoHandler {
|
|
|
2917
2913
|
class MergeComputedValueHandler extends PropertyInfoHandler {
|
|
2918
2914
|
handle(property, builder) {
|
|
2919
2915
|
if (property.functionBody != null && property.type === types/* .SchemaTypes.Computed */.L.Computed) {
|
|
2920
|
-
const
|
|
2916
|
+
const factory = builder.get("factory");
|
|
2917
|
+
const args = [
|
|
2921
2918
|
"source",
|
|
2922
2919
|
"collectionName"
|
|
2923
2920
|
];
|
|
2924
2921
|
if (property.injected != null) {
|
|
2925
|
-
|
|
2926
|
-
const parameter = factory.createParameter(property.injected);
|
|
2927
|
-
factory.parameters(parameter);
|
|
2928
|
-
parameterNames.push(parameter.name);
|
|
2922
|
+
args.push(factory.bind(property.injected));
|
|
2929
2923
|
}
|
|
2930
|
-
const declarationsSlot = builder.get("factory.function.header");
|
|
2931
|
-
const defaultFunctionWithParameters = this.toNamedFunction(property.functionBody.toString(), declarationsSlot);
|
|
2932
|
-
defaultFunctionWithParameters.builder.parameters(...parameterNames.map((w, i)=>({
|
|
2933
|
-
name: defaultFunctionWithParameters.parameters[i],
|
|
2934
|
-
callName: w
|
|
2935
|
-
})));
|
|
2936
2924
|
const slot = builder.get("factory.function.assignments");
|
|
2937
2925
|
const enrichedAssignmentPath = property.getAssignmentPath({
|
|
2938
2926
|
parent: "destination"
|
|
2939
2927
|
});
|
|
2940
2928
|
// We want to recompute the value always in case there are changes
|
|
2941
|
-
slot.assign(enrichedAssignmentPath).value(
|
|
2929
|
+
slot.assign(enrichedAssignmentPath).value(this.emitBoundCall(factory, property.functionBody, args));
|
|
2942
2930
|
return builder;
|
|
2943
2931
|
}
|
|
2944
2932
|
return super.handle(property, builder);
|
|
@@ -3011,7 +2999,7 @@ class MergeFunctionHandler extends PropertyInfoHandler {
|
|
|
3011
2999
|
* reference is adopted as-is — same as the primitive copy this replaces.
|
|
3012
3000
|
*/ class MergeArrayHandler extends PropertyInfoHandler {
|
|
3013
3001
|
handle(property, builder) {
|
|
3014
|
-
if (isArrayValued(property.type)) {
|
|
3002
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
3015
3003
|
const selectorPath = property.getSelectrorPath({
|
|
3016
3004
|
parent: "source",
|
|
3017
3005
|
assignmentType: "FORCE_NULLABLE_OR_OPTIONAL"
|
|
@@ -3348,7 +3336,7 @@ class CloneArrayHandler extends PropertyInfoHandler {
|
|
|
3348
3336
|
super(), this.useFromPropertyName = useFromPropertyName;
|
|
3349
3337
|
}
|
|
3350
3338
|
handle(property, builder) {
|
|
3351
|
-
if (isArrayValued(property.type)) {
|
|
3339
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
3352
3340
|
// Arrays are leaf properties — they have no child PropertyInfos, so the
|
|
3353
3341
|
// copy must happen here for every array, including nullable/optional ones.
|
|
3354
3342
|
// The `!== undefined` guard below covers absent values; an explicit null is copied as
|
|
@@ -3374,7 +3362,7 @@ class CloneArrayHandler extends PropertyInfoHandler {
|
|
|
3374
3362
|
// across merges), and a Proxy cannot pass a structured-clone boundary.
|
|
3375
3363
|
const elementType = property.innerSchema?.type;
|
|
3376
3364
|
let copyExpression;
|
|
3377
|
-
if (hasPrimitiveElements(property.type, elementType)) {
|
|
3365
|
+
if ((0,propertyKind/* .hasPrimitiveElements */.L)(property.type, elementType)) {
|
|
3378
3366
|
copyExpression = `[...${entitySelectorPath}]`;
|
|
3379
3367
|
} else if (elementType === types/* .SchemaTypes.Date */.L.Date) {
|
|
3380
3368
|
copyExpression = `${entitySelectorPath}.map(function (v) { return v == null ? v : new Date(v); })`;
|
|
@@ -3493,7 +3481,7 @@ class CloneObjectHandler extends PropertyInfoHandler {
|
|
|
3493
3481
|
// Anything that copies by assignment. An array-valued property must not land here:
|
|
3494
3482
|
// assigning the reference shares it with the source, which is the whole point of
|
|
3495
3483
|
// CloneArrayHandler.
|
|
3496
|
-
if (property.type != types/* .SchemaTypes.Object */.L.Object && isArrayValued(property.type) === false) {
|
|
3484
|
+
if (property.type != types/* .SchemaTypes.Object */.L.Object && (0,propertyKind/* .isArrayValued */.l)(property.type) === false) {
|
|
3497
3485
|
const slot = builder.get("if");
|
|
3498
3486
|
const useFromPropertyName = this.useFromPropertyName;
|
|
3499
3487
|
const entitySelectorPath = property.getSelectrorPath({
|
|
@@ -3556,7 +3544,7 @@ class CloneHandlerBuilder {
|
|
|
3556
3544
|
|
|
3557
3545
|
class CompareArrayHandler extends PropertyInfoHandler {
|
|
3558
3546
|
handle(property, builder) {
|
|
3559
|
-
if (isArrayValued(property.type)) {
|
|
3547
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
3560
3548
|
let compare = builder.getOrDefault("result.variable.compare");
|
|
3561
3549
|
const leftCompare = property.getSelectrorPath({
|
|
3562
3550
|
parent: "a"
|
|
@@ -3851,7 +3839,6 @@ class DeserializeDeserializerHandler extends PropertyInfoHandler {
|
|
|
3851
3839
|
handle(property, builder) {
|
|
3852
3840
|
if (property.valueDeserializer != null) {
|
|
3853
3841
|
let objectBuilder = builder.getOrDefault("result.variable.object");
|
|
3854
|
-
const assignmentBuilder = builder.getOrDefault("functions");
|
|
3855
3842
|
// Read the incoming record by `from` (storage) name
|
|
3856
3843
|
const entitySelectorPath = property.getSelectrorPath({
|
|
3857
3844
|
parent: "unserialized",
|
|
@@ -3864,18 +3851,16 @@ class DeserializeDeserializerHandler extends PropertyInfoHandler {
|
|
|
3864
3851
|
name: "object"
|
|
3865
3852
|
});
|
|
3866
3853
|
}
|
|
3867
|
-
const
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
callName: entitySelectorPath
|
|
3871
|
-
})));
|
|
3854
|
+
const call = this.emitBoundCall(builder, property.valueDeserializer, [
|
|
3855
|
+
entitySelectorPath
|
|
3856
|
+
]);
|
|
3872
3857
|
if (property.parent == null) {
|
|
3873
|
-
objectBuilder.property(`${property.name}: ${
|
|
3858
|
+
objectBuilder.property(`${property.name}: ${call}`);
|
|
3874
3859
|
return builder;
|
|
3875
3860
|
}
|
|
3876
3861
|
const slotPath = new SlotPath(...property.getParentPathArray());
|
|
3877
3862
|
objectBuilder = objectBuilder.get(slotPath.get());
|
|
3878
|
-
objectBuilder.property(`${property.name}: ${
|
|
3863
|
+
objectBuilder.property(`${property.name}: ${call}`);
|
|
3879
3864
|
return builder;
|
|
3880
3865
|
}
|
|
3881
3866
|
return super.handle(property, builder);
|
|
@@ -3901,7 +3886,7 @@ class DeserializeDeserializerHandler extends PropertyInfoHandler {
|
|
|
3901
3886
|
return `[...${selector}]`;
|
|
3902
3887
|
}
|
|
3903
3888
|
handle(property, builder) {
|
|
3904
|
-
if (isArrayValued(property.type)) {
|
|
3889
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
3905
3890
|
const slotPath = new SlotPath("result.variable.object");
|
|
3906
3891
|
// Create the result object when this is the first property iterated —
|
|
3907
3892
|
// handler output cannot depend on schema property order
|
|
@@ -4142,7 +4127,7 @@ class HashComputedValueHandler extends PropertyInfoHandler {
|
|
|
4142
4127
|
* objects would collapse every value to "[object Object]" and collide.
|
|
4143
4128
|
*/ class HashArrayHandler extends PropertyInfoHandler {
|
|
4144
4129
|
handle(property, builder) {
|
|
4145
|
-
if (isArrayValued(property.type)) {
|
|
4130
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
4146
4131
|
let stringBuilder = builder.getOrDefault("hash-object-return.variable.string");
|
|
4147
4132
|
const entitySelectorPath = property.getSelectrorPath({
|
|
4148
4133
|
parent: "entity"
|
|
@@ -4307,7 +4292,7 @@ class EnableChangeTrackingObjectHandler extends PropertyInfoHandler {
|
|
|
4307
4292
|
* mark the root entity dirty instead of being silently lost on save.
|
|
4308
4293
|
*/ class EnableChangeTrackingArrayHandler extends PropertyInfoHandler {
|
|
4309
4294
|
handle(property, builder) {
|
|
4310
|
-
if (isArrayValued(property.type)) {
|
|
4295
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
4311
4296
|
const assignmentSlot = builder.get("assignment");
|
|
4312
4297
|
const childSelectorPath = property.getSelectrorPath({
|
|
4313
4298
|
parent: "entity"
|
|
@@ -4384,7 +4369,7 @@ class FreezeObjectHandler extends PropertyInfoHandler {
|
|
|
4384
4369
|
|
|
4385
4370
|
class FreezeArrayHandler extends PropertyInfoHandler {
|
|
4386
4371
|
handle(property, builder) {
|
|
4387
|
-
if (isArrayValued(property.type)) {
|
|
4372
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
4388
4373
|
const assignmentSlot = builder.get("assignment");
|
|
4389
4374
|
const childSelectorPath = property.getSelectrorPath({
|
|
4390
4375
|
parent: "entity"
|
|
@@ -4520,7 +4505,6 @@ class SerializeSerializerHandler extends PropertyInfoHandler {
|
|
|
4520
4505
|
handle(property, builder) {
|
|
4521
4506
|
if (property.valueSerializer != null) {
|
|
4522
4507
|
const slot = builder.getOrDefault("if");
|
|
4523
|
-
const assignmentBuilder = builder.getOrDefault("functions");
|
|
4524
4508
|
// Serialize maps in-memory shape -> storage shape: read the entity by
|
|
4525
4509
|
// property name, write the result by `from` (storage) name
|
|
4526
4510
|
const entitySelectorPath = property.getSelectrorPath({
|
|
@@ -4530,17 +4514,15 @@ class SerializeSerializerHandler extends PropertyInfoHandler {
|
|
|
4530
4514
|
parent: "result",
|
|
4531
4515
|
useFromPropertyName: true
|
|
4532
4516
|
});
|
|
4533
|
-
const
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
callName: entitySelectorPath
|
|
4537
|
-
})));
|
|
4517
|
+
const call = this.emitBoundCall(builder, property.valueSerializer, [
|
|
4518
|
+
entitySelectorPath
|
|
4519
|
+
]);
|
|
4538
4520
|
if (property.parent == null) {
|
|
4539
|
-
slot.if(`Object.hasOwn(entity, "${property.name}")`).appendBody(`${resultSelectorPath} = ${
|
|
4521
|
+
slot.if(`Object.hasOwn(entity, "${property.name}")`).appendBody(`${resultSelectorPath} = ${call}`);
|
|
4540
4522
|
return builder;
|
|
4541
4523
|
}
|
|
4542
4524
|
// Nested serializer: same pattern as SerializeValueHandler — if block for parent existence, then assign via serializer
|
|
4543
|
-
this.emitSerializeNestedAssignment(property, slot,
|
|
4525
|
+
this.emitSerializeNestedAssignment(property, slot, call);
|
|
4544
4526
|
return builder;
|
|
4545
4527
|
}
|
|
4546
4528
|
return super.handle(property, builder);
|
|
@@ -4599,7 +4581,7 @@ class SerializeComputedHandler extends PropertyInfoHandler {
|
|
|
4599
4581
|
return `[...${selector}]`;
|
|
4600
4582
|
}
|
|
4601
4583
|
handle(property, builder) {
|
|
4602
|
-
if (isArrayValued(property.type)) {
|
|
4584
|
+
if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
|
|
4603
4585
|
const slot = builder.get("if");
|
|
4604
4586
|
// Serialize maps in-memory shape -> storage shape: read the entity by
|
|
4605
4587
|
// property name, write the result by `from` (storage) name
|
|
@@ -5503,8 +5485,8 @@ const arrayConverter = (property, context)=>{
|
|
|
5503
5485
|
// Create the function using new Function()
|
|
5504
5486
|
// If no parameters, call with just the body; otherwise spread the params
|
|
5505
5487
|
const fn = params.length > 0 ? new Function(...params, functionBody) : new Function(functionBody);
|
|
5506
|
-
// Wrap it so toString() returns the original arrow function string
|
|
5507
|
-
//
|
|
5488
|
+
// Wrap it so toString() returns the original arrow function string, so
|
|
5489
|
+
// serializing the rehydrated schema writes the same functionSource again
|
|
5508
5490
|
recreatedFn = Object.assign(fn, {
|
|
5509
5491
|
toString: ()=>functionSource
|
|
5510
5492
|
});
|
|
@@ -5513,7 +5495,7 @@ const arrayConverter = (property, context)=>{
|
|
|
5513
5495
|
recreatedFn = ()=>{
|
|
5514
5496
|
throw new Error(`Cannot recreate computed property ${computedProp.name}: ${e instanceof Error ? e.message : 'unknown error'}`);
|
|
5515
5497
|
};
|
|
5516
|
-
//
|
|
5498
|
+
// Keep functionSource re-parseable if this schema is serialized again
|
|
5517
5499
|
Object.assign(recreatedFn, {
|
|
5518
5500
|
toString: ()=>`() => { throw new Error("Cannot recreate computed property ${computedProp.name}"); }`
|
|
5519
5501
|
});
|
|
@@ -5650,39 +5632,16 @@ class SetHandlerBuilder {
|
|
|
5650
5632
|
}
|
|
5651
5633
|
}
|
|
5652
5634
|
|
|
5653
|
-
;// CONCATENATED MODULE: ./src/schema/
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
function assertPropertyHandled(generatorName, property, result) {
|
|
5681
|
-
if (result == null) {
|
|
5682
|
-
throw new Error(`Schema compilation failed: no '${generatorName}' code generator handles property '${property.getAssignmentPath()}' (type: ${property.type}). Add a handler for this property shape or mark it not applicable in the ${generatorName} chain.`);
|
|
5683
|
-
}
|
|
5684
|
-
}
|
|
5685
|
-
function createChangeTracker() {
|
|
5635
|
+
;// CONCATENATED MODULE: ./src/schema/changeTracker.ts
|
|
5636
|
+
/**
|
|
5637
|
+
* Builds the proxy factory that change-tracks an entity.
|
|
5638
|
+
*
|
|
5639
|
+
* Generated schema code receives the result as a bound value — a parameter of the generated
|
|
5640
|
+
* factory — and never refers to this module by name. Name references do not survive a minifier,
|
|
5641
|
+
* which renames the declaration but cannot see inside generated source text (#40, #46). The
|
|
5642
|
+
* returned function holds no per-entity state, so one per compiled schema is shared by every
|
|
5643
|
+
* entity it tracks.
|
|
5644
|
+
*/ function createChangeTracker() {
|
|
5686
5645
|
const DIRTY_ENTITY_MARKER = "isDirty";
|
|
5687
5646
|
const CHANGES_ENTITY_KEY = "changes";
|
|
5688
5647
|
const ORIGINAL_ENTITY_KEY = "original";
|
|
@@ -5781,6 +5740,40 @@ function createChangeTracker() {
|
|
|
5781
5740
|
return new Proxy(entity, proxyHandler);
|
|
5782
5741
|
};
|
|
5783
5742
|
}
|
|
5743
|
+
|
|
5744
|
+
;// CONCATENATED MODULE: ./src/schema/SchemaDefinition.ts
|
|
5745
|
+
|
|
5746
|
+
|
|
5747
|
+
|
|
5748
|
+
|
|
5749
|
+
|
|
5750
|
+
|
|
5751
|
+
|
|
5752
|
+
|
|
5753
|
+
|
|
5754
|
+
|
|
5755
|
+
|
|
5756
|
+
|
|
5757
|
+
|
|
5758
|
+
|
|
5759
|
+
|
|
5760
|
+
|
|
5761
|
+
|
|
5762
|
+
|
|
5763
|
+
|
|
5764
|
+
|
|
5765
|
+
|
|
5766
|
+
|
|
5767
|
+
|
|
5768
|
+
|
|
5769
|
+
|
|
5770
|
+
|
|
5771
|
+
|
|
5772
|
+
function assertPropertyHandled(generatorName, property, result) {
|
|
5773
|
+
if (result == null) {
|
|
5774
|
+
throw new Error(`Schema compilation failed: no '${generatorName}' code generator handles property '${property.getAssignmentPath()}' (type: ${property.type}). Add a handler for this property shape or mark it not applicable in the ${generatorName} chain.`);
|
|
5775
|
+
}
|
|
5776
|
+
}
|
|
5784
5777
|
class SchemaDefinition extends SchemaBase {
|
|
5785
5778
|
instance;
|
|
5786
5779
|
type = types/* .SchemaTypes.Definition */.L.Definition;
|
|
@@ -5831,10 +5824,22 @@ class SchemaDefinition extends SchemaBase {
|
|
|
5831
5824
|
throw e;
|
|
5832
5825
|
}
|
|
5833
5826
|
}
|
|
5834
|
-
|
|
5827
|
+
/**
|
|
5828
|
+
* Compiles `builder` into a function taking `fnArgs`.
|
|
5829
|
+
*
|
|
5830
|
+
* A builder with bindings is compiled one level out: an outer function whose parameters are
|
|
5831
|
+
* the bindings, called once here with their values, returns the function that is kept. The
|
|
5832
|
+
* bound values become closure variables of that function, so the per-call cost is a context
|
|
5833
|
+
* read rather than anything resolved by name.
|
|
5834
|
+
*/ createFunction(builder, ...fnArgs) {
|
|
5835
5835
|
const body = builder.toString();
|
|
5836
|
+
const bindings = builder.getBindings();
|
|
5836
5837
|
try {
|
|
5837
|
-
|
|
5838
|
+
if (bindings.length === 0) {
|
|
5839
|
+
return Function(...fnArgs, body);
|
|
5840
|
+
}
|
|
5841
|
+
const outer = Function(...bindings.map((w)=>w.name), `return function(${fnArgs.join(", ")}) {\n${body}\n}`);
|
|
5842
|
+
return outer(...bindings.map((w)=>w.value));
|
|
5838
5843
|
} catch (e) {
|
|
5839
5844
|
logger/* .logger.error */.vF.error(`Error compiling schema function. Function Body: ${body}`);
|
|
5840
5845
|
throw e;
|
|
@@ -5967,9 +5972,11 @@ class SchemaDefinition extends SchemaBase {
|
|
|
5967
5972
|
const serializeHandler = serializeHandlerBuilder.build();
|
|
5968
5973
|
const compareIdsHandler = compareIdsHandlerBuilder.build();
|
|
5969
5974
|
const setHandlerHanlder = setHandlerBuilder.build();
|
|
5975
|
+
// Handed to the generated functions as a value, never embedded as source and called
|
|
5976
|
+
// by name — a minifier renames the declaration and breaks every schema (#40).
|
|
5977
|
+
const changeTracker = createChangeTracker();
|
|
5970
5978
|
const changeTrackingCodeBuilder = new blocks/* .CodeBuilder */.Nl();
|
|
5971
|
-
changeTrackingCodeBuilder.
|
|
5972
|
-
changeTrackingCodeBuilder.slot("declarations").variable("enableChangeTracking").value('createChangeTracker()');
|
|
5979
|
+
changeTrackingCodeBuilder.bind(changeTracker, "enableChangeTracking");
|
|
5973
5980
|
// Nested proxies are installed by assigning through already-proxied parents;
|
|
5974
5981
|
// pause tracking during setup so those writes don't register as changes
|
|
5975
5982
|
changeTrackingCodeBuilder.slot("pause").raw('\tconst hadTracking = entity.__tracking__ != null;\n\tif (!hadTracking) { Object.defineProperty(entity, "__tracking__", { value: { changes: {}, isDirty: false, original: {}, isPaused: false }, configurable: true, writable: true, enumerable: false }); }\n\tconst wasPaused = entity.__tracking__.isPaused;\n\tentity.__tracking__.isPaused = true;');
|
|
@@ -5998,9 +6005,10 @@ class SchemaDefinition extends SchemaBase {
|
|
|
5998
6005
|
}).parameters({
|
|
5999
6006
|
name: "collectionName",
|
|
6000
6007
|
value: this.collectionName
|
|
6008
|
+
}, {
|
|
6009
|
+
name: "changeTracker",
|
|
6010
|
+
value: changeTracker
|
|
6001
6011
|
});
|
|
6002
|
-
enricherFunctionRoot.slot("changeTracker").raw(`${createChangeTracker.toString()}`);
|
|
6003
|
-
enricherFunctionRoot.slot("changeTrackerFunction").raw(`\tconst changeTracker = createChangeTracker();`);
|
|
6004
6012
|
const enricherFunctionBody = enricherFunctionRoot.function(undefined, {
|
|
6005
6013
|
name: "function"
|
|
6006
6014
|
}).parameters("entity", "changeTrackingType").return();
|
|
@@ -6235,6 +6243,8 @@ class SchemaDefinition extends SchemaBase {
|
|
|
6235
6243
|
enricherFunctionBody.get("append").insert(deserializeCodeBuilder.get("result"));
|
|
6236
6244
|
enricherFunctionBody.get("append").insert(deserializeCodeBuilder.get("if"));
|
|
6237
6245
|
enricherFunctionRoot.replace("function", new blocks/* .FunctionBuilder */.kF(undefined).parameters("unserialized", "changeTrackingType").return());
|
|
6246
|
+
// The deserialize slots moved in above call the deserializers bound on their own builder
|
|
6247
|
+
enricherFunctionRoot.parameters(...deserializeCodeBuilder.getBindings());
|
|
6238
6248
|
const postProcessGenerator = this.createReturnFunction(enricherCodeBuilder);
|
|
6239
6249
|
const postProcessParams = enricherFunctionRoot.getParameters();
|
|
6240
6250
|
// Combine prepare and serialize
|
|
@@ -6243,6 +6253,10 @@ class SchemaDefinition extends SchemaBase {
|
|
|
6243
6253
|
preprocessCodeBuilder.get("main").insert(serializeCodeBuilder.get("assignments"));
|
|
6244
6254
|
preprocessCodeBuilder.get("main").insert(serializeCodeBuilder.get("functions"));
|
|
6245
6255
|
preprocessCodeBuilder.get("main").insert(serializeCodeBuilder.get("if"));
|
|
6256
|
+
// Likewise the serialize slots call the serializers bound on the serialize builder
|
|
6257
|
+
for (const binding of serializeCodeBuilder.getBindings()){
|
|
6258
|
+
preprocessCodeBuilder.bind(binding.value, binding.name);
|
|
6259
|
+
}
|
|
6246
6260
|
const getIdsFunction = this.createFunction(idSelectorCodeBuilder, "entity");
|
|
6247
6261
|
const getHashTypeFunction = this.createFunction(hashTypeCodeBuilder, "entity");
|
|
6248
6262
|
const prepareFunction = this.createFunction(prepareCodeBuilder, "entity");
|
|
@@ -6884,6 +6898,8 @@ const s = {
|
|
|
6884
6898
|
|
|
6885
6899
|
|
|
6886
6900
|
|
|
6901
|
+
// EXTERNAL MODULE: ./src/schema/utils/storageDates.ts
|
|
6902
|
+
var storageDates = __webpack_require__(894);
|
|
6887
6903
|
;// CONCATENATED MODULE: ./src/schema/index.ts
|
|
6888
6904
|
|
|
6889
6905
|
|
|
@@ -6896,6 +6912,7 @@ const s = {
|
|
|
6896
6912
|
|
|
6897
6913
|
|
|
6898
6914
|
|
|
6915
|
+
|
|
6899
6916
|
})();
|
|
6900
6917
|
|
|
6901
6918
|
module.exports = __webpack_exports__;
|