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,28 +1,211 @@
1
1
  /**
2
2
  * @file compile/issue.ts
3
3
  * @brief Diagnostic issue source 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 { UUID_PATTERN } from "../schema/index.js";
6
8
  import { pushRegex, stringRef } from "./context.js";
7
9
  import { stringLiteral } from "./names.js";
8
10
  /**
9
11
  * @brief emit pattern issue.
12
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
13
+ * stable across runtime and AOT emission.
14
+ * @param value Generated expression for the string value.
15
+ * @param path Generated expression for the current diagnostic path.
16
+ * @param issues Generated expression for the diagnostic buffer.
17
+ * @param regex Pattern used by the schema check.
18
+ * @param name Human-readable pattern name stored in the issue.
19
+ * @param context Shared code-generation context.
20
+ * @returns JavaScript source that appends a pattern issue when the test fails.
10
21
  */
11
22
  export function emitPatternIssue(value, path, issues, regex, name, context) {
12
23
  const source = regex === UUID_PATTERN ? UUID_PATTERN : regex;
13
24
  const index = pushRegex(context, source);
14
25
  const access = `r[${String(index)}]`;
15
- return `if(((${access}.lastIndex=0),!${access}.test(${value}))){${emitIssueExpr(issues, path, "expected_pattern", stringRef(context, name), stringLiteral("string"))}}`;
26
+ const test = regexNeedsLastIndexReset(source)
27
+ ? `((${access}.lastIndex=0),!${access}.test(${value}))`
28
+ : `!${access}.test(${value})`;
29
+ /*
30
+ * Pattern names live in the string side table. That keeps generated source
31
+ * stable even when users provide long or escaped pattern descriptions.
32
+ */
33
+ return `if(${test}){${emitIssueExpr(issues, path, "expected_pattern", stringRef(context, name), stringLiteral("string"))}}`;
34
+ }
35
+ /**
36
+ * @brief emit pattern issue at one appended path segment.
37
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
38
+ * stable across runtime and AOT emission.
39
+ * @param value Generated expression for the string value.
40
+ * @param path Generated expression for the current diagnostic path.
41
+ * @param segmentExpression Generated expression for the appended segment.
42
+ * @param issues Generated expression for the diagnostic buffer.
43
+ * @param regex Pattern used by the schema check.
44
+ * @param name Human-readable pattern name stored in the issue.
45
+ * @param context Shared code-generation context.
46
+ * @returns JavaScript source that appends a one-segment pattern issue.
47
+ */
48
+ export function emitPatternIssueAtSegment(value, path, segmentExpression, issues, regex, name, context) {
49
+ const source = regex === UUID_PATTERN ? UUID_PATTERN : regex;
50
+ const index = pushRegex(context, source);
51
+ const access = `r[${String(index)}]`;
52
+ const test = regexNeedsLastIndexReset(source)
53
+ ? `((${access}.lastIndex=0),!${access}.test(${value}))`
54
+ : `!${access}.test(${value})`;
55
+ return `if(${test}){${emitIssueExprAtSegment(issues, path, segmentExpression, "expected_pattern", stringRef(context, name), stringLiteral("string"))}}`;
56
+ }
57
+ /**
58
+ * @brief emit pattern issue at two appended path segments.
59
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
60
+ * stable across runtime and AOT emission.
61
+ * @param value Generated expression for the string value.
62
+ * @param path Generated expression for the current diagnostic path.
63
+ * @param firstSegmentExpression Generated expression for the first appended segment.
64
+ * @param secondSegmentExpression Generated expression for the second appended segment.
65
+ * @param issues Generated expression for the diagnostic buffer.
66
+ * @param regex Pattern used by the schema check.
67
+ * @param name Human-readable pattern name stored in the issue.
68
+ * @param context Shared code-generation context.
69
+ * @returns JavaScript source that appends a two-segment pattern issue.
70
+ */
71
+ export function emitPatternIssueAtTwoSegments(value, path, firstSegmentExpression, secondSegmentExpression, issues, regex, name, context) {
72
+ const source = regex === UUID_PATTERN ? UUID_PATTERN : regex;
73
+ const index = pushRegex(context, source);
74
+ const access = `r[${String(index)}]`;
75
+ const test = regexNeedsLastIndexReset(source)
76
+ ? `((${access}.lastIndex=0),!${access}.test(${value}))`
77
+ : `!${access}.test(${value})`;
78
+ return `if(${test}){${emitIssueExprAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_pattern", stringRef(context, name), stringLiteral("string"))}}`;
79
+ }
80
+ /**
81
+ * @brief Decide whether a RegExp must be reset before generated testing.
82
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
83
+ * stable across runtime and AOT emission.
84
+ * @param regex RegExp stored in the generated side table.
85
+ * @returns True for stateful global or sticky expressions.
86
+ */
87
+ function regexNeedsLastIndexReset(regex) {
88
+ return regex.global || regex.sticky;
16
89
  }
