@routier/core 0.6.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.
Files changed (70) hide show
  1. package/dist/assertions/index.cjs +19 -8
  2. package/dist/assertions/index.cjs.map +1 -1
  3. package/dist/assertions/index.d.ts +5 -1
  4. package/dist/assertions/index.js +21 -9
  5. package/dist/assertions/index.js.map +1 -1
  6. package/dist/codegen/blocks.d.ts +17 -1
  7. package/dist/codegen/handlers/types.d.ts +13 -5
  8. package/dist/codegen/index.cjs +28 -0
  9. package/dist/codegen/index.cjs.map +1 -1
  10. package/dist/codegen/index.js +28 -0
  11. package/dist/codegen/index.js.map +1 -1
  12. package/dist/collections/MemoryDataCollection.d.ts +8 -0
  13. package/dist/collections/index.cjs +141 -4
  14. package/dist/collections/index.cjs.map +1 -1
  15. package/dist/collections/index.js +141 -4
  16. package/dist/collections/index.js.map +1 -1
  17. package/dist/expressions/callSource.d.ts +41 -0
  18. package/dist/expressions/evaluate.d.ts +3 -0
  19. package/dist/expressions/fold.d.ts +7 -0
  20. package/dist/expressions/index.cjs +1985 -242
  21. package/dist/expressions/index.cjs.map +1 -1
  22. package/dist/expressions/index.d.ts +2 -0
  23. package/dist/expressions/index.js +1997 -243
  24. package/dist/expressions/index.js.map +1 -1
  25. package/dist/expressions/parser.d.ts +42 -1
  26. package/dist/expressions/types.d.ts +45 -26
  27. package/dist/expressions/utils.d.ts +19 -1
  28. package/dist/index.cjs +3139 -680
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.js +3479 -997
  31. package/dist/index.js.map +1 -1
  32. package/dist/performance/index.cjs +6 -4
  33. package/dist/performance/index.cjs.map +1 -1
  34. package/dist/performance/index.js +6 -4
  35. package/dist/performance/index.js.map +1 -1
  36. package/dist/pipeline/index.cjs +6 -4
  37. package/dist/pipeline/index.cjs.map +1 -1
  38. package/dist/pipeline/index.js +6 -4
  39. package/dist/pipeline/index.js.map +1 -1
  40. package/dist/plugins/EphemeralDataPlugin.d.ts +8 -0
  41. package/dist/plugins/index.cjs +2921 -411
  42. package/dist/plugins/index.cjs.map +1 -1
  43. package/dist/plugins/index.js +2863 -343
  44. package/dist/plugins/index.js.map +1 -1
  45. package/dist/plugins/query/QueryOptionsCollection.d.ts +48 -10
  46. package/dist/plugins/query/describeFilter.d.ts +83 -0
  47. package/dist/plugins/query/explain.d.ts +71 -9
  48. package/dist/plugins/query/index.d.ts +2 -0
  49. package/dist/plugins/query/join.d.ts +4 -1
  50. package/dist/plugins/query/renames.d.ts +27 -0
  51. package/dist/plugins/query/types.d.ts +50 -4
  52. package/dist/plugins/translators/SqlTranslator.d.ts +15 -0
  53. package/dist/schema/PropertyInfo.d.ts +0 -1
  54. package/dist/schema/SchemaDefinition.d.ts +8 -0
  55. package/dist/schema/changeTracker.d.ts +10 -0
  56. package/dist/schema/index.cjs +298 -288
  57. package/dist/schema/index.cjs.map +1 -1
  58. package/dist/schema/index.d.ts +1 -0
  59. package/dist/schema/index.js +301 -290
  60. package/dist/schema/index.js.map +1 -1
  61. package/dist/schema/types.d.ts +8 -7
  62. package/dist/schema/utils/storageDates.d.ts +25 -0
  63. package/dist/transfer/index.cjs.map +1 -1
  64. package/dist/transfer/index.js.map +1 -1
  65. package/dist/utilities/index.cjs +306 -68
  66. package/dist/utilities/index.cjs.map +1 -1
  67. package/dist/utilities/index.js +306 -68
  68. package/dist/utilities/index.js.map +1 -1
  69. package/package.json +2 -2
  70. package/dist/codegen/utils.d.ts +0 -22
@@ -344,6 +344,14 @@ class FunctionFactoryBuilder extends ContainerBlock {
344
344
  this._params.push(...params);
345
345
  return this;
346
346
  }
347
+ /**
348
+ * Adds a factory parameter carrying `value` and returns its name, for generated code to
349
+ * refer to. See `CodeBuilder.bind` for why values travel this way.
350
+ */ bind(value) {
351
+ const parameter = this.createParameter(value);
352
+ this._params.push(parameter);
353
+ return parameter.name;
354
+ }
347
355
  return() {
348
356
  this._return = true;
349
357
  return this;
@@ -459,6 +467,26 @@ class IfBuilder extends ContainerBlock {
459
467
  }
460
468
  }
