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
@@ -4,23 +4,23 @@ import { freezeIssueArray, makeIssue } from "../issue/index.js";
4
4
  import { err, ok } from "../result/index.js";
5
5
  import { freezeSchema, isSchemaValue } from "../schema/index.js";
6
6
  /**
7
- * @brief async decoder run symbol.
7
+ * @brief Private runner slot for async decoder instances.
8
+ * @details Decoder helpers keep validation failures explicit in Result values while
9
+ * preserving the original input value.
8
10
  */
9
11
  const AsyncDecoderRunSymbol = Symbol("TypeSea.asyncDecoder.run");
10
12
  /**
11
- * @brief constructed async decoders.
13
+ * @brief Real async decoder instances tracked without extending object lifetime.
14
+ * @details Decoder helpers keep validation failures explicit in Result values while
15
+ * preserving the original input value.
12
16
  */
13
17
  const constructedAsyncDecoders = new WeakSet();
14
18
  /**
15
- * @brief base async decoder.
16
- * @details Owns its state directly; methods expose receiver checks and explicit result flow.
17
- * @invariant Construction leaves the instance in a fully usable state before it escapes.
19
+ * @brief Frozen wrapper around one async decode runner.
20
+ * @details Receiver validation mirrors BaseDecoder so detached method calls do
21
+ * not bypass TypeSea's object construction checks.
18
22
  */
