typesea 0.1.0 → 0.3.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 (301) hide show
  1. package/CHANGELOG.md +85 -6
  2. package/README.md +143 -28
  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 +19 -3
  7. package/dist/aot/index.d.ts.map +1 -1
  8. package/dist/aot/index.js +115 -17
  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 +43 -9
  13. package/dist/builders/composite.d.ts.map +1 -1
  14. package/dist/builders/composite.js +100 -17
  15. package/dist/builders/index.d.ts +8 -5
  16. package/dist/builders/index.d.ts.map +1 -1
  17. package/dist/builders/index.js +7 -4
  18. package/dist/builders/modifier.d.ts +36 -5
  19. package/dist/builders/modifier.d.ts.map +1 -1
  20. package/dist/builders/modifier.js +52 -5
  21. package/dist/builders/object/guard.d.ts +72 -24
  22. package/dist/builders/object/guard.d.ts.map +1 -1
  23. package/dist/builders/object/guard.js +139 -29
  24. package/dist/builders/object/index.d.ts +4 -2
  25. package/dist/builders/object/index.d.ts.map +1 -1
  26. package/dist/builders/object/index.js +3 -1
  27. package/dist/builders/object/schema.d.ts +88 -11
  28. package/dist/builders/object/schema.d.ts.map +1 -1
  29. package/dist/builders/object/schema.js +290 -23
  30. package/dist/builders/object/types.d.ts +20 -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/runtime.d.ts +40 -0
  34. package/dist/builders/runtime.d.ts.map +1 -0
  35. package/dist/builders/runtime.js +150 -0
  36. package/dist/builders/scalar.d.ts +49 -9
  37. package/dist/builders/scalar.d.ts.map +1 -1
  38. package/dist/builders/scalar.js +87 -9
  39. package/dist/builders/table.d.ts +35 -5
  40. package/dist/builders/table.d.ts.map +1 -1
  41. package/dist/builders/table.js +35 -5
  42. package/dist/builders/types.d.ts +20 -4
  43. package/dist/builders/types.d.ts.map +1 -1
  44. package/dist/builders/types.js +2 -0
  45. package/dist/compile/check-composite.d.ts +25 -2
  46. package/dist/compile/check-composite.d.ts.map +1 -1
  47. package/dist/compile/check-composite.js +699 -27
  48. package/dist/compile/check-scalar.d.ts +88 -0
  49. package/dist/compile/check-scalar.d.ts.map +1 -1
  50. package/dist/compile/check-scalar.js +570 -3
  51. package/dist/compile/check.d.ts +12 -0
  52. package/dist/compile/check.d.ts.map +1 -1
  53. package/dist/compile/check.js +62 -3
  54. package/dist/compile/context.d.ts +47 -9
  55. package/dist/compile/context.d.ts.map +1 -1
  56. package/dist/compile/context.js +53 -8
  57. package/dist/compile/first.d.ts +26 -0
  58. package/dist/compile/first.d.ts.map +1 -0
  59. package/dist/compile/first.js +850 -0
  60. package/dist/compile/graph-predicate.d.ts +4 -2
  61. package/dist/compile/graph-predicate.d.ts.map +1 -1
  62. package/dist/compile/graph-predicate.js +2272 -165
  63. package/dist/compile/guard.d.ts +16 -24
  64. package/dist/compile/guard.d.ts.map +1 -1
  65. package/dist/compile/guard.js +202 -72
  66. package/dist/compile/index.d.ts +3 -1
  67. package/dist/compile/index.d.ts.map +1 -1
  68. package/dist/compile/index.js +2 -0
  69. package/dist/compile/issue.d.ts +110 -0
  70. package/dist/compile/issue.d.ts.map +1 -1
  71. package/dist/compile/issue.js +184 -1
  72. package/dist/compile/names.d.ts +12 -2
  73. package/dist/compile/names.d.ts.map +1 -1
  74. package/dist/compile/names.js +19 -3
  75. package/dist/compile/predicate.d.ts +24 -0
  76. package/dist/compile/predicate.d.ts.map +1 -1
  77. package/dist/compile/predicate.js +287 -10
  78. package/dist/compile/runtime.d.ts +100 -13
  79. package/dist/compile/runtime.d.ts.map +1 -1
  80. package/dist/compile/runtime.js +56 -6
  81. package/dist/compile/source.d.ts +10 -2
  82. package/dist/compile/source.d.ts.map +1 -1
  83. package/dist/compile/source.js +385 -26
  84. package/dist/compile/types.d.ts +22 -0
  85. package/dist/compile/types.d.ts.map +1 -1
  86. package/dist/compile/types.js +2 -0
  87. package/dist/decoder/index.d.ts +92 -46
  88. package/dist/decoder/index.d.ts.map +1 -1
  89. package/dist/decoder/index.js +266 -39
  90. package/dist/evaluate/check-composite.d.ts +111 -2
  91. package/dist/evaluate/check-composite.d.ts.map +1 -1
  92. package/dist/evaluate/check-composite.js +343 -8
  93. package/dist/evaluate/check-scalar.d.ts +25 -0
  94. package/dist/evaluate/check-scalar.d.ts.map +1 -1
  95. package/dist/evaluate/check-scalar.js +124 -3
  96. package/dist/evaluate/check.d.ts +7 -0
  97. package/dist/evaluate/check.d.ts.map +1 -1
  98. package/dist/evaluate/check.js +62 -4
  99. package/dist/evaluate/index.d.ts +2 -0
  100. package/dist/evaluate/index.d.ts.map +1 -1
  101. package/dist/evaluate/index.js +2 -0
  102. package/dist/evaluate/issue.d.ts +11 -1
  103. package/dist/evaluate/issue.d.ts.map +1 -1
  104. package/dist/evaluate/issue.js +15 -1
  105. package/dist/evaluate/predicate.d.ts +16 -5
  106. package/dist/evaluate/predicate.d.ts.map +1 -1
  107. package/dist/evaluate/predicate.js +20 -5
  108. package/dist/evaluate/shared.d.ts +78 -13
  109. package/dist/evaluate/shared.d.ts.map +1 -1
  110. package/dist/evaluate/shared.js +101 -8
  111. package/dist/evaluate/state.d.ts +35 -13
  112. package/dist/evaluate/state.d.ts.map +1 -1
  113. package/dist/evaluate/state.js +35 -2
  114. package/dist/guard/array.d.ts +48 -0
  115. package/dist/guard/array.d.ts.map +1 -0
  116. package/dist/guard/array.js +84 -0
  117. package/dist/guard/base.d.ts +111 -31
  118. package/dist/guard/base.d.ts.map +1 -1
  119. package/dist/guard/base.js +165 -32
  120. package/dist/guard/date.d.ts +34 -0
  121. package/dist/guard/date.d.ts.map +1 -0
  122. package/dist/guard/date.js +60 -0
  123. package/dist/guard/error.d.ts +10 -5
  124. package/dist/guard/error.d.ts.map +1 -1
  125. package/dist/guard/error.js +10 -5
  126. package/dist/guard/index.d.ts +4 -0
  127. package/dist/guard/index.d.ts.map +1 -1
  128. package/dist/guard/index.js +4 -0
  129. package/dist/guard/number.d.ts +86 -11
  130. package/dist/guard/number.d.ts.map +1 -1
  131. package/dist/guard/number.js +159 -11
  132. package/dist/guard/props.d.ts +27 -3
  133. package/dist/guard/props.d.ts.map +1 -1
  134. package/dist/guard/props.js +27 -3
  135. package/dist/guard/read.d.ts +115 -10
  136. package/dist/guard/read.d.ts.map +1 -1
  137. package/dist/guard/read.js +185 -10
  138. package/dist/guard/registry.d.ts +12 -2
  139. package/dist/guard/registry.d.ts.map +1 -1
  140. package/dist/guard/registry.js +15 -3
  141. package/dist/guard/string.d.ts +115 -13
  142. package/dist/guard/string.d.ts.map +1 -1
  143. package/dist/guard/string.js +250 -13
  144. package/dist/guard/types.d.ts +110 -40
  145. package/dist/guard/types.d.ts.map +1 -1
  146. package/dist/guard/types.js +2 -0
  147. package/dist/index.d.ts +5 -5
  148. package/dist/index.d.ts.map +1 -1
  149. package/dist/index.js +4 -4
  150. package/dist/internal/index.d.ts +42 -6
  151. package/dist/internal/index.d.ts.map +1 -1
  152. package/dist/internal/index.js +51 -8
  153. package/dist/ir/builder.d.ts +17 -127
  154. package/dist/ir/builder.d.ts.map +1 -1
  155. package/dist/ir/builder.js +80 -137
  156. package/dist/ir/freeze.d.ts +4 -0
  157. package/dist/ir/freeze.d.ts.map +1 -1
  158. package/dist/ir/freeze.js +66 -0
  159. package/dist/ir/index.d.ts +3 -1
  160. package/dist/ir/index.d.ts.map +1 -1
  161. package/dist/ir/index.js +2 -0
  162. package/dist/ir/regexp.d.ts +2 -0
  163. package/dist/ir/regexp.d.ts.map +1 -1
  164. package/dist/ir/regexp.js +2 -0
  165. package/dist/ir/types.d.ts +94 -56
  166. package/dist/ir/types.d.ts.map +1 -1
  167. package/dist/ir/types.js +2 -0
  168. package/dist/ir/validate.d.ts +8 -1
  169. package/dist/ir/validate.d.ts.map +1 -1
  170. package/dist/ir/validate.js +511 -61
  171. package/dist/issue/index.d.ts +42 -10
  172. package/dist/issue/index.d.ts.map +1 -1
  173. package/dist/issue/index.js +65 -11
  174. package/dist/json-schema/emit-combinator.d.ts +44 -4
  175. package/dist/json-schema/emit-combinator.d.ts.map +1 -1
  176. package/dist/json-schema/emit-combinator.js +44 -4
  177. package/dist/json-schema/emit-composite.d.ts +16 -2
  178. package/dist/json-schema/emit-composite.d.ts.map +1 -1
  179. package/dist/json-schema/emit-composite.js +81 -13
  180. package/dist/json-schema/emit-scalar.d.ts +26 -3
  181. package/dist/json-schema/emit-scalar.d.ts.map +1 -1
  182. package/dist/json-schema/emit-scalar.js +124 -10
  183. package/dist/json-schema/emit-types.d.ts +11 -1
  184. package/dist/json-schema/emit-types.d.ts.map +1 -1
  185. package/dist/json-schema/emit-types.js +2 -0
  186. package/dist/json-schema/emit.d.ts +12 -1
  187. package/dist/json-schema/emit.d.ts.map +1 -1
  188. package/dist/json-schema/emit.js +23 -3
  189. package/dist/json-schema/freeze.d.ts +13 -2
  190. package/dist/json-schema/freeze.d.ts.map +1 -1
  191. package/dist/json-schema/freeze.js +41 -8
  192. package/dist/json-schema/index.d.ts +16 -2
  193. package/dist/json-schema/index.d.ts.map +1 -1
  194. package/dist/json-schema/index.js +23 -3
  195. package/dist/json-schema/issue.d.ts +4 -1
  196. package/dist/json-schema/issue.d.ts.map +1 -1
  197. package/dist/json-schema/issue.js +4 -1
  198. package/dist/json-schema/read.d.ts +24 -3
  199. package/dist/json-schema/read.d.ts.map +1 -1
  200. package/dist/json-schema/read.js +59 -12
  201. package/dist/json-schema/types.d.ts +45 -16
  202. package/dist/json-schema/types.d.ts.map +1 -1
  203. package/dist/json-schema/types.js +2 -0
  204. package/dist/kind/index.d.ts +40 -28
  205. package/dist/kind/index.d.ts.map +1 -1
  206. package/dist/kind/index.js +41 -13
  207. package/dist/lower/index.d.ts +6 -1
  208. package/dist/lower/index.d.ts.map +1 -1
  209. package/dist/lower/index.js +462 -46
  210. package/dist/message/index.d.ts +64 -10
  211. package/dist/message/index.d.ts.map +1 -1
  212. package/dist/message/index.js +155 -17
  213. package/dist/optimize/algebraic.d.ts +54 -0
  214. package/dist/optimize/algebraic.d.ts.map +1 -0
  215. package/dist/optimize/algebraic.js +314 -0
  216. package/dist/optimize/compact.d.ts +8 -1
  217. package/dist/optimize/compact.d.ts.map +1 -1
  218. package/dist/optimize/compact.js +13 -2
  219. package/dist/optimize/domain.d.ts +16 -0
  220. package/dist/optimize/domain.d.ts.map +1 -0
  221. package/dist/optimize/domain.js +619 -0
  222. package/dist/optimize/fold-boolean.d.ts +17 -2
  223. package/dist/optimize/fold-boolean.d.ts.map +1 -1
  224. package/dist/optimize/fold-boolean.js +59 -14
  225. package/dist/optimize/fold-common.d.ts +43 -8
  226. package/dist/optimize/fold-common.d.ts.map +1 -1
  227. package/dist/optimize/fold-common.js +37 -6
  228. package/dist/optimize/fold-constraints.d.ts +33 -0
  229. package/dist/optimize/fold-constraints.d.ts.map +1 -0
  230. package/dist/optimize/fold-constraints.js +484 -0
  231. package/dist/optimize/fold-scalar.d.ts +98 -13
  232. package/dist/optimize/fold-scalar.d.ts.map +1 -1
  233. package/dist/optimize/fold-scalar.js +98 -13
  234. package/dist/optimize/fold.d.ts +8 -1
  235. package/dist/optimize/fold.d.ts.map +1 -1
  236. package/dist/optimize/fold.js +22 -2
  237. package/dist/optimize/index.d.ts +9 -1
  238. package/dist/optimize/index.d.ts.map +1 -1
  239. package/dist/optimize/index.js +18 -3
  240. package/dist/optimize/map-node.d.ts +3 -1
  241. package/dist/optimize/map-node.d.ts.map +1 -1
  242. package/dist/optimize/map-node.js +48 -3
  243. package/dist/optimize/peephole.d.ts +16 -0
  244. package/dist/optimize/peephole.d.ts.map +1 -0
  245. package/dist/optimize/peephole.js +254 -0
  246. package/dist/optimize/remap.d.ts +2 -0
  247. package/dist/optimize/remap.d.ts.map +1 -1
  248. package/dist/optimize/remap.js +2 -0
  249. package/dist/optimize/rewrite.d.ts +13 -8
  250. package/dist/optimize/rewrite.d.ts.map +1 -1
  251. package/dist/optimize/rewrite.js +13 -8
  252. package/dist/plan/cache.d.ts +9 -3
  253. package/dist/plan/cache.d.ts.map +1 -1
  254. package/dist/plan/cache.js +34 -6
  255. package/dist/plan/index.d.ts +2 -0
  256. package/dist/plan/index.d.ts.map +1 -1
  257. package/dist/plan/index.js +2 -0
  258. package/dist/plan/predicate.d.ts +2 -0
  259. package/dist/plan/predicate.d.ts.map +1 -1
  260. package/dist/plan/predicate.js +298 -29
  261. package/dist/plan/schema-predicate.d.ts +6 -0
  262. package/dist/plan/schema-predicate.d.ts.map +1 -1
  263. package/dist/plan/schema-predicate.js +382 -19
  264. package/dist/plan/types.d.ts +2 -0
  265. package/dist/plan/types.d.ts.map +1 -1
  266. package/dist/plan/types.js +2 -0
  267. package/dist/result/index.d.ts +19 -5
  268. package/dist/result/index.d.ts.map +1 -1
  269. package/dist/result/index.js +10 -2
  270. package/dist/schema/common.d.ts +69 -6
  271. package/dist/schema/common.d.ts.map +1 -1
  272. package/dist/schema/common.js +104 -10
  273. package/dist/schema/freeze.d.ts +4 -0
  274. package/dist/schema/freeze.d.ts.map +1 -1
  275. package/dist/schema/freeze.js +40 -0
  276. package/dist/schema/index.d.ts +5 -2
  277. package/dist/schema/index.d.ts.map +1 -1
  278. package/dist/schema/index.js +4 -1
  279. package/dist/schema/lazy.d.ts +4 -0
  280. package/dist/schema/lazy.d.ts.map +1 -1
  281. package/dist/schema/lazy.js +4 -0
  282. package/dist/schema/literal.d.ts +7 -1
  283. package/dist/schema/literal.d.ts.map +1 -1
  284. package/dist/schema/literal.js +7 -1
  285. package/dist/schema/types.d.ts +109 -100
  286. package/dist/schema/types.d.ts.map +1 -1
  287. package/dist/schema/types.js +13 -2
  288. package/dist/schema/undefined.d.ts +17 -0
  289. package/dist/schema/undefined.d.ts.map +1 -0
  290. package/dist/schema/undefined.js +77 -0
  291. package/dist/schema/validate.d.ts +8 -1
  292. package/dist/schema/validate.d.ts.map +1 -1
  293. package/dist/schema/validate.js +255 -57
  294. package/docs/api.md +128 -8
  295. package/docs/assets/benchmark-headline.svg +163 -0
  296. package/docs/engine-notes.md +62 -15
  297. package/docs/index.html +1340 -702
  298. package/docs/ko/api.md +375 -0
  299. package/docs/ko/engine-notes.md +156 -0
  300. package/docs/ko/readme.md +378 -0
  301. package/package.json +66 -65