461
469
  class CodeBuilder extends ContainerBlock {
470
+ _bindings = [];
471
+ /**
472
+ * Makes `value` available to the generated function under the returned name.
473
+ *
474
+ * Generated code must never reach a runtime value by its source name or by pasting its
475
+ * source text: a minifier renames the declaration and cannot see inside the generated
476
+ * string, and pasted source loses the scope it closed over (#40, #46). A binding is passed
477
+ * in as a real value when the function is compiled, so it survives any bundler.
478
+ */ bind(value, name = `binding${this._bindings.length}`) {
479
+ this._bindings.push({
480
+ name,
481
+ value
482
+ });
483
+ return name;
484
+ }
485
+ getBindings() {
486
+ return [
487
+ ...this._bindings
488
+ ];
489
+ }
462
490
  toString() {
463
491
  return this._lines.map((line)=>typeof line === 'string' ? this.indent(line) : line.toString()).join('\n\n');
464
492
  }
@@ -541,6 +569,129 @@ var HashType = /*#__PURE__*/ function(HashType) {
541
569
  }({});
542
570
 
543
571
 
572
+ },
573
+ 575(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
574
+ __webpack_require__.d(__webpack_exports__, {
575
+ L: () => (hasPrimitiveElements),
576
+ l: () => (isArrayValued)
577
+ });
578
+ /* import */ var _types__rspack_import_0 = __webpack_require__(537);
579
+
580
+ /**
581
+ * Types whose runtime value is a JS array.
582
+ *
583
+ * `Array` and `Vector` are the same thing to every layer that copies, compares, hashes or
584
+ * freezes a value — a vector is a list of numbers and nothing more. They differ only where a
585
+ * backend chooses storage, which is the one place that should ask for `SchemaTypes.Vector` by
586
+ * name.
587
+ *
588
+ * This exists so adding a third array-shaped type is one edit rather than a hunt through
589
+ * twelve handlers. Missing one of those is silent in the worst way: a vector that clones by
590
+ * reference is shared with the change tracker's copy, so overwriting an embedding produces no
591
+ * diff and the save reports nothing to do.
592
+ */ const ARRAY_VALUED_TYPES = new Set([
593
+ _types__rspack_import_0/* .SchemaTypes.Array */.L.Array,
594
+ _types__rspack_import_0/* .SchemaTypes.Vector */.L.Vector
595
+ ]);
596
+ /** 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);
597
+ /**
598
+ * True when the property's elements are primitives, so a spread is a sufficient copy.
599
+ *
600
+ * A vector is always numbers, so it never needs the per-element deep copy an array of objects
601
+ * or dates does.
602
+ */ const PRIMITIVE_ELEMENT_TYPES = new Set([
603
+ _types__rspack_import_0/* .SchemaTypes.String */.L.String,
604
+ _types__rspack_import_0/* .SchemaTypes.Number */.L.Number,
605
+ _types__rspack_import_0/* .SchemaTypes.Boolean */.L.Boolean
606
+ ]);
607
+ const hasPrimitiveElements = (type, elementType)=>type === _types__rspack_import_0/* .SchemaTypes.Vector */.L.Vector || PRIMITIVE_ELEMENT_TYPES.has(elementType);
608
+
609
+
610
+ },
611
+ 894(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
612
+ __webpack_require__.d(__webpack_exports__, {
613
+ T: () => (getStorageDateReviver)
614
+ });
615
+ /* import */ var _types__rspack_import_0 = __webpack_require__(537);
616
+ /* import */ var _propertyKind__rspack_import_1 = __webpack_require__(575);
617
+
618
+
619
+ const collectDatePaths = (properties, paths)=>{
620
+ for (const property of properties){
621
+ // The stored value belongs to whoever wrote it: a custom serializer, deserializer or
622
+ // transform reads it back, and would be handed a Date it did not expect. Unmapped
623
+ // properties are never stored.
624
+ if (property.valueSerializer != null || property.valueDeserializer != null || property.transform != null || property.isUnmapped) {
625
+ continue;
626
+ }
627
+ if (property.type === _types__rspack_import_0/* .SchemaTypes.Object */.L.Object) {
628
+ collectDatePaths(property.children, paths);
629
+ continue;
630
+ }
631
+ const isArray = (0,_propertyKind__rspack_import_1/* .isArrayValued */.l)(property.type) && property.innerSchema?.type === _types__rspack_import_0/* .SchemaTypes.Date */.L.Date;
632
+ if (property.type !== _types__rspack_import_0/* .SchemaTypes.Date */.L.Date && isArray === false) {
633
+ continue;
634
+ }
635
+ paths.push({
636
+ segments: [
637
+ ...property.getParentPathArray({
638
+ useFromPropertyName: true
639
+ }),
640
+ property.getResolvedName()
641
+ ],
642
+ isArray
643
+ });
644
+ }
645
+ };
646
+ const reviveAt = (record, path)=>{
647
+ const { segments } = path;
648
+ let parent = record;
649
+ for(let i = 0, length = segments.length - 1; i < length; i++){
650
+ parent = parent[segments[i]];
651
+ // An absent or null parent holds no date
652
+ if (parent == null || typeof parent !== "object") {
653
+ return;
654
+ }
655
+ }
656
+ const key = segments[segments.length - 1];
657
+ const value = parent[key];
658
+ if (path.isArray === false) {
659
+ if (typeof value === "string") {
660
+ parent[key] = new Date(value);
661
+ }
662
+ return;
663
+ }
664
+ if (Array.isArray(value)) {
665
+ for(let i = 0, length = value.length; i < length; i++){
666
+ if (typeof value[i] === "string") {
667
+ value[i] = new Date(value[i]);
668
+ }
669
+ }
670
+ }
671
+ };
672
+ /** Per schema: `null` for a schema with no dates, so a caller can skip the pass. */ const revivers = new WeakMap();
673
+ /**
674
+ * The reviver for `schema`'s records, or `null` when it declares no dates.
675
+ *
676
+ * Built once per compiled schema. A read revives every row it returns, so the paths are resolved
677
+ * here rather than per row.
678
+ */ const getStorageDateReviver = (schema)=>{
679
+ const cached = revivers.get(schema);
680
+ if (cached !== undefined) {
681
+ return cached;
682
+ }
683
+ const paths = [];
684
+ collectDatePaths(schema.properties, paths);
685
+ const reviver = paths.length === 0 ? null : (record)=>{
686
+ for(let i = 0, length = paths.length; i < length; i++){
687
+ reviveAt(record, paths[i]);
688
+ }
689
+ };
690
+ revivers.set(schema, reviver);
691
+ return reviver;
692
+ };
693
+
694
+
544
695
  },
