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,59 +1,124 @@
1
1
  /**
2
2
  * @file shared.ts
3
3
  * @brief Shared scalar helpers for schema evaluation.
4
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
5
+ * aligned with compiled behavior.
4
6
  */
5
7
  import type { DiscriminatedUnionCase, LiteralValue, ObjectKeyLookup, Schema } from "../schema/index.js";
6
8
  /**
7
- * @brief unknown record.
9
+ * @brief Object shape accepted by object and record validators.
10
+ * @details Values stay indexed by string keys only after the caller proves the
11
+ * input is not null and not an array.
8
12
  */
9
13
  export type UnknownRecord = Readonly<Record<string, unknown>>;
10
14
  /**
11
- * @brief data property descriptor.
12
- * @details Defines the subset of descriptors whose value is stable for one validation read.
15
+ * @brief Descriptor subset safe for validation reads.
16
+ * @details Only data descriptors are accepted because accessor descriptors can
17
+ * execute user code and can return different values across reads.
13
18
  * @invariant Accessor descriptors never match this contract.
14
19
  */
15
20
  export interface DataPropertyDescriptor {
16
21
  /**
17
- * @brief value.
18
- * @details The captured data slot is unknown until the schema-specific validator consumes it.
22
+ * @brief Captured property value.
23
+ * @details The value remains unknown until a schema-specific validator consumes it.
19
24
  * @invariant Accessing this field does not execute user getter code.
20
25
  */
21
26
  readonly value: unknown;
22
27
  }
23
28
  /**
24
- * @brief has object key.
29
+ * @brief Check membership in an object schema key lookup.
30
+ * @param keyLookup Null-prototype lookup generated by object schema construction.
31
+ * @param key Candidate own key.
32
+ * @returns True when the key belongs to the schema shape.
33
+ * @details The lookup is used instead of `in` so prototype pollution cannot make
34
+ * an undeclared key appear valid.
25
35
  */
26
36
  export declare function hasObjectKey(keyLookup: ObjectKeyLookup, key: string): boolean;
27
37
  /**
28
- * @brief read own data property.
38
+ * @brief Read one own data property from a runtime object.
29
39
  * @details Reads one own property through its descriptor so getters are not executed.
40
+ * @param record Plain object being validated.
41
+ * @param key Own key to inspect.
30
42
  * @returns Own data descriptor, or undefined for missing/accessor properties.
31
43
  */
32
44
  export declare function readOwnDataProperty(record: UnknownRecord, key: string): DataPropertyDescriptor | undefined;
33
45
  /**
34
- * @brief find discriminated union case.
46
+ * @brief Select a discriminated-union branch by its literal tag value.
47
+ * @details The case list is already builder-validated for unique literals, so a
48
+ * linear scan is enough for interpreter diagnostics while preserving declaration
49
+ * order and avoiding a per-schema map allocation.
50
+ * @param cases Closed discriminated union case list.
51
+ * @param value Discriminant string read from input.
52
+ * @returns Matching case schema, or undefined when the value is unknown.
35
53
  */
36
54
  export declare function findDiscriminatedUnionCase(cases: readonly DiscriminatedUnionCase[], value: string): Schema | undefined;
37
55
  /**
38
- * @brief is strict true.
56
+ * @brief Test for the only accepted refinement success value.
57
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
58
+ * aligned with compiled behavior.
59
+ * @param value Predicate return value.
60
+ * @returns True only for the boolean literal true.
39
61
  */
40
62
  export declare function isStrictTrue(value: unknown): boolean;
41
63
  /**
42
- * @brief is plain record.
64
+ * @brief Test whether a value can host object-schema properties.
65
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
66
+ * aligned with compiled behavior.
67
+ * @param value Candidate runtime value.
68
+ * @returns True for non-array object values.
43
69
  */
44
70
  export declare function isPlainRecord(value: unknown): value is UnknownRecord;
45
71
  /**
46
- * @brief is data property descriptor.
72
+ * @brief Test whether a descriptor carries a stable data slot.
47
73
  * @details Checks that a descriptor contains a data value instead of getter/setter code.
74
+ * @param descriptor Descriptor returned by Object.getOwnPropertyDescriptor.
48
75
  * @returns True when the descriptor has a stable value slot.
49
76
  */
50
77
  export declare function isDataPropertyDescriptor(descriptor: PropertyDescriptor): descriptor is DataPropertyDescriptor;