17
90
  /**
18
91
  * @brief emit issue.
92
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
93
+ * stable across runtime and AOT emission.
94
+ * @param issues Generated expression for the diagnostic buffer.
95
+ * @param path Generated expression for the current diagnostic path.
96
+ * @param code Issue code string.
97
+ * @param expected Expected type or condition text.
98
+ * @param actualExpression Generated expression for actual type text.
99
+ * @returns JavaScript source that appends an issue at the current path.
19
100
  */
20
101
  export function emitIssue(issues, path, code, expected, actualExpression) {
21
102
  return emitIssueExpr(issues, path, code, stringLiteral(expected), actualExpression);
22
103
  }
104
+ /**
105
+ * @brief emit issue at one appended path segment.
106
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
107
+ * stable across runtime and AOT emission.
108
+ * @param issues Generated expression for the diagnostic buffer.
109
+ * @param path Generated expression for the current diagnostic path.
110
+ * @param segmentExpression Generated expression for the appended segment.
111
+ * @param code Issue code string.
112
+ * @param expected Expected type or condition text.
113
+ * @param actualExpression Generated expression for actual type text.
114
+ * @returns JavaScript source that appends an issue under one extra segment.
115
+ */
116
+ export function emitIssueAtSegment(issues, path, segmentExpression, code, expected, actualExpression) {
117
+ return emitIssueExprAtSegment(issues, path, segmentExpression, code, stringLiteral(expected), actualExpression);
118
+ }
119
+ /**
120
+ * @brief emit issue at two appended path segments.
121
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
122
+ * stable across runtime and AOT emission.
123
+ * @param issues Generated expression for the diagnostic buffer.
124
+ * @param path Generated expression for the current diagnostic path.
125
+ * @param firstSegmentExpression Generated expression for the first appended segment.
126
+ * @param secondSegmentExpression Generated expression for the second appended segment.
127
+ * @param code Issue code string.
128
+ * @param expected Expected type or condition text.
129
+ * @param actualExpression Generated expression for actual type text.
130
+ * @returns JavaScript source that appends an issue under two extra segments.
131
+ */
132
+ export function emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, code, expected, actualExpression) {
133
+ return emitIssueExprAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, code, stringLiteral(expected), actualExpression);
134
+ }
23
135
  /**
24
136
  * @brief emit issue expr.
137
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
138
+ * stable across runtime and AOT emission.
139
+ * @param issues Generated expression for the diagnostic buffer.
140
+ * @param path Generated expression for the current diagnostic path.
141
+ * @param code Issue code string.
142
+ * @param expectedExpression Generated expression for expected text.
143
+ * @param actualExpression Generated expression for actual type text.
144
+ * @returns JavaScript source that appends an issue using expression operands.
25
145
  */
26
146
  export function emitIssueExpr(issues, path, code, expectedExpression, actualExpression) {
27
147
  return `q(${issues},${path},${stringLiteral(code)},${expectedExpression},${actualExpression});`;
28
148
  }
