typesea 0.1.0 → 0.2.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 (285) hide show
  1. package/CHANGELOG.md +67 -6
  2. package/README.md +98 -17
  3. package/dist/adapters/index.d.ts +50 -8
  4. package/dist/adapters/index.d.ts.map +1 -1
  5. package/dist/adapters/index.js +169 -48
  6. package/dist/aot/index.d.ts +18 -2
  7. package/dist/aot/index.d.ts.map +1 -1
  8. package/dist/aot/index.js +93 -14
  9. package/dist/async/index.d.ts +28 -56
  10. package/dist/async/index.d.ts.map +1 -1
  11. package/dist/async/index.js +94 -37
  12. package/dist/builders/composite.d.ts +37 -6
  13. package/dist/builders/composite.d.ts.map +1 -1
  14. package/dist/builders/composite.js +84 -10
  15. package/dist/builders/index.d.ts +2 -0
  16. package/dist/builders/index.d.ts.map +1 -1
  17. package/dist/builders/index.js +2 -0
  18. package/dist/builders/modifier.d.ts +30 -5
  19. package/dist/builders/modifier.d.ts.map +1 -1
  20. package/dist/builders/modifier.js +38 -5
  21. package/dist/builders/object/guard.d.ts +18 -22
  22. package/dist/builders/object/guard.d.ts.map +1 -1
  23. package/dist/builders/object/guard.js +26 -26
  24. package/dist/builders/object/index.d.ts +2 -0
  25. package/dist/builders/object/index.d.ts.map +1 -1
  26. package/dist/builders/object/index.js +2 -0
  27. package/dist/builders/object/schema.d.ts +55 -9
  28. package/dist/builders/object/schema.d.ts.map +1 -1
  29. package/dist/builders/object/schema.js +92 -15
  30. package/dist/builders/object/types.d.ts +5 -31
  31. package/dist/builders/object/types.d.ts.map +1 -1
  32. package/dist/builders/object/types.js +2 -0
  33. package/dist/builders/scalar.d.ts +29 -8
  34. package/dist/builders/scalar.d.ts.map +1 -1
  35. package/dist/builders/scalar.js +33 -8
  36. package/dist/builders/table.d.ts +4 -0
  37. package/dist/builders/table.d.ts.map +1 -1
  38. package/dist/builders/table.js +4 -0
  39. package/dist/builders/types.d.ts +14 -4
  40. package/dist/builders/types.d.ts.map +1 -1
  41. package/dist/builders/types.js +2 -0
  42. package/dist/compile/check-composite.d.ts +22 -1
  43. package/dist/compile/check-composite.d.ts.map +1 -1
  44. package/dist/compile/check-composite.js +564 -24
  45. package/dist/compile/check-scalar.d.ts +78 -0
  46. package/dist/compile/check-scalar.d.ts.map +1 -1
  47. package/dist/compile/check-scalar.js +432 -1
  48. package/dist/compile/check.d.ts +12 -0
  49. package/dist/compile/check.d.ts.map +1 -1
  50. package/dist/compile/check.js +37 -0
  51. package/dist/compile/context.d.ts +47 -9
  52. package/dist/compile/context.d.ts.map +1 -1
  53. package/dist/compile/context.js +51 -8
  54. package/dist/compile/graph-predicate.d.ts +4 -2
  55. package/dist/compile/graph-predicate.d.ts.map +1 -1
  56. package/dist/compile/graph-predicate.js +1907 -171
  57. package/dist/compile/guard.d.ts +15 -24
  58. package/dist/compile/guard.d.ts.map +1 -1
  59. package/dist/compile/guard.js +158 -74
  60. package/dist/compile/index.d.ts +3 -1
  61. package/dist/compile/index.d.ts.map +1 -1
  62. package/dist/compile/index.js +2 -0
  63. package/dist/compile/issue.d.ts +110 -0
  64. package/dist/compile/issue.d.ts.map +1 -1
  65. package/dist/compile/issue.js +184 -1
  66. package/dist/compile/names.d.ts +12 -2
  67. package/dist/compile/names.d.ts.map +1 -1
  68. package/dist/compile/names.js +19 -3
  69. package/dist/compile/predicate.d.ts +24 -0
  70. package/dist/compile/predicate.d.ts.map +1 -1
  71. package/dist/compile/predicate.js +131 -5
  72. package/dist/compile/runtime.d.ts +80 -12
  73. package/dist/compile/runtime.d.ts.map +1 -1
  74. package/dist/compile/runtime.js +25 -6
  75. package/dist/compile/source.d.ts +10 -2
  76. package/dist/compile/source.d.ts.map +1 -1
  77. package/dist/compile/source.js +361 -26
  78. package/dist/compile/types.d.ts +20 -0
  79. package/dist/compile/types.d.ts.map +1 -1
  80. package/dist/compile/types.js +2 -0
  81. package/dist/decoder/index.d.ts +32 -46
  82. package/dist/decoder/index.d.ts.map +1 -1
  83. package/dist/decoder/index.js +102 -38
  84. package/dist/evaluate/check-composite.d.ts +59 -0
  85. package/dist/evaluate/check-composite.d.ts.map +1 -1
  86. package/dist/evaluate/check-composite.js +151 -3
  87. package/dist/evaluate/check-scalar.d.ts +16 -0
  88. package/dist/evaluate/check-scalar.d.ts.map +1 -1
  89. package/dist/evaluate/check-scalar.js +32 -0
  90. package/dist/evaluate/check.d.ts +7 -0
  91. package/dist/evaluate/check.d.ts.map +1 -1
  92. package/dist/evaluate/check.js +43 -0
  93. package/dist/evaluate/index.d.ts +2 -0
  94. package/dist/evaluate/index.d.ts.map +1 -1
  95. package/dist/evaluate/index.js +2 -0
  96. package/dist/evaluate/issue.d.ts +11 -1
  97. package/dist/evaluate/issue.d.ts.map +1 -1
  98. package/dist/evaluate/issue.js +15 -1
  99. package/dist/evaluate/predicate.d.ts +16 -5
  100. package/dist/evaluate/predicate.d.ts.map +1 -1
  101. package/dist/evaluate/predicate.js +20 -5
  102. package/dist/evaluate/shared.d.ts +59 -13
  103. package/dist/evaluate/shared.d.ts.map +1 -1
  104. package/dist/evaluate/shared.js +66 -8
  105. package/dist/evaluate/state.d.ts +35 -13
  106. package/dist/evaluate/state.d.ts.map +1 -1
  107. package/dist/evaluate/state.js +35 -2
  108. package/dist/guard/base.d.ts +79 -29
  109. package/dist/guard/base.d.ts.map +1 -1
  110. package/dist/guard/base.js +91 -29
  111. package/dist/guard/error.d.ts +10 -5
  112. package/dist/guard/error.d.ts.map +1 -1
  113. package/dist/guard/error.js +10 -5
  114. package/dist/guard/index.d.ts +2 -0
  115. package/dist/guard/index.d.ts.map +1 -1
  116. package/dist/guard/index.js +2 -0
  117. package/dist/guard/number.d.ts +26 -11
  118. package/dist/guard/number.d.ts.map +1 -1
  119. package/dist/guard/number.js +30 -11
  120. package/dist/guard/props.d.ts +27 -3
  121. package/dist/guard/props.d.ts.map +1 -1
  122. package/dist/guard/props.js +27 -3
  123. package/dist/guard/read.d.ts +62 -9
  124. package/dist/guard/read.d.ts.map +1 -1
  125. package/dist/guard/read.js +83 -10
  126. package/dist/guard/registry.d.ts +12 -2
  127. package/dist/guard/registry.d.ts.map +1 -1
  128. package/dist/guard/registry.js +15 -3
  129. package/dist/guard/string.d.ts +33 -13
  130. package/dist/guard/string.d.ts.map +1 -1
  131. package/dist/guard/string.js +37 -13
  132. package/dist/guard/types.d.ts +92 -40
  133. package/dist/guard/types.d.ts.map +1 -1
  134. package/dist/guard/types.js +2 -0
  135. package/dist/index.d.ts +1 -1
  136. package/dist/index.d.ts.map +1 -1
  137. package/dist/internal/index.d.ts +42 -6
  138. package/dist/internal/index.d.ts.map +1 -1
  139. package/dist/internal/index.js +51 -8
  140. package/dist/ir/builder.d.ts +16 -126
  141. package/dist/ir/builder.d.ts.map +1 -1
  142. package/dist/ir/builder.js +77 -137
  143. package/dist/ir/freeze.d.ts +4 -0
  144. package/dist/ir/freeze.d.ts.map +1 -1
  145. package/dist/ir/freeze.js +59 -0
  146. package/dist/ir/index.d.ts +3 -1
  147. package/dist/ir/index.d.ts.map +1 -1
  148. package/dist/ir/index.js +2 -0
  149. package/dist/ir/regexp.d.ts +2 -0
  150. package/dist/ir/regexp.d.ts.map +1 -1
  151. package/dist/ir/regexp.js +2 -0
  152. package/dist/ir/types.d.ts +90 -55
  153. package/dist/ir/types.d.ts.map +1 -1
  154. package/dist/ir/types.js +2 -0
  155. package/dist/ir/validate.d.ts +8 -1
  156. package/dist/ir/validate.d.ts.map +1 -1
  157. package/dist/ir/validate.js +477 -61
  158. package/dist/issue/index.d.ts +41 -9
  159. package/dist/issue/index.d.ts.map +1 -1
  160. package/dist/issue/index.js +61 -11
  161. package/dist/json-schema/emit-combinator.d.ts +44 -4
  162. package/dist/json-schema/emit-combinator.d.ts.map +1 -1
  163. package/dist/json-schema/emit-combinator.js +44 -4
  164. package/dist/json-schema/emit-composite.d.ts +10 -0
  165. package/dist/json-schema/emit-composite.d.ts.map +1 -1
  166. package/dist/json-schema/emit-composite.js +15 -1
  167. package/dist/json-schema/emit-scalar.d.ts +26 -3
  168. package/dist/json-schema/emit-scalar.d.ts.map +1 -1
  169. package/dist/json-schema/emit-scalar.js +70 -9
  170. package/dist/json-schema/emit-types.d.ts +11 -1
  171. package/dist/json-schema/emit-types.d.ts.map +1 -1
  172. package/dist/json-schema/emit-types.js +2 -0
  173. package/dist/json-schema/emit.d.ts +12 -1
  174. package/dist/json-schema/emit.d.ts.map +1 -1
  175. package/dist/json-schema/emit.js +12 -1
  176. package/dist/json-schema/freeze.d.ts +13 -2
  177. package/dist/json-schema/freeze.d.ts.map +1 -1
  178. package/dist/json-schema/freeze.js +41 -8
  179. package/dist/json-schema/index.d.ts +16 -2
  180. package/dist/json-schema/index.d.ts.map +1 -1
  181. package/dist/json-schema/index.js +23 -3
  182. package/dist/json-schema/issue.d.ts +4 -1
  183. package/dist/json-schema/issue.d.ts.map +1 -1
  184. package/dist/json-schema/issue.js +4 -1
  185. package/dist/json-schema/read.d.ts +24 -3
  186. package/dist/json-schema/read.d.ts.map +1 -1
  187. package/dist/json-schema/read.js +59 -12
  188. package/dist/json-schema/types.d.ts +38 -15
  189. package/dist/json-schema/types.d.ts.map +1 -1
  190. package/dist/json-schema/types.js +2 -0
  191. package/dist/kind/index.d.ts +15 -28
  192. package/dist/kind/index.d.ts.map +1 -1
  193. package/dist/kind/index.js +15 -10
  194. package/dist/lower/index.d.ts +6 -1
  195. package/dist/lower/index.d.ts.map +1 -1
  196. package/dist/lower/index.js +411 -44
  197. package/dist/message/index.d.ts +46 -10
  198. package/dist/message/index.d.ts.map +1 -1
  199. package/dist/message/index.js +88 -17
  200. package/dist/optimize/algebraic.d.ts +54 -0
  201. package/dist/optimize/algebraic.d.ts.map +1 -0
  202. package/dist/optimize/algebraic.js +314 -0
  203. package/dist/optimize/compact.d.ts +8 -1
  204. package/dist/optimize/compact.d.ts.map +1 -1
  205. package/dist/optimize/compact.js +13 -2
  206. package/dist/optimize/domain.d.ts +16 -0
  207. package/dist/optimize/domain.d.ts.map +1 -0
  208. package/dist/optimize/domain.js +615 -0
  209. package/dist/optimize/fold-boolean.d.ts +17 -2
  210. package/dist/optimize/fold-boolean.d.ts.map +1 -1
  211. package/dist/optimize/fold-boolean.js +59 -14
  212. package/dist/optimize/fold-common.d.ts +43 -8
  213. package/dist/optimize/fold-common.d.ts.map +1 -1
  214. package/dist/optimize/fold-common.js +37 -6
  215. package/dist/optimize/fold-constraints.d.ts +33 -0
  216. package/dist/optimize/fold-constraints.d.ts.map +1 -0
  217. package/dist/optimize/fold-constraints.js +484 -0
  218. package/dist/optimize/fold-scalar.d.ts +98 -13
  219. package/dist/optimize/fold-scalar.d.ts.map +1 -1
  220. package/dist/optimize/fold-scalar.js +98 -13
  221. package/dist/optimize/fold.d.ts +8 -1
  222. package/dist/optimize/fold.d.ts.map +1 -1
  223. package/dist/optimize/fold.js +22 -2
  224. package/dist/optimize/index.d.ts +9 -1
  225. package/dist/optimize/index.d.ts.map +1 -1
  226. package/dist/optimize/index.js +18 -3
  227. package/dist/optimize/map-node.d.ts +3 -1
  228. package/dist/optimize/map-node.d.ts.map +1 -1
  229. package/dist/optimize/map-node.js +45 -3
  230. package/dist/optimize/peephole.d.ts +16 -0
  231. package/dist/optimize/peephole.d.ts.map +1 -0
  232. package/dist/optimize/peephole.js +254 -0
  233. package/dist/optimize/remap.d.ts +2 -0
  234. package/dist/optimize/remap.d.ts.map +1 -1
  235. package/dist/optimize/remap.js +2 -0
  236. package/dist/optimize/rewrite.d.ts +13 -8
  237. package/dist/optimize/rewrite.d.ts.map +1 -1
  238. package/dist/optimize/rewrite.js +13 -8
  239. package/dist/plan/cache.d.ts +9 -3
  240. package/dist/plan/cache.d.ts.map +1 -1
  241. package/dist/plan/cache.js +21 -5
  242. package/dist/plan/index.d.ts +2 -0
  243. package/dist/plan/index.d.ts.map +1 -1
  244. package/dist/plan/index.js +2 -0
  245. package/dist/plan/predicate.d.ts +2 -0
  246. package/dist/plan/predicate.d.ts.map +1 -1
  247. package/dist/plan/predicate.js +268 -29
  248. package/dist/plan/schema-predicate.d.ts +6 -0
  249. package/dist/plan/schema-predicate.d.ts.map +1 -1
  250. package/dist/plan/schema-predicate.js +117 -13
  251. package/dist/plan/types.d.ts +2 -0
  252. package/dist/plan/types.d.ts.map +1 -1
  253. package/dist/plan/types.js +2 -0
  254. package/dist/result/index.d.ts +19 -5
  255. package/dist/result/index.d.ts.map +1 -1
  256. package/dist/result/index.js +10 -2
  257. package/dist/schema/common.d.ts +69 -6
  258. package/dist/schema/common.d.ts.map +1 -1
  259. package/dist/schema/common.js +104 -10
  260. package/dist/schema/freeze.d.ts +4 -0
  261. package/dist/schema/freeze.d.ts.map +1 -1
  262. package/dist/schema/freeze.js +18 -0
  263. package/dist/schema/index.d.ts +3 -0
  264. package/dist/schema/index.d.ts.map +1 -1
  265. package/dist/schema/index.js +3 -0
  266. package/dist/schema/lazy.d.ts +4 -0
  267. package/dist/schema/lazy.d.ts.map +1 -1
  268. package/dist/schema/lazy.js +4 -0
  269. package/dist/schema/literal.d.ts +7 -1
  270. package/dist/schema/literal.d.ts.map +1 -1
  271. package/dist/schema/literal.js +7 -1
  272. package/dist/schema/types.d.ts +20 -96
  273. package/dist/schema/types.d.ts.map +1 -1
  274. package/dist/schema/types.js +5 -1
  275. package/dist/schema/undefined.d.ts +17 -0
  276. package/dist/schema/undefined.d.ts.map +1 -0
  277. package/dist/schema/undefined.js +72 -0
  278. package/dist/schema/validate.d.ts +8 -1
  279. package/dist/schema/validate.d.ts.map +1 -1
  280. package/dist/schema/validate.js +146 -55
  281. package/docs/api.md +57 -0
  282. package/docs/assets/benchmark-headline.svg +163 -0
  283. package/docs/engine-notes.md +58 -15
  284. package/docs/index.html +130 -110
  285. package/package.json +65 -65