@@ -1,12 +1,16 @@
1
1
  /**
2
2
  * @file schema-predicate.ts
3
3
  * @brief Schema-specialized predicate kernels for validation plans.
4
+ * @details Plan helpers keep schema-specialized execution aligned with optimized IR while
5
+ * preserving interpreter parity.
4
6
  */
5
- import { NumberCheckTag, ObjectModeTag, PresenceTag, SchemaTag, StringCheckTag } from "../kind/index.js";
6
- import { UUID_PATTERN, resolveLazySchema } from "../schema/index.js";
7
- import { findDiscriminatedUnionCase, hasObjectKey, isDataPropertyDescriptor, isPlainRecord, readOwnDataProperty } from "../evaluate/shared.js";
7
+ import { ArrayCheckTag, DateCheckTag, NumberCheckTag, ObjectModeTag, PresenceTag, SchemaTag, StringCheckTag } from "../kind/index.js";
8
+ import { EMAIL_PATTERN, IPV4_PATTERN, IPV6_PATTERN, ISO_DATETIME_PATTERN, ISO_DATE_PATTERN, ULID_PATTERN, URL_PATTERN, UUID_PATTERN, resolveLazySchema, schemaCanAcceptUndefined } from "../schema/index.js";
9
+ import { findDiscriminatedUnionCase, hasObjectKey, isArrayIndexKey, isDataPropertyDescriptor, isValidDateObject, isPlainRecord, ordinaryHasInstance, readDateTime, readOwnDataProperty } from "../evaluate/shared.js";
8
10
  /**
9
11
  * @brief execute schema kernel.
12
+ * @details Plan helpers keep schema-specialized execution aligned with optimized IR while
13
+ * preserving interpreter parity.
10
14
  */