149
+ /**
150
+ * @brief emit issue expr at one appended path segment.
151
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
152
+ * stable across runtime and AOT emission.
153
+ * @param issues Generated expression for the diagnostic buffer.
154
+ * @param path Generated expression for the current diagnostic path.
155
+ * @param segmentExpression Generated expression for the appended segment.
156
+ * @param code Issue code string.
157
+ * @param expectedExpression Generated expression for expected text.
158
+ * @param actualExpression Generated expression for actual type text.
159
+ * @returns JavaScript source using the most compact one-segment issue helper.
160
+ */
161
+ export function emitIssueExprAtSegment(issues, path, segmentExpression, code, expectedExpression, actualExpression) {
162
+ const stringIndex = readStringRefIndex(segmentExpression);
163
+ if (stringIndex !== undefined) {
164
+ /*
165
+ * q1s reuses the pre-frozen path segment cache for static string keys.
166
+ * Dynamic segments still go through q1 because their value is known only
167
+ * inside the generated validator.
168
+ */
169
+ return `q1s(${issues},${path},${stringIndex},${stringLiteral(code)},${expectedExpression},${actualExpression});`;
170
+ }
171
+ return `q1(${issues},${path},${segmentExpression},${stringLiteral(code)},${expectedExpression},${actualExpression});`;
172
+ }
173
+ /**
174
+ * @brief emit issue expr at two appended path segments.
175
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
176
+ * stable across runtime and AOT emission.
177
+ * @param issues Generated expression for the diagnostic buffer.
178
+ * @param path Generated expression for the current diagnostic path.
179
+ * @param firstSegmentExpression Generated expression for the first appended segment.
180
+ * @param secondSegmentExpression Generated expression for the second appended segment.
181
+ * @param code Issue code string.
182
+ * @param expectedExpression Generated expression for expected text.
183
+ * @param actualExpression Generated expression for actual type text.
184
+ * @returns JavaScript source using the two-segment issue helper.
185
+ */
186
+ export function emitIssueExprAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, code, expectedExpression, actualExpression) {
187
+ return `q2(${issues},${path},${firstSegmentExpression},${secondSegmentExpression},${stringLiteral(code)},${expectedExpression},${actualExpression});`;
188
+ }
189
+ /**
190
+ * @brief Extract the numeric side-table index from a generated string reference.
191
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
192
+ * stable across runtime and AOT emission.
193
+ * @param expression Candidate generated expression such as `u[3]`.
194
+ * @returns Index text when the expression is a plain string-table read.
195
+ */
196
+ function readStringRefIndex(expression) {
197
+ if (!expression.startsWith("u[") || !expression.endsWith("]")) {
198
+ return undefined;
199
+ }
200
+ const value = expression.slice(2, -1);
201
+ if (value.length === 0) {
202
+ return undefined;
203
+ }
204
+ for (let index = 0; index < value.length; index += 1) {
205
+ const code = value.charCodeAt(index);
206
+ if (code < 48 || code > 57) {
207
+ return undefined;
208
+ }
209
+ }
210
+ return value;
211
+ }
@@ -1,16 +1,26 @@
1
1
  /**
2
2
  * @file compile-names.ts
3
3
  * @brief Generated function-name and string literal helpers.
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
  * @invariant User-provided names never enter generated source until they are
6
8
  * reduced to a strict-mode-safe identifier with a fixed length bound.
7
9
  */
8
10
  /**
9
- * @brief safe function name.
11
+ * @brief Convert a user supplied compile name into a strict-mode function id.
12
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
13
+ * stable across runtime and AOT emission.
14
+ * @param value Requested public function name.
15
+ * @returns Identifier-safe, reserved-word-safe, bounded function name.
10
16
  */
11
17
  export declare function safeFunctionName(value: string): string;
12
18
  /**
13
- * @brief string literal.
19
+ * @brief Quote a string for generated JavaScript source.
20
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
21
+ * stable across runtime and AOT emission.
22
+ * @param value Runtime string to embed.
23
+ * @returns JSON-escaped string literal source.
14
24
  */
15
25
  export declare function stringLiteral(value: string): string;
16
26
  //# sourceMappingURL=names.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../src/compile/names.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYtD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD"}
1
+ {"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../src/compile/names.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAgBtD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD"}
@@ -1,13 +1,19 @@
1
1
  /**
2
2
  * @file compile-names.ts
3
3
  * @brief Generated function-name and string literal helpers.
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
  * @invariant User-provided names never enter generated source until they are
6
8
  * reduced to a strict-mode-safe identifier with a fixed length bound.
7
9
  */
8
10
  const MAX_GENERATED_FUNCTION_NAME_LENGTH = 96;
9
11
  /**
10
- * @brief safe function name.
12
+ * @brief Convert a user supplied compile name into a strict-mode function id.
13
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
14
+ * stable across runtime and AOT emission.
15
+ * @param value Requested public function name.
16
+ * @returns Identifier-safe, reserved-word-safe, bounded function name.
11
17
  */