@@ -1,24 +1,102 @@
1
1
  /**
2
2
  * @file compile/check-scalar.ts
3
3
  * @brief Scalar diagnostic validator snippets.
4
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
5
+ * stable across runtime and AOT emission.
4
6
  */
5
7
  import { SchemaTag } from "../kind/index.js";
6
8
  import { type LiteralValue, type Schema } from "../schema/index.js";
7
9
  import type { EmitContext } from "./types.js";
8
10
  /**
9
11
  * @brief emit string check.
12
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
13
+ * stable across runtime and AOT emission.
14
+ * @param schema String schema with scalar checks.
15
+ * @param value Generated expression for the candidate value.
16
+ * @param path Generated expression for the current diagnostic path.
17
+ * @param issues Generated expression for the issue buffer.
18
+ * @param context Shared code-generation context.
19
+ * @returns JavaScript source for root string diagnostics.
10
20
  */
11
21
  export declare function emitStringCheck(schema: Extract<Schema, {
12
22
  readonly tag: typeof SchemaTag.String;
13
23
  }>, value: string, path: string, issues: string, context: EmitContext): string;
24
+ /**
25
+ * @brief emit leaf check at one appended path segment.
26
+ * @details This path is used by object-field diagnostics to avoid building a
27
+ * mutable path frame and calling a child collector for scalar schemas.
28
+ * @param schema Candidate leaf schema.
29
+ * @param value Generated expression for the candidate value.
30
+ * @param path Generated expression for the current diagnostic path.
31
+ * @param segmentExpression Generated expression for the appended path segment.
32
+ * @param issues Generated expression for the issue buffer.
33
+ * @param context Shared code-generation context.
34
+ * @returns Inline diagnostic source, or undefined when a full child collector is required.
35
+ */
36
+ export declare function emitLeafCheckAtSegment(schema: Schema, value: string, path: string, segmentExpression: string, issues: string, context: EmitContext): string | undefined;
37
+ /**
38
+ * @brief emit leaf check for a proven undefined value at one path segment.
39
+ * @details Array and tuple holes are known to be undefined. Emitting only the
40
+ * reachable type or literal issue keeps generated collectors smaller and avoids
41
+ * cold constraint branches that V8 still has to parse.
42
+ * @param schema Candidate leaf schema.
43
+ * @param path Generated expression for the current diagnostic path.
44
+ * @param segmentExpression Generated expression for the appended path segment.
45
+ * @param issues Generated expression for the issue buffer.
46
+ * @param context Shared code-generation context.
47
+ * @returns Inline diagnostic source, or undefined when a full child collector is required.
48
+ */
49
+ export declare function emitUndefinedLeafCheckAtSegment(schema: Schema, path: string, segmentExpression: string, issues: string, context: EmitContext): string | undefined;
50
+ /**
51
+ * @brief emit leaf check at two appended path segments.
52
+ * @details Used by object-field array/record diagnostics to avoid push/pop path
53
+ * mutation when both parent key and child key are known in generated source.
54
+ * @param schema Candidate leaf schema.
55
+ * @param value Generated expression for the candidate value.
56
+ * @param path Generated expression for the current diagnostic path.
57
+ * @param firstSegmentExpression Generated expression for the parent segment.
58
+ * @param secondSegmentExpression Generated expression for the child segment.
59
+ * @param issues Generated expression for the issue buffer.
60
+ * @param context Shared code-generation context.
61
+ * @returns Inline diagnostic source, or undefined when a full child collector is required.
62
+ */
63
+ export declare function emitLeafCheckAtTwoSegments(schema: Schema, value: string, path: string, firstSegmentExpression: string, secondSegmentExpression: string, issues: string, context: EmitContext): string | undefined;
64
+ /**
65
+ * @brief emit leaf check for a proven undefined value at two path segments.
66
+ * @details Array and tuple holes under object fields are known to be undefined,
67
+ * so the emitter can skip value reads and emit only reachable leaf issues.
68
+ * @param schema Candidate leaf schema.
69
+ * @param path Generated expression for the current diagnostic path.
70
+ * @param firstSegmentExpression Generated expression for the parent segment.
71
+ * @param secondSegmentExpression Generated expression for the child segment.
72
+ * @param issues Generated expression for the issue buffer.
73
+ * @param context Shared code-generation context.
74
+ * @returns Inline diagnostic source, or undefined when a full child collector is required.
75
+ */
76
+ export declare function emitUndefinedLeafCheckAtTwoSegments(schema: Schema, path: string, firstSegmentExpression: string, secondSegmentExpression: string, issues: string, context: EmitContext): string | undefined;
14
77
  /**
15
78
  * @brief emit number check.
79
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
80
+ * stable across runtime and AOT emission.
81
+ * @param schema Number schema with scalar checks.
82
+ * @param value Generated expression for the candidate value.
83
+ * @param path Generated expression for the current diagnostic path.
84
+ * @param issues Generated expression for the issue buffer.
85
+ * @returns JavaScript source for root number diagnostics.
16
86
  */