51
78
  /**
52
- * @brief actual type.
79
+ * @brief Test whether a property name is an in-bounds array index.
80
+ * @details Array validation ignores non-index own properties exactly as indexed
81
+ * loops do, but this helper lets sparse arrays avoid scanning every hole.
82
+ * @param key Own property name returned from an array object.
83
+ * @param length Current array length used as the upper bound.
84
+ * @returns True for canonical own array-index names below the current length.
85
+ * @invariant The result matches the indexes visited by a `0..length` loop.
86
+ */
87
+ export declare function isArrayIndexKey(key: string, length: number): boolean;
88
+ /**
89
+ * @brief Convert a runtime value into TypeSea's diagnostic type label.
90
+ * @details JavaScript reports null as object and NaN as number. Diagnostics use
91
+ * more precise labels so failure reports describe the actual value shape seen by
92
+ * validators.
93
+ * @param value Candidate runtime value.
94
+ * @returns Stable diagnostic type label.
53
95
  */
54
96
  export declare function actualType(value: unknown): string;
55
97
  /**
56
- * @brief literal to expected.
98
+ * @brief Validate a Date object without reading user-overridable methods.
99
+ * @param value Candidate runtime value.
100
+ * @returns True when value is a Date with a finite time value.
101
+ */
102
+ export declare function isValidDateObject(value: unknown): value is Date;
103
+ /**
104
+ * @brief Read a Date object's time value through the intrinsic method.
105
+ * @param value Date object already accepted by isValidDateObject.
106
+ * @returns Epoch millisecond value.
107
+ */
108
+ export declare function readDateTime(value: Date): number;
109
+ /**
110
+ * @brief Execute ordinary instanceof without invoking custom hasInstance hooks.
111
+ * @param value Candidate runtime value.
112
+ * @param constructor Constructor function stored in the schema.
113
+ * @returns True when the ordinary prototype-chain check accepts the value.
114
+ */
115
+ export declare function ordinaryHasInstance(value: unknown, constructor: abstract new (...args: never[]) => unknown): boolean;
116
+ /**
117
+ * @brief Render a literal schema value for the `expected` diagnostic field.
118
+ * @details String values are JSON-quoted and negative zero is preserved because
119
+ * both cases are otherwise easy to misread in generated messages.
120
+ * @param value Literal value from a schema.
121
+ * @returns Stable expected-value label for diagnostics.
57
122
  */
58
123
  export declare function literalToExpected(value: LiteralValue): string;
59
124
  //# sourceMappingURL=shared.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/evaluate/shared.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,sBAAsB,EACtB,YAAY,EACZ,eAAe,EACf,MAAM,EACP,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IAErC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAE7E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,MAAM,GACV,sBAAsB,GAAG,SAAS,CAMpC;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,SAAS,sBAAsB,EAAE,EACxC,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,SAAS,CAQpB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAEpE;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,kBAAkB,GAC7B,UAAU,IAAI,sBAAsB,CAEtC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAiBjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAiB7D"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/evaluate/shared.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACR,sBAAsB,EACtB,YAAY,EACZ,eAAe,EACf,MAAM,EACT,MAAM,oBAAoB,CAAC;AAI5B;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IAEnC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAE7E;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAC/B,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,MAAM,GACZ,sBAAsB,GAAG,SAAS,CAMpC;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACtC,KAAK,EAAE,SAAS,sBAAsB,EAAE,EACxC,KAAK,EAAE,MAAM,GACd,MAAM,GAAG,SAAS,CAQpB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEpD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAEpE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACpC,UAAU,EAAE,kBAAkB,GAC/B,UAAU,IAAI,sBAAsB,CAEtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAcpE;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CA0BjD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,IAAI,CAG/D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,CAEhD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAC/B,KAAK,EAAE,OAAO,EACd,WAAW,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,GACxD,OAAO,CAET;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAiB7D"}
@@ -1,16 +1,26 @@
1
1
  /**
2
2
  * @file shared.ts
3
3
  * @brief Shared scalar helpers for schema evaluation.
4
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
5
+ * aligned with compiled behavior.
4
6
  */
