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,13 +1,22 @@
1
1
  import { copyIssueArray, freezeIssueArray, isIssueCodeValue, makeIssue } from "../issue/index.js";
2
2
  import { err } from "../result/index.js";
3
3
  /**
4
- * @brief define messages.
4
+ * @brief Freeze a user catalog after validating its keys and templates.
5
+ * @details Message helpers keep structured issues separate from human-readable formatting
6
+ * until callers request text.
7
+ * @param catalog Partial message catalog supplied by the application.
8
+ * @returns Frozen catalog that can be reused across validations.
5
9
  */
6
10
  export function defineMessages(catalog) {
7
11
  return Object.freeze(copyCatalog(catalog));
8
12
  }
9
13
  /**
10
- * @brief format issue.
14
+ * @brief Render one issue into a localized human-readable message.
15
+ * @details The issue is copied before rendering so user callbacks cannot mutate
16
+ * shared diagnostic objects through accidental aliasing.
17
+ * @param issue Issue object to render.
18
+ * @param options Optional locale, catalog, and path formatter.
19
+ * @returns Rendered message text.
11
20
  */
12
21
  export function formatIssue(issue, options) {
13
22
  const copied = copyIssueArray([issue]);
@@ -18,7 +27,12 @@ export function formatIssue(issue, options) {
18
27
  return renderIssue(first, readOptions(options));
19
28
  }
20
29
  /**
21
- * @brief format issues.
30
+ * @brief Render a frozen list of issues into localized message strings.
31
+ * @details The issue array is copied before rendering so caller-owned issue
32
+ * objects cannot change while user path formatters or templates execute.
33
+ * @param issues Issue list to render.
34
+ * @param options Optional locale, catalog, and path formatter.
35
+ * @returns Frozen list of rendered messages aligned with the input issue order.
22
36
  */
23
37
  export function formatIssues(issues, options) {
24
38
  const copied = copyIssueArray(issues);
@@ -33,7 +47,13 @@ export function formatIssues(issues, options) {
33
47
  return Object.freeze(messages);
34
48
  }
35
49
  /**
36
- * @brief with messages.
50
+ * @brief Attach rendered messages to every issue in a failed check result.
51
+ * @details Successful results are returned unchanged. Failed results are copied
52
+ * into fresh issue objects so structured diagnostics keep their original fields
53
+ * while gaining a stable human-readable message.
54
+ * @param result Check result to decorate.
55
+ * @param options Optional locale, catalog, and path formatter.
56
+ * @returns Original success result or a failed result with rendered messages.
37
57
  */
38
58
  export function withMessages(result, options) {
39
59
  if (result.ok) {
@@ -51,7 +71,13 @@ export function withMessages(result, options) {
51
71
  return err(freezeIssueArray(issues));
52
72
  }
53
73
  /**
54
- * @brief render issue.
74
+ * @brief Select the template source and render one normalized issue.
75
+ * @details Custom catalogs take precedence, issue-local messages are respected
76
+ * next, and built-in catalogs are the final fallback. That order lets adapters
77
+ * inject precise messages without losing defaults.
78
+ * @param issue Issue currently being rendered.
79
+ * @param options Resolved message rendering configuration.
80
+ * @returns Rendered message text.
55
81
  */
56
82
  function renderIssue(issue, options) {
57
83
  const context = makeContext(issue, options.pathFormatter);
@@ -65,7 +91,12 @@ function renderIssue(issue, options) {
65
91
  return renderTemplate(defaultCatalogs[options.locale][issue.code], issue, context);
66
92
  }
67
93
  /**
68
- * @brief make context.
94
+ * @brief Build the stable template context for one issue.
95
+ * @details Missing expected or actual fields become `"unknown"` so templates
96
+ * can stay branch-free and every placeholder always has a string value.
97
+ * @param issue Issue currently being rendered.
98
+ * @param pathFormatter Formatter selected by resolved options.
99
+ * @returns Context object passed to string and function templates.
69
100
  */
70
101
  function makeContext(issue, pathFormatter) {
71
102
  return {
@@ -76,7 +107,14 @@ function makeContext(issue, pathFormatter) {
76
107
  };
77
108
  }
78
109
  /**
79
- * @brief render template.
110
+ * @brief Render a string or callback template against one issue context.
111
+ * @details Function templates are checked at runtime because they cross into
112
+ * user code. String templates use fixed token replacement without regular
113
+ * expressions, keeping the common path allocation pattern predictable.
114
+ * @param template Template selected for this issue code.
115
+ * @param issue Issue currently being rendered.
116
+ * @param context Preformatted replacement context.
117
+ * @returns Rendered message text.
80
118
  */
81
119
  function renderTemplate(template, issue, context) {
82
120
  if (typeof template === "function") {
@@ -93,7 +131,11 @@ function renderTemplate(template, issue, context) {
93
131
  .split("{actual}").join(context.actual);
94
132
  }
95
133
  /**
96
- * @brief read options.
134
+ * @brief Normalize public rendering options into the internal shape.
135
+ * @details Validation happens once at the entry point. The render loop then
136
+ * works with concrete locale and formatter values without repeated guards.
137
+ * @param options Optional user configuration.
138
+ * @returns Resolved message rendering configuration.
97
139
  */
98
140
  function readOptions(options) {
99
141
  if (options === undefined) {
@@ -116,7 +158,11 @@ function readOptions(options) {
116
158
  };
117
159
  }
118
160
  /**
119
- * @brief read locale.
161
+ * @brief Validate and normalize the requested message locale.
162
+ * @details Message helpers keep structured issues separate from human-readable formatting
163
+ * until callers request text.
164
+ * @param value Locale field from the public options object.
165
+ * @returns Built-in locale identifier, defaulting to English.
120
166
  */
121
167
  function readLocale(value) {
122
168
  if (value === undefined || value === "en") {
@@ -128,7 +174,12 @@ function readLocale(value) {
128
174
  throw new TypeError("message locale must be en or ko");
129
175
  }
130
176
  /**
131
- * @brief read path formatter.
177
+ * @brief Validate the optional user path formatter.
178
+ * @details The returned wrapper enforces the string return contract at the
179
+ * boundary where user code is invoked, keeping downstream template replacement
180
+ * code simple.
181
+ * @param value Formatter value from public options.
182
+ * @returns Safe formatter callback used by the renderer.
132
183
  */
133
184
  function readPathFormatter(value) {
134
185
  if (value === undefined) {
@@ -147,7 +198,12 @@ function readPathFormatter(value) {
147
198
  };
148
199
  }
149
200
  /**
150
- * @brief copy catalog.
201
+ * @brief Validate and copy a user message catalog.
202
+ * @details The renderer stores only recognized issue-code keys and accepted
203
+ * template forms. Copying also prevents later caller mutation from changing
204
+ * messages during validation.
205
+ * @param value Candidate catalog object.
206
+ * @returns Catalog copy accepted by the renderer.
151
207
  */
152
208
  function copyCatalog(value) {
153
209
  if (!isRecord(value)) {
@@ -172,13 +228,21 @@ function copyCatalog(value) {
172
228
  return copied;
173
229
  }
174
230
  /**
175
- * @brief is issue message template.
231
+ * @brief Check whether a catalog value is an accepted template form.
232
+ * @details Message helpers keep structured issues separate from human-readable formatting
233
+ * until callers request text.
234
+ * @param value Candidate catalog entry value.
235
+ * @returns True for string templates or formatter functions.
176
236
  */
177
237
  function isIssueMessageTemplate(value) {
178
238
  return typeof value === "string" || typeof value === "function";
179
239
  }
180
240
  /**
181
- * @brief default path formatter.
241
+ * @brief Render a TypeSea issue path using JSON-like bracket segments.
242
+ * @details The root is `$`, numeric segments render as indexes, and string
243
+ * segments are JSON-escaped so dots or brackets in field names stay unambiguous.
244
+ * @param path Issue path to render.
245
+ * @returns Stable path string for message templates.
182
246
  */
183
247
  function defaultPathFormatter(path) {
184
248
  if (path.length === 0) {
@@ -197,13 +261,16 @@ function defaultPathFormatter(path) {
197
261
  return result;
198
262
  }
199
263
  /**
200
- * @brief is record.
264
+ * @brief Check record.
265
+ * @details This helper keeps a local invariant explicit at the module boundary.
201
266
  */
202
267
  function isRecord(value) {
203
268
  return typeof value === "object" && value !== null && !Array.isArray(value);
204
269
  }
205
270
  /**
206
- * @brief en catalog.
271
+ * @brief Built-in English issue message catalog.
272
+ * @details Templates stay terse and token-based so the same renderer can handle
273
+ * built-in and user-defined catalogs without locale-specific code paths.
207
274
  */
208
275
  const enCatalog = Object.freeze({
209
276
  expected_string: "Expected string at {path}; received {actual}.",
@@ -232,7 +299,9 @@ const enCatalog = Object.freeze({
232
299
  unrecognized_key: "Unrecognized key at {path}; expected {expected}."
233
300
  });
234
301
  /**
235
- * @brief ko catalog.
302
+ * @brief Built-in Korean issue message catalog.
303
+ * @details The catalog mirrors English issue-code coverage exactly so locale
304
+ * switching cannot expose missing template keys at runtime.
236
305
  */
237
306
  const koCatalog = Object.freeze({
238
307
  expected_string: "{path}에서 문자열이 필요하지만 {actual}을 받았습니다.",
@@ -261,7 +330,9 @@ const koCatalog = Object.freeze({
261
330
  unrecognized_key: "{path}에서 알 수 없는 키입니다. 기대값은 {expected}입니다."
262
331
  });
263
332
  /**
264
- * @brief default catalogs.
333
+ * @brief Frozen lookup table for built-in message catalogs.
334
+ * @details The table is keyed by normalized locale values, letting renderIssue
335
+ * index without optional fallback logic after option resolution.
265
336
  */
266
337
  const defaultCatalogs = Object.freeze({
267
338
  en: enCatalog,
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @file algebraic.ts
3
+ * @brief Boolean algebra simplification for validation predicates.
4
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
5
+ * before code generation consumes the graph.
6
+ */
7
+ import { NodeTag } from "../kind/index.js";
8
+ import type { GraphNode, NodeId } from "../ir/index.js";
9
+ export interface AlgebraicFold {
10
+ /**
11
+ * @brief True when an And fold has proven false.
12
+ * @details The caller replaces the whole conjunction with a constant false node.
13
+ */
14
+ readonly contradiction: boolean;
15
+ /**
16
+ * @brief True when an Or fold has proven true.
17
+ * @details The caller replaces the whole disjunction with a constant true node.
18
+ */
19
+ readonly tautology: boolean;
20
+ /**
21
+ * @brief Remaining operand ids after algebraic simplification.
22
+ * @details Operand order is preserved so generated code keeps stable branch ordering.
23
+ */
24
+ readonly values: readonly NodeId[];
25
+ }
26
+ /**
27
+ * @brief Flatten nested boolean folds of the same kind.
28
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
29
+ * before code generation consumes the graph.
30
+ * @param values Input operand ids.
31
+ * @param nodes Graph node table used to inspect nested folds.
32
+ * @param tag Boolean fold kind to flatten.
33
+ * @returns Operand list with same-kind nested folds expanded in place.
34
+ */
35
+ export declare function flattenBooleanValues(values: readonly NodeId[], nodes: readonly GraphNode[], tag: typeof NodeTag.And | typeof NodeTag.Or): readonly NodeId[];
36
+ /**
37
+ * @brief Simplify operands of an And fold.
38
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
39
+ * before code generation consumes the graph.
40
+ * @param values Input operand ids.
41
+ * @param nodes Graph node table used to inspect nested complement forms.
42
+ * @returns Simplification result with contradiction status and kept operands.
43
+ */
44
+ export declare function simplifyAndValues(values: readonly NodeId[], nodes: readonly GraphNode[]): AlgebraicFold;
45
+ /**
46
+ * @brief Simplify operands of an Or fold.
47
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
48
+ * before code generation consumes the graph.
49
+ * @param values Input operand ids.
50
+ * @param nodes Graph node table used to inspect nested complement forms.
51
+ * @returns Simplification result with tautology status and kept operands.
52
+ */
53
+ export declare function simplifyOrValues(values: readonly NodeId[], nodes: readonly GraphNode[]): AlgebraicFold;
54
+ //# sourceMappingURL=algebraic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"algebraic.d.ts","sourceRoot":"","sources":["../../src/optimize/algebraic.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,EACR,SAAS,EACT,MAAM,EACT,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,aAAa;IAC1B;;;OAGG;IACH,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAEhC;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAChC,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,GAAG,EAAE,OAAO,OAAO,CAAC,GAAG,GAAG,OAAO,OAAO,CAAC,EAAE,GAC5C,SAAS,MAAM,EAAE,CAmBnB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,SAAS,SAAS,EAAE,GAC5B,aAAa,CAuCf;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC5B,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,SAAS,SAAS,EAAE,GAC5B,aAAa,CAuCf"}
@@ -0,0 +1,314 @@
1
+ /**
2
+ * @file algebraic.ts
3
+ * @brief Boolean algebra simplification for validation predicates.
4
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
5
+ * before code generation consumes the graph.
6
+ */
7
+ import { NodeTag } from "../kind/index.js";
8
+ /**
9
+ * @brief Flatten nested boolean folds of the same kind.
10
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
11
+ * before code generation consumes the graph.
12
+ * @param values Input operand ids.
13
+ * @param nodes Graph node table used to inspect nested folds.
14
+ * @param tag Boolean fold kind to flatten.
15
+ * @returns Operand list with same-kind nested folds expanded in place.
16
+ */
17
+ export function flattenBooleanValues(values, nodes, tag) {
18
+ const flattened = [];
19
+ for (let index = 0; index < values.length; index += 1) {
20
+ const value = values[index];
21
+ if (value === undefined) {
22
+ continue;
23
+ }
24
+ const node = nodes[value];
25
+ if (node?.tag === tag) {
26
+ /*
27
+ * And(And(a,b),c) and Or(Or(a,b),c) are associative. Flattening
28
+ * reduces later duplicate and complement checks to one linear pass.
29
+ */
30
+ appendFlattenedBooleanValues(flattened, node.values, nodes, tag);
31
+ }
32
+ else {
33
+ flattened.push(value);
34
+ }
35
+ }
36
+ return flattened;
37
+ }
38
+ /**
39
+ * @brief Simplify operands of an And fold.
40
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
41
+ * before code generation consumes the graph.
42
+ * @param values Input operand ids.
43
+ * @param nodes Graph node table used to inspect nested complement forms.
44
+ * @returns Simplification result with contradiction status and kept operands.
45
+ */
46
+ export function simplifyAndValues(values, nodes) {
47
+ const kept = [];
48
+ const seen = new Set();
49
+ const positive = new Set();
50
+ const negative = new Set();
51
+ for (let index = 0; index < values.length; index += 1) {
52
+ const value = values[index];
53
+ if (value === undefined || seen.has(value)) {
54
+ continue;
55
+ }
56
+ if (isAbsorbedAndValue(value, nodes, seen)) {
57
+ /*
58
+ * a && (a || b) is equivalent to a. The Or branch cannot make the
59
+ * validation stricter once the shared value is already required.
60
+ */
61
+ continue;
62
+ }
63
+ if (hasComplementConflict(value, nodes, positive, negative)) {
64
+ /*
65
+ * a && !a is impossible for side-effect-free predicate nodes. Only
66
+ * complement-safe nodes are allowed into the positive/negative sets.
67
+ */
68
+ return {
69
+ contradiction: true,
70
+ tautology: false,
71
+ values: []
72
+ };
73
+ }
74
+ rememberComplementValue(value, nodes, positive, negative);
75
+ seen.add(value);
76
+ kept.push(value);
77
+ }
78
+ return {
79
+ contradiction: false,
80
+ tautology: false,
81
+ values: kept
82
+ };
83
+ }
84
+ /**
85
+ * @brief Simplify operands of an Or fold.
86
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
87
+ * before code generation consumes the graph.
88
+ * @param values Input operand ids.
89
+ * @param nodes Graph node table used to inspect nested complement forms.
90
+ * @returns Simplification result with tautology status and kept operands.
91
+ */
92
+ export function simplifyOrValues(values, nodes) {
93
+ const kept = [];
94
+ const seen = new Set();
95
+ const positive = new Set();
96
+ const negative = new Set();
97
+ for (let index = 0; index < values.length; index += 1) {
98
+ const value = values[index];
99
+ if (value === undefined || seen.has(value)) {
100
+ continue;
101
+ }
102
+ if (isAbsorbedOrValue(value, nodes, seen)) {
103
+ /*
104
+ * a || (a && b) is equivalent to a. The And branch cannot widen the
105
+ * accepted set once the shared value already passes.
106
+ */
107
+ continue;
108
+ }
109
+ if (hasComplementConflict(value, nodes, positive, negative)) {
110
+ /*
111
+ * a || !a is always true for complement-safe predicates, so the Or
112
+ * fold can collapse to a tautology.
113
+ */
114
+ return {
115
+ contradiction: false,
116
+ tautology: true,
117
+ values: []
118
+ };
119
+ }
120
+ rememberComplementValue(value, nodes, positive, negative);
121
+ seen.add(value);
122
+ kept.push(value);
123
+ }
124
+ return {
125
+ contradiction: false,
126
+ tautology: false,
127
+ values: kept
128
+ };
129
+ }
130
+ /**
131
+ * @brief Recursively append flattened operands.
132
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
133
+ * before code generation consumes the graph.
134
+ * @param output Destination operand list.
135
+ * @param values Source operand ids.
136
+ * @param nodes Graph node table used to inspect nested folds.
137
+ * @param tag Boolean fold kind to flatten.
138
+ */
139
+ function appendFlattenedBooleanValues(output, values, nodes, tag) {
140
+ for (let index = 0; index < values.length; index += 1) {
141
+ const value = values[index];
142
+ if (value === undefined) {
143
+ continue;
144
+ }
145
+ const node = nodes[value];
146
+ if (node?.tag === tag) {
147
+ appendFlattenedBooleanValues(output, node.values, nodes, tag);
148
+ }
149
+ else {
150
+ output.push(value);
151
+ }
152
+ }
153
+ }
154
+ /**
155
+ * @brief Test And absorption for `a && (a || b)`.
156
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
157
+ * before code generation consumes the graph.
158
+ * @param value Candidate operand id.
159
+ * @param nodes Graph node table.
160
+ * @param seen Operands already kept by the parent And.
161
+ * @returns True when the candidate is redundant.
162
+ */
163
+ function isAbsorbedAndValue(value, nodes, seen) {
164
+ const node = nodes[value];
165
+ if (node?.tag !== NodeTag.Or) {
166
+ return false;
167
+ }
168
+ return containsSeenValue(node.values, seen);
169
+ }
170
+ /**
171
+ * @brief Test Or absorption for `a || (a && b)`.
172
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
173
+ * before code generation consumes the graph.
174
+ * @param value Candidate operand id.
175
+ * @param nodes Graph node table.
176
+ * @param seen Operands already kept by the parent Or.
177
+ * @returns True when the candidate is redundant.
178
+ */
179
+ function isAbsorbedOrValue(value, nodes, seen) {
180
+ const node = nodes[value];
181
+ if (node?.tag !== NodeTag.And) {
182
+ return false;
183
+ }
184
+ return containsSeenValue(node.values, seen);
185
+ }
186
+ /**
187
+ * @brief Test whether a nested fold contains an operand already kept.
188
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
189
+ * before code generation consumes the graph.
190
+ * @param values Nested fold operand ids.
191
+ * @param seen Parent fold operands already kept.
192
+ * @returns True when the nested fold repeats a kept operand.
193
+ */
194
+ function containsSeenValue(values, seen) {
195
+ for (let index = 0; index < values.length; index += 1) {
196
+ const value = values[index];
197
+ if (value !== undefined && seen.has(value)) {
198
+ return true;
199
+ }
200
+ }
201
+ return false;
202
+ }
203
+ /**
204
+ * @brief Detect a positive/negative complement conflict.
205
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
206
+ * before code generation consumes the graph.
207
+ * @param value Candidate operand id.
208
+ * @param nodes Graph node table.
209
+ * @param positive Complement-safe positive operands already seen.
210
+ * @param negative Complement-safe negated operands already seen.
211
+ * @returns True when the candidate conflicts with prior operands.
212
+ */
213
+ function hasComplementConflict(value, nodes, positive, negative) {
214
+ const negated = readNegatedValue(value, nodes);
215
+ if (negated !== undefined) {
216
+ return isComplementSafe(negated, nodes) && positive.has(negated);
217
+ }
218
+ return isComplementSafe(value, nodes) && negative.has(value);
219
+ }
220
+ /**
221
+ * @brief Record a complement-safe operand in positive or negative form.
222
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
223
+ * before code generation consumes the graph.
224
+ * @param value Candidate operand id.
225
+ * @param nodes Graph node table.
226
+ * @param positive Mutable set for positive operands.
227
+ * @param negative Mutable set for negated operands.
228
+ */
229
+ function rememberComplementValue(value, nodes, positive, negative) {
230
+ const negated = readNegatedValue(value, nodes);
231
+ if (negated !== undefined) {
232
+ if (isComplementSafe(negated, nodes)) {
233
+ negative.add(negated);
234
+ }
235
+ return;
236
+ }
237
+ if (isComplementSafe(value, nodes)) {
238
+ positive.add(value);
239
+ }
240
+ }
241
+ /**
242
+ * @brief Read the operand of a Not node.
243
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
244
+ * before code generation consumes the graph.
245
+ * @param value Candidate node id.
246
+ * @param nodes Graph node table.
247
+ * @returns Inner node id for Not, otherwise undefined.
248
+ */
249
+ function readNegatedValue(value, nodes) {
250
+ const node = nodes[value];
251
+ return node?.tag === NodeTag.Not ? node.value : undefined;
252
+ }
253
+ /**
254
+ * @brief Decide whether a node is safe for complement algebra.
255
+ * @details Only pure structural predicates are allowed. Nodes that inspect user
256
+ * predicates or nested graph execution stay out of `a`/`!a` folding.
257
+ * @param value Candidate node id.
258
+ * @param nodes Graph node table.
259
+ * @returns True when complement laws can be applied to the node.
260
+ */
261
+ function isComplementSafe(value, nodes) {
262
+ const node = nodes[value];
263
+ if (node === undefined) {
264
+ return false;
265
+ }
266
+ switch (node.tag) {
267
+ case NodeTag.Const:
268
+ return typeof node.value === "boolean";
269
+ case NodeTag.IsString:
270
+ case NodeTag.IsNumber:
271
+ case NodeTag.IsBoolean:
272
+ case NodeTag.IsBigInt:
273
+ case NodeTag.IsSymbol:
274
+ case NodeTag.IsObject:
275
+ case NodeTag.IsArray:
276
+ case NodeTag.IsUndefined:
277
+ case NodeTag.IsNull:
278
+ case NodeTag.IsInteger:
279
+ case NodeTag.Equals:
280
+ case NodeTag.Gte:
281
+ case NodeTag.Lte:
282
+ case NodeTag.StringMin:
283
+ case NodeTag.StringMax:
284
+ case NodeTag.Regex:
285
+ case NodeTag.HasOwn:
286
+ case NodeTag.HasOwnData:
287
+ case NodeTag.StrictKeys:
288
+ return true;
289
+ case NodeTag.Not:
290
+ return isComplementSafe(node.value, nodes);
291
+ case NodeTag.And:
292
+ case NodeTag.Or:
293
+ return areComplementSafeValues(node.values, nodes);
294
+ default:
295
+ return false;
296
+ }
297
+ }
298
+ /**
299
+ * @brief Decide whether every value in a boolean fold is complement-safe.
300
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
301
+ * before code generation consumes the graph.
302
+ * @param values Operand ids from a nested fold.
303
+ * @param nodes Graph node table.
304
+ * @returns True when the whole nested fold can participate in complement laws.
305
+ */
306
+ function areComplementSafeValues(values, nodes) {
307
+ for (let index = 0; index < values.length; index += 1) {
308
+ const value = values[index];
309
+ if (value === undefined || !isComplementSafe(value, nodes)) {
310
+ return false;
311
+ }
312
+ }
313
+ return true;
314
+ }
@@ -1,10 +1,17 @@
1
1
  /**
2
2
  * @file compact.ts
3
3
  * @brief Reachability compaction for optimized graphs.
4
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
5
+ * before code generation consumes the graph.
4
6
  */
5
7
  import type { Graph } from "../ir/index.js";
6
8
  /**
7
- * @brief compact reachable.
9
+ * @brief Remove unreachable IR nodes and remap the remaining node ids densely.
10
+ * @details Earlier optimizer passes may leave replaced nodes in the arena so
11
+ * alias bookkeeping stays simple. This pass is the boundary that rewrites the
12
+ * graph back into the dense id space expected by codegen and public graph reads.
13
+ * @param graph Graph produced by earlier optimizer passes.
14
+ * @returns Graph containing only nodes reachable from entry and result.
8
15
  */
9
16
  export declare function compactReachable(graph: Graph): Graph;
10
17
  //# sourceMappingURL=compact.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compact.d.ts","sourceRoot":"","sources":["../../src/optimize/compact.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAqB,MAAM,gBAAgB,CAAC;AAG/D;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAyBpD"}
1
+ {"version":3,"file":"compact.d.ts","sourceRoot":"","sources":["../../src/optimize/compact.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAqB,MAAM,gBAAgB,CAAC;AAG/D;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAyBpD"}
@@ -1,10 +1,17 @@
1
1
  /**
2
2
  * @file compact.ts
3
3
  * @brief Reachability compaction for optimized graphs.
4
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
5
+ * before code generation consumes the graph.
4
6
  */
5
7
  import { remapId, remapNode } from "./remap.js";
6
8
  /**
7
- * @brief compact reachable.
9
+ * @brief Remove unreachable IR nodes and remap the remaining node ids densely.
10
+ * @details Earlier optimizer passes may leave replaced nodes in the arena so
11
+ * alias bookkeeping stays simple. This pass is the boundary that rewrites the
12
+ * graph back into the dense id space expected by codegen and public graph reads.
13
+ * @param graph Graph produced by earlier optimizer passes.
14
+ * @returns Graph containing only nodes reachable from entry and result.
8
15
  */
9
16
  export function compactReachable(graph) {
10
17
  const reachable = markReachable(graph);
@@ -33,7 +40,11 @@ export function compactReachable(graph) {
33
40
  };
34
41
  }
35
42
  /**
36
- * @brief mark reachable.
43
+ * @brief Mark graph nodes reachable from the entry and result roots.
44
+ * @details The scan walks dependency edges with an explicit stack to avoid
45
+ * recursion limits on large generated schemas.
46
+ * @param graph Graph to scan.
47
+ * @returns Boolean reachability bitmap aligned with the original node table.
37
48
  */
38
49
  function markReachable(graph) {
39
50
  const reachable = new Array(graph.nodes.length).fill(false);
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @file domain.ts
3
+ * @brief Validation-domain specialization for dispatch child graphs.
4
+ * @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
5
+ * before code generation consumes the graph.
6
+ */
7
+ import type { Graph } from "../ir/index.js";
8
+ /**
9
+ * @brief Specialize nested validation graphs with domain knowledge.
10
+ * @details Dispatch nodes already know the primitive domain of each child arm.
11
+ * This pass pushes that fact into child graphs so redundant type checks collapse.
12
+ * @param graph Root graph to specialize.
13
+ * @returns The original graph when no node changed, otherwise a rewritten graph.
14
+ */
15
+ export declare function specializeDomains(graph: Graph): Graph;
16
+ //# sourceMappingURL=domain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../src/optimize/domain.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAER,KAAK,EAIR,MAAM,gBAAgB,CAAC;AAiDxB;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAsBrD"}