17
87
  export declare function emitNumberCheck(schema: Extract<Schema, {
18
88
  readonly tag: typeof SchemaTag.Number;
19
89
  }>, value: string, path: string, issues: string): string;
20
90
  /**
21
91
  * @brief emit literal check.
92
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
93
+ * stable across runtime and AOT emission.
94
+ * @param value Literal expected by the schema.
95
+ * @param checked Generated expression for the candidate value.
96
+ * @param path Generated expression for the current diagnostic path.
97
+ * @param issues Generated expression for the issue buffer.
98
+ * @param context Shared code-generation context.
99
+ * @returns JavaScript source for root literal diagnostics.
22
100
  */
23
101
  export declare function emitLiteralCheck(value: LiteralValue, checked: string, path: string, issues: string, context: EmitContext): string;
24
102
  //# sourceMappingURL=check-scalar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"check-scalar.d.ts","sourceRoot":"","sources":["../../src/compile/check-scalar.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEL,SAAS,EAEV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,MAAM,EACZ,MAAM,oBAAoB,CAAC;AAQ5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,MAAM,CAAA;CAAE,CAAC,EAClE,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACnB,MAAM,CA4CR;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,MAAM,CAAA;CAAE,CAAC,EAClE,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,MAAM,CA+CR;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACnB,MAAM,CASR"}