12
18
  export function safeFunctionName(value) {
13
19
  const replaced = value.replace(/[^$_a-zA-Z0-9]/gu, "_");
@@ -17,19 +23,29 @@ export function safeFunctionName(value) {
17
23
  if (/^[$_a-zA-Z]/u.test(bounded) && !reservedFunctionNames.has(bounded)) {
18
24
  return bounded;
19
25
  }
26
+ /*
27
+ * Prefixing recovers names that start with a digit or collide with reserved
28
+ * words while keeping the final identifier under the same length cap.
29
+ */
20
30
  const prefixed = `_${bounded}`;
21
31
  return prefixed.length > MAX_GENERATED_FUNCTION_NAME_LENGTH
22
32
  ? prefixed.slice(0, MAX_GENERATED_FUNCTION_NAME_LENGTH)
23
33
  : prefixed;
24
34
  }
25
35
  /**
26
- * @brief string literal.
36
+ * @brief Quote a string for generated JavaScript source.
37
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
38
+ * stable across runtime and AOT emission.
39
+ * @param value Runtime string to embed.
40
+ * @returns JSON-escaped string literal source.
27
41
  */
28
42
  export function stringLiteral(value) {
29
43
  return JSON.stringify(value);
30
44
  }
31
45
  /**
32
- * @brief reserved function names.
46
+ * @brief Strict-mode names that cannot be emitted as generated function ids.
47
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
48
+ * stable across runtime and AOT emission.
33
49
  */
34
50
  const reservedFunctionNames = new Set([
35
51
  "arguments",
@@ -1,23 +1,47 @@
1
1
  /**
2
2
  * @file compile/predicate.ts
3
3
  * @brief Boolean validator source 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 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 represented by the predicate.
14
+ * @param context Shared code-generation context.
15
+ * @returns Generated predicate function name.
16
+ * @invariant The same schema object maps to one predicate function per bundle.
9
17
  */
10
18
  export declare function emitFunction(schema: Schema, context: EmitContext): string;
11
19
  /**
12
20
  * @brief emit 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 predicate sources.
24
+ * @returns Concatenated JavaScript function declarations.
13
25
  */
14
26
  export declare function emitFunctions(context: EmitContext): string;
15
27
  /**
16
28
  * @brief emit expression.
29
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
30
+ * stable across runtime and AOT emission.
31
+ * @param schema Schema represented by the expression.
32
+ * @param value Generated expression for the candidate value.
33
+ * @param context Shared code-generation context.
34
+ * @returns JavaScript expression that evaluates to a boolean.
17
35
  */
18
36
  export declare function emitExpression(schema: Schema, value: string, context: EmitContext): string;
19
37
  /**
20
38
  * @brief emit union.
39
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
40
+ * stable across runtime and AOT emission.
41
+ * @param options Union option schemas.
42
+ * @param value Generated expression for the candidate value.
43
+ * @param context Shared code-generation context.
44
+ * @returns JavaScript expression for the union predicate.
21
45
  */
22
46
  export declare function emitUnion(options: readonly Schema[], value: string, context: EmitContext): string;
23
47
  //# sourceMappingURL=predicate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"predicate.d.ts","sourceRoot":"","sources":["../../src/compile/predicate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,EAGL,KAAK,MAAM,EACZ,MAAM,oBAAoB,CAAC;AAO5B,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAE9D;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAczE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAU1D;AAsBD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,GACnB,MAAM,CA+CR;AA0PD;;GAEG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,GACnB,MAAM,CAYR"}
1
+ {"version":3,"file":"predicate.d.ts","sourceRoot":"","sources":["../../src/compile/predicate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,EAIH,KAAK,MAAM,EACd,MAAM,oBAAoB,CAAC;AAO5B,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAE9D;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAkBzE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAU1D;AA4BD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC1B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,GACrB,MAAM,CAuDR;AAyUD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACrB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,GACrB,MAAM,CAYR"}
@@ -1,18 +1,30 @@
1
1
  /**
2
2
  * @file compile/predicate.ts
3
3
  * @brief Boolean validator source 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 { NumberCheckTag, ObjectModeTag, PresenceTag, SchemaTag, StringCheckTag } from "../kind/index.js";
6
8
  import { UUID_PATTERN } from "../schema/index.js";
7
9
  import { pushLiteral, pushRegex, pushSchema, stringRef } from "./context.js";
8
10
  /**
9
11
  * @brief emit function.
12
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
13
+ * stable across runtime and AOT emission.
14
+ * @param schema Schema represented by the predicate.
15
+ * @param context Shared code-generation context.
16
+ * @returns Generated predicate function name.
17
+ * @invariant The same schema object maps to one predicate function per bundle.
10
18
  */
11
19
  export function emitFunction(schema, context) {
12
20
  const cached = context.functionNames.get(schema);
13
21
  if (cached !== undefined) {
14
22
  return cached;
15
23
  }
24
+ /*
25
+ * Register before body emission so recursive references can point at the
26
+ * function name even while its body is still under construction.
27
+ */
16
28
  const name = `p${String(context.functions.length)}`;
17
29
  const source = {
18
30
  name,
@@ -25,6 +37,10 @@ export function emitFunction(schema, context) {
25
37
  }
26
38
  /**
27
39
  * @brief emit functions.
40
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
41
+ * stable across runtime and AOT emission.
42
+ * @param context Shared code-generation context with accumulated predicate sources.
43
+ * @returns Concatenated JavaScript function declarations.
28
44
  */
29
45
  export function emitFunctions(context) {
30
46
  const chunks = new Array(context.functions.length);
@@ -39,6 +55,12 @@ export function emitFunctions(context) {
39
55
  }
40
56
  /**
41
57
  * @brief emit body.
58
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
59
+ * stable across runtime and AOT emission.
60
+ * @param schema Schema represented by this predicate body.
61
+ * @param value Generated expression for the candidate value.
62
+ * @param context Shared code-generation context.
63
+ * @returns JavaScript source for a predicate function body.
42
64
  */
43
65
  function emitBody(schema, value, context) {
44
66
  switch (schema.tag) {
@@ -58,6 +80,12 @@ function emitBody(schema, value, context) {
58
80
  }
59
81
  /**
60
82
  * @brief emit expression.
83
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
84
+ * stable across runtime and AOT emission.
85
+ * @param schema Schema represented by the expression.
86
+ * @param value Generated expression for the candidate value.
87
+ * @param context Shared code-generation context.
88
+ * @returns JavaScript expression that evaluates to a boolean.
61
89
  */
62
90
  export function emitExpression(schema, value, context) {
63
91
  switch (schema.tag) {
@@ -78,6 +106,10 @@ export function emitExpression(schema, value, context) {
78
106
  case SchemaTag.Literal:
79
107
  return `Object.is(${value},l[${String(pushLiteral(context, schema.value))}])`;
80
108
  case SchemaTag.Array:
109
+ /*
110
+ * Composite schemas get their own functions. That keeps deeply nested
111
+ * predicates readable to V8 and avoids duplicating loops at each use site.
112
+ */
81
113
  return `${emitFunction(schema, context)}(${value})`;
82
114
  case SchemaTag.Tuple:
83
115
  return `${emitFunction(schema, context)}(${value})`;
@@ -100,14 +132,29 @@ export function emitExpression(schema, value, context) {
100
132
  return emitExpression(schema.inner, value, context);
101
133
  case SchemaTag.Lazy:
102
134
  case SchemaTag.Refine:
135
+ /*
136
+ * User predicates and lazy resolution remain behind the runtime `d`
137
+ * helper because generated source cannot inline their behavior.
138
+ */
103
139
  return `d(${String(pushSchema(context, schema))},${value})`;
104
140
  }
105
141
  }
106
142
  /**
107
143
  * @brief emit array body.
144
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
145
+ * stable across runtime and AOT emission.
146
+ * @param item Schema applied to each logical slot.
147
+ * @param value Generated expression for the array value.
148
+ * @param context Shared code-generation context.
149
+ * @returns JavaScript source for an array predicate body.
108
150
  */
109
151
  function emitArrayBody(item, value, context) {
110
152
  const itemFunction = emitFunction(item, context);
153
+ /*
154
+ * Descriptor reads block accessor-backed slots without executing getters.
155
+ * Holes are forwarded as undefined so optional item schemas keep normal JS
156
+ * sparse-array semantics.
157
+ */
111
158
  return [
112
159
  `if(!Array.isArray(${value}))return false;`,
113
160
  `for(let i=0;i<${value}.length;i+=1){`,
@@ -120,9 +167,19 @@ function emitArrayBody(item, value, context) {
120
167
  }
121
168
  /**
122
169
  * @brief emit record body.
170
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
171
+ * stable across runtime and AOT emission.
172
+ * @param item Schema applied to each own enumerable string key.
173
+ * @param value Generated expression for the record value.
174
+ * @param context Shared code-generation context.
175
+ * @returns JavaScript source for a record predicate body.
123
176
  */
124
177
  function emitRecordBody(item, value, context) {
125
178
  const itemFunction = emitFunction(item, context);
179
+ /*
180
+ * Object.keys intentionally ignores inherited and non-enumerable keys,
181
+ * matching TypeSea record semantics while keeping iteration predictable.
182
+ */
126
183
  return [
127
184
  `if(!o(${value}))return false;`,
128
185
  `const ks=Object.keys(${value});`,
@@ -137,6 +194,9 @@ function emitRecordBody(item, value, context) {
137
194
  /**
138
195
  * @brief emit tuple body.
139
196
  * @details Emits tuple validation as straight-line descriptor reads and early returns.
197
+ * @param items Tuple item schemas.
198
+ * @param value Generated expression for the tuple value.
199
+ * @param context Shared code-generation context.
140
200
  * @returns Generated tuple predicate body.
141
201
  */
142
202
  function emitTupleBody(items, value, context) {
@@ -150,6 +210,10 @@ function emitTupleBody(items, value, context) {
150
210
  }
151
211
  const descriptor = `d${String(index)}`;
152
212
  const itemValue = `v${String(index)}`;
213
+ /*
214
+ * Tuple arity is already checked above. Each index still needs descriptor
215
+ * validation because an accessor slot would execute user code if read.
216
+ */
153
217
  chunks.push(`const ${descriptor}=gp(${value},${String(index)});`, `if(${descriptor}!==undefined&&!h.call(${descriptor},"value"))return false;`, `const ${itemValue}=${descriptor}===undefined?undefined:${descriptor}.value;`, `if(!${emitExpression(item, itemValue, context)})return false;`);
154
218
  }
155
219
  chunks.push("return true;");
@@ -158,6 +222,9 @@ function emitTupleBody(items, value, context) {
158
222
  /**
159
223
  * @brief emit object body.
160
224
  * @details Emits object validation as Ajv-style straight-line code with local descriptor variables.
225
+ * @param schema Object schema to emit.
226
+ * @param value Generated expression for the object value.
227
+ * @param context Shared code-generation context.
161
228
  * @returns Generated object predicate body.
162
229
  */
163
230
  function emitObjectBody(schema, value, context) {
@@ -174,6 +241,10 @@ function emitObjectBody(schema, value, context) {
174
241
  const itemValue = `v${String(index)}`;
175
242
  chunks.push(`const ${descriptor}=gp(${value},${key});`);
176
243
  if (entry.presence === PresenceTag.Optional) {
244
+ /*
245
+ * Optional own accessors are rejected. A missing descriptor is valid,
246
+ * but an own non-data property at the key is still hostile input.
247
+ */
177
248
  chunks.push(`if(${descriptor}!==undefined){`, `if(!h.call(${descriptor},"value"))return false;`, `const ${itemValue}=${descriptor}.value;`, `if(!${emitExpression(entry.schema, itemValue, context)})return false;`, `}else if(h.call(${value},${key}))return false;`);
178
249
  }
179
250
  else {
@@ -186,6 +257,9 @@ function emitObjectBody(schema, value, context) {
186
257
  /**
187
258
  * @brief emit strict object key body.
188
259
  * @details Emits a low-allocation known-key check specialized for one object shape.
260
+ * @param schema Object schema with mode and entries.
261
+ * @param value Generated expression for the object value.
262
+ * @param context Shared code-generation context.
189
263
  * @returns Generated strict-key prelude, or an empty string for passthrough objects.
190
264
  */
191
265
  function emitStrictObjectKeyBody(schema, value, context) {
@@ -203,6 +277,10 @@ function emitStrictObjectKeyBody(schema, value, context) {
203
277
  if (comparisons.length === 0) {
204
278
  return `if(Reflect.ownKeys(${value}).length!==0)return false;`;
205
279
  }
280
+ /*
281
+ * Reflect.ownKeys is required for strict objects because symbol and
282
+ * non-enumerable extras are still extras.
283
+ */
206
284
  return [
207
285
  `const xs=Reflect.ownKeys(${value});`,
208
286
  "for(let i=0;i<xs.length;i+=1){",
@@ -214,6 +292,10 @@ function emitStrictObjectKeyBody(schema, value, context) {
214
292
  /**
215
293
  * @brief emit discriminated union body.
216
294
  * @details Emits discriminant selection once and dispatches to branch validators.
295
+ * @param key Discriminant property name.
296
+ * @param cases Closed discriminated union cases.
297
+ * @param value Generated expression for the candidate object.
298
+ * @param context Shared code-generation context.
217
299
  * @returns Generated discriminated-union predicate body.
218
300
  */
219
301
  function emitDiscriminatedUnionBody(key, cases, value, context) {
@@ -237,6 +319,12 @@ function emitDiscriminatedUnionBody(key, cases, value, context) {
237
319
  }
238
320
  /**
239
321
  * @brief emit string.
322
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
323
+ * stable across runtime and AOT emission.
324
+ * @param schema String schema with scalar checks.
325
+ * @param value Generated expression for the candidate value.
326
+ * @param context Shared code-generation context.
327
+ * @returns JavaScript expression for the string predicate.
240
328
  */
241
329
  function emitString(schema, value, context) {
242
330
  const parts = [`(typeof ${value}==="string")`];
@@ -265,13 +353,25 @@ function emitString(schema, value, context) {
265
353
  }
266
354
  /**
267
355
  * @brief emit number.
356
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
357
+ * stable across runtime and AOT emission.
358
+ * @param schema Number schema with scalar checks.
359
+ * @param value Generated expression for the candidate value.
360
+ * @returns JavaScript expression for the number predicate.
268
361
  */
269
362
  function emitNumber(schema, value) {
270
- const parts = [
271
- `(typeof ${value}==="number")`,
272
- `Number.isFinite(${value})`
273
- ];
363
+ const integer = numberChecksRequireInteger(schema.checks);
364
+ const parts = integer
365
+ ? [`Number.isInteger(${value})`]
366
+ : [
367
+ `(typeof ${value}==="number")`,
368
+ `Number.isFinite(${value})`
369
+ ];
274
370
  const checks = schema.checks;
371
+ /*
372
+ * Number.isInteger already proves finite number, so integer schemas avoid
373
+ * emitting a separate typeof/finite pair.
374
+ */
275
375
  for (let index = 0; index < checks.length; index += 1) {
276
376
  const check = checks[index];
277
377
  if (check === undefined) {
@@ -279,7 +379,6 @@ function emitNumber(schema, value) {
279
379
  }
280
380
  switch (check.tag) {
281
381
  case NumberCheckTag.Integer:
282
- parts.push(`Number.isInteger(${value})`);
283
382
  break;
284
383
  case NumberCheckTag.Gte:
285
384
  parts.push(`(${value}>=${String(check.value)})`);
@@ -291,8 +390,29 @@ function emitNumber(schema, value) {
291
390
  }
292
391
  return `(${parts.join("&&")})`;
293
392
  }
393
+ /**
394
+ * @brief Test whether a number schema contains an integer constraint.
395
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
396
+ * stable across runtime and AOT emission.
397
+ * @param checks Number check list.
398
+ * @returns True when Number.isInteger can replace the broader number guard.
399
+ */
400
+ function numberChecksRequireInteger(checks) {
401
+ for (let index = 0; index < checks.length; index += 1) {
402
+ if (checks[index]?.tag === NumberCheckTag.Integer) {
403
+ return true;
404
+ }
405
+ }
406
+ return false;
407
+ }
294
408
  /**
295
409
  * @brief emit union.
410
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
411
+ * stable across runtime and AOT emission.
412
+ * @param options Union option schemas.
413
+ * @param value Generated expression for the candidate value.
414
+ * @param context Shared code-generation context.
415
+ * @returns JavaScript expression for the union predicate.
296
416
  */
297
417
  export function emitUnion(options, value, context) {
298
418
  const parts = [];
@@ -309,6 +429,12 @@ export function emitUnion(options, value, context) {
309
429
  }
310
430
  /**
311
431
  * @brief emit regex.
432
+ * @details Generated-source helpers keep the side-table ABI and JavaScript source shape
433
+ * stable across runtime and AOT emission.
434
+ * @param value Generated expression for the candidate string.
435
+ * @param regex Pattern to test.
436
+ * @param context Shared code-generation context.
437
+ * @returns JavaScript expression that resets lastIndex and tests the regex.
312
438
  */
313
439
  function emitRegex(value, regex, context) {
314
440
  const index = pushRegex(context, regex);