11
15
  export function executeSchemaKernel(schema, value, state, runChild) {
12
16
  switch (schema.tag) {
@@ -18,6 +22,8 @@ export function executeSchemaKernel(schema, value, state, runChild) {
18
22
  return isStringSchema(schema, value);
19
23
  case SchemaTag.Number:
20
24
  return isNumberSchema(schema, value);
25
+ case SchemaTag.Date:
26
+ return isDateSchema(schema, value);
21
27
  case SchemaTag.BigInt:
22
28
  return typeof value === "bigint";
23
29
  case SchemaTag.Symbol:
@@ -27,11 +33,19 @@ export function executeSchemaKernel(schema, value, state, runChild) {
27
33
  case SchemaTag.Literal:
28
34
  return Object.is(value, schema.value);
29
35
  case SchemaTag.Array:
30
- return isArraySchema(schema.item, value, state, runChild);
36
+ return isArraySchema(schema, value, state, runChild);
31
37
  case SchemaTag.Tuple:
32
- return isTupleSchema(schema.items, value, state, runChild);
38
+ return isTupleSchema(schema, value, state, runChild);
33
39
  case SchemaTag.Record:
34
40
  return isRecordSchema(schema.value, value, state, runChild);
41
+ case SchemaTag.Map:
42
+ return isMapSchema(schema, value, state, runChild);
43
+ case SchemaTag.Set:
44
+ return isSetSchema(schema, value, state, runChild);
45
+ case SchemaTag.InstanceOf:
46
+ return ordinaryHasInstance(value, schema.constructor);
47
+ case SchemaTag.Property:
48
+ return isPropertySchema(schema, value, state, runChild);
35
49
  case SchemaTag.Object:
36
50
  return isObjectSchema(schema, value, state, runChild);
37
51
  case SchemaTag.Union:
@@ -56,7 +70,12 @@ export function executeSchemaKernel(schema, value, state, runChild) {
56
70
  }
57
71
  }
58
72
  /**
59
- * @brief is string schema.
73
+ * @brief Execute a string schema against one runtime value.
74
+ * @param schema String schema with normalized checks.
75
+ * @param value Candidate runtime value.
76
+ * @returns True when the value is a string and every string check passes.
77
+ * @details Regex state is reset around each test so global or sticky patterns do
78
+ * not leak `lastIndex` across validation calls.
60
79
  */
61
80
  function isStringSchema(schema, value) {
62
81
  if (typeof value !== "string") {
@@ -93,12 +112,66 @@ function isStringSchema(schema, value) {
93
112
  }
94
113
  UUID_PATTERN.lastIndex = 0;
95
114
  break;
115
+ case StringCheckTag.Email:
116
+ EMAIL_PATTERN.lastIndex = 0;
117
+ if (!EMAIL_PATTERN.test(value)) {
118
+ return false;
119
+ }
120
+ EMAIL_PATTERN.lastIndex = 0;
121
+ break;
122
+ case StringCheckTag.Url:
123
+ URL_PATTERN.lastIndex = 0;
124
+ if (!URL_PATTERN.test(value)) {
125
+ return false;
126
+ }
127
+ URL_PATTERN.lastIndex = 0;
128
+ break;
129
+ case StringCheckTag.IsoDate:
130
+ ISO_DATE_PATTERN.lastIndex = 0;
131
+ if (!ISO_DATE_PATTERN.test(value)) {
132
+ return false;
133
+ }
134
+ ISO_DATE_PATTERN.lastIndex = 0;
135
+ break;
136
+ case StringCheckTag.IsoDateTime:
137
+ ISO_DATETIME_PATTERN.lastIndex = 0;
138
+ if (!ISO_DATETIME_PATTERN.test(value)) {
139
+ return false;
140
+ }
141
+ ISO_DATETIME_PATTERN.lastIndex = 0;
142
+ break;
143
+ case StringCheckTag.Ulid:
144
+ ULID_PATTERN.lastIndex = 0;
145
+ if (!ULID_PATTERN.test(value)) {
146
+ return false;
147
+ }
148
+ ULID_PATTERN.lastIndex = 0;
149
+ break;
150
+ case StringCheckTag.Ipv4:
151
+ IPV4_PATTERN.lastIndex = 0;
152
+ if (!IPV4_PATTERN.test(value)) {
153
+ return false;
154
+ }
155
+ IPV4_PATTERN.lastIndex = 0;
156
+ break;
157
+ case StringCheckTag.Ipv6:
158
+ IPV6_PATTERN.lastIndex = 0;
159
+ if (!IPV6_PATTERN.test(value)) {
160
+ return false;
161
+ }
162
+ IPV6_PATTERN.lastIndex = 0;
163
+ break;
96
164
  }
97
165
  }
98
166
  return true;
99
167
  }
100
168
  /**
101
- * @brief is number schema.
169
+ * @brief Execute a number schema against one runtime value.
170
+ * @details Plan helpers keep schema-specialized execution aligned with optimized IR while
171
+ * preserving interpreter parity.
172
+ * @param schema Number schema with normalized checks.
173
+ * @param value Candidate runtime value.
174
+ * @returns True when the value is finite and satisfies every numeric check.
102
175
  */
103
176
  function isNumberSchema(schema, value) {
104
177
  if (typeof value !== "number" || !Number.isFinite(value)) {
@@ -126,17 +199,82 @@ function isNumberSchema(schema, value) {
126
199
  return false;
127
200
  }
128
201
  break;
202
+ case NumberCheckTag.Gt:
203
+ if (value <= check.value) {
204
+ return false;
205
+ }
206
+ break;
207
+ case NumberCheckTag.Lt:
208
+ if (value >= check.value) {
209
+ return false;
210
+ }
211
+ break;
212
+ case NumberCheckTag.MultipleOf:
213
+ if (value % check.value !== 0) {
214
+ return false;
215
+ }
216
+ break;
217
+ }
218
+ }
219
+ return true;
220
+ }
221
+ /**
222
+ * @brief Execute a Date schema against one runtime value.
223
+ * @param schema Date schema with normalized epoch-millisecond checks.
224
+ * @param value Candidate runtime value.
225
+ * @returns True when the value is a valid Date satisfying every bound.
226
+ */
227
+ function isDateSchema(schema, value) {
228
+ if (!isValidDateObject(value)) {
229
+ return false;
230
+ }
231
+ const time = readDateTime(value);
232
+ const checks = schema.checks;
233
+ for (let index = 0; index < checks.length; index += 1) {
234
+ const check = checks[index];
235
+ if (check === undefined) {
236
+ return false;
237
+ }
238
+ switch (check.tag) {
239
+ case DateCheckTag.Min:
240
+ if (time < check.value) {
241
+ return false;
242
+ }
243
+ break;
244
+ case DateCheckTag.Max:
245
+ if (time > check.value) {
246
+ return false;
247
+ }
248
+ break;
129
249
  }
130
250
  }
131
251
  return true;
132
252
  }
133
253
  /**
134
- * @brief is array schema.
254
+ * @brief Execute array validation with sparse-slot semantics.
255
+ * @details Plan helpers keep schema-specialized execution aligned with optimized IR while
256
+ * preserving interpreter parity.
257
+ * @param item Schema applied to each logical array slot.
258
+ * @param value Candidate value supplied by the caller.
259
+ * @param state Shared recursion and cycle state.
260
+ * @param runChild Dispatcher for nested schema predicates.
261
+ * @returns True when the value satisfies the array schema.
135
262
  */
136
- function isArraySchema(item, value, state, runChild) {
263
+ function isArraySchema(schema, value, state, runChild) {
137
264
  if (!Array.isArray(value)) {
138
265
  return false;
139
266
  }
267
+ if (!arrayLengthChecksPass(schema, value.length)) {
268
+ return false;
269
+ }
270
+ const item = schema.item;
271
+ if (schemaCanAcceptUndefined(item)) {
272
+ /*
273
+ * Undefined-valid item schemas make holes valid. Use the present-index
274
+ * walker so sparse arrays do not pay for absent slots.
275
+ */
276
+ return isPresentArraySchema(item, value, state, runChild);
277
+ }
140
278
  for (let index = 0; index < value.length; index += 1) {
141
279
  const property = readArrayIndexDataProperty(value, index);
142
280
  if (property === null ||
@@ -147,10 +285,81 @@ function isArraySchema(item, value, state, runChild) {
147
285
  return true;
148
286
  }
149
287
  /**
150
- * @brief is tuple schema.
288
+ * @brief Test array length checks after Array.isArray succeeds.
289
+ * @param schema Array schema with normalized checks.
290
+ * @param length Candidate array length.
291
+ * @returns True when every configured length bound accepts the length.
292
+ */
293
+ function arrayLengthChecksPass(schema, length) {
294
+ const checks = schema.checks;
295
+ for (let index = 0; index < checks.length; index += 1) {
296
+ const check = checks[index];
297
+ if (check === undefined) {
298
+ return false;
299
+ }
300
+ switch (check.tag) {
301
+ case ArrayCheckTag.Min:
302
+ if (length < check.value) {
303
+ return false;
304
+ }
305
+ break;
306
+ case ArrayCheckTag.Max:
307
+ if (length > check.value) {
308
+ return false;
309
+ }
310
+ break;
311
+ }
312
+ }
313
+ return true;
314
+ }
315
+ /**
316
+ * @brief Validate only present indexes for undefined-accepting item schemas.
317
+ * @details Skips holes only when `undefined` is already accepted by the item schema.
318
+ * @param item Schema applied to each present own index.
319
+ * @param value Array already proven by the caller.
320
+ * @param state Shared recursion and cycle state.
321
+ * @param runChild Dispatcher for nested schema predicates.
322
+ * @returns True when every present own index satisfies the item schema.
323
+ */
324
+ function isPresentArraySchema(item, value, state, runChild) {
325
+ const keys = Object.getOwnPropertyNames(value);
326
+ for (let keyIndex = 0; keyIndex < keys.length; keyIndex += 1) {
327
+ const key = keys[keyIndex];
328
+ if (key === undefined || !isArrayIndexKey(key, value.length)) {
329
+ continue;
330
+ }
331
+ /*
332
+ * Accessor-backed present indexes are rejected here because reading them
333
+ * would run user code and break the safe validation boundary.
334
+ */
335
+ const property = readArrayKeyDataProperty(value, key);
336
+ if (property === null ||
337
+ (property !== undefined && !runChild(item, property.value, state))) {
338
+ return false;
339
+ }
340
+ }
341
+ return true;
342
+ }
343
+ /**
344
+ * @brief Execute fixed-arity tuple validation.
345
+ * @details Plan helpers keep schema-specialized execution aligned with optimized IR while
346
+ * preserving interpreter parity.
347
+ * @param items Schema for each tuple index.
348
+ * @param value Candidate runtime value.
349
+ * @param state Shared recursion and cycle state.
350
+ * @param runChild Dispatcher for nested schema predicates.
351
+ * @returns True when length and every indexed item match exactly.
151
352
  */
152
- function isTupleSchema(items, value, state, runChild) {
153
- if (!Array.isArray(value) || value.length !== items.length) {
353
+ function isTupleSchema(schema, value, state, runChild) {
354
+ if (!Array.isArray(value)) {
355
+ return false;
356
+ }
357
+ const items = schema.items;
358
+ const rest = schema.rest;
359
+ if (rest === undefined && value.length !== items.length) {
360
+ return false;
361
+ }
362
+ if (rest !== undefined && value.length < items.length) {
154
363
  return false;
155
364
  }
156
365
  for (let index = 0; index < items.length; index += 1) {
@@ -162,13 +371,38 @@ function isTupleSchema(items, value, state, runChild) {
162
371
  return false;
163
372
  }
164
373
  }
374
+ if (rest !== undefined) {
375
+ for (let index = items.length; index < value.length; index += 1) {
376
+ const property = readArrayIndexDataProperty(value, index);
377
+ if (property === null ||
378
+ !runChild(rest, property === undefined ? undefined : property.value, state)) {
379
+ return false;
380
+ }
381
+ }
382
+ }
165
383
  return true;
166
384
  }
167
385
  /**
168
- * @brief read array index data property.
386
+ * @brief Read one tuple or dense-array index through a descriptor.
387
+ * @details Plan helpers keep schema-specialized execution aligned with optimized IR while
388
+ * preserving interpreter parity.
389
+ * @param value Array being inspected.
390
+ * @param index Numeric index.
391
+ * @returns Data descriptor, undefined for a hole, or null for an accessor slot.
169
392
  */
170
393
  function readArrayIndexDataProperty(value, index) {
171
- const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
394
+ return readArrayKeyDataProperty(value, String(index));
395
+ }
396
+ /**
397
+ * @brief Read one canonical array index key without executing accessors.
398
+ * @details Plan helpers keep schema-specialized execution aligned with optimized IR while
399
+ * preserving interpreter parity.
400
+ * @param value Array being inspected.
401
+ * @param key Canonical array index key.
402
+ * @returns Data descriptor, undefined for a hole, or null for an accessor slot.
403
+ */
404
+ function readArrayKeyDataProperty(value, key) {
405
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
172
406
  if (descriptor === undefined) {
173
407
  return undefined;
174
408
  }
@@ -178,7 +412,8 @@ function readArrayIndexDataProperty(value, index) {
178
412
  return descriptor;
179
413
  }
180
414
  /**
181
- * @brief is record schema.
415
+ * @brief Check record schema.
416
+ * @details This helper keeps a local invariant explicit at the module boundary.
182
417
  */
183
418
  function isRecordSchema(item, value, state, runChild) {
184
419
  if (!isPlainRecord(value)) {
@@ -198,7 +433,83 @@ function isRecordSchema(item, value, state, runChild) {
198
433
  return true;
199
434
  }
200
435
  /**
201
- * @brief is object schema.
436
+ * @brief Check Map schema.
437
+ * @param schema Map schema with key and value validators.
438
+ * @param value Candidate runtime value.
439
+ * @param state Shared recursion and cycle state.
440
+ * @param runChild Dispatcher for nested predicates.
441
+ * @returns True when every entry key and value satisfies its schema.
442
+ */
443
+ function isMapSchema(schema, value, state, runChild) {
444
+ if (!(value instanceof Map)) {
445
+ return false;
446
+ }
447
+ const iterator = Map.prototype.entries.call(value);
448
+ for (;;) {
449
+ const step = iterator.next();
450
+ if (step.done === true) {
451
+ return true;
452
+ }
453
+ const pair = step.value;
454
+ if (!runChild(schema.key, pair[0], state) ||
455
+ !runChild(schema.value, pair[1], state)) {
456
+ return false;
457
+ }
458
+ }
459
+ }
460
+ /**
461
+ * @brief Check Set schema.
462
+ * @param schema Set schema with item validator.
463
+ * @param value Candidate runtime value.
464
+ * @param state Shared recursion and cycle state.
465
+ * @param runChild Dispatcher for nested predicates.
466
+ * @returns True when every Set item satisfies its schema.
467
+ */
468
+ function isSetSchema(schema, value, state, runChild) {
469
+ if (!(value instanceof Set)) {
470
+ return false;
471
+ }
472
+ const iterator = Set.prototype.values.call(value);
473
+ for (;;) {
474
+ const step = iterator.next();
475
+ if (step.done === true) {
476
+ return true;
477
+ }
478
+ if (!runChild(schema.item, step.value, state)) {
479
+ return false;
480
+ }
481
+ }
482
+ }
483
+ /**
484
+ * @brief Check property schema.
485
+ * @param schema Property schema with base and own data property validators.
486
+ * @param value Candidate runtime value.
487
+ * @param state Shared recursion and cycle state.
488
+ * @param runChild Dispatcher for nested predicates.
489
+ * @returns True when base and property value both pass.
490
+ */
491
+ function isPropertySchema(schema, value, state, runChild) {
492
+ if (!runChild(schema.base, value, state)) {
493
+ return false;
494
+ }
495
+ if (((typeof value !== "object" && typeof value !== "function") || value === null)) {
496
+ return false;
497
+ }
498
+ const descriptor = Object.getOwnPropertyDescriptor(value, schema.key);
499
+ return descriptor !== undefined &&
500
+ isDataPropertyDescriptor(descriptor) &&
501
+ runChild(schema.value, descriptor.value, state);
502
+ }
503
+ /**
504
+ * @brief Execute object schema validation.
505
+ * @param schema Object schema with ordered entries and strict-mode lookup.
506
+ * @param value Candidate runtime value.
507
+ * @param state Shared recursion and cycle state.
508
+ * @param runChild Dispatcher for nested property schemas.
509
+ * @returns True when required/optional fields and strict-key rules pass.
510
+ * @details Required properties are read through descriptors. In strict mode, the
511
+ * all-required path can compare own key counts; optional shapes must inspect
512
+ * each key so extra symbol or undeclared string keys fail closed.
202
513
  */
203
514
  function isObjectSchema(schema, value, state, runChild) {
204
515
  if (!isPlainRecord(value)) {
@@ -228,6 +539,9 @@ function isObjectSchema(schema, value, state, runChild) {
228
539
  }
229
540
  }
230
541
  if (schema.mode === ObjectModeTag.Strict) {
542
+ if (schema.catchall !== undefined) {
543
+ return validateObjectCatchall(schema, record, state, runChild);
544
+ }
231
545
  if (allRequired) {
232
546
  return Object.getOwnPropertyNames(record).length === entries.length &&
233
547
  Object.getOwnPropertySymbols(record).length === 0;
@@ -240,10 +554,50 @@ function isObjectSchema(schema, value, state, runChild) {
240
554
  }
241
555
  }
242
556
  }
557
+ if (schema.catchall !== undefined) {
558
+ return validateObjectCatchall(schema, record, state, runChild);
559
+ }
560
+ return true;
561
+ }
562
+ /**
563
+ * @brief Validate undeclared own object keys through a catchall schema.
564
+ * @param schema Object schema carrying known-key metadata and catchall schema.
565
+ * @param record Runtime object already proven to be a plain record.
566
+ * @param state Shared recursion and cycle state.
567
+ * @param runChild Dispatcher for the catchall schema.
568
+ * @returns True when every extra own data property satisfies the catchall.
569
+ */
570
+ function validateObjectCatchall(schema, record, state, runChild) {
571
+ const catchall = schema.catchall;
572
+ if (catchall === undefined) {
573
+ return true;
574
+ }
575
+ const keys = Reflect.ownKeys(record);
576
+ for (let index = 0; index < keys.length; index += 1) {
577
+ const key = keys[index];
578
+ if (key === undefined ||
579
+ (typeof key === "string" && hasObjectKey(schema.keyLookup, key))) {
580
+ continue;
581
+ }
582
+ const descriptor = Object.getOwnPropertyDescriptor(record, key);
583
+ if (descriptor === undefined || !isDataPropertyDescriptor(descriptor)) {
584
+ return false;
585
+ }
586
+ if (!runChild(catchall, descriptor.value, state)) {
587
+ return false;
588
+ }
589
+ }
243
590
  return true;
244
591
  }
245
592
  /**
246
- * @brief is union schema.
593
+ * @brief Execute a general union by probing options in order.
594
+ * @details Plan helpers keep schema-specialized execution aligned with optimized IR while
595
+ * preserving interpreter parity.
596
+ * @param options Union option schemas.
597
+ * @param value Candidate runtime value.
598
+ * @param state Shared recursion and cycle state.
599
+ * @param runChild Dispatcher for nested option schemas.
600
+ * @returns True when at least one option accepts the value.
247
601
  */
248
602
  function isUnionSchema(options, value, state, runChild) {
249
603
  for (let index = 0; index < options.length; index += 1) {
@@ -255,7 +609,15 @@ function isUnionSchema(options, value, state, runChild) {
255
609
  return false;
256
610
  }
257
611
  /**
258
- * @brief is discriminated union schema.
612
+ * @brief Execute a discriminated union through its tag field.
613
+ * @details Plan helpers keep schema-specialized execution aligned with optimized IR while
614
+ * preserving interpreter parity.
615
+ * @param key Discriminant property name.
616
+ * @param cases Closed case table.
617
+ * @param value Candidate runtime value.
618
+ * @param state Shared recursion and cycle state.
619
+ * @param runChild Dispatcher for selected case schema.
620
+ * @returns True when the discriminant is a string and the selected case passes.
259
621
  */
260
622
  function isDiscriminatedUnionSchema(key, cases, value, state, runChild) {
261
623
  if (!isPlainRecord(value)) {
@@ -270,7 +632,8 @@ function isDiscriminatedUnionSchema(key, cases, value, state, runChild) {
270
632
  return selected !== undefined && runChild(selected, value, state);
271
633
  }
272
634
  /**
273
- * @brief is strict true.
635
+ * @brief Check strict true.
636
+ * @details This helper keeps a local invariant explicit at the module boundary.
274
637
  */
275
638
  function isStrictTrue(value) {
276
639
  return value === true;
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * @file types.ts
3
3
  * @brief Optimized validation plan contracts.
4
+ * @details Plan helpers keep schema-specialized execution aligned with optimized IR while
5
+ * preserving interpreter parity.
4
6
  */
5
7
  import type { Graph } from "../ir/index.js";
6
8
  import type { Schema } from "../schema/index.js";
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/plan/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/plan/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACrC"}
@@ -1,5 +1,7 @@
1
1
  /**
2
2
  * @file types.ts
3
3
  * @brief Optimized validation plan contracts.
4
+ * @details Plan helpers keep schema-specialized execution aligned with optimized IR while
5
+ * preserving interpreter parity.
4
6
  */
5
7
  export {};
@@ -1,27 +1,41 @@
1
1
  /**
2
- * @brief result.
2
+ * @brief Explicit success-or-failure value used instead of implicit exceptions.
3
+ * @details Public validators return Result so failure is visible in the type
4
+ * system and callers must handle diagnostics deliberately.
3
5
  */
4
6
  export type Result<TValue, TError> = Ok<TValue> | Err<TError>;
5
7
  /**
6
- * @brief ok.
8
+ * @brief Successful Result variant.
9
+ * @details The payload is named `value` so consumers can destructure success
10
+ * without colliding with the failure-side `error` field.
7
11
  */
8
12
  export interface Ok<TValue> {
9
13
  readonly ok: true;
10
14
  readonly value: TValue;
11
15
  }
12
16
  /**
13
- * @brief err.
17
+ * @brief Failed Result variant.
18
+ * @details Errors remain typed payloads rather than thrown control flow, which
19
+ * keeps validation and decoding APIs predictable under composition.
14
20
  */
15
21
  export interface Err<TError> {
16
22
  readonly ok: false;
17
23
  readonly error: TError;
18
24
  }
19
25
  /**
20
- * @brief ok.
26
+ * @brief Construct a frozen successful Result.
27
+ * @details Result helpers keep success and failure explicit in value space instead of
28
+ * relying on implicit control flow.
29
+ * @param value Value produced by a successful operation.
30
+ * @returns Immutable success variant.
21
31
  */
22
32
  export declare function ok<TValue>(value: TValue): Result<TValue, never>;
23
33
  /**
24
- * @brief err.
34
+ * @brief Construct a frozen failed Result.
35
+ * @details Result helpers keep success and failure explicit in value space instead of
36
+ * relying on implicit control flow.
37
+ * @param error Typed failure payload.
38
+ * @returns Immutable failure variant.
25
39
  */
26
40
  export declare function err<TError>(error: TError): Result<never, TError>;
27
41
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/result/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,IAC7B,EAAE,CAAC,MAAM,CAAC,GACV,GAAG,CAAC,MAAM,CAAC,CAAC;AAEhB;;GAEG;AACH,MAAM,WAAW,EAAE,CAAC,MAAM;IACxB,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,GAAG,CAAC,MAAM;IACzB,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAM/D;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAMhE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/result/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,IAC3B,EAAE,CAAC,MAAM,CAAC,GACV,GAAG,CAAC,MAAM,CAAC,CAAC;AAElB;;;;GAIG;AACH,MAAM,WAAW,EAAE,CAAC,MAAM;IACtB,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,GAAG,CAAC,MAAM;IACvB,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAM/D;AAED;;;;;;GAMG;AACH,wBAAgB,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAMhE"}
@@ -1,5 +1,9 @@
1
1
  /**
2
- * @brief ok.
2
+ * @brief Construct a frozen successful Result.
3
+ * @details Result helpers keep success and failure explicit in value space instead of
4
+ * relying on implicit control flow.
5
+ * @param value Value produced by a successful operation.
6
+ * @returns Immutable success variant.
3
7
  */
4
8
  export function ok(value) {
5
9
  const result = {
@@ -9,7 +13,11 @@ export function ok(value) {
9
13
  return Object.freeze(result);
10
14
  }
11
15
  /**
12
- * @brief err.
16
+ * @brief Construct a frozen failed Result.
17
+ * @details Result helpers keep success and failure explicit in value space instead of
18
+ * relying on implicit control flow.
19
+ * @param error Typed failure payload.
20
+ * @returns Immutable failure variant.
13
21
  */
14
22
  export function err(error) {
15
23
  const result = {