litedbmodel 2.0.0 → 2.0.2

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 (163) hide show
  1. package/dist/scp/authoring-sql.d.ts +78 -0
  2. package/dist/scp/authoring-sql.d.ts.map +1 -1
  3. package/dist/scp/authoring-sql.js +110 -2
  4. package/dist/scp/authoring-sql.js.map +1 -1
  5. package/dist/scp/catalog.d.ts +5 -2
  6. package/dist/scp/catalog.d.ts.map +1 -1
  7. package/dist/scp/catalog.js +32 -1
  8. package/dist/scp/catalog.js.map +1 -1
  9. package/dist/scp/codegen.d.ts +143 -85
  10. package/dist/scp/codegen.d.ts.map +1 -1
  11. package/dist/scp/codegen.js +374 -90
  12. package/dist/scp/codegen.js.map +1 -1
  13. package/dist/scp/coltype.d.ts +41 -0
  14. package/dist/scp/coltype.d.ts.map +1 -0
  15. package/dist/scp/coltype.js +188 -0
  16. package/dist/scp/coltype.js.map +1 -0
  17. package/dist/scp/dialect.d.ts +12 -3
  18. package/dist/scp/dialect.d.ts.map +1 -1
  19. package/dist/scp/dialect.js +12 -3
  20. package/dist/scp/dialect.js.map +1 -1
  21. package/dist/scp/find-filter-guard.d.ts +68 -0
  22. package/dist/scp/find-filter-guard.d.ts.map +1 -0
  23. package/dist/scp/find-filter-guard.js +88 -0
  24. package/dist/scp/find-filter-guard.js.map +1 -0
  25. package/dist/scp/fragment/assemble.d.ts +61 -0
  26. package/dist/scp/fragment/assemble.d.ts.map +1 -0
  27. package/dist/scp/fragment/assemble.js +156 -0
  28. package/dist/scp/fragment/assemble.js.map +1 -0
  29. package/dist/scp/fragment/compile-pg.d.ts +107 -0
  30. package/dist/scp/fragment/compile-pg.d.ts.map +1 -0
  31. package/dist/scp/fragment/compile-pg.js +142 -0
  32. package/dist/scp/fragment/compile-pg.js.map +1 -0
  33. package/dist/scp/fragment/index.d.ts +16 -0
  34. package/dist/scp/fragment/index.d.ts.map +1 -0
  35. package/dist/scp/fragment/index.js +34 -0
  36. package/dist/scp/fragment/index.js.map +1 -0
  37. package/dist/scp/fragment/model.d.ts +119 -0
  38. package/dist/scp/fragment/model.d.ts.map +1 -0
  39. package/dist/scp/fragment/model.js +66 -0
  40. package/dist/scp/fragment/model.js.map +1 -0
  41. package/dist/scp/fragment/pg-array-type.d.ts +13 -0
  42. package/dist/scp/fragment/pg-array-type.d.ts.map +1 -0
  43. package/dist/scp/fragment/pg-array-type.js +34 -0
  44. package/dist/scp/fragment/pg-array-type.js.map +1 -0
  45. package/dist/scp/guard.d.ts +2 -6
  46. package/dist/scp/guard.d.ts.map +1 -1
  47. package/dist/scp/guard.js +19 -22
  48. package/dist/scp/guard.js.map +1 -1
  49. package/dist/scp/index.cjs +18695 -3921
  50. package/dist/scp/index.d.ts +41 -24
  51. package/dist/scp/index.d.ts.map +1 -1
  52. package/dist/scp/index.js +134 -49
  53. package/dist/scp/index.js.map +1 -1
  54. package/dist/scp/index.mjs +4830 -1432
  55. package/dist/scp/makesql/authoring-compile.d.ts +90 -0
  56. package/dist/scp/makesql/authoring-compile.d.ts.map +1 -0
  57. package/dist/scp/makesql/authoring-compile.js +494 -0
  58. package/dist/scp/makesql/authoring-compile.js.map +1 -0
  59. package/dist/scp/makesql/compile-crud.d.ts +133 -0
  60. package/dist/scp/makesql/compile-crud.d.ts.map +1 -0
  61. package/dist/scp/makesql/compile-crud.js +288 -0
  62. package/dist/scp/makesql/compile-crud.js.map +1 -0
  63. package/dist/scp/makesql/compile-relation.d.ts +157 -0
  64. package/dist/scp/makesql/compile-relation.d.ts.map +1 -0
  65. package/dist/scp/makesql/compile-relation.js +425 -0
  66. package/dist/scp/makesql/compile-relation.js.map +1 -0
  67. package/dist/scp/makesql/compile-select.d.ts +52 -0
  68. package/dist/scp/makesql/compile-select.d.ts.map +1 -0
  69. package/dist/scp/makesql/compile-select.js +58 -0
  70. package/dist/scp/makesql/compile-select.js.map +1 -0
  71. package/dist/scp/makesql/compile.d.ts +63 -0
  72. package/dist/scp/makesql/compile.d.ts.map +1 -0
  73. package/dist/scp/makesql/compile.js +99 -0
  74. package/dist/scp/makesql/compile.js.map +1 -0
  75. package/dist/scp/makesql/handler.d.ts +58 -0
  76. package/dist/scp/makesql/handler.d.ts.map +1 -0
  77. package/dist/scp/makesql/handler.js +113 -0
  78. package/dist/scp/makesql/handler.js.map +1 -0
  79. package/dist/scp/makesql/index.d.ts +33 -0
  80. package/dist/scp/makesql/index.d.ts.map +1 -0
  81. package/dist/scp/makesql/index.js +114 -0
  82. package/dist/scp/makesql/index.js.map +1 -0
  83. package/dist/scp/makesql/ir.d.ts +42 -0
  84. package/dist/scp/makesql/ir.d.ts.map +1 -0
  85. package/dist/scp/makesql/ir.js +66 -0
  86. package/dist/scp/makesql/ir.js.map +1 -0
  87. package/dist/scp/makesql/json-array.d.ts +84 -0
  88. package/dist/scp/makesql/json-array.d.ts.map +1 -0
  89. package/dist/scp/makesql/json-array.js +118 -0
  90. package/dist/scp/makesql/json-array.js.map +1 -0
  91. package/dist/scp/makesql/json-batch.d.ts +102 -0
  92. package/dist/scp/makesql/json-batch.d.ts.map +1 -0
  93. package/dist/scp/makesql/json-batch.js +269 -0
  94. package/dist/scp/makesql/json-batch.js.map +1 -0
  95. package/dist/scp/makesql/makesql.d.ts +99 -0
  96. package/dist/scp/makesql/makesql.d.ts.map +1 -0
  97. package/dist/scp/makesql/makesql.js +122 -0
  98. package/dist/scp/makesql/makesql.js.map +1 -0
  99. package/dist/scp/makesql/outtype.d.ts +44 -0
  100. package/dist/scp/makesql/outtype.d.ts.map +1 -0
  101. package/dist/scp/makesql/outtype.js +197 -0
  102. package/dist/scp/makesql/outtype.js.map +1 -0
  103. package/dist/scp/makesql/pool-executor.d.ts +47 -0
  104. package/dist/scp/makesql/pool-executor.d.ts.map +1 -0
  105. package/dist/scp/makesql/pool-executor.js +50 -0
  106. package/dist/scp/makesql/pool-executor.js.map +1 -0
  107. package/dist/scp/makesql/static-bundle.d.ts +187 -0
  108. package/dist/scp/makesql/static-bundle.d.ts.map +1 -0
  109. package/dist/scp/makesql/static-bundle.js +1113 -0
  110. package/dist/scp/makesql/static-bundle.js.map +1 -0
  111. package/dist/scp/makesql/tx.d.ts +216 -0
  112. package/dist/scp/makesql/tx.d.ts.map +1 -0
  113. package/dist/scp/makesql/tx.js +788 -0
  114. package/dist/scp/makesql/tx.js.map +1 -0
  115. package/dist/scp/makesql/writeouttype.d.ts +66 -0
  116. package/dist/scp/makesql/writeouttype.d.ts.map +1 -0
  117. package/dist/scp/makesql/writeouttype.js +195 -0
  118. package/dist/scp/makesql/writeouttype.js.map +1 -0
  119. package/dist/scp/relation.d.ts +86 -74
  120. package/dist/scp/relation.d.ts.map +1 -1
  121. package/dist/scp/relation.js +186 -120
  122. package/dist/scp/relation.js.map +1 -1
  123. package/dist/scp/runtime.d.ts +158 -211
  124. package/dist/scp/runtime.d.ts.map +1 -1
  125. package/dist/scp/runtime.js +250 -515
  126. package/dist/scp/runtime.js.map +1 -1
  127. package/dist/scp/typed-object.d.ts +12 -1
  128. package/dist/scp/typed-object.d.ts.map +1 -1
  129. package/dist/scp/typed-object.js +25 -4
  130. package/dist/scp/typed-object.js.map +1 -1
  131. package/docs/proposal/litedbmodel-v2-scp-architecture.md +51 -0
  132. package/docs/proposal/v0-coverage-matrix.md +157 -0
  133. package/docs/proposal/v2-completeness-plan.md +90 -0
  134. package/docs/proposal/v2-sql-parity-checklist.md +162 -0
  135. package/package.json +3 -3
  136. package/dist/scp/bridge.d.ts +0 -64
  137. package/dist/scp/bridge.d.ts.map +0 -1
  138. package/dist/scp/bridge.js +0 -329
  139. package/dist/scp/bridge.js.map +0 -1
  140. package/dist/scp/compile-dialect.d.ts +0 -39
  141. package/dist/scp/compile-dialect.d.ts.map +0 -1
  142. package/dist/scp/compile-dialect.js +0 -62
  143. package/dist/scp/compile-dialect.js.map +0 -1
  144. package/dist/scp/compile-sqlite.d.ts +0 -114
  145. package/dist/scp/compile-sqlite.d.ts.map +0 -1
  146. package/dist/scp/compile-sqlite.js +0 -149
  147. package/dist/scp/compile-sqlite.js.map +0 -1
  148. package/dist/scp/ir.d.ts +0 -92
  149. package/dist/scp/ir.d.ts.map +0 -1
  150. package/dist/scp/ir.js +0 -28
  151. package/dist/scp/ir.js.map +0 -1
  152. package/dist/scp/render.d.ts +0 -40
  153. package/dist/scp/render.d.ts.map +0 -1
  154. package/dist/scp/render.js +0 -170
  155. package/dist/scp/render.js.map +0 -1
  156. package/dist/scp/write-plan.d.ts +0 -161
  157. package/dist/scp/write-plan.d.ts.map +0 -1
  158. package/dist/scp/write-plan.js +0 -528
  159. package/dist/scp/write-plan.js.map +0 -1
  160. package/dist/scp/write-runtime.d.ts +0 -80
  161. package/dist/scp/write-runtime.d.ts.map +0 -1
  162. package/dist/scp/write-runtime.js +0 -167
  163. package/dist/scp/write-runtime.js.map +0 -1
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ /**
3
+ * litedbmodel v2 SCP — the MINIMAL fragment model (epic #43 reset).
4
+ *
5
+ * ## The locked vocabulary (owner-specified — nothing else exists here)
6
+ *
7
+ * The portable artifact is ONLY a combination of **fragments**. There is NO
8
+ * abstract "Expression IR", NO relation-op / operator kinds for SQL structure,
9
+ * NO `FragmentTree` connector algebra, NO `{where}` splice marker. SQL structure
10
+ * (`= ANY`, `CROSS JOIN LATERAL`, `UNNEST`, subquery, cast, batch shapes) lives
11
+ * ENTIRELY as TEXT inside `sql`.
12
+ *
13
+ * fragment = { sql: string, params: Param[], skip?: PresenceCondition }
14
+ *
15
+ * - A query is an ordered list of fragments.
16
+ * - Assembling = concatenate the `sql` of every PRESENT fragment, and concatenate
17
+ * their `params` in order. If a fragment's `skip` is satisfied, BOTH its `sql`
18
+ * and its `params` are omitted.
19
+ *
20
+ * Param = EITHER
21
+ * (a) a **value-spec** — how to compute the bound value from input at runtime:
22
+ * an input-ref / wire-ref / a small closed value-expression
23
+ * (e.g. `coalesce(input.limit, 20)`). This computes the VALUE only.
24
+ * OR
25
+ * (b) a **nested fragment** — a raw SQL sub-piece with its own params. This is
26
+ * how subqueries / sub-expressions are represented: NOT as IR constructs,
27
+ * just a nested { sql, params }.
28
+ *
29
+ * Array-parameter placeholder expansion is DRIVER-side, not modeled here. On
30
+ * PostgreSQL an array param binds directly (`= ANY(?::int[])`), so the text is
31
+ * static and the array is ONE param. On MySQL/SQLite (no array binding) the DRIVER
32
+ * expands an array param into `(?, ?, …)` at bind time. The bundle stays
33
+ * "string + params" regardless.
34
+ *
35
+ * The whole model is plain JSON / serializable so a thin runtime in any language
36
+ * reads it identically.
37
+ */
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.isFragment = isFragment;
40
+ exports.isWhereGroup = isWhereGroup;
41
+ exports.isInputRef = isInputRef;
42
+ exports.isWireRef = isWireRef;
43
+ exports.isLiteral = isLiteral;
44
+ exports.isValueExpr = isValueExpr;
45
+ // ============================================================================
46
+ // Type guards (structural — a nested-fragment param has `sql`; value-specs don't)
47
+ // ============================================================================
48
+ function isFragment(p) {
49
+ return typeof p.sql === 'string';
50
+ }
51
+ function isWhereGroup(n) {
52
+ return Array.isArray(n.where);
53
+ }
54
+ function isInputRef(v) {
55
+ return Array.isArray(v.input);
56
+ }
57
+ function isWireRef(v) {
58
+ return Array.isArray(v.wire);
59
+ }
60
+ function isLiteral(v) {
61
+ return 'literal' in v;
62
+ }
63
+ function isValueExpr(v) {
64
+ return typeof v.op === 'string' && Array.isArray(v.args);
65
+ }
66
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/scp/fragment/model.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;;AAyGH,gCAEC;AAED,oCAEC;AAED,gCAEC;AACD,8BAEC;AACD,8BAEC;AACD,kCAEC;AAvBD,+EAA+E;AAC/E,kFAAkF;AAClF,+EAA+E;AAE/E,SAAgB,UAAU,CAAC,CAAe;IACxC,OAAO,OAAQ,CAAc,CAAC,GAAG,KAAK,QAAQ,CAAC;AACjD,CAAC;AAED,SAAgB,YAAY,CAAC,CAAO;IAClC,OAAO,KAAK,CAAC,OAAO,CAAE,CAAgB,CAAC,KAAK,CAAC,CAAC;AAChD,CAAC;AAED,SAAgB,UAAU,CAAC,CAAY;IACrC,OAAO,KAAK,CAAC,OAAO,CAAE,CAAc,CAAC,KAAK,CAAC,CAAC;AAC9C,CAAC;AACD,SAAgB,SAAS,CAAC,CAAY;IACpC,OAAO,KAAK,CAAC,OAAO,CAAE,CAAa,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC;AACD,SAAgB,SAAS,CAAC,CAAY;IACpC,OAAO,SAAS,IAAK,CAAkB,CAAC;AAC1C,CAAC;AACD,SAAgB,WAAW,CAAC,CAAY;IACtC,OAAO,OAAQ,CAAe,CAAC,EAAE,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAE,CAAe,CAAC,IAAI,CAAC,CAAC;AACzF,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * PostgreSQL array-type inference for compile-time cast text.
3
+ *
4
+ * VERBATIM reuse of the ORIGINAL `LazyRelation.inferPgArrayType` logic so the
5
+ * `?::<type>[]` cast text a fragment carries is byte-identical to the tuned
6
+ * builder. sqlCast (from the target column's metadata) wins; otherwise the element
7
+ * type is inferred from the compile-time sample values.
8
+ *
9
+ * (This is TEXT chosen at build time; it is NOT an IR "kind". The array itself is
10
+ * bound as ONE param on PostgreSQL.)
11
+ */
12
+ export declare function inferPgArrayTypeForCompile(values: unknown[], sqlCast?: string): string;
13
+ //# sourceMappingURL=pg-array-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg-array-type.d.ts","sourceRoot":"","sources":["../../../src/scp/fragment/pg-array-type.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAYtF"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.inferPgArrayTypeForCompile = inferPgArrayTypeForCompile;
4
+ /**
5
+ * PostgreSQL array-type inference for compile-time cast text.
6
+ *
7
+ * VERBATIM reuse of the ORIGINAL `LazyRelation.inferPgArrayType` logic so the
8
+ * `?::<type>[]` cast text a fragment carries is byte-identical to the tuned
9
+ * builder. sqlCast (from the target column's metadata) wins; otherwise the element
10
+ * type is inferred from the compile-time sample values.
11
+ *
12
+ * (This is TEXT chosen at build time; it is NOT an IR "kind". The array itself is
13
+ * bound as ONE param on PostgreSQL.)
14
+ */
15
+ function inferPgArrayTypeForCompile(values, sqlCast) {
16
+ if (sqlCast)
17
+ return `${sqlCast}[]`;
18
+ if (values.length === 0)
19
+ return 'text[]';
20
+ const sample = values[0];
21
+ if (typeof sample === 'number') {
22
+ if (values.every((v) => Number.isInteger(v)))
23
+ return 'int[]';
24
+ return 'numeric[]';
25
+ }
26
+ if (typeof sample === 'bigint')
27
+ return 'bigint[]';
28
+ if (typeof sample === 'boolean')
29
+ return 'boolean[]';
30
+ if (sample instanceof Date)
31
+ return 'timestamp[]';
32
+ return 'text[]';
33
+ }
34
+ //# sourceMappingURL=pg-array-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg-array-type.js","sourceRoot":"","sources":["../../../src/scp/fragment/pg-array-type.ts"],"names":[],"mappings":";;AAWA,gEAYC;AAvBD;;;;;;;;;;GAUG;AACH,SAAgB,0BAA0B,CAAC,MAAiB,EAAE,OAAgB;IAC5E,IAAI,OAAO;QAAE,OAAO,GAAG,OAAO,IAAI,CAAC;IACnC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,OAAO,CAAC;QAC7D,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAC;IAClD,IAAI,OAAO,MAAM,KAAK,SAAS;QAAE,OAAO,WAAW,CAAC;IACpD,IAAI,MAAM,YAAY,IAAI;QAAE,OAAO,aAAa,CAAC;IACjD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -9,7 +9,8 @@
9
9
  * plus the operator-set check.
10
10
  */
11
11
  import { type Component, type ComponentGraphIR } from 'behavior-contracts';
12
- import type { CompiledOperation, ExprNode } from './ir';
12
+ /** A bc Expression IR node (closed operator set). Structural alias — a JSON expression tree. */
13
+ export type ExprNode = unknown;
13
14
  /**
14
15
  * Assert one Expression IR node is portable: no residue (functions/Date/…) and every
15
16
  * operator-node key is in bc's closed set. Literals (number/string/bool/null) and arrays
@@ -23,11 +24,6 @@ import type { CompiledOperation, ExprNode } from './ir';
23
24
  * semantics exactly — see {@link walkExpr} for the `obj` field-map special case.
24
25
  */
25
26
  export declare function assertExprPortable(node: ExprNode, path?: string): void;
26
- /**
27
- * Assert a whole compiled operation emits only portable Expression IR (static params +
28
- * fragment tree). Throws {@link PortabilityError} on the first non-portable construct.
29
- */
30
- export declare function assertOperationPortable(op: CompiledOperation): void;
31
27
  /**
32
28
  * Assert every Expression IR node in ONE lowered component's port wiring is portable
33
29
  * (WS2 AC). Walks every `componentRef`/`map` node's `ports` (and `map.over` / `map.when`)
@@ -1 +1 @@
1
- {"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/scp/guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAmF,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC5J,OAAO,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAA0B,MAAM,MAAM,CAAC;AAEhF;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,SAAM,GAAG,IAAI,CAGnE;AAwDD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,iBAAiB,GAAG,IAAI,CAGnE;AAID;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAgBlE;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,gBAAgB,GAAG,IAAI,CAEvE"}
1
+ {"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/scp/guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAmF,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE5J,gGAAgG;AAChG,MAAM,MAAM,QAAQ,GAAG,OAAO,CAAC;AAE/B;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,SAAM,GAAG,IAAI,CAGnE;AAgDD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAgBlE;AAoBD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,gBAAgB,GAAG,IAAI,CAEvE"}
package/dist/scp/guard.js CHANGED
@@ -11,7 +11,6 @@
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.assertExprPortable = assertExprPortable;
14
- exports.assertOperationPortable = assertOperationPortable;
15
14
  exports.assertComponentPortable = assertComponentPortable;
16
15
  exports.assertComponentGraphPortable = assertComponentGraphPortable;
17
16
  const behavior_contracts_1 = require("behavior-contracts");
@@ -76,25 +75,6 @@ function walkExpr(node, path) {
76
75
  for (const k of keys)
77
76
  walkExpr(node[k], `${path}.${k}`);
78
77
  }
79
- /** Assert a fragment (and its slots + `when`) emits only portable Expression IR. */
80
- function assertFragmentPortable(node, path) {
81
- if ('connector' in node) {
82
- node.fragments.forEach((f, i) => assertFragmentPortable(f, `${path}.fragments[${i}]`));
83
- return;
84
- }
85
- if (node.when !== undefined)
86
- assertExprPortable(node.when, `${path}.when`);
87
- node.params.forEach((p, i) => assertExprPortable(p, `${path}.params[${i}]`));
88
- }
89
- /**
90
- * Assert a whole compiled operation emits only portable Expression IR (static params +
91
- * fragment tree). Throws {@link PortabilityError} on the first non-portable construct.
92
- */
93
- function assertOperationPortable(op) {
94
- op.params.forEach((p, i) => assertExprPortable(p, `$.params[${i}]`));
95
- if (op.where !== null)
96
- assertFragmentPortable(op.where, '$.where');
97
- }
98
78
  // ── Authoring→IR lower guard (WS2, #22 — auto-applied on the single compile path) ─────
99
79
  /**
100
80
  * Assert every Expression IR node in ONE lowered component's port wiring is portable
@@ -109,7 +89,7 @@ function assertComponentPortable(component) {
109
89
  for (const n of component.body) {
110
90
  if ('map' in n) {
111
91
  assertExprPortable(n.map.over, `${at}/${n.id}.map.over`);
112
- assertExprPortable(n.map.ports, `${at}/${n.id}.map.ports`);
92
+ assertPortsPortable(n.map.ports, `${at}/${n.id}.map.ports`);
113
93
  if (n.map.when !== undefined)
114
94
  assertExprPortable(n.map.when, `${at}/${n.id}.map.when`);
115
95
  }
@@ -119,11 +99,28 @@ function assertComponentPortable(component) {
119
99
  assertExprPortable(n.cond.else, `${at}/${n.id}.cond.else`);
120
100
  }
121
101
  else {
122
- assertExprPortable(n.ports, `${at}/${n.id}.ports`);
102
+ assertPortsPortable(n.ports, `${at}/${n.id}.ports`);
123
103
  }
124
104
  }
125
105
  assertExprPortable(component.output, `${at}.output`);
126
106
  }
107
+ /**
108
+ * A component node's `ports` (and a `map.ports`) is a FIELD MAP — port NAME → ExprNode — not an
109
+ * Expression node itself. Walk each port VALUE as an expression, never the ports object as a whole:
110
+ * a SINGLE-port node (`{ table: 'posts' }`, e.g. a `Count` with only `table`) would otherwise be
111
+ * misread by {@link walkExpr}'s single-key = OPERATOR heuristic as an unknown-opcode `{table:…}`
112
+ * node. Recursing the values sidesteps that (same rationale bc's guard applies to `{obj:{…}}`).
113
+ */
114
+ function assertPortsPortable(ports, path) {
115
+ if (ports === null || typeof ports !== 'object' || Array.isArray(ports)) {
116
+ // Not a ports map (shouldn't happen for a well-formed node) — defer to the expr walker.
117
+ assertExprPortable(ports, path);
118
+ return;
119
+ }
120
+ for (const [name, value] of Object.entries(ports)) {
121
+ assertExprPortable(value, `${path}.${name}`);
122
+ }
123
+ }
127
124
  /**
128
125
  * Assert every component of a lowered Component-graph IR is portable (WS2 AC). The
129
126
  * authoring lower path ({@link publishBehaviors} / {@link compileEager}) invokes this
@@ -1 +1 @@
1
- {"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/scp/guard.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/scp/guard.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AAmBH,gDAGC;AAwDD,0DAgBC;AA0BD,oEAEC;AAxHD,2DAA4J;AAK5J;;;;;;;;;;;GAWG;AACH,SAAgB,kBAAkB,CAAC,IAAc,EAAE,IAAI,GAAG,GAAG;IAC3D,IAAA,mCAAc,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACvB,CAAC;AAED,SAAS,QAAQ,CAAC,IAAa,EAAE,IAAY;IAC3C,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO;IACtD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,6EAA6E;QAC7E,mEAAmE;QACnE,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,CAAC,4CAAuB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,qCAAgB,CAAC,IAAI,EAAE,uBAAuB,EAAE,2DAA2D,CAAC,GAAG,4CAAuB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnK,CAAC;QACD,MAAM,GAAG,GAAI,IAAgC,CAAC,EAAE,CAAC,CAAC;QAClD,mFAAmF;QACnF,qFAAqF;QACrF,+EAA+E;QAC/E,uFAAuF;QACvF,0EAA0E;QAC1E,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;YACjB,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClE,MAAM,IAAI,qCAAgB,CAAC,GAAG,IAAI,MAAM,EAAE,uDAAuD,IAAI,OAAO,CAAC,CAAC;YAChH,CAAC;YACD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAA8B,CAAC,EAAE,CAAC;gBACpE,oFAAoF;gBACpF,gFAAgF;gBAChF,IAAI,CAAC,KAAK,yCAAoB,EAAE,CAAC;oBAC/B,MAAM,IAAI,qCAAgB,CAAC,GAAG,IAAI,MAAM,EAAE,kCAAkC,yCAAoB,mCAAmC,IAAI,MAAM,CAAC,CAAC;gBACjJ,CAAC;gBACD,QAAQ,CAAC,CAAC,EAAE,GAAG,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAC;YAClC,CAAC;YACD,OAAO;QACT,CAAC;QACD,6EAA6E;QAC7E,QAAQ,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAC/B,OAAO;IACT,CAAC;IACD,yFAAyF;IACzF,0FAA0F;IAC1F,gFAAgF;IAChF,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,QAAQ,CAAE,IAAgC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;AACvF,CAAC;AAED,yFAAyF;AAEzF;;;;;;;GAOG;AACH,SAAgB,uBAAuB,CAAC,SAAoB;IAC1D,MAAM,EAAE,GAAG,cAAc,SAAS,CAAC,IAAI,GAAG,CAAC;IAC3C,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACf,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;YACzD,mBAAmB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;YAC5D,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS;gBAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;QACzF,CAAC;aAAM,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;YACvB,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;YACvD,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;YAC3D,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;QAC7D,CAAC;aAAM,CAAC;YACN,mBAAmB,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IACD,kBAAkB,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;GAMG;AACH,SAAS,mBAAmB,CAAC,KAAc,EAAE,IAAY;IACvD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,wFAAwF;QACxF,kBAAkB,CAAC,KAAiB,EAAE,IAAI,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;QAC7E,kBAAkB,CAAC,KAAiB,EAAE,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAgB,4BAA4B,CAAC,EAAoB;IAC/D,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,UAAU;QAAE,uBAAuB,CAAC,CAAC,CAAC,CAAC;AAC5D,CAAC"}