7
+ const MAX_ARRAY_INDEX = 4_294_967_294;
5
8
  /**
6
- * @brief has object key.
9
+ * @brief Check membership in an object schema key lookup.
10
+ * @param keyLookup Null-prototype lookup generated by object schema construction.
11
+ * @param key Candidate own key.
12
+ * @returns True when the key belongs to the schema shape.
13
+ * @details The lookup is used instead of `in` so prototype pollution cannot make
14
+ * an undeclared key appear valid.
7
15
  */
8
16
  export function hasObjectKey(keyLookup, key) {
9
17
  return Object.prototype.hasOwnProperty.call(keyLookup, key);
10
18
  }
11
19
  /**
12
- * @brief read own data property.
20
+ * @brief Read one own data property from a runtime object.
13
21
  * @details Reads one own property through its descriptor so getters are not executed.
22
+ * @param record Plain object being validated.
23
+ * @param key Own key to inspect.
14
24
  * @returns Own data descriptor, or undefined for missing/accessor properties.
15
25
  */
16
26
  export function readOwnDataProperty(record, key) {
@@ -21,7 +31,13 @@ export function readOwnDataProperty(record, key) {
21
31
  return descriptor;
22
32
  }
23
33
  /**
24
- * @brief find discriminated union case.
34
+ * @brief Select a discriminated-union branch by its literal tag value.
35
+ * @details The case list is already builder-validated for unique literals, so a
36
+ * linear scan is enough for interpreter diagnostics while preserving declaration
37
+ * order and avoiding a per-schema map allocation.
38
+ * @param cases Closed discriminated union case list.
39
+ * @param value Discriminant string read from input.
40
+ * @returns Matching case schema, or undefined when the value is unknown.
25
41
  */
26
42
  export function findDiscriminatedUnionCase(cases, value) {
27
43
  for (let index = 0; index < cases.length; index += 1) {
@@ -33,27 +49,65 @@ export function findDiscriminatedUnionCase(cases, value) {
33
49
  return undefined;
34
50
  }
35
51
  /**
36
- * @brief is strict true.
52
+ * @brief Test for the only accepted refinement success value.
53
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
54
+ * aligned with compiled behavior.
55
+ * @param value Predicate return value.
56
+ * @returns True only for the boolean literal true.
37
57
  */
38
58
  export function isStrictTrue(value) {
39
59
  return value === true;
40
60
  }
41
61
  /**
42
- * @brief is plain record.
62
+ * @brief Test whether a value can host object-schema properties.
63
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
64
+ * aligned with compiled behavior.
65
+ * @param value Candidate runtime value.
66
+ * @returns True for non-array object values.
43
67
  */
44
68
  export function isPlainRecord(value) {
45
69
  return typeof value === "object" && value !== null && !Array.isArray(value);
46
70
  }
47
71
  /**
48
- * @brief is data property descriptor.
72
+ * @brief Test whether a descriptor carries a stable data slot.
49
73
  * @details Checks that a descriptor contains a data value instead of getter/setter code.
74
+ * @param descriptor Descriptor returned by Object.getOwnPropertyDescriptor.
50
75
  * @returns True when the descriptor has a stable value slot.
51
76
  */
52
77
  export function isDataPropertyDescriptor(descriptor) {
53
78
  return Object.prototype.hasOwnProperty.call(descriptor, "value");
54
79
  }
55
80
  /**
56
- * @brief actual type.
81
+ * @brief Test whether a property name is an in-bounds array index.
82
+ * @details Array validation ignores non-index own properties exactly as indexed
83
+ * loops do, but this helper lets sparse arrays avoid scanning every hole.
84
+ * @param key Own property name returned from an array object.
85
+ * @param length Current array length used as the upper bound.
86
+ * @returns True for canonical own array-index names below the current length.
87
+ * @invariant The result matches the indexes visited by a `0..length` loop.
88
+ */
89
+ export function isArrayIndexKey(key, length) {
90
+ if (key.length === 0 || key === "length") {
91
+ return false;
92
+ }
93
+ /*
94
+ * Enumeration APIs expose array indexes as strings. Round-tripping through
95
+ * Number rejects aliases such as "01", floats, negative keys, and length.
96
+ */
97
+ const index = Number(key);
98
+ return Number.isInteger(index) &&
99
+ index >= 0 &&
100
+ index <= MAX_ARRAY_INDEX &&
101
+ index < length &&
102
+ String(index) === key;
103
+ }
104
+ /**
105
+ * @brief Convert a runtime value into TypeSea's diagnostic type label.
106
+ * @details JavaScript reports null as object and NaN as number. Diagnostics use
107
+ * more precise labels so failure reports describe the actual value shape seen by
108
+ * validators.
109
+ * @param value Candidate runtime value.
110
+ * @returns Stable diagnostic type label.
57
111
  */
58
112
  export function actualType(value) {
59
113
  if (value === null) {
@@ -62,6 +116,15 @@ export function actualType(value) {
62
116
  if (Array.isArray(value)) {
63
117
  return "array";
64
118
  }
119
+ if (value instanceof Date) {
120
+ return "date";
121
+ }
122
+ if (value instanceof Map) {
123
+ return "map";
124
+ }
125
+ if (value instanceof Set) {
126
+ return "set";
127
+ }
65
128
  if (typeof value === "bigint") {
66
129
  return "bigint";
67
130
  }
@@ -74,7 +137,37 @@ export function actualType(value) {
74
137
  return typeof value;
75
138
  }
76
139
  /**
77
- * @brief literal to expected.
140
+ * @brief Validate a Date object without reading user-overridable methods.
141
+ * @param value Candidate runtime value.
142
+ * @returns True when value is a Date with a finite time value.
143
+ */
144
+ export function isValidDateObject(value) {
145
+ return value instanceof Date &&
146
+ Number.isFinite(Date.prototype.getTime.call(value));
147
+ }
148
+ /**
149
+ * @brief Read a Date object's time value through the intrinsic method.
150
+ * @param value Date object already accepted by isValidDateObject.
151
+ * @returns Epoch millisecond value.
152
+ */
153
+ export function readDateTime(value) {
154
+ return Date.prototype.getTime.call(value);
155
+ }
156
+ /**
157
+ * @brief Execute ordinary instanceof without invoking custom hasInstance hooks.
158
+ * @param value Candidate runtime value.
159
+ * @param constructor Constructor function stored in the schema.
160
+ * @returns True when the ordinary prototype-chain check accepts the value.
161
+ */
162
+ export function ordinaryHasInstance(value, constructor) {
163
+ return Function.prototype[Symbol.hasInstance].call(constructor, value);
164
+ }
165
+ /**
166
+ * @brief Render a literal schema value for the `expected` diagnostic field.
167
+ * @details String values are JSON-quoted and negative zero is preserved because
168
+ * both cases are otherwise easy to misread in generated messages.
169
+ * @param value Literal value from a schema.
170
+ * @returns Stable expected-value label for diagnostics.
78
171
  */
79
172
  export function literalToExpected(value) {
80
173
  if (value === null) {
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * @file state.ts
3
3
  * @brief Recursive validation state for cyclic input graphs.
4
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
5
+ * aligned with compiled behavior.
4
6
  */
5
7
  import type { Schema } from "../schema/index.js";
6
8
  /**
@@ -11,6 +13,8 @@ import type { Schema } from "../schema/index.js";
11
13
  export type ValidationEnterResult = "entered" | "cycle" | "budget";
12
14
  /**
13
15
  * @brief default max validation depth.
16
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
17
+ * aligned with compiled behavior.
14
18
  * @invariant The value stays below the V8 stack depth that recursive lazy schemas can exhaust.
15
19
  */
16
20
  export declare const DEFAULT_MAX_VALIDATION_DEPTH = 256;
@@ -26,40 +30,58 @@ export interface GraphEvaluationFrame {
26
30
  }
27
31
  /**
28
32
  * @brief validation state.
33
+ * @details Bundles recursion guards, lazy-resolution guards, and reusable graph
34
+ * frames so interpreter and IR execution observe the same limits.
29
35
  */
30
36
  export interface ValidationState {
31
37
  readonly active: WeakMap<object, WeakSet<Schema>>;
32
38
  readonly graphFrames: GraphEvaluationFrame[];
33
39
  readonly resolving: WeakSet<object>;
34
40
  /**
35
- * @brief depth.
36
- * @details Counts active recursive validator frames owned by this state object.
37
- * @invariant The value is incremented only after budget admission and decremented by `leaveValidation`.
38
- */
41
+ * @brief depth.
42
+ * @details Counts active recursive validator frames owned by this state object.
43
+ * @invariant The value is incremented only after budget admission and decremented by `leaveValidation`.
44
+ */
39
45
  depth: number;
40
46
  /**
41
- * @brief graph depth.
42
- * @details Counts active nested graph executions using `graphFrames` as a stack.
43
- * @invariant Incremented by IR execution before frame use and decremented after it.
44
- */
47
+ * @brief graph depth.
48
+ * @details Counts active nested graph executions using `graphFrames` as a stack.
49
+ * @invariant Incremented by IR execution before frame use and decremented after it.
50
+ */
45
51
  graphDepth: number;
46
52
  /**
47
- * @brief max depth.
48
- * @details Hard cap for recursive validator frames.
49
- * @invariant Entering past this limit returns `budget` instead of recursing.
50
- */
53
+ * @brief max depth.
54
+ * @details Hard cap for recursive validator frames.
55
+ * @invariant Entering past this limit returns `budget` instead of recursing.
56
+ */
51
57
  readonly maxDepth: number;
52
58
  }
53
59
  /**
54
- * @brief make validation state.
60
+ * @brief Allocate recursion and graph-frame state for one validation run.
61
+ * @returns Fresh validation state for one top-level validation operation.
62
+ * @details State is allocated per call so cycle tracking cannot leak between
63
+ * unrelated inputs.
55
64
  */
56
65
  export declare function makeValidationState(): ValidationState;
57
66
  /**
58
67
  * @brief enter validation.
68
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
69
+ * aligned with compiled behavior.
70
+ * @param schema Schema being entered.
71
+ * @param value Candidate runtime value.
72
+ * @param state Shared validation state.
73
+ * @returns Enter result describing cycle, budget, or admitted recursion.
74
+ * @post `state.depth` is incremented only for the entered result.
59
75
  */
60
76
  export declare function enterValidation(schema: Schema, value: unknown, state: ValidationState): ValidationEnterResult;
61
77
  /**
62
78
  * @brief leave validation.
79
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
80
+ * aligned with compiled behavior.
81
+ * @param schema Schema leaving validation.
82
+ * @param value Candidate runtime value.
83
+ * @param state Shared validation state.
84
+ * @post Reverses the depth and active-pair effects of `enterValidation`.
63
85
  */
64
86
  export declare function leaveValidation(schema: Schema, value: unknown, state: ValidationState): void;
65
87
  //# sourceMappingURL=state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/evaluate/state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAC7B,SAAS,GACT,OAAO,GACP,QAAQ,CAAC;AAEb;;;GAGG;AACH,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAClD,QAAQ,CAAC,WAAW,EAAE,oBAAoB,EAAE,CAAC;IAC7C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpC;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,eAAe,CASrD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,eAAe,GACrB,qBAAqB,CAoBvB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,eAAe,GACrB,IAAI,CAUN"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/evaluate/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAC3B,SAAS,GACT,OAAO,GACP,QAAQ,CAAC;AAEf;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACjC,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAClD,QAAQ,CAAC,WAAW,EAAE,oBAAoB,EAAE,CAAC;IAC7C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpC;;;;KAIC;IACD,KAAK,EAAE,MAAM,CAAC;IAEd;;;;KAIC;IACD,UAAU,EAAE,MAAM,CAAC;IAEnB;;;;KAIC;IACD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,eAAe,CASrD;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC3B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,eAAe,GACvB,qBAAqB,CA6BvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC3B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,eAAe,GACvB,IAAI,CAUN"}
@@ -1,14 +1,21 @@
1
1
  /**
2
2
  * @file state.ts
3
3
  * @brief Recursive validation state for cyclic input graphs.
4
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
5
+ * aligned with compiled behavior.
4
6
  */
5
7
  /**
6
8
  * @brief default max validation depth.
9
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
10
+ * aligned with compiled behavior.
7
11
  * @invariant The value stays below the V8 stack depth that recursive lazy schemas can exhaust.
8
12
  */
9
13
  export const DEFAULT_MAX_VALIDATION_DEPTH = 256;
10
14
  /**
11
- * @brief make validation state.
15
+ * @brief Allocate recursion and graph-frame state for one validation run.
16
+ * @returns Fresh validation state for one top-level validation operation.
17
+ * @details State is allocated per call so cycle tracking cannot leak between
18
+ * unrelated inputs.
12
19
  */
13
20
  export function makeValidationState() {
14
21
  return {
@@ -22,10 +29,22 @@ export function makeValidationState() {
22
29
  }
23
30
  /**
24
31
  * @brief enter validation.
32
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
33
+ * aligned with compiled behavior.
34
+ * @param schema Schema being entered.
35
+ * @param value Candidate runtime value.
36
+ * @param state Shared validation state.
37
+ * @returns Enter result describing cycle, budget, or admitted recursion.
38
+ * @post `state.depth` is incremented only for the entered result.
25
39
  */
26
40
  export function enterValidation(schema, value, state) {
27
41
  const cached = isReferenceValue(value) ? state.active.get(value) : undefined;
28
42
  if (cached?.has(schema) === true) {
43
+ /*
44
+ * The same schema/value pair is already active. Returning cycle prevents
45
+ * infinite recursion on cyclic object graphs while preserving success for
46
+ * the already-open branch.
47
+ */
29
48
  return "cycle";
30
49
  }
31
50
  if (state.depth >= state.maxDepth) {
@@ -36,6 +55,10 @@ export function enterValidation(schema, value, state) {
36
55
  return "entered";
37
56
  }
38
57
  if (cached !== undefined) {
58
+ /*
59
+ * WeakSet membership is per object identity. Adding the schema marks this
60
+ * exact pair as active until leaveValidation removes it.
61
+ */
39
62
  cached.add(schema);
40
63
  return "entered";
41
64
  }
@@ -46,6 +69,12 @@ export function enterValidation(schema, value, state) {
46
69
  }
47
70
  /**
48
71
  * @brief leave validation.
72
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
73
+ * aligned with compiled behavior.
74
+ * @param schema Schema leaving validation.
75
+ * @param value Candidate runtime value.
76
+ * @param state Shared validation state.
77
+ * @post Reverses the depth and active-pair effects of `enterValidation`.
49
78
  */
50
79
  export function leaveValidation(schema, value, state) {
51
80
  if (!isReferenceValue(value)) {
@@ -59,7 +88,11 @@ export function leaveValidation(schema, value, state) {
59
88
  state.depth -= 1;
60
89
  }
61
90
  /**
62
- * @brief is reference value.
91
+ * @brief Test whether a value can participate in object graph cycles.
92
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
93
+ * aligned with compiled behavior.
94
+ * @param value Candidate runtime value.
95
+ * @returns True for objects and functions that can participate in cycles.
63
96
  */
64
97
  function isReferenceValue(value) {
65
98
  return (typeof value === "object" && value !== null) || typeof value === "function";
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @file array.ts
3
+ * @brief Array guard implementation.
4
+ * @details Array helpers append immutable length constraints while preserving
5
+ * the item schema owned by the original guard.
6
+ */
7
+ import type { ArraySchema } from "../schema/index.js";
8
+ import { BaseGuard } from "./base.js";
9
+ import type { Presence } from "./types.js";
10
+ /**
11
+ * @brief Persistent builder for homogeneous array predicates.
12
+ * @details Length methods allocate a fresh schema record. The item schema is
13
+ * reused by identity because guard construction has already frozen it.
14
+ */
15
+ export declare class ArrayGuard<TItem, TPresence extends Presence = "required"> extends BaseGuard<TItem[], TPresence> {
16
+ /**
17
+ * @brief Construct a frozen array guard.
18
+ * @param schema Array schema backing this guard.
19
+ * @post The receiver has no mutable instance state after construction.
20
+ */
21
+ constructor(schema: ArraySchema);
22
+ /**
23
+ * @brief Require an inclusive minimum array length.
24
+ * @param value Non-negative integer lower bound.
25
+ * @returns Fresh ArrayGuard with an appended minimum length check.
26
+ */
27
+ min(value: number): ArrayGuard<TItem, TPresence>;
28
+ /**
29
+ * @brief Require an inclusive maximum array length.
30
+ * @param value Non-negative integer upper bound.
31
+ * @returns Fresh ArrayGuard with an appended maximum length check.
32
+ */
33
+ max(value: number): ArrayGuard<TItem, TPresence>;
34
+ /**
35
+ * @brief Require one exact array length.
36
+ * @param value Non-negative integer exact length.
37
+ * @returns Fresh ArrayGuard with matching minimum and maximum length checks.
38
+ * @details Exact length is represented as two ordinary bounds so every
39
+ * backend can reuse the same comparison and diagnostic paths.
40
+ */
41
+ length(value: number): ArrayGuard<TItem, TPresence>;
42
+ /**
43
+ * @brief Require at least one array element.
44
+ * @returns Fresh ArrayGuard with a minimum length of one.
45
+ */
46
+ nonempty(): ArrayGuard<TItem, TPresence>;
47
+ }
48
+ //# sourceMappingURL=array.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src/guard/array.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACH,SAAS,EAEZ,MAAM,WAAW,CAAC;AAMnB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;GAIG;AACH,qBAAa,UAAU,CACnB,KAAK,EACL,SAAS,SAAS,QAAQ,GAAG,UAAU,CACzC,SAAQ,SAAS,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC;IAEnC;;;;OAIG;gBACgB,MAAM,EAAE,WAAW;IAKtC;;;;OAIG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC;IAgBvD;;;;OAIG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC;IAgBvD;;;;;;OAMG;IACI,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC;IAK1D;;;OAGG;IACI,QAAQ,IAAI,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC;CAGlD"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * @file array.ts
3
+ * @brief Array guard implementation.
4
+ * @details Array helpers append immutable length constraints while preserving
5
+ * the item schema owned by the original guard.
6
+ */
7
+ import { ArrayCheckTag, SchemaTag } from "../kind/index.js";
8
+ import { BaseGuard, setArrayGuardFactory } from "./base.js";
9
+ import { checkArrayLengthBound, readArrayConstructorSchema, readArrayMethodSchema } from "./read.js";
10
+ /**
11
+ * @brief Persistent builder for homogeneous array predicates.
12
+ * @details Length methods allocate a fresh schema record. The item schema is
13
+ * reused by identity because guard construction has already frozen it.
14
+ */
15
+ export class ArrayGuard extends BaseGuard {
16
+ /**
17
+ * @brief Construct a frozen array guard.
18
+ * @param schema Array schema backing this guard.
19
+ * @post The receiver has no mutable instance state after construction.
20
+ */
21
+ constructor(schema) {
22
+ super(readArrayConstructorSchema(schema));
23
+ Object.freeze(this);
24
+ }
25
+ /**
26
+ * @brief Require an inclusive minimum array length.
27
+ * @param value Non-negative integer lower bound.
28
+ * @returns Fresh ArrayGuard with an appended minimum length check.
29
+ */
30
+ min(value) {
31
+ const schema = readArrayMethodSchema(this, "array min receiver");
32
+ const bound = checkArrayLengthBound(value, "min");
33
+ return new ArrayGuard({
34
+ tag: SchemaTag.Array,
35
+ item: schema.item,
36
+ checks: [
37
+ ...schema.checks,
38
+ {
39
+ tag: ArrayCheckTag.Min,
40
+ value: bound
41
+ }
42
+ ]
43
+ });
44
+ }
45
+ /**
46
+ * @brief Require an inclusive maximum array length.
47
+ * @param value Non-negative integer upper bound.
48
+ * @returns Fresh ArrayGuard with an appended maximum length check.
49
+ */
50
+ max(value) {
51
+ const schema = readArrayMethodSchema(this, "array max receiver");
52
+ const bound = checkArrayLengthBound(value, "max");
53
+ return new ArrayGuard({
54
+ tag: SchemaTag.Array,
55
+ item: schema.item,
56
+ checks: [
57
+ ...schema.checks,
58
+ {
59
+ tag: ArrayCheckTag.Max,
60
+ value: bound
61
+ }
62
+ ]
63
+ });
64
+ }
65
+ /**
66
+ * @brief Require one exact array length.
67
+ * @param value Non-negative integer exact length.
68
+ * @returns Fresh ArrayGuard with matching minimum and maximum length checks.
69
+ * @details Exact length is represented as two ordinary bounds so every
70
+ * backend can reuse the same comparison and diagnostic paths.
71
+ */
72
+ length(value) {
73
+ const bound = checkArrayLengthBound(value, "exact");
74
+ return this.min(bound).max(bound);
75
+ }
76
+ /**
77
+ * @brief Require at least one array element.
78
+ * @returns Fresh ArrayGuard with a minimum length of one.
79
+ */
80
+ nonempty() {
81
+ return this.min(1);
82
+ }
83
+ }
84
+ setArrayGuardFactory((schema) => new ArrayGuard(schema));