545
696
  581(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
546
697
  __webpack_require__.d(__webpack_exports__, {
@@ -616,12 +767,14 @@ const isLogLevel = (value)=>typeof value === 'string' && LOG_LEVELS.includes(val
616
767
  const debug = process.env.DEBUG;
617
768
  if (debug === 'routier' || debug === '*') return 'debug';
618
769
  const env = "production"?.toLowerCase();
619
- // `test` is deliberately absent. It used to be here, which meant no test suite anywhere
620
- // could run Routier quietly. Opt in with DEBUG=routier or ROUTIER_LOG_LEVEL when a test
621
- // needs the output.
622
770
  if (env === 'dev' || env === 'development') return 'debug';
623
771
  }
624
- return 'silent';
772
+ // Warnings are on unless something turns them off.
773
+ //
774
+ // Routier warns when a query returns correct rows a slower way than it could, or when a filter
775
+ // compares types that can never match. Both are the caller's to act on, and a default of
776
+ // `silent` meant the only people who ever saw them were the ones who already knew to look.
777
+ return 'warn';
625
778
  };
626
779
  let level = resolveLevel();
627
780
  let rank = RANK[level];
@@ -918,7 +1071,7 @@ var __webpack_exports__ = {};
918
1071
 
919
1072
  // EXPORTS
920
1073
  __webpack_require__.d(__webpack_exports__, {
921
- ly: () => (/* reexport */ isArrayValued),
1074
+ ly: () => (/* reexport */ propertyKind/* .isArrayValued */.l),
922
1075
  Qc: () => (/* reexport */ SchemaDate),
923
1076
  dF: () => (/* reexport */ SchemaDefinition),
924
1077
  VG: () => (/* reexport */ compiledSchemaToJsonSchema),
@@ -929,7 +1082,7 @@ __webpack_require__.d(__webpack_exports__, {
929
1082
  qQ: () => (/* reexport */ SchemaIdentity),
930
1083
  _t: () => (/* reexport */ SchemaDistinct),
931
1084
  PG: () => (/* reexport */ SchemaNumber),
932
- LL: () => (/* reexport */ hasPrimitiveElements),
1085
+ LL: () => (/* reexport */ propertyKind/* .hasPrimitiveElements */.L),
933
1086
  IB: () => (/* reexport */ SchemaTracked),
934
1087
  L$: () => (/* reexport */ rehydrateSchemaFromJsonSchema),
935
1088
  CW: () => (/* reexport */ SchemaSerialize),
@@ -945,10 +1098,11 @@ __webpack_require__.d(__webpack_exports__, {
945
1098
  w_: () => (/* reexport */ SchemaBoolean),
946
1099
  Od: () => (/* reexport */ extractTypeInfo),
947
1100
  r5: () => (/* reexport */ SchemaComputed),
948
- UX: () => (/* reexport */ propertyInfoToJsonSchema),
1101
+ TH: () => (/* reexport */ storageDates/* .getStorageDateReviver */.T),
949
1102
  XM: () => (/* reexport */ SchemaString),
950
1103
  Cg: () => (/* reexport */ SchemaFile),
951
1104
  FR: () => (/* reexport */ SchemaBase),
1105
+ UX: () => (/* reexport */ propertyInfoToJsonSchema),
952
1106
  s: () => (/* reexport */ s),
953
1107
  yV: () => (/* reexport */ SchemaTag),
954
1108
  ge: () => (/* reexport */ SchemaSearchable),
@@ -1765,12 +1919,6 @@ class SchemaComputed extends SchemaBase {
1765
1919
  ;// CONCATENATED MODULE: ./src/schema/PropertyInfo.ts
1766
1920
 
1767
1921
 
1768
- const SUPPORTED_DESERIALIZATION_TYPES = new Set([
1769
- types/* .SchemaTypes.Boolean */.L.Boolean,
1770
- types/* .SchemaTypes.Date */.L.Date,
1771
- types/* .SchemaTypes.Number */.L.Number,
1772
- types/* .SchemaTypes.String */.L.String
1773
- ]);
1774
1922
  /**
1775
1923
  * Represents metadata and utilities for a property in a schema, including its type, name, parent, children, and serialization details.
1776
1924
  */ class PropertyInfo {
@@ -1890,9 +2038,6 @@ const SUPPORTED_DESERIALIZATION_TYPES = new Set([
1890
2038
  get isRenamed() {
1891
2039
  return !!this.from;
1892
2040
  }
1893
- get supportsDeserialization() {
1894
- return this.valueDeserializer != null || SUPPORTED_DESERIALIZATION_TYPES.has(this.type);
1895
- }
1896
2041
  _getPropertyChain() {
1897
2042
  if (this._propertyChainCache) {
1898
2043
  return this._propertyChainCache;
@@ -2145,7 +2290,7 @@ const SUPPORTED_DESERIALIZATION_TYPES = new Set([
2145
2290
  if (this.type === types/* .SchemaTypes.Boolean */.L.Boolean) {
2146
2291
  return Boolean(value);
2147
2292
  }
2148
- throw new Error(`Unsupported deserialization for type. Type: ${this.type}`);
2293
+ return value;
2149
2294
  }
2150
2295
  }
2151
2296
 
@@ -2172,78 +2317,9 @@ class SlotPath {
2172
2317
 
2173
2318
  // EXTERNAL MODULE: ./src/errors/SchemaError.ts
2174
2319
  var SchemaError = __webpack_require__(131);
2175
- ;// CONCATENATED MODULE: ./src/codegen/utils.ts
2176
- /**
2177
- * Counts non-overlapping occurrences of a term in text.
2178
- *
2179
- * Behavior:
2180
- * - Case-sensitive matching
2181
- * - If the search term is composed entirely of word characters (A–Z, a–z, 0–9, _),
2182
- * enforce whole-word boundaries so "red" does not match inside "redder".
2183
- * - If the search term contains any non-word character (e.g. "=>", "()", "::"),
2184
- * match anywhere without boundary checks (useful for symbols).
2185
- * - Non-overlapping matches (after a hit, advances by term length)
2186
- * - Optimized single-character fast path; otherwise uses indexOf loop
2187
- *
2188
- * Examples:
2189
- * - countWordOccurance("red redder red", "red") => 2
2190
- * - countWordOccurance("()=>{}", "=>") => 1
2191
- * - countWordOccurance("aaaa", "aa") => 2 (non-overlapping)
2192
- *
2193
- * @param text The source text to scan
2194
- * @param word The term to match (must be non-empty)
2195
- * @returns The number of occurrences found
2196
- */ const countWordOccurance = (text, word)=>{
2197
- const wl = word.length;
2198
- const tl = text.length;
2199
- if (wl === 0 || wl > tl) return 0;
2200
- // Fast path for single-character words
2201
- if (wl === 1) {
2202
- let c = 0;
2203
- const code = word.charCodeAt(0);
2204
- for(let i = 0; i < tl; i++)if (text.charCodeAt(i) === code) c++;
2205
- return c;
2206
- }
2207
- let count = 0;
2208
- let i = 0;
2209
- function isWordCharCode(c) {
2210
- return c >= 48 && c <= 57 // 0-9
2211
- || c >= 65 && c <= 90 // A-Z
2212
- || c >= 97 && c <= 122 // a-z
2213
- || c === 95; // _
2214
- }
2215
- // Decide whether to enforce word boundaries based on the search term
2216
- let enforceWordBoundaries = true;
2217
- for(let k = 0; k < wl; k++){
2218
- const cc = word.charCodeAt(k);
2219
- if (!isWordCharCode(cc)) {
2220
- enforceWordBoundaries = false;
2221
- break;
2222
- }
2223
- }
2224
- while(true){
2225
- i = text.indexOf(word, i);
2226
- if (i === -1) break;
2227
- if (enforceWordBoundaries) {
2228
- const left = i - 1;
2229
- const right = i + wl;
2230
- const leftOk = left < 0 || !isWordCharCode(text.charCodeAt(left));
2231
- const rightOk = right >= tl || !isWordCharCode(text.charCodeAt(right));
2232
- if (leftOk && rightOk) count++;
2233
- } else {
2234
- // No boundary enforcement for symbol-containing terms
2235
- count++;
2236
- }
2237
- i += wl; // non-overlapping word matches
2238
- }
2239
- return count;
2240
- };
2241
-
2242
2320
  ;// CONCATENATED MODULE: ./src/codegen/handlers/types.ts
2243
2321
 
2244
2322
 
2245
-
2246
-
2247
2323
  /**
2248
2324
  * Terminal link for chains that apply only to a subset of properties (keys,
2249
2325
  * identities). Returning the builder marks every other property as
@@ -2419,34 +2495,16 @@ class PropertyInfoHandler {
2419
2495
  }
2420
2496
  enriched.property(`${property.name}: ${entitySelectorPath}`);
2421
2497
  }
2422
- toNamedFunction(stringifiedFunction, parent) {
2423
- const name = `_${(0,uuid/* .uuid */.u)()}`;
2424
- const builder = parent.function(name);
2425
- const occurences = countWordOccurance(stringifiedFunction, "=>");
2426
- if (occurences > 0) {
2427
- const split = stringifiedFunction.split("=>").map((w)=>w.trim());
2428
- const parameters = split[0].replace(/\(|\)/g, "").split(",");
2429
- let body = split[1];
2430
- if (occurences > 1) {
2431
- // we have a function that returns a function
2432
- const index = stringifiedFunction.indexOf("=>");
2433
- body = stringifiedFunction.slice(index + 2, stringifiedFunction.length);
2434
- }
2435
- if (body.startsWith("{") === true && body.endsWith("}")) {
2436
- // Remove brackets, wrapping function will have them
2437
- builder.appendBody(body.slice(1, body.length - 1));
2438
- return {
2439
- builder,
2440
- parameters
2441
- };
2442
- }
2443
- builder.appendBody(`return ${body};`);
2444
- return {
2445
- builder,
2446
- parameters
2447
- };
2448
- }
2449
- throw new Error("Only arrow functions are allowed in the schema definition: function () {} ---> () => {}");
2498
+ /**
2499
+ * Binds a function the schema author supplied (a default, a computed, a serializer) into
2500
+ * the generated code and returns the expression that calls it with `args`.
2501
+ *
2502
+ * The function is passed in by value rather than pasted in as source text. Pasted source
2503
+ * loses the scope it was written in, so a default that called an imported helper threw, and
2504
+ * it had to be parsed back apart, which only worked for arrows: a bundler that lowers arrows
2505
+ * to `function` expressions, or renames what they refer to, broke every schema (#46).
2506
+ */ emitBoundCall(target, fn, args) {
2507
+ return `${target.bind(fn)}(${args.join(", ")})`;
2450
2508
  }
2451
2509
  }
2452
2510
 
@@ -2606,28 +2664,21 @@ class EnrichmentPrimitiveHandler extends PropertyInfoHandler {
2606
2664
  class EnrichmentFunctionHandler extends PropertyInfoHandler {
2607
2665
  handle(property, builder) {
2608
2666
  if (property.functionBody != null && property.type === types/* .SchemaTypes.Function */.L.Function) {
2609
- const parameterNames = [
2667
+ const factory = builder.get("factory");
2668
+ const args = [
2610
2669
  "enriched",
2611
2670
  "collectionName"
2612
2671
  ];
2613
2672
  if (property.injected != null) {
2614
- const factory = builder.get("factory");
2615
- const parameter = factory.createParameter(property.injected);
2616
- factory.parameters(parameter);
2617
- parameterNames.push(parameter.name);
2673
+ args.push(factory.bind(property.injected));
2618
2674
  }
2619
- const declarationsSlot = builder.get("factory.function.declarations");
2620
- // Unwrap the functions to removing currying
2621
- const defaultFunctionWithParameters = this.toNamedFunction(property.functionBody.toString(), declarationsSlot);
2622
- defaultFunctionWithParameters.builder.parameters(...parameterNames.map((w, i)=>({
2623
- name: defaultFunctionWithParameters.parameters[i],
2624
- callName: w
2625
- })));
2626
2675
  const slot = builder.get("factory.function.assignment");
2627
2676
  const enrichedAssignmentPath = property.getAssignmentPath({
2628
2677
  parent: "enriched"
2629
2678
  });
2630
- slot.assign(enrichedAssignmentPath).value(defaultFunctionWithParameters.builder.toCallable());
2679
+ // The definition is curried: calling it with the entity returns the function the
2680
+ // property holds
2681
+ slot.assign(enrichedAssignmentPath).value(this.emitBoundCall(factory, property.functionBody, args));
2631
2682
  return builder;
2632
2683
  }
2633
2684
  return super.handle(property, builder);
@@ -2682,34 +2733,17 @@ class EnrichmentDefaultFunctionHandler extends PropertyInfoHandler {
2682
2733
  handle(property, builder) {
2683
2734
  if (property.defaultValue != null && typeof property.defaultValue === "function") {
2684
2735
  this.setEnrichedProperty(property, builder);
2685
- // we need to add the call for this function too, want to create an if
2686
- const declarationsSlot = builder.get("factory.function.declarations");
2687
- if (property.injected != null) {
2688
- const factory = builder.get("factory");
2689
- if (factory == null) {
2690
- throw new Error("Error building enricher, could not find slot for factory");
2691
- }
2692
- const parameter = factory.createParameter(property.injected);
2693
- factory.parameters(parameter);
2694
- const defaultFunctionWithParameters = this.toNamedFunction(property.defaultValue.toString(), declarationsSlot);
2695
- // This is ok, defaults can only inject one parameter anyways
2696
- defaultFunctionWithParameters.builder.parameters(...defaultFunctionWithParameters.parameters.map((w)=>({
2697
- name: w,
2698
- callName: parameter.name
2699
- })));
2700
- const ifsSlot = builder.get("factory.function.ifs");
2701
- const enrichedAssignmentPath = property.getAssignmentPath({
2702
- parent: "enriched"
2703
- });
2704
- ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${defaultFunctionWithParameters.builder.toCallable()}`);
2705
- return builder;
2706
- }
2707
- const defaultFunction = this.toNamedFunction(property.defaultValue.toString(), declarationsSlot);
2736
+ const factory = builder.get("factory");
2737
+ // Defaults take at most one argument: the injected value, when there is one
2738
+ const args = property.injected != null ? [
2739
+ factory.bind(property.injected)
2740
+ ] : [];
2741
+ const call = this.emitBoundCall(factory, property.defaultValue, args);
2708
2742
  const ifsSlot = builder.get("factory.function.ifs");
2709
2743
  const enrichedAssignmentPath = property.getAssignmentPath({
2710
2744
  parent: "enriched"
2711
2745
  });
2712
- ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${defaultFunction.builder.toCallable()}`);
2746
+ ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${call}`);
2713
2747
  return builder;
2714
2748
  }
2715
2749
  return super.handle(property, builder);
@@ -2722,22 +2756,15 @@ class EnrichmentDefaultFunctionHandler extends PropertyInfoHandler {
2722
2756
  class EnrichmentComputedValueHandler extends PropertyInfoHandler {
2723
2757
  handle(property, builder) {
2724
2758
  if (property.functionBody != null && property.type === types/* .SchemaTypes.Computed */.L.Computed) {
2725
- const parameterNames = [
2759
+ const factory = builder.get("factory");
2760
+ const args = [
2726
2761
  "enriched",
2727
2762
  "collectionName"
2728
2763
  ];
2729
2764
  if (property.injected != null) {
2730
- const factory = builder.get("factory");
2731
- const parameter = factory.createParameter(property.injected);
2732
- factory.parameters(parameter);
2733
- parameterNames.push(parameter.name);
2765
+ args.push(factory.bind(property.injected));
2734
2766
  }
2735
- const declarationsSlot = builder.get("factory.function.declarations");
2736
- const defaultFunctionWithParameters = this.toNamedFunction(property.functionBody.toString(), declarationsSlot);
2737
- defaultFunctionWithParameters.builder.parameters(...parameterNames.map((w, i)=>({
2738
- name: defaultFunctionWithParameters.parameters[i],
2739
- callName: w
2740
- })));
2767
+ const call = this.emitBoundCall(factory, property.functionBody, args);
2741
2768
  // Compute-once semantics for computed keys/identities: an existing value is
2742
2769
  // carried into the enriched literal and never recomputed — a key must stay
2743
2770
  // stable once assigned (content-hash ids would otherwise churn as the
@@ -2750,44 +2777,15 @@ class EnrichmentComputedValueHandler extends PropertyInfoHandler {
2750
2777
  const enrichedAssignmentPath = property.getAssignmentPath({
2751
2778
  parent: "enriched"
2752
2779
  });
2753
- ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${defaultFunctionWithParameters.builder.toCallable()}`);
2780
+ ifsSlot.if(`${enrichedAssignmentPath} == null`).appendBody(`${enrichedAssignmentPath} = ${call}`);
2754
2781
  return builder;
2755
2782
  }
2756
2783
  return super.handle(property, builder);
2757
2784
  }
2758
2785
  }
2759
2786
 
2760
- ;// CONCATENATED MODULE: ./src/schema/utils/propertyKind.ts
2761
-
2762
- /**
2763
- * Types whose runtime value is a JS array.
2764
- *
2765
- * `Array` and `Vector` are the same thing to every layer that copies, compares, hashes or
2766
- * freezes a value — a vector is a list of numbers and nothing more. They differ only where a
2767
- * backend chooses storage, which is the one place that should ask for `SchemaTypes.Vector` by
2768
- * name.
2769
- *
2770
- * This exists so adding a third array-shaped type is one edit rather than a hunt through
2771
- * twelve handlers. Missing one of those is silent in the worst way: a vector that clones by
2772
- * reference is shared with the change tracker's copy, so overwriting an embedding produces no
2773
- * diff and the save reports nothing to do.
2774
- */ const ARRAY_VALUED_TYPES = new Set([
2775
- types/* .SchemaTypes.Array */.L.Array,
2776
- types/* .SchemaTypes.Vector */.L.Vector
2777
- ]);
2778
- /** 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);
2779
- /**
2780
- * True when the property's elements are primitives, so a spread is a sufficient copy.
2781
- *
2782
- * A vector is always numbers, so it never needs the per-element deep copy an array of objects
2783
- * or dates does.
2784
- */ const PRIMITIVE_ELEMENT_TYPES = new Set([
2785
- types/* .SchemaTypes.String */.L.String,
2786
- types/* .SchemaTypes.Number */.L.Number,
2787
- types/* .SchemaTypes.Boolean */.L.Boolean
2788
- ]);
2789
- const hasPrimitiveElements = (type, elementType)=>type === types/* .SchemaTypes.Vector */.L.Vector || PRIMITIVE_ELEMENT_TYPES.has(elementType);
2790
-
2787
+ // EXTERNAL MODULE: ./src/schema/utils/propertyKind.ts
2788
+ var propertyKind = __webpack_require__(575);
2791
2789
  ;// CONCATENATED MODULE: ./src/codegen/handlers/enrichment/EnrichmentArrayHandler.ts
2792
2790
 
2793
2791
 
@@ -2797,7 +2795,7 @@ const hasPrimitiveElements = (type, elementType)=>type === types/* .SchemaTypes.
2797
2795
  * mark the root entity dirty instead of being silently lost on save.
2798
2796
  */ class EnrichmentArrayHandler extends PropertyInfoHandler {
2799
2797
  handle(property, builder) {
2800
- if (isArrayValued(property.type)) {
2798
+ if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
2801
2799
  // Place the property in the enriched literal like any other leaf
2802
2800
  this.setEnrichedProperty(property, builder);
2803
2801
  const enrichedPath = property.getAssignmentPath({
@@ -2839,13 +2837,10 @@ class MergeDefaultFunctionHandler extends PropertyInfoHandler {
2839
2837
  // we are changing merge to be more like enrich so we can handle injections
2840
2838
  // we may need to change more. Need to move towards factories
2841
2839
  if (property.defaultValue != null && typeof property.defaultValue === "function") {
2842
- const defaultFunctionParameters = [];
2843
- if (property.injected != null) {
2844
- const factory = builder.get("factory");
2845
- const parameter = factory.createParameter(property.injected);
2846
- factory.parameters(parameter);
2847
- defaultFunctionParameters.push(parameter.name);
2848
- }
2840
+ const factory = builder.get("factory");
2841
+ const args = property.injected != null ? [
2842
+ factory.bind(property.injected)
2843
+ ] : [];
2849
2844
  // A defaulted property still merges from the source; the default only fills
2850
2845
  // the gap when neither side has a value
2851
2846
  this.emitMergeCopy(property, builder, {
@@ -2861,15 +2856,9 @@ class MergeDefaultFunctionHandler extends PropertyInfoHandler {
2861
2856
  const assignmentPath = property.getAssignmentPath({
2862
2857
  parent: "destination"
2863
2858
  });
2864
- const declarationsSlot = builder.get("factory.function.header");
2865
- const defaultFunctionWithParameters = this.toNamedFunction(property.defaultValue.toString(), declarationsSlot);
2866
- defaultFunctionWithParameters.builder.parameters(...defaultFunctionParameters.map((w, i)=>({
2867
- name: defaultFunctionWithParameters.parameters[i],
2868
- callName: w
2869
- })));
2870
2859
  const defaultIf = ifsSlot.if(`${selectorPath} == null`);
2871
2860
  this.emitDestinationAncestorGuards(property, defaultIf);
2872
- defaultIf.appendBody(`${assignmentPath} = ${defaultFunctionWithParameters.builder.toCallable()}`);
2861
+ defaultIf.appendBody(`${assignmentPath} = ${this.emitBoundCall(factory, property.defaultValue, args)}`);
2873
2862
  return builder;
2874
2863
  }
2875
2864
  return super.handle(property, builder);
@@ -2910,28 +2899,20 @@ class MergePrimitiveHandler extends PropertyInfoHandler {
2910
2899
  class MergeComputedValueHandler extends PropertyInfoHandler {
2911
2900
  handle(property, builder) {
2912
2901
  if (property.functionBody != null && property.type === types/* .SchemaTypes.Computed */.L.Computed) {
2913
- const parameterNames = [
2902
+ const factory = builder.get("factory");
2903
+ const args = [
2914
2904
  "source",
2915
2905
  "collectionName"
2916
2906
  ];
2917
2907
  if (property.injected != null) {
2918
- const factory = builder.get("factory");
2919
- const parameter = factory.createParameter(property.injected);
2920
- factory.parameters(parameter);
2921
- parameterNames.push(parameter.name);
2908
+ args.push(factory.bind(property.injected));
2922
2909
  }
2923
- const declarationsSlot = builder.get("factory.function.header");
2924
- const defaultFunctionWithParameters = this.toNamedFunction(property.functionBody.toString(), declarationsSlot);
2925
- defaultFunctionWithParameters.builder.parameters(...parameterNames.map((w, i)=>({
2926
- name: defaultFunctionWithParameters.parameters[i],
2927
- callName: w
2928
- })));
2929
2910
  const slot = builder.get("factory.function.assignments");
2930
2911
  const enrichedAssignmentPath = property.getAssignmentPath({
2931
2912
  parent: "destination"
2932
2913
  });
2933
2914
  // We want to recompute the value always in case there are changes
2934
- slot.assign(enrichedAssignmentPath).value(defaultFunctionWithParameters.builder.toCallable());
2915
+ slot.assign(enrichedAssignmentPath).value(this.emitBoundCall(factory, property.functionBody, args));
2935
2916
  return builder;
2936
2917
  }
2937
2918
  return super.handle(property, builder);
@@ -3004,7 +2985,7 @@ class MergeFunctionHandler extends PropertyInfoHandler {
3004
2985
  * reference is adopted as-is — same as the primitive copy this replaces.
3005
2986
  */ class MergeArrayHandler extends PropertyInfoHandler {
3006
2987
  handle(property, builder) {
3007
- if (isArrayValued(property.type)) {
2988
+ if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
3008
2989
  const selectorPath = property.getSelectrorPath({
3009
2990
  parent: "source",
3010
2991
  assignmentType: "FORCE_NULLABLE_OR_OPTIONAL"
@@ -3341,7 +3322,7 @@ class CloneArrayHandler extends PropertyInfoHandler {
3341
3322
  super(), this.useFromPropertyName = useFromPropertyName;
3342
3323
  }
3343
3324
  handle(property, builder) {
3344
- if (isArrayValued(property.type)) {
3325
+ if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
3345
3326
  // Arrays are leaf properties — they have no child PropertyInfos, so the
3346
3327
  // copy must happen here for every array, including nullable/optional ones.
3347
3328
  // The `!== undefined` guard below covers absent values; an explicit null is copied as
@@ -3367,7 +3348,7 @@ class CloneArrayHandler extends PropertyInfoHandler {
3367
3348
  // across merges), and a Proxy cannot pass a structured-clone boundary.
3368
3349
  const elementType = property.innerSchema?.type;
3369
3350
  let copyExpression;
3370
- if (hasPrimitiveElements(property.type, elementType)) {
3351
+ if ((0,propertyKind/* .hasPrimitiveElements */.L)(property.type, elementType)) {
3371
3352
  copyExpression = `[...${entitySelectorPath}]`;
3372
3353
  } else if (elementType === types/* .SchemaTypes.Date */.L.Date) {
3373
3354
  copyExpression = `${entitySelectorPath}.map(function (v) { return v == null ? v : new Date(v); })`;
@@ -3486,7 +3467,7 @@ class CloneObjectHandler extends PropertyInfoHandler {
3486
3467
  // Anything that copies by assignment. An array-valued property must not land here:
3487
3468
  // assigning the reference shares it with the source, which is the whole point of
3488
3469
  // CloneArrayHandler.
3489
- if (property.type != types/* .SchemaTypes.Object */.L.Object && isArrayValued(property.type) === false) {
3470
+ if (property.type != types/* .SchemaTypes.Object */.L.Object && (0,propertyKind/* .isArrayValued */.l)(property.type) === false) {
3490
3471
  const slot = builder.get("if");
3491
3472
  const useFromPropertyName = this.useFromPropertyName;
3492
3473
  const entitySelectorPath = property.getSelectrorPath({
@@ -3549,7 +3530,7 @@ class CloneHandlerBuilder {
3549
3530
 
3550
3531
  class CompareArrayHandler extends PropertyInfoHandler {
3551
3532
  handle(property, builder) {
3552
- if (isArrayValued(property.type)) {
3533
+ if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
3553
3534
  let compare = builder.getOrDefault("result.variable.compare");
3554
3535
  const leftCompare = property.getSelectrorPath({
3555
3536
  parent: "a"
@@ -3844,7 +3825,6 @@ class DeserializeDeserializerHandler extends PropertyInfoHandler {
3844
3825
  handle(property, builder) {
3845
3826
  if (property.valueDeserializer != null) {
3846
3827
  let objectBuilder = builder.getOrDefault("result.variable.object");
3847
- const assignmentBuilder = builder.getOrDefault("functions");
3848
3828
  // Read the incoming record by `from` (storage) name
3849
3829
  const entitySelectorPath = property.getSelectrorPath({
3850
3830
  parent: "unserialized",
@@ -3857,18 +3837,16 @@ class DeserializeDeserializerHandler extends PropertyInfoHandler {
3857
3837
  name: "object"
3858
3838
  });
3859
3839
  }
3860
- const defaultFunctionWithParameters = this.toNamedFunction(property.valueDeserializer.toString(), assignmentBuilder);
3861
- defaultFunctionWithParameters.builder.parameters(...defaultFunctionWithParameters.parameters.map((_, i)=>({
3862
- name: defaultFunctionWithParameters.parameters[i],
3863
- callName: entitySelectorPath
3864
- })));
3840
+ const call = this.emitBoundCall(builder, property.valueDeserializer, [
3841
+ entitySelectorPath
3842
+ ]);
3865
3843
  if (property.parent == null) {
3866
- objectBuilder.property(`${property.name}: ${defaultFunctionWithParameters.builder.toCallable()}`);
3844
+ objectBuilder.property(`${property.name}: ${call}`);
3867
3845
  return builder;
3868
3846
  }
3869
3847
  const slotPath = new SlotPath(...property.getParentPathArray());
3870
3848
  objectBuilder = objectBuilder.get(slotPath.get());
3871
- objectBuilder.property(`${property.name}: ${defaultFunctionWithParameters.builder.toCallable()}`);
3849
+ objectBuilder.property(`${property.name}: ${call}`);
3872
3850
  return builder;
3873
3851
  }
3874
3852
  return super.handle(property, builder);
@@ -3894,7 +3872,7 @@ class DeserializeDeserializerHandler extends PropertyInfoHandler {
3894
3872
  return `[...${selector}]`;
3895
3873
  }
3896
3874
  handle(property, builder) {
3897
- if (isArrayValued(property.type)) {
3875
+ if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
3898
3876
  const slotPath = new SlotPath("result.variable.object");
3899
3877
  // Create the result object when this is the first property iterated —
3900
3878
  // handler output cannot depend on schema property order
@@ -4135,7 +4113,7 @@ class HashComputedValueHandler extends PropertyInfoHandler {
4135
4113
  * objects would collapse every value to "[object Object]" and collide.
4136
4114
  */ class HashArrayHandler extends PropertyInfoHandler {
4137
4115
  handle(property, builder) {
4138
- if (isArrayValued(property.type)) {
4116
+ if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
4139
4117
  let stringBuilder = builder.getOrDefault("hash-object-return.variable.string");
4140
4118
  const entitySelectorPath = property.getSelectrorPath({
4141
4119
  parent: "entity"
@@ -4300,7 +4278,7 @@ class EnableChangeTrackingObjectHandler extends PropertyInfoHandler {
4300
4278
  * mark the root entity dirty instead of being silently lost on save.
4301
4279
  */ class EnableChangeTrackingArrayHandler extends PropertyInfoHandler {
4302
4280
  handle(property, builder) {
4303
- if (isArrayValued(property.type)) {
4281
+ if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
4304
4282
  const assignmentSlot = builder.get("assignment");
4305
4283
  const childSelectorPath = property.getSelectrorPath({
4306
4284
  parent: "entity"
@@ -4377,7 +4355,7 @@ class FreezeObjectHandler extends PropertyInfoHandler {
4377
4355
 
4378
4356
  class FreezeArrayHandler extends PropertyInfoHandler {
4379
4357
  handle(property, builder) {
4380
- if (isArrayValued(property.type)) {
4358
+ if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
4381
4359
  const assignmentSlot = builder.get("assignment");
4382
4360
  const childSelectorPath = property.getSelectrorPath({
4383
4361
  parent: "entity"
@@ -4513,7 +4491,6 @@ class SerializeSerializerHandler extends PropertyInfoHandler {
4513
4491
  handle(property, builder) {
4514
4492
  if (property.valueSerializer != null) {
4515
4493
  const slot = builder.getOrDefault("if");
4516
- const assignmentBuilder = builder.getOrDefault("functions");
4517
4494
  // Serialize maps in-memory shape -> storage shape: read the entity by
4518
4495
  // property name, write the result by `from` (storage) name
4519
4496
  const entitySelectorPath = property.getSelectrorPath({
@@ -4523,17 +4500,15 @@ class SerializeSerializerHandler extends PropertyInfoHandler {
4523
4500
  parent: "result",
4524
4501
  useFromPropertyName: true
4525
4502
  });
4526
- const defaultFunctionWithParameters = this.toNamedFunction(property.valueSerializer.toString(), assignmentBuilder);
4527
- defaultFunctionWithParameters.builder.parameters(...defaultFunctionWithParameters.parameters.map((_, i)=>({
4528
- name: defaultFunctionWithParameters.parameters[i],
4529
- callName: entitySelectorPath
4530
- })));
4503
+ const call = this.emitBoundCall(builder, property.valueSerializer, [
4504
+ entitySelectorPath
4505
+ ]);
4531
4506
  if (property.parent == null) {
4532
- slot.if(`Object.hasOwn(entity, "${property.name}")`).appendBody(`${resultSelectorPath} = ${defaultFunctionWithParameters.builder.toCallable()}`);
4507
+ slot.if(`Object.hasOwn(entity, "${property.name}")`).appendBody(`${resultSelectorPath} = ${call}`);
4533
4508
  return builder;
4534
4509
  }
4535
4510
  // Nested serializer: same pattern as SerializeValueHandler — if block for parent existence, then assign via serializer
4536
- this.emitSerializeNestedAssignment(property, slot, defaultFunctionWithParameters.builder.toCallable());
4511
+ this.emitSerializeNestedAssignment(property, slot, call);
4537
4512
  return builder;
4538
4513
  }
4539
4514
  return super.handle(property, builder);
@@ -4592,7 +4567,7 @@ class SerializeComputedHandler extends PropertyInfoHandler {
4592
4567
  return `[...${selector}]`;
4593
4568
  }
4594
4569
  handle(property, builder) {
4595
- if (isArrayValued(property.type)) {
4570
+ if ((0,propertyKind/* .isArrayValued */.l)(property.type)) {
4596
4571
  const slot = builder.get("if");
4597
4572
  // Serialize maps in-memory shape -> storage shape: read the entity by
4598
4573
  // property name, write the result by `from` (storage) name
@@ -5496,8 +5471,8 @@ const arrayConverter = (property, context)=>{
5496
5471
  // Create the function using new Function()
5497
5472
  // If no parameters, call with just the body; otherwise spread the params
5498
5473
  const fn = params.length > 0 ? new Function(...params, functionBody) : new Function(functionBody);
5499
- // Wrap it so toString() returns the original arrow function string
5500
- // This is needed because the schema system validates that functions are arrow functions
5474
+ // Wrap it so toString() returns the original arrow function string, so
5475
+ // serializing the rehydrated schema writes the same functionSource again
5501
5476
  recreatedFn = Object.assign(fn, {
5502
5477
  toString: ()=>functionSource
5503
5478
  });
@@ -5506,7 +5481,7 @@ const arrayConverter = (property, context)=>{
5506
5481
  recreatedFn = ()=>{
5507
5482
  throw new Error(`Cannot recreate computed property ${computedProp.name}: ${e instanceof Error ? e.message : 'unknown error'}`);
5508
5483
  };
5509
- // Ensure toString returns an arrow function for validation
5484
+ // Keep functionSource re-parseable if this schema is serialized again
5510
5485
  Object.assign(recreatedFn, {
5511
5486
  toString: ()=>`() => { throw new Error("Cannot recreate computed property ${computedProp.name}"); }`
5512
5487
  });
@@ -5643,39 +5618,16 @@ class SetHandlerBuilder {
5643
5618
  }
5644
5619
  }
5645
5620
 
5646
- ;// CONCATENATED MODULE: ./src/schema/SchemaDefinition.ts
5647
-
5648
-
5649
-
5650
-
5651
-
5652
-
5653
-
5654
-
5655
-
5656
-
5657
-
5658
-
5659
-
5660
-
5661
-
5662
-
5663
-
5664
-
5665
-
5666
-
5667
-
5668
-
5669
-
5670
-
5671
-
5672
-
5673
- function assertPropertyHandled(generatorName, property, result) {
5674
- if (result == null) {
5675
- 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.`);
5676
- }
5677
- }
5678
- function createChangeTracker() {
5621
+ ;// CONCATENATED MODULE: ./src/schema/changeTracker.ts
5622
+ /**
5623
+ * Builds the proxy factory that change-tracks an entity.
5624
+ *
5625
+ * Generated schema code receives the result as a bound value — a parameter of the generated
5626
+ * factory — and never refers to this module by name. Name references do not survive a minifier,
5627
+ * which renames the declaration but cannot see inside generated source text (#40, #46). The
5628
+ * returned function holds no per-entity state, so one per compiled schema is shared by every
5629
+ * entity it tracks.
5630
+ */ function createChangeTracker() {
5679
5631
  const DIRTY_ENTITY_MARKER = "isDirty";
5680
5632
  const CHANGES_ENTITY_KEY = "changes";
5681
5633
  const ORIGINAL_ENTITY_KEY = "original";
@@ -5774,6 +5726,40 @@ function createChangeTracker() {
5774
5726
  return new Proxy(entity, proxyHandler);
5775
5727
  };
5776
5728
  }
5729
+
5730
+ ;// CONCATENATED MODULE: ./src/schema/SchemaDefinition.ts
5731
+
5732
+
5733
+
5734
+
5735
+
5736
+
5737
+
5738
+
5739
+
5740
+
5741
+
5742
+
5743
+
5744
+
5745
+
5746
+
5747
+
5748
+
5749
+
5750
+
5751
+
5752
+
5753
+
5754
+
5755
+
5756
+
5757
+
5758
+ function assertPropertyHandled(generatorName, property, result) {
5759
+ if (result == null) {
5760
+ 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.`);
5761
+ }
5762
+ }
5777
5763
  class SchemaDefinition extends SchemaBase {
5778
5764
  instance;
5779
5765
  type = types/* .SchemaTypes.Definition */.L.Definition;
@@ -5824,10 +5810,22 @@ class SchemaDefinition extends SchemaBase {
5824
5810
  throw e;
5825
5811
  }
5826
5812
  }
5827
- createFunction(builder, ...fnArgs) {
5813
+ /**
5814
+ * Compiles `builder` into a function taking `fnArgs`.
5815
+ *
5816
+ * A builder with bindings is compiled one level out: an outer function whose parameters are
5817
+ * the bindings, called once here with their values, returns the function that is kept. The
5818
+ * bound values become closure variables of that function, so the per-call cost is a context
5819
+ * read rather than anything resolved by name.
5820
+ */ createFunction(builder, ...fnArgs) {
5828
5821
  const body = builder.toString();
5822
+ const bindings = builder.getBindings();
5829
5823
  try {
5830
- return Function(...fnArgs, body);
5824
+ if (bindings.length === 0) {
5825
+ return Function(...fnArgs, body);
5826
+ }
5827
+ const outer = Function(...bindings.map((w)=>w.name), `return function(${fnArgs.join(", ")}) {\n${body}\n}`);
5828
+ return outer(...bindings.map((w)=>w.value));
5831
5829
  } catch (e) {
5832
5830
  logger/* .logger.error */.vF.error(`Error compiling schema function. Function Body: ${body}`);
5833
5831
  throw e;
@@ -5960,9 +5958,11 @@ class SchemaDefinition extends SchemaBase {
5960
5958
  const serializeHandler = serializeHandlerBuilder.build();
5961
5959
  const compareIdsHandler = compareIdsHandlerBuilder.build();
5962
5960
  const setHandlerHanlder = setHandlerBuilder.build();
5961
+ // Handed to the generated functions as a value, never embedded as source and called
5962
+ // by name — a minifier renames the declaration and breaks every schema (#40).
5963
+ const changeTracker = createChangeTracker();
5963
5964
  const changeTrackingCodeBuilder = new blocks/* .CodeBuilder */.Nl();
5964
- changeTrackingCodeBuilder.raw(`${createChangeTracker.toString()}`);
5965
- changeTrackingCodeBuilder.slot("declarations").variable("enableChangeTracking").value('createChangeTracker()');
5965
+ changeTrackingCodeBuilder.bind(changeTracker, "enableChangeTracking");
5966
5966
  // Nested proxies are installed by assigning through already-proxied parents;
5967
5967
  // pause tracking during setup so those writes don't register as changes
5968
5968
  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;');
@@ -5991,9 +5991,10 @@ class SchemaDefinition extends SchemaBase {
5991
5991
  }).parameters({
5992
5992
  name: "collectionName",
5993
5993
  value: this.collectionName
5994
+ }, {
5995
+ name: "changeTracker",
5996
+ value: changeTracker
5994
5997
  });
5995
- enricherFunctionRoot.slot("changeTracker").raw(`${createChangeTracker.toString()}`);
5996
- enricherFunctionRoot.slot("changeTrackerFunction").raw(`\tconst changeTracker = createChangeTracker();`);
5997
5998
  const enricherFunctionBody = enricherFunctionRoot.function(undefined, {
5998
5999
  name: "function"
5999
6000
  }).parameters("entity", "changeTrackingType").return();
@@ -6228,6 +6229,8 @@ class SchemaDefinition extends SchemaBase {
6228
6229
  enricherFunctionBody.get("append").insert(deserializeCodeBuilder.get("result"));
6229
6230
  enricherFunctionBody.get("append").insert(deserializeCodeBuilder.get("if"));
6230
6231
  enricherFunctionRoot.replace("function", new blocks/* .FunctionBuilder */.kF(undefined).parameters("unserialized", "changeTrackingType").return());
6232
+ // The deserialize slots moved in above call the deserializers bound on their own builder
6233
+ enricherFunctionRoot.parameters(...deserializeCodeBuilder.getBindings());
6231
6234
  const postProcessGenerator = this.createReturnFunction(enricherCodeBuilder);
6232
6235
  const postProcessParams = enricherFunctionRoot.getParameters();
6233
6236
  // Combine prepare and serialize
@@ -6236,6 +6239,10 @@ class SchemaDefinition extends SchemaBase {
6236
6239
  preprocessCodeBuilder.get("main").insert(serializeCodeBuilder.get("assignments"));
6237
6240
  preprocessCodeBuilder.get("main").insert(serializeCodeBuilder.get("functions"));
6238
6241
  preprocessCodeBuilder.get("main").insert(serializeCodeBuilder.get("if"));
6242
+ // Likewise the serialize slots call the serializers bound on the serialize builder
6243
+ for (const binding of serializeCodeBuilder.getBindings()){
6244
+ preprocessCodeBuilder.bind(binding.value, binding.name);
6245
+ }
6239
6246
  const getIdsFunction = this.createFunction(idSelectorCodeBuilder, "entity");
6240
6247
  const getHashTypeFunction = this.createFunction(hashTypeCodeBuilder, "entity");
6241
6248
  const prepareFunction = this.createFunction(prepareCodeBuilder, "entity");
@@ -6877,6 +6884,8 @@ const s = {
6877
6884
 
6878
6885
 
6879
6886
 
6887
+ // EXTERNAL MODULE: ./src/schema/utils/storageDates.ts
6888
+ var storageDates = __webpack_require__(894);
6880
6889
  ;// CONCATENATED MODULE: ./src/schema/index.ts
6881
6890
 
6882
6891
 
@@ -6889,6 +6898,7 @@ const s = {
6889
6898
 
6890
6899
 
6891
6900
 
6901
+
6892
6902
  })();
6893
6903
 
6894
6904
  var __webpack_exports__HashType = __webpack_exports__.$H;
@@ -6925,12 +6935,13 @@ var __webpack_exports__SchemaVector = __webpack_exports__.TF;
6925
6935
  var __webpack_exports__compiledSchemaToJsonSchema = __webpack_exports__.VG;
6926
6936
  var __webpack_exports__createStandardJsonSchemaProps = __webpack_exports__.hM;
6927
6937
  var __webpack_exports__extractTypeInfo = __webpack_exports__.Od;
6938
+ var __webpack_exports__getStorageDateReviver = __webpack_exports__.TH;
6928
6939
  var __webpack_exports__hasPrimitiveElements = __webpack_exports__.LL;
6929
6940
  var __webpack_exports__isArrayValued = __webpack_exports__.ly;
6930
6941
  var __webpack_exports__propertyInfoToJsonSchema = __webpack_exports__.UX;
6931
6942
  var __webpack_exports__rehydrateSchemaFromJsonSchema = __webpack_exports__.L$;
6932
6943
  var __webpack_exports__rehydrateSchemaFromJsonString = __webpack_exports__.Dk;
6933
6944
  var __webpack_exports__s = __webpack_exports__.s;
6934
- export { __webpack_exports__HashType as HashType, __webpack_exports__PropertyInfo as PropertyInfo, __webpack_exports__SchemaArray as SchemaArray, __webpack_exports__SchemaBase as SchemaBase, __webpack_exports__SchemaBoolean as SchemaBoolean, __webpack_exports__SchemaComputed as SchemaComputed, __webpack_exports__SchemaDate as SchemaDate, __webpack_exports__SchemaDefault as SchemaDefault, __webpack_exports__SchemaDefinition as SchemaDefinition, __webpack_exports__SchemaDeserialize as SchemaDeserialize, __webpack_exports__SchemaDistinct as SchemaDistinct, __webpack_exports__SchemaFile as SchemaFile, __webpack_exports__SchemaForeignKey as SchemaForeignKey, __webpack_exports__SchemaFrom as SchemaFrom, __webpack_exports__SchemaFunction as SchemaFunction, __webpack_exports__SchemaIdentity as SchemaIdentity, __webpack_exports__SchemaIndex as SchemaIndex, __webpack_exports__SchemaKey as SchemaKey, __webpack_exports__SchemaNullable as SchemaNullable, __webpack_exports__SchemaNumber as SchemaNumber, __webpack_exports__SchemaObject as SchemaObject, __webpack_exports__SchemaOptional as SchemaOptional, __webpack_exports__SchemaReadonly as SchemaReadonly, __webpack_exports__SchemaSearchable as SchemaSearchable, __webpack_exports__SchemaSerialize as SchemaSerialize, __webpack_exports__SchemaString as SchemaString, __webpack_exports__SchemaTag as SchemaTag, __webpack_exports__SchemaTracked as SchemaTracked, __webpack_exports__SchemaTransform as SchemaTransform, __webpack_exports__SchemaTypes as SchemaTypes, __webpack_exports__SchemaVector as SchemaVector, __webpack_exports__compiledSchemaToJsonSchema as compiledSchemaToJsonSchema, __webpack_exports__createStandardJsonSchemaProps as createStandardJsonSchemaProps, __webpack_exports__extractTypeInfo as extractTypeInfo, __webpack_exports__hasPrimitiveElements as hasPrimitiveElements, __webpack_exports__isArrayValued as isArrayValued, __webpack_exports__propertyInfoToJsonSchema as propertyInfoToJsonSchema, __webpack_exports__rehydrateSchemaFromJsonSchema as rehydrateSchemaFromJsonSchema, __webpack_exports__rehydrateSchemaFromJsonString as rehydrateSchemaFromJsonString, __webpack_exports__s as s };
6945
+ export { __webpack_exports__HashType as HashType, __webpack_exports__PropertyInfo as PropertyInfo, __webpack_exports__SchemaArray as SchemaArray, __webpack_exports__SchemaBase as SchemaBase, __webpack_exports__SchemaBoolean as SchemaBoolean, __webpack_exports__SchemaComputed as SchemaComputed, __webpack_exports__SchemaDate as SchemaDate, __webpack_exports__SchemaDefault as SchemaDefault, __webpack_exports__SchemaDefinition as SchemaDefinition, __webpack_exports__SchemaDeserialize as SchemaDeserialize, __webpack_exports__SchemaDistinct as SchemaDistinct, __webpack_exports__SchemaFile as SchemaFile, __webpack_exports__SchemaForeignKey as SchemaForeignKey, __webpack_exports__SchemaFrom as SchemaFrom, __webpack_exports__SchemaFunction as SchemaFunction, __webpack_exports__SchemaIdentity as SchemaIdentity, __webpack_exports__SchemaIndex as SchemaIndex, __webpack_exports__SchemaKey as SchemaKey, __webpack_exports__SchemaNullable as SchemaNullable, __webpack_exports__SchemaNumber as SchemaNumber, __webpack_exports__SchemaObject as SchemaObject, __webpack_exports__SchemaOptional as SchemaOptional, __webpack_exports__SchemaReadonly as SchemaReadonly, __webpack_exports__SchemaSearchable as SchemaSearchable, __webpack_exports__SchemaSerialize as SchemaSerialize, __webpack_exports__SchemaString as SchemaString, __webpack_exports__SchemaTag as SchemaTag, __webpack_exports__SchemaTracked as SchemaTracked, __webpack_exports__SchemaTransform as SchemaTransform, __webpack_exports__SchemaTypes as SchemaTypes, __webpack_exports__SchemaVector as SchemaVector, __webpack_exports__compiledSchemaToJsonSchema as compiledSchemaToJsonSchema, __webpack_exports__createStandardJsonSchemaProps as createStandardJsonSchemaProps, __webpack_exports__extractTypeInfo as extractTypeInfo, __webpack_exports__getStorageDateReviver as getStorageDateReviver, __webpack_exports__hasPrimitiveElements as hasPrimitiveElements, __webpack_exports__isArrayValued as isArrayValued, __webpack_exports__propertyInfoToJsonSchema as propertyInfoToJsonSchema, __webpack_exports__rehydrateSchemaFromJsonSchema as rehydrateSchemaFromJsonSchema, __webpack_exports__rehydrateSchemaFromJsonString as rehydrateSchemaFromJsonString, __webpack_exports__s as s };
6935
6946
 
6936
6947
  //# sourceMappingURL=index.js.map