1
+ {"version":3,"file":"check-scalar.d.ts","sourceRoot":"","sources":["../../src/compile/check-scalar.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAEH,SAAS,EAEZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEH,KAAK,YAAY,EACjB,KAAK,MAAM,EACd,MAAM,oBAAoB,CAAC;AAe5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC3B,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,MAAM,CAAA;CAAE,CAAC,EAClE,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACrB,MAAM,CAgDR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAClC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACrB,MAAM,GAAG,SAAS,CAkFpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,+BAA+B,CAC3C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACrB,MAAM,GAAG,SAAS,CAqEpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACtC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,sBAAsB,EAAE,MAAM,EAC9B,uBAAuB,EAAE,MAAM,EAC/B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACrB,MAAM,GAAG,SAAS,CAsFpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mCAAmC,CAC/C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,sBAAsB,EAAE,MAAM,EAC9B,uBAAuB,EAAE,MAAM,EAC/B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACrB,MAAM,GAAG,SAAS,CA4EpB;AA4MD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC3B,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,MAAM,CAAA;CAAE,CAAC,EAClE,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACf,MAAM,CAmDR;AA+KD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC5B,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACrB,MAAM,CAaR"}
@@ -1,20 +1,35 @@
1
1
  /**
2
2
  * @file compile/check-scalar.ts
3
3
  * @brief Scalar diagnostic validator snippets.
4
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
5
+ * stable across runtime and AOT emission.
4
6
  */
5
7
  import { NumberCheckTag, SchemaTag, StringCheckTag } from "../kind/index.js";
6
8
  import { UUID_PATTERN } from "../schema/index.js";
7
9
  import { pushLiteral } from "./context.js";
8
- import { emitIssue, emitIssueExpr, emitPatternIssue } from "./issue.js";
10
+ import { emitIssue, emitIssueAtSegment, emitIssueAtTwoSegments, emitIssueExpr, emitIssueExprAtSegment, emitIssueExprAtTwoSegments, emitPatternIssueAtSegment, emitPatternIssueAtTwoSegments, emitPatternIssue } from "./issue.js";
9
11
  import { stringLiteral } from "./names.js";
12
+ import { emitUnion } from "./predicate.js";
10
13
  /**
11
14
  * @brief emit string check.
15
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
16
+ * stable across runtime and AOT emission.
17
+ * @param schema String schema with scalar checks.
18
+ * @param value Generated expression for the candidate value.
19
+ * @param path Generated expression for the current diagnostic path.
20
+ * @param issues Generated expression for the issue buffer.
21
+ * @param context Shared code-generation context.
22
+ * @returns JavaScript source for root string diagnostics.
12
23
  */
13
24
  export function emitStringCheck(schema, value, path, issues, context) {
14
25
  const parts = [
15
26
  `if(typeof ${value}!=="string"){${emitIssue(issues, path, "expected_string", "string", `a(${value})`)}return;}`
16
27
  ];
17
28
  const checks = schema.checks;
29
+ /*
30
+ * Constraint diagnostics run only after the type guard returns. This avoids
31
+ * meaningless length or pattern reads on non-string values.
32
+ */
18
33
  for (let index = 0; index < checks.length; index += 1) {
19
34
  const check = checks[index];
20
35
  if (check === undefined) {
@@ -37,14 +52,261 @@ export function emitStringCheck(schema, value, path, issues, context) {
37
52
  }
38
53
  return parts.join("");
39
54
  }
55
+ /**
56
+ * @brief emit leaf check at one appended path segment.
57
+ * @details This path is used by object-field diagnostics to avoid building a
58
+ * mutable path frame and calling a child collector for scalar schemas.
59
+ * @param schema Candidate leaf schema.
60
+ * @param value Generated expression for the candidate value.
61
+ * @param path Generated expression for the current diagnostic path.
62
+ * @param segmentExpression Generated expression for the appended path segment.
63
+ * @param issues Generated expression for the issue buffer.
64
+ * @param context Shared code-generation context.
65
+ * @returns Inline diagnostic source, or undefined when a full child collector is required.
66
+ */
67
+ export function emitLeafCheckAtSegment(schema, value, path, segmentExpression, issues, context) {
68
+ switch (schema.tag) {
69
+ case SchemaTag.Unknown:
70
+ return "";
71
+ case SchemaTag.Never:
72
+ return emitIssueAtSegment(issues, path, segmentExpression, "expected_never", "never", `a(${value})`);
73
+ case SchemaTag.String:
74
+ return emitStringCheckAtSegment(schema, value, path, segmentExpression, issues, context);
75
+ case SchemaTag.Number:
76
+ return emitNumberCheckAtSegment(schema, value, path, segmentExpression, issues);
77
+ case SchemaTag.BigInt:
78
+ return `if(typeof ${value}!=="bigint"){${emitIssueAtSegment(issues, path, segmentExpression, "expected_bigint", "bigint", `a(${value})`)}}`;
79
+ case SchemaTag.Symbol:
80
+ return `if(typeof ${value}!=="symbol"){${emitIssueAtSegment(issues, path, segmentExpression, "expected_symbol", "symbol", `a(${value})`)}}`;
81
+ case SchemaTag.Boolean:
82
+ return `if(typeof ${value}!=="boolean"){${emitIssueAtSegment(issues, path, segmentExpression, "expected_boolean", "boolean", `a(${value})`)}}`;
83
+ case SchemaTag.Literal:
84
+ return emitLiteralCheckAtSegment(schema.value, value, path, segmentExpression, issues, context);
85
+ case SchemaTag.Union:
86
+ /*
87
+ * Primitive unions are cheap enough to inline. Complex union branches
88
+ * already delegate through emitUnion and child predicate helpers.
89
+ */
90
+ return `if(!${emitUnion(schema.options, value, context)}){${emitIssueAtSegment(issues, path, segmentExpression, "expected_union", "union", `a(${value})`)}}`;
91
+ default:
92
+ return undefined;
93
+ }
94
+ }
95
+ /**
96
+ * @brief emit leaf check for a proven undefined value at one path segment.
97
+ * @details Array and tuple holes are known to be undefined. Emitting only the
98
+ * reachable type or literal issue keeps generated collectors smaller and avoids
99
+ * cold constraint branches that V8 still has to parse.
100
+ * @param schema Candidate leaf schema.
101
+ * @param path Generated expression for the current diagnostic path.
102
+ * @param segmentExpression Generated expression for the appended path segment.
103
+ * @param issues Generated expression for the issue buffer.
104
+ * @param context Shared code-generation context.
105
+ * @returns Inline diagnostic source, or undefined when a full child collector is required.
106
+ */
107
+ export function emitUndefinedLeafCheckAtSegment(schema, path, segmentExpression, issues, context) {
108
+ switch (schema.tag) {
109
+ case SchemaTag.Unknown:
110
+ return "";
111
+ case SchemaTag.Never:
112
+ return emitIssueAtSegment(issues, path, segmentExpression, "expected_never", "never", stringLiteral("undefined"));
113
+ case SchemaTag.String:
114
+ return emitIssueAtSegment(issues, path, segmentExpression, "expected_string", "string", stringLiteral("undefined"));
115
+ case SchemaTag.Number:
116
+ return emitIssueAtSegment(issues, path, segmentExpression, "expected_number", "number", stringLiteral("undefined"));
117
+ case SchemaTag.BigInt:
118
+ return emitIssueAtSegment(issues, path, segmentExpression, "expected_bigint", "bigint", stringLiteral("undefined"));
119
+ case SchemaTag.Symbol:
120
+ return emitIssueAtSegment(issues, path, segmentExpression, "expected_symbol", "symbol", stringLiteral("undefined"));
121
+ case SchemaTag.Boolean:
122
+ return emitIssueAtSegment(issues, path, segmentExpression, "expected_boolean", "boolean", stringLiteral("undefined"));
123
+ case SchemaTag.Literal:
124
+ return emitUndefinedLiteralCheckAtSegment(schema.value, path, segmentExpression, issues, context);
125
+ default:
126
+ return undefined;
127
+ }
128
+ }
129
+ /**
130
+ * @brief emit leaf check at two appended path segments.
131
+ * @details Used by object-field array/record diagnostics to avoid push/pop path
132
+ * mutation when both parent key and child key are known in generated source.
133
+ * @param schema Candidate leaf schema.
134
+ * @param value Generated expression for the candidate value.
135
+ * @param path Generated expression for the current diagnostic path.
136
+ * @param firstSegmentExpression Generated expression for the parent segment.
137
+ * @param secondSegmentExpression Generated expression for the child segment.
138
+ * @param issues Generated expression for the issue buffer.
139
+ * @param context Shared code-generation context.
140
+ * @returns Inline diagnostic source, or undefined when a full child collector is required.
141
+ */
142
+ export function emitLeafCheckAtTwoSegments(schema, value, path, firstSegmentExpression, secondSegmentExpression, issues, context) {
143
+ switch (schema.tag) {
144
+ case SchemaTag.Unknown:
145
+ return "";
146
+ case SchemaTag.Never:
147
+ return emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_never", "never", `a(${value})`);
148
+ case SchemaTag.String:
149
+ return emitStringCheckAtTwoSegments(schema, value, path, firstSegmentExpression, secondSegmentExpression, issues, context);
150
+ case SchemaTag.Number:
151
+ return emitNumberCheckAtTwoSegments(schema, value, path, firstSegmentExpression, secondSegmentExpression, issues);
152
+ case SchemaTag.BigInt:
153
+ return `if(typeof ${value}!=="bigint"){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_bigint", "bigint", `a(${value})`)}}`;
154
+ case SchemaTag.Symbol:
155
+ return `if(typeof ${value}!=="symbol"){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_symbol", "symbol", `a(${value})`)}}`;
156
+ case SchemaTag.Boolean:
157
+ return `if(typeof ${value}!=="boolean"){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_boolean", "boolean", `a(${value})`)}}`;
158
+ case SchemaTag.Literal:
159
+ return emitLiteralCheckAtTwoSegments(schema.value, value, path, firstSegmentExpression, secondSegmentExpression, issues, context);
160
+ case SchemaTag.Union:
161
+ return `if(!${emitUnion(schema.options, value, context)}){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_union", "union", `a(${value})`)}}`;
162
+ default:
163
+ return undefined;
164
+ }
165
+ }
166
+ /**
167
+ * @brief emit leaf check for a proven undefined value at two path segments.
168
+ * @details Array and tuple holes under object fields are known to be undefined,
169
+ * so the emitter can skip value reads and emit only reachable leaf issues.
170
+ * @param schema Candidate leaf schema.
171
+ * @param path Generated expression for the current diagnostic path.
172
+ * @param firstSegmentExpression Generated expression for the parent segment.
173
+ * @param secondSegmentExpression Generated expression for the child segment.
174
+ * @param issues Generated expression for the issue buffer.
175
+ * @param context Shared code-generation context.
176
+ * @returns Inline diagnostic source, or undefined when a full child collector is required.
177
+ */
178
+ export function emitUndefinedLeafCheckAtTwoSegments(schema, path, firstSegmentExpression, secondSegmentExpression, issues, context) {
179
+ switch (schema.tag) {
180
+ case SchemaTag.Unknown:
181
+ return "";
182
+ case SchemaTag.Never:
183
+ return emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_never", "never", stringLiteral("undefined"));
184
+ case SchemaTag.String:
185
+ return emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_string", "string", stringLiteral("undefined"));
186
+ case SchemaTag.Number:
187
+ return emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_number", "number", stringLiteral("undefined"));
188
+ case SchemaTag.BigInt:
189
+ return emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_bigint", "bigint", stringLiteral("undefined"));
190
+ case SchemaTag.Symbol:
191
+ return emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_symbol", "symbol", stringLiteral("undefined"));
192
+ case SchemaTag.Boolean:
193
+ return emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_boolean", "boolean", stringLiteral("undefined"));
194
+ case SchemaTag.Literal:
195
+ return emitUndefinedLiteralCheckAtTwoSegments(schema.value, path, firstSegmentExpression, secondSegmentExpression, issues, context);
196
+ default:
197
+ return undefined;
198
+ }
199
+ }
200
+ /**
201
+ * @brief emit string check at one appended path segment.
202
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
203
+ * stable across runtime and AOT emission.
204
+ * @param schema String schema with scalar checks.
205
+ * @param value Generated expression for the candidate value.
206
+ * @param path Generated expression for the current diagnostic path.
207
+ * @param segmentExpression Generated expression for the appended path segment.
208
+ * @param issues Generated expression for the issue buffer.
209
+ * @param context Shared code-generation context.
210
+ * @returns JavaScript source for one-segment string diagnostics.
211
+ */
212
+ function emitStringCheckAtSegment(schema, value, path, segmentExpression, issues, context) {
213
+ const checks = schema.checks;
214
+ if (checks.length === 0) {
215
+ /*
216
+ * No constraints means no else block is needed. The generated collector
217
+ * stays as a single type branch.
218
+ */
219
+ return `if(typeof ${value}!=="string"){${emitIssueAtSegment(issues, path, segmentExpression, "expected_string", "string", `a(${value})`)}}`;
220
+ }
221
+ const parts = [
222
+ `if(typeof ${value}!=="string"){${emitIssueAtSegment(issues, path, segmentExpression, "expected_string", "string", `a(${value})`)}}else{`
223
+ ];
224
+ for (let index = 0; index < checks.length; index += 1) {
225
+ const check = checks[index];
226
+ if (check === undefined) {
227
+ continue;
228
+ }
229
+ switch (check.tag) {
230
+ case StringCheckTag.Min:
231
+ parts.push(`if(${value}.length<${String(check.value)}){${emitIssueAtSegment(issues, path, segmentExpression, "expected_min_length", `length >= ${String(check.value)}`, `"length "+String(${value}.length)`)}}`);
232
+ break;
233
+ case StringCheckTag.Max:
234
+ parts.push(`if(${value}.length>${String(check.value)}){${emitIssueAtSegment(issues, path, segmentExpression, "expected_max_length", `length <= ${String(check.value)}`, `"length "+String(${value}.length)`)}}`);
235
+ break;
236
+ case StringCheckTag.Regex:
237
+ parts.push(emitPatternIssueAtSegment(value, path, segmentExpression, issues, check.regex, check.name, context));
238
+ break;
239
+ case StringCheckTag.Uuid:
240
+ parts.push(emitPatternIssueAtSegment(value, path, segmentExpression, issues, UUID_PATTERN, "uuid", context));
241
+ break;
242
+ }
243
+ }
244
+ parts.push("}");
245
+ return parts.join("");
246
+ }
247
+ /**
248
+ * @brief emit string check at two appended path segments.
249
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
250
+ * stable across runtime and AOT emission.
251
+ * @param schema String schema with scalar checks.
252
+ * @param value Generated expression for the candidate value.
253
+ * @param path Generated expression for the current diagnostic path.
254
+ * @param firstSegmentExpression Generated expression for the parent segment.
255
+ * @param secondSegmentExpression Generated expression for the child segment.
256
+ * @param issues Generated expression for the issue buffer.
257
+ * @param context Shared code-generation context.
258
+ * @returns JavaScript source for two-segment string diagnostics.
259
+ */
260
+ function emitStringCheckAtTwoSegments(schema, value, path, firstSegmentExpression, secondSegmentExpression, issues, context) {
261
+ const checks = schema.checks;
262
+ if (checks.length === 0) {
263
+ return `if(typeof ${value}!=="string"){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_string", "string", `a(${value})`)}}`;
264
+ }
265
+ const parts = [
266
+ `if(typeof ${value}!=="string"){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_string", "string", `a(${value})`)}}else{`
267
+ ];
268
+ for (let index = 0; index < checks.length; index += 1) {
269
+ const check = checks[index];
270
+ if (check === undefined) {
271
+ continue;
272
+ }
273
+ switch (check.tag) {
274
+ case StringCheckTag.Min:
275
+ parts.push(`if(${value}.length<${String(check.value)}){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_min_length", `length >= ${String(check.value)}`, `"length "+String(${value}.length)`)}}`);
276
+ break;
277
+ case StringCheckTag.Max:
278
+ parts.push(`if(${value}.length>${String(check.value)}){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_max_length", `length <= ${String(check.value)}`, `"length "+String(${value}.length)`)}}`);
279
+ break;
280
+ case StringCheckTag.Regex:
281
+ parts.push(emitPatternIssueAtTwoSegments(value, path, firstSegmentExpression, secondSegmentExpression, issues, check.regex, check.name, context));
282
+ break;
283
+ case StringCheckTag.Uuid:
284
+ parts.push(emitPatternIssueAtTwoSegments(value, path, firstSegmentExpression, secondSegmentExpression, issues, UUID_PATTERN, "uuid", context));
285
+ break;
286
+ }
287
+ }
288
+ parts.push("}");
289
+ return parts.join("");
290
+ }
40
291
  /**
41
292
  * @brief emit number check.
293
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
294
+ * stable across runtime and AOT emission.
295
+ * @param schema Number schema with scalar checks.
296
+ * @param value Generated expression for the candidate value.
297
+ * @param path Generated expression for the current diagnostic path.
298
+ * @param issues Generated expression for the issue buffer.
299
+ * @returns JavaScript source for root number diagnostics.
42
300
  */
43
301
  export function emitNumberCheck(schema, value, path, issues) {
44
302
  const parts = [
45
303
  `if(typeof ${value}!=="number"||!Number.isFinite(${value})){${emitIssue(issues, path, "expected_number", "number", `a(${value})`)}return;}`
46
304
  ];
47
305
  const checks = schema.checks;
306
+ /*
307
+ * Bounds and integer diagnostics are emitted only after the finite-number
308
+ * guard, so generated code never compares non-number values to bounds.
309
+ */
48
310
  for (let index = 0; index < checks.length; index += 1) {
49
311
  const check = checks[index];
50
312
  if (check === undefined) {
@@ -64,10 +326,179 @@ export function emitNumberCheck(schema, value, path, issues) {
64
326
  }
65
327
  return parts.join("");
66
328
  }
329
+ /**
330
+ * @brief emit number check at one appended path segment.
331
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
332
+ * stable across runtime and AOT emission.
333
+ * @param schema Number schema with scalar checks.
334
+ * @param value Generated expression for the candidate value.
335
+ * @param path Generated expression for the current diagnostic path.
336
+ * @param segmentExpression Generated expression for the appended path segment.
337
+ * @param issues Generated expression for the issue buffer.
338
+ * @returns JavaScript source for one-segment number diagnostics.
339
+ */
340
+ function emitNumberCheckAtSegment(schema, value, path, segmentExpression, issues) {
341
+ const checks = schema.checks;
342
+ if (checks.length === 0) {
343
+ /*
344
+ * Plain number schemas need only the finite-number guard. Emitting an
345
+ * else block would add cold code with no diagnostic work.
346
+ */
347
+ return `if(typeof ${value}!=="number"||!Number.isFinite(${value})){${emitIssueAtSegment(issues, path, segmentExpression, "expected_number", "number", `a(${value})`)}}`;
348
+ }
349
+ const parts = [
350
+ `if(typeof ${value}!=="number"||!Number.isFinite(${value})){${emitIssueAtSegment(issues, path, segmentExpression, "expected_number", "number", `a(${value})`)}}else{`
351
+ ];
352
+ for (let index = 0; index < checks.length; index += 1) {
353
+ const check = checks[index];
354
+ if (check === undefined) {
355
+ continue;
356
+ }
357
+ switch (check.tag) {
358
+ case NumberCheckTag.Integer:
359
+ parts.push(`if(!Number.isInteger(${value})){${emitIssueExprAtSegment(issues, path, segmentExpression, "expected_integer", stringLiteral("integer"), stringLiteral("number"))}}`);
360
+ break;
361
+ case NumberCheckTag.Gte:
362
+ parts.push(`if(${value}<${String(check.value)}){${emitIssueAtSegment(issues, path, segmentExpression, "expected_gte", `>= ${String(check.value)}`, `String(${value})`)}}`);
363
+ break;
364
+ case NumberCheckTag.Lte:
365
+ parts.push(`if(${value}>${String(check.value)}){${emitIssueAtSegment(issues, path, segmentExpression, "expected_lte", `<= ${String(check.value)}`, `String(${value})`)}}`);
366
+ break;
367
+ }
368
+ }
369
+ parts.push("}");
370
+ return parts.join("");
371
+ }
372
+ /**
373
+ * @brief emit number check at two appended path segments.
374
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
375
+ * stable across runtime and AOT emission.
376
+ * @param schema Number schema with scalar checks.
377
+ * @param value Generated expression for the candidate value.
378
+ * @param path Generated expression for the current diagnostic path.
379
+ * @param firstSegmentExpression Generated expression for the parent segment.
380
+ * @param secondSegmentExpression Generated expression for the child segment.
381
+ * @param issues Generated expression for the issue buffer.
382
+ * @returns JavaScript source for two-segment number diagnostics.
383
+ */
384
+ function emitNumberCheckAtTwoSegments(schema, value, path, firstSegmentExpression, secondSegmentExpression, issues) {
385
+ const checks = schema.checks;
386
+ if (checks.length === 0) {
387
+ return `if(typeof ${value}!=="number"||!Number.isFinite(${value})){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_number", "number", `a(${value})`)}}`;
388
+ }
389
+ const parts = [
390
+ `if(typeof ${value}!=="number"||!Number.isFinite(${value})){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_number", "number", `a(${value})`)}}else{`
391
+ ];
392
+ for (let index = 0; index < checks.length; index += 1) {
393
+ const check = checks[index];
394
+ if (check === undefined) {
395
+ continue;
396
+ }
397
+ switch (check.tag) {
398
+ case NumberCheckTag.Integer:
399
+ parts.push(`if(!Number.isInteger(${value})){${emitIssueExprAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_integer", stringLiteral("integer"), stringLiteral("number"))}}`);
400
+ break;
401
+ case NumberCheckTag.Gte:
402
+ parts.push(`if(${value}<${String(check.value)}){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_gte", `>= ${String(check.value)}`, `String(${value})`)}}`);
403
+ break;
404
+ case NumberCheckTag.Lte:
405
+ parts.push(`if(${value}>${String(check.value)}){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_lte", `<= ${String(check.value)}`, `String(${value})`)}}`);
406
+ break;
407
+ }
408
+ }
409
+ parts.push("}");
410
+ return parts.join("");
411
+ }
67
412
  /**
68
413
  * @brief emit literal check.
414
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
415
+ * stable across runtime and AOT emission.
416
+ * @param value Literal expected by the schema.
417
+ * @param checked Generated expression for the candidate value.
418
+ * @param path Generated expression for the current diagnostic path.
419
+ * @param issues Generated expression for the issue buffer.
420
+ * @param context Shared code-generation context.
421
+ * @returns JavaScript source for root literal diagnostics.
69
422
  */
70
423
  export function emitLiteralCheck(value, checked, path, issues, context) {
71
424
  const index = pushLiteral(context, value);
425
+ /*
426
+ * Object.is preserves JavaScript literal edge cases such as NaN and -0.
427
+ * The expected value stays in the literal side table rather than source text.
428
+ */
72
429
  return `if(!Object.is(${checked},l[${String(index)}])){${emitIssueExpr(issues, path, "expected_literal", `le(l[${String(index)}])`, `a(${checked})`)}}`;
73
430
  }
431
+ /**
432
+ * @brief emit literal check at one appended path segment.
433
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
434
+ * stable across runtime and AOT emission.
435
+ * @param value Literal expected by the schema.
436
+ * @param checked Generated expression for the candidate value.
437
+ * @param path Generated expression for the current diagnostic path.
438
+ * @param segmentExpression Generated expression for the appended path segment.
439
+ * @param issues Generated expression for the issue buffer.
440
+ * @param context Shared code-generation context.
441
+ * @returns JavaScript source for one-segment literal diagnostics.
442
+ */
443
+ function emitLiteralCheckAtSegment(value, checked, path, segmentExpression, issues, context) {
444
+ const index = pushLiteral(context, value);
445
+ return `if(!Object.is(${checked},l[${String(index)}])){${emitIssueExprAtSegment(issues, path, segmentExpression, "expected_literal", `le(l[${String(index)}])`, `a(${checked})`)}}`;
446
+ }
447
+ /**
448
+ * @brief emit literal check at two appended path segments.
449
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
450
+ * stable across runtime and AOT emission.
451
+ * @param value Literal expected by the schema.
452
+ * @param checked Generated expression for the candidate value.
453
+ * @param path Generated expression for the current diagnostic path.
454
+ * @param firstSegmentExpression Generated expression for the parent segment.
455
+ * @param secondSegmentExpression Generated expression for the child segment.
456
+ * @param issues Generated expression for the issue buffer.
457
+ * @param context Shared code-generation context.
458
+ * @returns JavaScript source for two-segment literal diagnostics.
459
+ */
460
+ function emitLiteralCheckAtTwoSegments(value, checked, path, firstSegmentExpression, secondSegmentExpression, issues, context) {
461
+ const index = pushLiteral(context, value);
462
+ return `if(!Object.is(${checked},l[${String(index)}])){${emitIssueExprAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_literal", `le(l[${String(index)}])`, `a(${checked})`)}}`;
463
+ }
464
+ /**
465
+ * @brief emit undefined literal check at one appended path segment.
466
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
467
+ * stable across runtime and AOT emission.
468
+ * @param value Literal expected by the schema.
469
+ * @param path Generated expression for the current diagnostic path.
470
+ * @param segmentExpression Generated expression for the appended path segment.
471
+ * @param issues Generated expression for the issue buffer.
472
+ * @param context Shared code-generation context.
473
+ * @returns Empty source when undefined is the expected literal, otherwise an issue.
474
+ */
475
+ function emitUndefinedLiteralCheckAtSegment(value, path, segmentExpression, issues, context) {
476
+ if (value === undefined) {
477
+ /*
478
+ * A sparse hole has already produced the exact expected literal. There is
479
+ * no diagnostic work left to emit.
480
+ */
481
+ return "";
482
+ }
483
+ const index = pushLiteral(context, value);
484
+ return emitIssueExprAtSegment(issues, path, segmentExpression, "expected_literal", `le(l[${String(index)}])`, stringLiteral("undefined"));
485
+ }
486
+ /**
487
+ * @brief emit undefined literal check at two appended path segments.
488
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
489
+ * stable across runtime and AOT emission.
490
+ * @param value Literal expected by the schema.
491
+ * @param path Generated expression for the current diagnostic path.
492
+ * @param firstSegmentExpression Generated expression for the parent segment.
493
+ * @param secondSegmentExpression Generated expression for the child segment.
494
+ * @param issues Generated expression for the issue buffer.
495
+ * @param context Shared code-generation context.
496
+ * @returns Empty source when undefined is the expected literal, otherwise an issue.
497
+ */
498
+ function emitUndefinedLiteralCheckAtTwoSegments(value, path, firstSegmentExpression, secondSegmentExpression, issues, context) {
499
+ if (value === undefined) {
500
+ return "";
501
+ }
502
+ const index = pushLiteral(context, value);
503
+ return emitIssueExprAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_literal", `le(l[${String(index)}])`, stringLiteral("undefined"));
504
+ }
@@ -1,15 +1,27 @@
1
1
  /**
2
2
  * @file compile/check.ts
3
3
  * @brief Diagnostic validator function table emitter.
4
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
5
+ * stable across runtime and AOT emission.
4
6
  */
5
7
  import type { Schema } from "../schema/index.js";
6
8
  import type { EmitContext } from "./types.js";
7
9
  /**
8
10
  * @brief emit check function.
11
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
12
+ * stable across runtime and AOT emission.
13
+ * @param schema Schema whose diagnostics should be emitted.
14
+ * @param context Shared code-generation context.
15
+ * @returns Generated diagnostic function name.
16
+ * @invariant The same schema object maps to one diagnostic function per bundle.
9
17
  */
10
18
  export declare function emitCheckFunction(schema: Schema, context: EmitContext): string;
11
19
  /**
12
20
  * @brief emit check functions.
21
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
22
+ * stable across runtime and AOT emission.
23
+ * @param context Shared code-generation context with accumulated check sources.
24
+ * @returns Concatenated JavaScript function declarations.
13
25
  */
14
26
  export declare function emitCheckFunctions(context: EmitContext): string;
15
27
  //# sourceMappingURL=check.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/compile/check.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAgBjD,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAE9D;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAc9E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAU/D"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/compile/check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAgBjD,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAE9D;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAkB9E;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAU/D"}