19
23
  export class BaseAsyncDecoder {
20
- /**
21
- * @brief constructor.
22
- * @post The receiver is initialized according to the class invariant before it can be observed.
23
- */
24
24
  constructor(run) {
25
25
  if (typeof run !== "function") {
26
26
  throw new TypeError("async decoder run must be a function");
@@ -29,15 +29,9 @@ export class BaseAsyncDecoder {
29
29
  constructedAsyncDecoders.add(this);
30
30
  Object.freeze(this);
31
31
  }
32
- /**
33
- * @brief decode async.
34
- */
35
32
  decodeAsync(value) {
36
33
  return readAsyncDecoderRunner(this, "async decoder receiver")(value);
37
34
  }
38
- /**
39
- * @brief refine async.
40
- */
41
35
  refineAsync(predicate, name) {
42
36
  if (typeof predicate !== "function") {
43
37
  throw new TypeError("async refinement predicate must be a function");
@@ -58,9 +52,6 @@ export class BaseAsyncDecoder {
58
52
  return failRefinement(name, decoded.value);
59
53
  });
60
54
  }
61
- /**
62
- * @brief transform async.
63
- */
64
55
  transformAsync(mapper) {
65
56
  if (typeof mapper !== "function") {
66
57
  throw new TypeError("async transform mapper must be a function");
@@ -74,9 +65,6 @@ export class BaseAsyncDecoder {
74
65
  return ok(await mapper(decoded.value));
75
66
  });
76
67
  }
77
- /**
78
- * @brief pipe async.
79
- */
80
68
  pipeAsync(next) {
81
69
  const run = readAsyncDecoderRunner(this, "async pipe receiver");
82
70
  const nextRun = readAsyncDecodeSourceRunner(next, "async pipe target");
@@ -90,44 +78,58 @@ export class BaseAsyncDecoder {
90
78
  }
91
79
  }
92
80
  /**
93
- * @brief async decoder.
81
+ * @brief Execute async decoder.
82
+ * @details This helper keeps a local invariant explicit at the module boundary.
94
83
  */
95
84
  export function asyncDecoder(source) {
96
85
  return makeAsyncDecoder(source);
97
86
  }
98
87
  /**
99
- * @brief async refine.
88
+ * @brief Execute async refine.
89
+ * @details This helper keeps a local invariant explicit at the module boundary.
100
90
  */
101
91
  export function asyncRefine(source, predicate, name) {
102
92
  return makeAsyncDecoder(source).refineAsync(predicate, name);
103
93
  }
104
94
  /**
105
- * @brief async transform.
95
+ * @brief Execute async transform.
96
+ * @details This helper keeps a local invariant explicit at the module boundary.
106
97
  */
107
98
  export function asyncTransform(source, mapper) {
108
99
  return makeAsyncDecoder(source).transformAsync(mapper);
109
100
  }
110
101
  /**
111
- * @brief async pipe.
102
+ * @brief Execute async pipe.
103
+ * @details This helper keeps a local invariant explicit at the module boundary.
112
104
  */
113
105
  export function asyncPipe(source, next) {
114
106
  return makeAsyncDecoder(source).pipeAsync(next);
115
107
  }
116
108
  /**
117
- * @brief is async decoder value.
109
+ * @brief Check async decoder value.
110
+ * @details This helper keeps a local invariant explicit at the module boundary.
118
111
  */
119
112
  export function isAsyncDecoderValue(value) {
120
113
  return isConstructedAsyncDecoder(value);
121
114
  }
122
115
  /**
123
- * @brief make async decoder.
116
+ * @brief Construct an async decoder from a guard, decoder, or async decoder.
117
+ * @details Decoder helpers keep validation failures explicit in Result values while
118
+ * preserving the original input value.
119
+ * @param source Source pipeline element.
120
+ * @returns Async decoder wrapping the normalized runner.
124
121
  */
125
122
  function makeAsyncDecoder(source) {
126
123
  const run = readAsyncDecodeSourceRunner(source, "async decoder source");
127
124
  return new BaseAsyncDecoder(run);
128
125
  }
129
126
  /**
130
- * @brief read async decode source runner.
127
+ * @brief Resolve an async decode source into a promise-returning runner.
128
+ * @param source Candidate source supplied to async decoder composition.
129
+ * @param label Message prefix for TypeError diagnostics.
130
+ * @returns Runner that always reports through a Promise.
131
+ * @details Sync decoders and guards are wrapped with Promise.resolve so the
132
+ * outer async pipeline has one uniform scheduling shape.
131
133
  */
132
134
  function readAsyncDecodeSourceRunner(source, label) {
133
135
  if (isConstructedAsyncDecoder(source)) {
@@ -140,7 +142,13 @@ function readAsyncDecodeSourceRunner(source, label) {
140
142
  return (value) => Promise.resolve(checkSchema(schema, value));
141
143
  }
142
144
  /**
143
- * @brief read async decoder runner.
145
+ * @brief Read the private runner from a constructed async decoder.
146
+ * @details Decoder helpers keep validation failures explicit in Result values while
147
+ * preserving the original input value.
148
+ * @param value Candidate async decoder object.
149
+ * @param label Message prefix for TypeError diagnostics.
150
+ * @returns Stored async decode runner.
151
+ * @throws TypeError when the value was not registered by the constructor.
144
152
  */
145
153
  function readAsyncDecoderRunner(value, label) {
146
154
  if (!isConstructedAsyncDecoder(value)) {
@@ -149,26 +157,41 @@ function readAsyncDecoderRunner(value, label) {
149
157
  return value[AsyncDecoderRunSymbol];
150
158
  }
151
159
  /**
152
- * @brief is constructed async decoder.
160
+ * @brief Test async decoder identity through the private registry.
161
+ * @details Decoder helpers keep validation failures explicit in Result values while
162
+ * preserving the original input value.
163
+ * @param value Candidate async decoder.
164
+ * @returns True when TypeSea constructed the instance.
153
165
  */
154
166
  function isConstructedAsyncDecoder(value) {
155
167
  return isRecord(value) && constructedAsyncDecoders.has(value);
156
168
  }
157
169
  /**
158
- * @brief read guard schema.
170
+ * @brief Normalize a guard-like source used in an async decode pipeline.
171
+ * @details Decoder helpers keep validation failures explicit in Result values while
172
+ * preserving the original input value.
173
+ * @param value Candidate guard-like source.
174
+ * @param label Message prefix for TypeError diagnostics.
175
+ * @returns Frozen schema used by the promise-wrapped check runner.
176
+ * @throws TypeError when the schema slot is absent or malformed.
159
177
  */
160
178
  function readGuardSchema(value, label) {
161
179
  if (!isRecord(value)) {
162
180
  throw new TypeError(`${label} must be a TypeSea guard or decoder`);
163
181
  }
164
- const schema = value["schema"];
182
+ const schema = readOwnDataProperty(value, "schema");
165
183
  if (!isSchemaValue(schema)) {
166
184
  throw new TypeError(`${label} must contain a valid TypeSea schema`);
167
185
  }
168
186
  return freezeSchema(schema);
169
187
  }
170
188
  /**
171
- * @brief fail refinement.
189
+ * @brief Build a single-issue failure for an async refinement.
190
+ * @details Decoder helpers keep validation failures explicit in Result values while
191
+ * preserving the original input value.
192
+ * @param name Diagnostic refinement name.
193
+ * @param value Runtime value rejected by the predicate.
194
+ * @returns Failure result with a root-level refinement issue.
172
195
  */
173
196
  function failRefinement(name, value) {
174
197
  return err(freezeIssueArray([
@@ -176,7 +199,11 @@ function failRefinement(name, value) {
176
199
  ]));
177
200
  }
178
201
  /**
179
- * @brief actual type.
202
+ * @brief Produce the compact runtime type label used in async decoder issues.
203
+ * @details Decoder helpers keep validation failures explicit in Result values while
204
+ * preserving the original input value.
205
+ * @param value Runtime value.
206
+ * @returns Stable diagnostic type name.
180
207
  */
181
208
  function actualType(value) {
182
209
  if (value === null) {
@@ -197,13 +224,23 @@ function actualType(value) {
197
224
  return typeof value;
198
225
  }
199
226
  /**
200
- * @brief is strict true.
227
+ * @brief Accept only the literal boolean success value from async predicates.
228
+ * @details Decoder helpers keep validation failures explicit in Result values while
229
+ * preserving the original input value.
230
+ * @param value Predicate return value.
231
+ * @returns True only for `true`.
201
232
  */
202
233
  function isStrictTrue(value) {
203
234
  return value === true;
204
235
  }
205
236
  /**
206
- * @brief define readonly property.
237
+ * @brief Define one immutable async decoder instance slot.
238
+ * @details Decoder helpers keep validation failures explicit in Result values while
239
+ * preserving the original input value.
240
+ * @param target Async decoder instance.
241
+ * @param key Public key or private symbol.
242
+ * @param value Stored field value.
243
+ * @param enumerable Whether the field should appear in enumeration.
207
244
  */
208
245
  function defineReadonlyProperty(target, key, value, enumerable) {
209
246
  Object.defineProperty(target, key, {
@@ -214,8 +251,28 @@ function defineReadonlyProperty(target, key, value, enumerable) {
214
251
  });
215
252
  }
216
253
  /**
217
- * @brief is record.
254
+ * @brief Accept objects that can carry async decoder or guard fields.
255
+ * @details Decoder helpers keep validation failures explicit in Result values while
256
+ * preserving the original input value.
257
+ * @param value Candidate object.
258
+ * @returns True for non-array objects.
218
259
  */
219
260
  function isRecord(value) {
220
261
  return typeof value === "object" && value !== null && !Array.isArray(value);
221
262
  }
263
+ /**
264
+ * @brief Read one own data slot from an async decode source.
265
+ * @details Decoder helpers keep validation failures explicit in Result values while
266
+ * preserving the original input value.
267
+ * @param value Object being normalized.
268
+ * @param key Field name or symbol.
269
+ * @returns Stored field value, or undefined when absent.
270
+ */
271
+ function readOwnDataProperty(value, key) {
272
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
273
+ if (descriptor === undefined ||
274
+ !Object.prototype.hasOwnProperty.call(descriptor, "value")) {
275
+ return undefined;
276
+ }
277
+ return descriptor.value;
278
+ }
@@ -1,31 +1,65 @@
1
1
  /**
2
2
  * @file composite.ts
3
3
  * @brief Composite guard builders.
4
+ * @details Builder helpers normalize user-facing fluent calls into immutable schema nodes
5
+ * with stable metadata.
4
6
  */
5
- import { BaseGuard, type Guard, type Infer, type Presence } from "../guard/index.js";
6
- import type { DiscriminatedUnionCases, InferTuple, TupleShape, UnionInput } from "./types.js";
7
+ import { ArrayGuard, BaseGuard, type Guard, type Infer, type Presence } from "../guard/index.js";
8
+ import type { DiscriminatedUnionCases, InferTuple, InferTupleWithRest, TupleShape, UnionInput } from "./types.js";
7
9
  /**
8
- * @brief array.
10
+ * @brief Build an array guard.
11
+ * @details Builder helpers normalize user-facing fluent calls into immutable schema nodes
12
+ * with stable metadata.
13
+ * @param item Guard used for each logical array slot.
14
+ * @returns Fresh array guard.
9
15
  */
10
- export declare function array<TGuard extends Guard<unknown, Presence>>(item: TGuard): BaseGuard<Infer<TGuard>[]>;
16
+ export declare function array<TGuard extends Guard<unknown, Presence>>(item: TGuard): ArrayGuard<Infer<TGuard>>;
11
17
  /**
12
- * @brief tuple.
18
+ * @brief Build a fixed-length tuple guard.
19
+ * @details Builder helpers normalize user-facing fluent calls into immutable schema nodes
20
+ * with stable metadata.
21
+ * @param shape Ordered guard list for tuple indexes.
22
+ * @returns Fresh tuple guard preserving item order.
23
+ * @throws TypeError when shape is not an array-like tuple input.
13
24
  */
14
25
  export declare function tuple<const TShape extends TupleShape>(shape: TShape): BaseGuard<InferTuple<TShape>>;
26
+ export declare function tuple<const TShape extends TupleShape, TRest extends Guard<unknown, Presence>>(shape: TShape, rest: TRest): BaseGuard<InferTupleWithRest<TShape, TRest>>;
15
27
  /**
16
- * @brief record.
28
+ * @brief Build a string-keyed record guard.
29
+ * @details Builder helpers normalize user-facing fluent calls into immutable schema nodes
30
+ * with stable metadata.
31
+ * @param value Guard used for each enumerable own record value.
32
+ * @returns Fresh record guard.
17
33
  */
18
34
  export declare function record<TGuard extends Guard<unknown, Presence>>(value: TGuard): BaseGuard<Readonly<Record<string, Infer<TGuard>>>>;
35
+ export declare function map<TKey extends Guard<unknown, Presence>, TValue extends Guard<unknown, Presence>>(key: TKey, value: TValue): BaseGuard<ReadonlyMap<Infer<TKey>, Infer<TValue>>>;
36
+ export declare function set<TItem extends Guard<unknown, Presence>>(item: TItem): BaseGuard<ReadonlySet<Infer<TItem>>>;
19
37
  /**
20
- * @brief union.
38
+ * @brief Build a union guard from one or more guards.
39
+ * @details Builder helpers normalize user-facing fluent calls into immutable schema nodes
40
+ * with stable metadata.
41
+ * @param guards Non-empty guard list.
42
+ * @returns Fresh union guard.
43
+ * @throws TypeError when called without guards.
21
44
  */
22
45
  export declare function union<const TGuards extends UnionInput>(...guards: TGuards): BaseGuard<Infer<TGuards[number]>>;
23
46
  /**
24
- * @brief intersect.
47
+ * @brief Build an intersection guard.
48
+ * @details Builder helpers normalize user-facing fluent calls into immutable schema nodes
49
+ * with stable metadata.
50
+ * @param left Left-hand guard.
51
+ * @param right Right-hand guard.
52
+ * @returns Fresh guard requiring both schemas to accept the value.
25
53
  */
26
54
  export declare function intersect<TLeft extends Guard<unknown, Presence>, TRight extends Guard<unknown, Presence>>(left: TLeft, right: TRight): BaseGuard<Infer<TLeft> & Infer<TRight>>;
27
55
  /**
28
- * @brief discriminated union.
56
+ * @brief Build a union whose branch can be selected by one literal property.
57
+ * @details This shape lowers to a dispatch table instead of a linear union
58
+ * scan, which is the fast path object unions should use.
59
+ * @param key Discriminant object key.
60
+ * @param cases Record from discriminant literal to branch guard.
61
+ * @returns Fresh discriminated-union guard.
62
+ * @throws TypeError when cases are empty or branch schemas do not require the tag.
29
63
  */
30
64
  export declare function discriminatedUnion<const TKey extends string, const TCases extends Readonly<Record<string, Guard<unknown, Presence>>>>(key: TKey, cases: TCases & DiscriminatedUnionCases<TKey, TCases>): BaseGuard<Infer<TCases[keyof TCases]>>;
31
65
  //# sourceMappingURL=composite.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"composite.d.ts","sourceRoot":"","sources":["../../src/builders/composite.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EACL,SAAS,EACT,KAAK,KAAK,EACV,KAAK,KAAK,EACV,KAAK,QAAQ,EACd,MAAM,mBAAmB,CAAC;AAM3B,OAAO,KAAK,EACV,uBAAuB,EACvB,UAAU,EACV,UAAU,EACV,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAgB,KAAK,CAAC,MAAM,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EAC3D,IAAI,EAAE,MAAM,GACX,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAK5B;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,CAAC,MAAM,SAAS,UAAU,EACnD,KAAK,EAAE,MAAM,GACZ,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAc/B;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,MAAM,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EAC5D,KAAK,EAAE,MAAM,GACZ,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAKpD;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,CAAC,OAAO,SAAS,UAAU,EACpD,GAAG,MAAM,EAAE,OAAO,GACjB,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAanC;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,KAAK,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EACtC,MAAM,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EAEvC,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,MAAM,GACZ,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAMzC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,CAAC,IAAI,SAAS,MAAM,EACzB,KAAK,CAAC,MAAM,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,EAEvE,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,MAAM,GAAG,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,GACpD,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,CA6BxC"}
1
+ {"version":3,"file":"composite.d.ts","sourceRoot":"","sources":["../../src/builders/composite.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EACH,UAAU,EACV,SAAS,EACT,KAAK,KAAK,EACV,KAAK,KAAK,EACV,KAAK,QAAQ,EAChB,MAAM,mBAAmB,CAAC;AAM3B,OAAO,KAAK,EACR,uBAAuB,EACvB,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,UAAU,EACb,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,MAAM,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EACzD,IAAI,EAAE,MAAM,GACb,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAM3B;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,KAAK,CAAC,MAAM,SAAS,UAAU,EACjD,KAAK,EAAE,MAAM,GACd,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AAEjC,wBAAgB,KAAK,CACjB,KAAK,CAAC,MAAM,SAAS,UAAU,EAC/B,KAAK,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EAEtC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,KAAK,GACZ,SAAS,CAAC,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AA4BhD;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,MAAM,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EAC1D,KAAK,EAAE,MAAM,GACd,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAKpD;AAED,wBAAgB,GAAG,CACf,IAAI,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EACrC,MAAM,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EAEvC,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,MAAM,GACd,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAMpD;AAED,wBAAgB,GAAG,CAAC,KAAK,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EACtD,IAAI,EAAE,KAAK,GACZ,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAKtC;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,KAAK,CAAC,OAAO,SAAS,UAAU,EAClD,GAAG,MAAM,EAAE,OAAO,GACnB,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAiBnC;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CACrB,KAAK,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EACtC,MAAM,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EAEvC,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,MAAM,GACd,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAMzC;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAC9B,KAAK,CAAC,IAAI,SAAS,MAAM,EACzB,KAAK,CAAC,MAAM,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,EAEvE,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,MAAM,GAAG,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,GACtD,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,CAiCxC"}
@@ -1,27 +1,35 @@
1
1
  /**
2
2
  * @file composite.ts
3
3
  * @brief Composite guard builders.
4
+ * @details Builder helpers normalize user-facing fluent calls into immutable schema nodes
5
+ * with stable metadata.
4
6
  */
5
7
  import { PresenceTag, SchemaTag } from "../kind/index.js";
6
- import { BaseGuard } from "../guard/index.js";
8
+ import { ArrayGuard, BaseGuard } from "../guard/index.js";
7
9
  import { isRecord, readGuardSchema } from "../internal/index.js";
8
10
  /**
9
- * @brief array.
11
+ * @brief Build an array guard.
12
+ * @details Builder helpers normalize user-facing fluent calls into immutable schema nodes
13
+ * with stable metadata.
14
+ * @param item Guard used for each logical array slot.
15
+ * @returns Fresh array guard.
10
16
  */
11
17
  export function array(item) {
12
- return new BaseGuard({
18
+ return new ArrayGuard({
13
19
  tag: SchemaTag.Array,
14
- item: readGuardSchema(item, "array item")
20
+ item: readGuardSchema(item, "array item"),
21
+ checks: []
15
22
  });
16
23
  }
17
- /**
18
- * @brief tuple.
19
- */
20
- export function tuple(shape) {
24
+ export function tuple(shape, rest) {
21
25
  const rawShape = shape;
22
26
  if (!Array.isArray(rawShape)) {
23
27
  throw new TypeError("tuple shape must be an array");
24
28
  }
29
+ /*
30
+ * Tuple indexes are read in order and stored as schemas, not guard objects,
31
+ * so later validation cannot observe mutation on user-held guard wrappers.
32
+ */
25
33
  const items = new Array(shape.length);
26
34
  for (let index = 0; index < shape.length; index += 1) {
27
35
  const guard = shape[index];
@@ -29,11 +37,18 @@ export function tuple(shape) {
29
37
  }
30
38
  return new BaseGuard({
31
39
  tag: SchemaTag.Tuple,
32
- items
40
+ items,
41
+ rest: rest === undefined
42
+ ? undefined
43
+ : readGuardSchema(rest, "tuple rest")
33
44
  });
34
45
  }
35
46
  /**
36
- * @brief record.
47
+ * @brief Build a string-keyed record guard.
48
+ * @details Builder helpers normalize user-facing fluent calls into immutable schema nodes
49
+ * with stable metadata.
50
+ * @param value Guard used for each enumerable own record value.
51
+ * @returns Fresh record guard.
37
52
  */
38
53
  export function record(value) {
39
54
  return new BaseGuard({
@@ -41,13 +56,35 @@ export function record(value) {
41
56
  value: readGuardSchema(value, "record value")
42
57
  });
43
58
  }
59
+ export function map(key, value) {
60
+ return new BaseGuard({
61
+ tag: SchemaTag.Map,
62
+ key: readGuardSchema(key, "map key"),
63
+ value: readGuardSchema(value, "map value")
64
+ });
65
+ }
66
+ export function set(item) {
67
+ return new BaseGuard({
68
+ tag: SchemaTag.Set,
69
+ item: readGuardSchema(item, "set item")
70
+ });
71
+ }
44
72
  /**
45
- * @brief union.
73
+ * @brief Build a union guard from one or more guards.
74
+ * @details Builder helpers normalize user-facing fluent calls into immutable schema nodes
75
+ * with stable metadata.
76
+ * @param guards Non-empty guard list.
77
+ * @returns Fresh union guard.
78
+ * @throws TypeError when called without guards.
46
79
  */
47
80
  export function union(...guards) {
48
81
  if (guards.length === 0) {
49
82
  throw new TypeError("union requires at least one guard");
50
83
  }
84
+ /*
85
+ * Preserve option order. Diagnostics and generated dispatch use this order
86
+ * when probing branches and constructing graph children.
87
+ */
51
88
  const options = new Array(guards.length);
52
89
  for (let index = 0; index < guards.length; index += 1) {
53
90
  const guard = guards[index];
@@ -59,7 +96,12 @@ export function union(...guards) {
59
96
  });
60
97
  }
61
98
  /**
62
- * @brief intersect.
99
+ * @brief Build an intersection guard.
100
+ * @details Builder helpers normalize user-facing fluent calls into immutable schema nodes
101
+ * with stable metadata.
102
+ * @param left Left-hand guard.
103
+ * @param right Right-hand guard.
104
+ * @returns Fresh guard requiring both schemas to accept the value.
63
105
  */
64
106
  export function intersect(left, right) {
65
107
  return new BaseGuard({
@@ -69,7 +111,13 @@ export function intersect(left, right) {
69
111
  });
70
112
  }
71
113
  /**
72
- * @brief discriminated union.
114
+ * @brief Build a union whose branch can be selected by one literal property.
115
+ * @details This shape lowers to a dispatch table instead of a linear union
116
+ * scan, which is the fast path object unions should use.
117
+ * @param key Discriminant object key.
118
+ * @param cases Record from discriminant literal to branch guard.
119
+ * @returns Fresh discriminated-union guard.
120
+ * @throws TypeError when cases are empty or branch schemas do not require the tag.
73
121
  */
74
122
  export function discriminatedUnion(key, cases) {
75
123
  if (typeof key !== "string") {
@@ -82,6 +130,10 @@ export function discriminatedUnion(key, cases) {
82
130
  if (entries.length === 0) {
83
131
  throw new TypeError("discriminated union requires at least one case");
84
132
  }
133
+ /*
134
+ * Object.entries defines the dispatch order. The literal string is taken
135
+ * from the case key and must be required by the branch schema below.
136
+ */
85
137
  const unionCases = new Array(entries.length);
86
138
  for (let index = 0; index < entries.length; index += 1) {
87
139
  const pair = entries[index];
@@ -102,7 +154,15 @@ export function discriminatedUnion(key, cases) {
102
154
  });
103
155
  }
104
156
  /**
105
- * @brief read discriminated union case schema.
157
+ * @brief Extract and validate one discriminated-union branch schema.
158
+ * @details A branch is accepted only when its object schema itself proves the
159
+ * discriminant literal. Without that proof, dispatch by table key could select
160
+ * a branch whose validator later accepts a different tag shape.
161
+ * @param guard Branch guard from the cases table.
162
+ * @param key Discriminant key shared by all cases.
163
+ * @param literal Literal value assigned to this case.
164
+ * @returns Branch schema after discriminant proof.
165
+ * @throws TypeError when the branch does not require its literal tag.
106
166
  */
107
167
  function readDiscriminatedUnionCaseSchema(guard, key, literal) {
108
168
  const schema = readGuardSchema(guard, `case ${literal}`);
@@ -112,7 +172,15 @@ function readDiscriminatedUnionCaseSchema(guard, key, literal) {
112
172
  return schema;
113
173
  }
114
174
  /**
115
- * @brief case requires discriminant.
175
+ * @brief Prove that a branch structurally requires the requested tag literal.
176
+ * @details Dispatch tables are only sound when accepting a branch implies that
177
+ * the discriminant key is present and equal to its table literal. The proof is
178
+ * intentionally structural and refuses schemas whose tag requirement is hidden
179
+ * behind runtime-only logic.
180
+ * @param schema Branch schema to inspect.
181
+ * @param key Discriminant key.
182
+ * @param literal Required literal value.
183
+ * @returns True when the branch structurally requires `key: literal`.
116
184
  */
117
185
  function caseRequiresDiscriminant(schema, key, literal) {
118
186
  const objectSchema = unwrapCaseObjectSchema(schema);
@@ -131,13 +199,22 @@ function caseRequiresDiscriminant(schema, key, literal) {
131
199
  return false;
132
200
  }
133
201
  /**
134
- * @brief unwrap case object schema.
202
+ * @brief Find the object schema that can prove a discriminant requirement.
203
+ * @details Brand and refinement wrappers do not change object shape, and either
204
+ * side of an intersection may supply the tag field. Other schema forms cannot
205
+ * provide the required object-field proof.
206
+ * @param schema Branch schema possibly wrapped by brand/refine/intersection.
207
+ * @returns Object schema used for discriminant inspection, or undefined.
135
208
  */
136
209
  function unwrapCaseObjectSchema(schema) {
137
210
  switch (schema.tag) {
138
211
  case SchemaTag.Object:
139
212
  return schema;
140
213
  case SchemaTag.Intersection:
214
+ /*
215
+ * A discriminant can be supplied by either side of an intersection.
216
+ * Search both sides before rejecting the case.
217
+ */
141
218
  return unwrapCaseObjectSchema(schema.left) ?? unwrapCaseObjectSchema(schema.right);
142
219
  case SchemaTag.Brand:
143
220
  case SchemaTag.Refine:
@@ -147,7 +224,13 @@ function unwrapCaseObjectSchema(schema) {
147
224
  }
148
225
  }
149
226
  /**
150
- * @brief schema requires literal.
227
+ * @brief Prove that a discriminant field schema accepts only one literal.
228
+ * @details Intersections may prove the literal from either side, while brand
229
+ * and refinement wrappers preserve the underlying literal requirement. Broader
230
+ * schemas are rejected because they would make table dispatch unsound.
231
+ * @param schema Schema attached to the discriminant property.
232
+ * @param literal Literal value required by the case.
233
+ * @returns True when the schema accepts only the requested literal.
151
234
  */
152
235
  function schemaRequiresLiteral(schema, literal) {
153
236
  switch (schema.tag) {
@@ -1,11 +1,14 @@
1
1
  /**
2
2
  * @file index.ts
3
3
  * @brief Public builder module aggregation.
4
+ * @details This barrel keeps public import paths stable while implementation files remain
5
+ * split by responsibility.
4
6
  */
5
- export { array, discriminatedUnion, intersect, record, tuple, union } from "./composite.js";
6
- export { lazy, nullable, optional, refine, undefinedable } from "./modifier.js";
7
- export { ObjectGuard, extend, object, omit, partial, pick, strictObject, type InferObject, type MergeObjectShapes, type ObjectGuardMode, type ObjectShape, type OmitObjectShape, type PartialObjectShape, type PickObjectShape } from "./object/index.js";
8
- export { bigintGuard, literal, neverGuard, symbolGuard, unknownGuard } from "./scalar.js";
7
+ export { array, discriminatedUnion, intersect, map, record, set, tuple, union } from "./composite.js";
8
+ export { lazy, nullable, nullish, optional, refine, undefinedable } from "./modifier.js";
9
+ export { ObjectGuard, catchall, deepPartial, extend, merge, object, omit, partial, passthrough, pick, required, safeExtend, strict, strictObject, strip, type DeepPartialObjectShape, type DeepPartialValue, type InferObject, type MaskSelectedKeys, type MergeObjectShapes, type ObjectKeyMask, type ObjectGuardMode, type ObjectShape, type OmitObjectShape, type OmitObjectShapeByMask, type PartialObjectShape, type PickObjectShape, type PickObjectShapeByMask, type RequiredObjectShape } from "./object/index.js";
10
+ export { bigintGuard, booleanGuard, dateGuard, enumValues, enumValues as enum, literal, neverGuard, nullGuard, numberGuard, symbolGuard, stringGuard, unknownGuard, undefinedGuard, voidGuard, type EnumValues } from "./scalar.js";
11
+ export { instanceOf, json, property, type InstanceConstructor, type JsonValue } from "./runtime.js";
9
12
  export { t } from "./table.js";
10
- export type { InferTuple, TupleShape } from "./types.js";
13
+ export type { InferTuple, InferTupleWithRest, TupleShape } from "./types.js";
11
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/builders/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,KAAK,EACL,kBAAkB,EAClB,SAAS,EACT,MAAM,EACN,KAAK,EACL,KAAK,EACN,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,aAAa,EACd,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,WAAW,EACX,MAAM,EACN,MAAM,EACN,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EACX,OAAO,EACP,UAAU,EACV,WAAW,EACX,YAAY,EACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAC/B,YAAY,EACV,UAAU,EACV,UAAU,EACX,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/builders/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACH,KAAK,EACL,kBAAkB,EAClB,SAAS,EACT,GAAG,EACH,MAAM,EACN,GAAG,EACH,KAAK,EACL,KAAK,EACR,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACH,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,MAAM,EACN,aAAa,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EACH,WAAW,EACX,QAAQ,EACR,WAAW,EACX,MAAM,EACN,KAAK,EACL,MAAM,EACN,IAAI,EACJ,OAAO,EACP,WAAW,EACX,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,MAAM,EACN,YAAY,EACZ,KAAK,EACL,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,WAAW,EACX,YAAY,EACZ,SAAS,EACT,UAAU,EACV,UAAU,IAAI,IAAI,EAClB,OAAO,EACP,UAAU,EACV,SAAS,EACT,WAAW,EACX,WAAW,EACX,WAAW,EACX,YAAY,EACZ,cAAc,EACd,SAAS,EACT,KAAK,UAAU,EAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EACH,UAAU,EACV,IAAI,EACJ,QAAQ,EACR,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAC/B,YAAY,EACR,UAAU,EACV,kBAAkB,EAClB,UAAU,EACb,MAAM,YAAY,CAAC"}
@@ -1,9 +1,12 @@
1
1
  /**
2
2
  * @file index.ts
3
3
  * @brief Public builder module aggregation.
4
+ * @details This barrel keeps public import paths stable while implementation files remain
5
+ * split by responsibility.
4
6
  */
5
- export { array, discriminatedUnion, intersect, record, tuple, union } from "./composite.js";
6
- export { lazy, nullable, optional, refine, undefinedable } from "./modifier.js";
7
- export { ObjectGuard, extend, object, omit, partial, pick, strictObject } from "./object/index.js";
8
- export { bigintGuard, literal, neverGuard, symbolGuard, unknownGuard } from "./scalar.js";
7
+ export { array, discriminatedUnion, intersect, map, record, set, tuple, union } from "./composite.js";
8
+ export { lazy, nullable, nullish, optional, refine, undefinedable } from "./modifier.js";
9
+ export { ObjectGuard, catchall, deepPartial, extend, merge, object, omit, partial, passthrough, pick, required, safeExtend, strict, strictObject, strip } from "./object/index.js";
10
+ export { bigintGuard, booleanGuard, dateGuard, enumValues, enumValues as enum, literal, neverGuard, nullGuard, numberGuard, symbolGuard, stringGuard, unknownGuard, undefinedGuard, voidGuard } from "./scalar.js";
11
+ export { instanceOf, json, property } from "./runtime.js";
9
12
  export { t } from "./table.js";