typesea 0.1.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 (271) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +21 -0
  3. package/README.md +320 -0
  4. package/dist/adapters/index.d.ts +152 -0
  5. package/dist/adapters/index.d.ts.map +1 -0
  6. package/dist/adapters/index.js +396 -0
  7. package/dist/aot/index.d.ts +33 -0
  8. package/dist/aot/index.d.ts.map +1 -0
  9. package/dist/aot/index.js +295 -0
  10. package/dist/async/index.d.ts +111 -0
  11. package/dist/async/index.d.ts.map +1 -0
  12. package/dist/async/index.js +221 -0
  13. package/dist/builders/composite.d.ts +31 -0
  14. package/dist/builders/composite.d.ts.map +1 -0
  15. package/dist/builders/composite.js +165 -0
  16. package/dist/builders/index.d.ts +11 -0
  17. package/dist/builders/index.d.ts.map +1 -0
  18. package/dist/builders/index.js +9 -0
  19. package/dist/builders/modifier.d.ts +26 -0
  20. package/dist/builders/modifier.d.ts.map +1 -0
  21. package/dist/builders/modifier.js +67 -0
  22. package/dist/builders/object/guard.d.ts +62 -0
  23. package/dist/builders/object/guard.d.ts.map +1 -0
  24. package/dist/builders/object/guard.js +113 -0
  25. package/dist/builders/object/index.d.ts +7 -0
  26. package/dist/builders/object/index.d.ts.map +1 -0
  27. package/dist/builders/object/index.js +5 -0
  28. package/dist/builders/object/schema.d.ts +44 -0
  29. package/dist/builders/object/schema.d.ts.map +1 -0
  30. package/dist/builders/object/schema.js +257 -0
  31. package/dist/builders/object/types.d.ts +63 -0
  32. package/dist/builders/object/types.d.ts.map +1 -0
  33. package/dist/builders/object/types.js +5 -0
  34. package/dist/builders/scalar.d.ts +39 -0
  35. package/dist/builders/scalar.d.ts.map +1 -0
  36. package/dist/builders/scalar.js +63 -0
  37. package/dist/builders/table.d.ts +53 -0
  38. package/dist/builders/table.d.ts.map +1 -0
  39. package/dist/builders/table.js +48 -0
  40. package/dist/builders/types.d.ts +26 -0
  41. package/dist/builders/types.d.ts.map +1 -0
  42. package/dist/builders/types.js +5 -0
  43. package/dist/compile/check-composite.d.ts +34 -0
  44. package/dist/compile/check-composite.d.ts.map +1 -0
  45. package/dist/compile/check-composite.js +117 -0
  46. package/dist/compile/check-scalar.d.ts +24 -0
  47. package/dist/compile/check-scalar.d.ts.map +1 -0
  48. package/dist/compile/check-scalar.js +73 -0
  49. package/dist/compile/check.d.ts +15 -0
  50. package/dist/compile/check.d.ts.map +1 -0
  51. package/dist/compile/check.js +98 -0
  52. package/dist/compile/context.d.ts +35 -0
  53. package/dist/compile/context.d.ts.map +1 -0
  54. package/dist/compile/context.js +72 -0
  55. package/dist/compile/graph-predicate.d.ts +19 -0
  56. package/dist/compile/graph-predicate.d.ts.map +1 -0
  57. package/dist/compile/graph-predicate.js +460 -0
  58. package/dist/compile/guard.d.ts +41 -0
  59. package/dist/compile/guard.d.ts.map +1 -0
  60. package/dist/compile/guard.js +180 -0
  61. package/dist/compile/index.d.ts +8 -0
  62. package/dist/compile/index.d.ts.map +1 -0
  63. package/dist/compile/index.js +6 -0
  64. package/dist/compile/issue.d.ts +18 -0
  65. package/dist/compile/issue.d.ts.map +1 -0
  66. package/dist/compile/issue.js +28 -0
  67. package/dist/compile/names.d.ts +16 -0
  68. package/dist/compile/names.d.ts.map +1 -0
  69. package/dist/compile/names.js +82 -0
  70. package/dist/compile/predicate.d.ts +23 -0
  71. package/dist/compile/predicate.d.ts.map +1 -0
  72. package/dist/compile/predicate.js +317 -0
  73. package/dist/compile/runtime.d.ts +55 -0
  74. package/dist/compile/runtime.d.ts.map +1 -0
  75. package/dist/compile/runtime.js +63 -0
  76. package/dist/compile/source.d.ts +11 -0
  77. package/dist/compile/source.d.ts.map +1 -0
  78. package/dist/compile/source.js +51 -0
  79. package/dist/compile/types.d.ts +52 -0
  80. package/dist/compile/types.d.ts.map +1 -0
  81. package/dist/compile/types.js +5 -0
  82. package/dist/decoder/index.d.ts +106 -0
  83. package/dist/decoder/index.d.ts.map +1 -0
  84. package/dist/decoder/index.js +262 -0
  85. package/dist/evaluate/check-composite.d.ts +39 -0
  86. package/dist/evaluate/check-composite.d.ts.map +1 -0
  87. package/dist/evaluate/check-composite.js +184 -0
  88. package/dist/evaluate/check-scalar.d.ts +20 -0
  89. package/dist/evaluate/check-scalar.d.ts.map +1 -0
  90. package/dist/evaluate/check-scalar.js +81 -0
  91. package/dist/evaluate/check.d.ts +11 -0
  92. package/dist/evaluate/check.d.ts.map +1 -0
  93. package/dist/evaluate/check.js +126 -0
  94. package/dist/evaluate/index.d.ts +7 -0
  95. package/dist/evaluate/index.d.ts.map +1 -0
  96. package/dist/evaluate/index.js +6 -0
  97. package/dist/evaluate/issue.d.ts +10 -0
  98. package/dist/evaluate/issue.d.ts.map +1 -0
  99. package/dist/evaluate/issue.js +11 -0
  100. package/dist/evaluate/predicate.d.ts +26 -0
  101. package/dist/evaluate/predicate.d.ts.map +1 -0
  102. package/dist/evaluate/predicate.js +37 -0
  103. package/dist/evaluate/shared.d.ts +59 -0
  104. package/dist/evaluate/shared.d.ts.map +1 -0
  105. package/dist/evaluate/shared.js +96 -0
  106. package/dist/evaluate/state.d.ts +65 -0
  107. package/dist/evaluate/state.d.ts.map +1 -0
  108. package/dist/evaluate/state.js +66 -0
  109. package/dist/guard/base.d.ts +72 -0
  110. package/dist/guard/base.d.ts.map +1 -0
  111. package/dist/guard/base.js +136 -0
  112. package/dist/guard/error.d.ts +19 -0
  113. package/dist/guard/error.d.ts.map +1 -0
  114. package/dist/guard/error.js +22 -0
  115. package/dist/guard/index.d.ts +10 -0
  116. package/dist/guard/index.d.ts.map +1 -0
  117. package/dist/guard/index.js +8 -0
  118. package/dist/guard/number.d.ts +32 -0
  119. package/dist/guard/number.d.ts.map +1 -0
  120. package/dist/guard/number.js +71 -0
  121. package/dist/guard/props.d.ts +18 -0
  122. package/dist/guard/props.d.ts.map +1 -0
  123. package/dist/guard/props.js +35 -0
  124. package/dist/guard/read.d.ts +42 -0
  125. package/dist/guard/read.d.ts.map +1 -0
  126. package/dist/guard/read.js +114 -0
  127. package/dist/guard/registry.d.ts +15 -0
  128. package/dist/guard/registry.d.ts.map +1 -0
  129. package/dist/guard/registry.js +21 -0
  130. package/dist/guard/string.d.ts +36 -0
  131. package/dist/guard/string.d.ts.map +1 -0
  132. package/dist/guard/string.js +95 -0
  133. package/dist/guard/types.d.ts +103 -0
  134. package/dist/guard/types.d.ts.map +1 -0
  135. package/dist/guard/types.js +5 -0
  136. package/dist/index.d.ts +14 -0
  137. package/dist/index.d.ts.map +1 -0
  138. package/dist/index.js +10 -0
  139. package/dist/internal/index.d.ts +34 -0
  140. package/dist/internal/index.d.ts.map +1 -0
  141. package/dist/internal/index.js +56 -0
  142. package/dist/ir/builder.d.ts +173 -0
  143. package/dist/ir/builder.d.ts.map +1 -0
  144. package/dist/ir/builder.js +481 -0
  145. package/dist/ir/freeze.d.ts +10 -0
  146. package/dist/ir/freeze.d.ts.map +1 -0
  147. package/dist/ir/freeze.js +102 -0
  148. package/dist/ir/index.d.ts +9 -0
  149. package/dist/ir/index.d.ts.map +1 -0
  150. package/dist/ir/index.js +7 -0
  151. package/dist/ir/regexp.d.ts +6 -0
  152. package/dist/ir/regexp.d.ts.map +1 -0
  153. package/dist/ir/regexp.js +12 -0
  154. package/dist/ir/types.d.ts +215 -0
  155. package/dist/ir/types.d.ts.map +1 -0
  156. package/dist/ir/types.js +5 -0
  157. package/dist/ir/validate.d.ts +10 -0
  158. package/dist/ir/validate.d.ts.map +1 -0
  159. package/dist/ir/validate.js +271 -0
  160. package/dist/issue/index.d.ts +44 -0
  161. package/dist/issue/index.d.ts.map +1 -0
  162. package/dist/issue/index.js +152 -0
  163. package/dist/json-schema/emit-combinator.d.ts +28 -0
  164. package/dist/json-schema/emit-combinator.d.ts.map +1 -0
  165. package/dist/json-schema/emit-combinator.js +96 -0
  166. package/dist/json-schema/emit-composite.d.ts +28 -0
  167. package/dist/json-schema/emit-composite.d.ts.map +1 -0
  168. package/dist/json-schema/emit-composite.js +127 -0
  169. package/dist/json-schema/emit-scalar.d.ts +25 -0
  170. package/dist/json-schema/emit-scalar.d.ts.map +1 -0
  171. package/dist/json-schema/emit-scalar.js +104 -0
  172. package/dist/json-schema/emit-types.d.ts +12 -0
  173. package/dist/json-schema/emit-types.d.ts.map +1 -0
  174. package/dist/json-schema/emit-types.js +5 -0
  175. package/dist/json-schema/emit.d.ts +12 -0
  176. package/dist/json-schema/emit.d.ts.map +1 -0
  177. package/dist/json-schema/emit.js +62 -0
  178. package/dist/json-schema/freeze.d.ts +14 -0
  179. package/dist/json-schema/freeze.d.ts.map +1 -0
  180. package/dist/json-schema/freeze.js +114 -0
  181. package/dist/json-schema/index.d.ts +20 -0
  182. package/dist/json-schema/index.d.ts.map +1 -0
  183. package/dist/json-schema/index.js +76 -0
  184. package/dist/json-schema/issue.d.ts +11 -0
  185. package/dist/json-schema/issue.d.ts.map +1 -0
  186. package/dist/json-schema/issue.js +14 -0
  187. package/dist/json-schema/read.d.ts +29 -0
  188. package/dist/json-schema/read.d.ts.map +1 -0
  189. package/dist/json-schema/read.js +87 -0
  190. package/dist/json-schema/types.d.ts +106 -0
  191. package/dist/json-schema/types.d.ts.map +1 -0
  192. package/dist/json-schema/types.js +5 -0
  193. package/dist/kind/index.d.ts +119 -0
  194. package/dist/kind/index.d.ts.map +1 -0
  195. package/dist/kind/index.js +94 -0
  196. package/dist/lower/index.d.ts +7 -0
  197. package/dist/lower/index.d.ts.map +1 -0
  198. package/dist/lower/index.js +199 -0
  199. package/dist/message/index.d.ts +51 -0
  200. package/dist/message/index.d.ts.map +1 -0
  201. package/dist/message/index.js +269 -0
  202. package/dist/optimize/compact.d.ts +10 -0
  203. package/dist/optimize/compact.d.ts.map +1 -0
  204. package/dist/optimize/compact.js +60 -0
  205. package/dist/optimize/fold-boolean.d.ts +15 -0
  206. package/dist/optimize/fold-boolean.d.ts.map +1 -0
  207. package/dist/optimize/fold-boolean.js +75 -0
  208. package/dist/optimize/fold-common.d.ts +45 -0
  209. package/dist/optimize/fold-common.d.ts.map +1 -0
  210. package/dist/optimize/fold-common.js +71 -0
  211. package/dist/optimize/fold-scalar.d.ts +59 -0
  212. package/dist/optimize/fold-scalar.d.ts.map +1 -0
  213. package/dist/optimize/fold-scalar.js +174 -0
  214. package/dist/optimize/fold.d.ts +10 -0
  215. package/dist/optimize/fold.d.ts.map +1 -0
  216. package/dist/optimize/fold.js +103 -0
  217. package/dist/optimize/index.d.ts +10 -0
  218. package/dist/optimize/index.d.ts.map +1 -0
  219. package/dist/optimize/index.js +23 -0
  220. package/dist/optimize/map-node.d.ts +21 -0
  221. package/dist/optimize/map-node.d.ts.map +1 -0
  222. package/dist/optimize/map-node.js +222 -0
  223. package/dist/optimize/remap.d.ts +30 -0
  224. package/dist/optimize/remap.d.ts.map +1 -0
  225. package/dist/optimize/remap.js +46 -0
  226. package/dist/optimize/rewrite.d.ts +22 -0
  227. package/dist/optimize/rewrite.d.ts.map +1 -0
  228. package/dist/optimize/rewrite.js +34 -0
  229. package/dist/plan/cache.d.ts +20 -0
  230. package/dist/plan/cache.d.ts.map +1 -0
  231. package/dist/plan/cache.js +122 -0
  232. package/dist/plan/index.d.ts +8 -0
  233. package/dist/plan/index.d.ts.map +1 -0
  234. package/dist/plan/index.js +6 -0
  235. package/dist/plan/predicate.d.ts +27 -0
  236. package/dist/plan/predicate.d.ts.map +1 -0
  237. package/dist/plan/predicate.js +415 -0
  238. package/dist/plan/schema-predicate.d.ts +15 -0
  239. package/dist/plan/schema-predicate.d.ts.map +1 -0
  240. package/dist/plan/schema-predicate.js +277 -0
  241. package/dist/plan/types.d.ts +18 -0
  242. package/dist/plan/types.d.ts.map +1 -0
  243. package/dist/plan/types.js +5 -0
  244. package/dist/result/index.d.ts +27 -0
  245. package/dist/result/index.d.ts.map +1 -0
  246. package/dist/result/index.js +20 -0
  247. package/dist/schema/common.d.ts +30 -0
  248. package/dist/schema/common.d.ts.map +1 -0
  249. package/dist/schema/common.js +102 -0
  250. package/dist/schema/freeze.d.ts +10 -0
  251. package/dist/schema/freeze.d.ts.map +1 -0
  252. package/dist/schema/freeze.js +163 -0
  253. package/dist/schema/index.d.ts +11 -0
  254. package/dist/schema/index.d.ts.map +1 -0
  255. package/dist/schema/index.js +9 -0
  256. package/dist/schema/lazy.d.ts +10 -0
  257. package/dist/schema/lazy.d.ts.map +1 -0
  258. package/dist/schema/lazy.js +25 -0
  259. package/dist/schema/literal.d.ts +10 -0
  260. package/dist/schema/literal.d.ts.map +1 -0
  261. package/dist/schema/literal.js +17 -0
  262. package/dist/schema/types.d.ts +243 -0
  263. package/dist/schema/types.d.ts.map +1 -0
  264. package/dist/schema/types.js +9 -0
  265. package/dist/schema/validate.d.ts +10 -0
  266. package/dist/schema/validate.d.ts.map +1 -0
  267. package/dist/schema/validate.js +268 -0
  268. package/docs/api.md +301 -0
  269. package/docs/engine-notes.md +153 -0
  270. package/docs/index.html +1242 -0
  271. package/package.json +68 -0
@@ -0,0 +1,1242 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta
7
+ name="description"
8
+ content="TypeSea documentation: zero-dependency TypeScript runtime narrowing with cached Sea-of-Nodes validation plans, runtime compilation, and AOT emission."
9
+ >
10
+ <title>TypeSea Docs</title>
11
+ <style>
12
+ :root {
13
+ color-scheme: light dark;
14
+ --bg: #f6f8f7;
15
+ --surface: #ffffff;
16
+ --surface-2: #eef2ef;
17
+ --ink: #1c2422;
18
+ --muted: #5c6a64;
19
+ --line: #dbe2dc;
20
+ --accent: #0f7a5c;
21
+ --accent-ink: #0b5c46;
22
+ --accent-soft: #d9f2e7;
23
+ --amber: #b45309;
24
+ --amber-soft: #fdecd3;
25
+ --violet: #6d28d9;
26
+ --violet-soft: #ede9fe;
27
+ --code-bg: #14181f;
28
+ --code-ink: #e8eef5;
29
+ --code-comment: #8b98a9;
30
+ --sidebar-bg: #1d2422;
31
+ --sidebar-ink: #e9efe9;
32
+ --sidebar-muted: #9fae a5;
33
+ --sidebar-muted: #9faea5;
34
+ --sidebar-line: rgba(233, 239, 233, 0.12);
35
+ --shadow: 0 10px 30px rgba(28, 36, 34, 0.07);
36
+ }
37
+
38
+ @media (prefers-color-scheme: dark) {
39
+ :root {
40
+ --bg: #12171a;
41
+ --surface: #191f23;
42
+ --surface-2: #1f272c;
43
+ --ink: #e4eae6;
44
+ --muted: #97a49d;
45
+ --line: #2a333a;
46
+ --accent: #34c496;
47
+ --accent-ink: #7fe0c0;
48
+ --accent-soft: rgba(52, 196, 150, 0.16);
49
+ --amber: #f0a24a;
50
+ --amber-soft: rgba(240, 162, 74, 0.16);
51
+ --violet: #a78bfa;
52
+ --violet-soft: rgba(167, 139, 250, 0.16);
53
+ --code-bg: #0d1116;
54
+ --code-ink: #dde5ee;
55
+ --sidebar-bg: #151b1e;
56
+ --shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
57
+ }
58
+ }
59
+
60
+ * {
61
+ box-sizing: border-box;
62
+ }
63
+
64
+ html {
65
+ scroll-behavior: smooth;
66
+ }
67
+
68
+ body {
69
+ min-width: 320px;
70
+ margin: 0;
71
+ background: var(--bg);
72
+ color: var(--ink);
73
+ font-family:
74
+ ui-sans-serif,
75
+ system-ui,
76
+ -apple-system,
77
+ "Segoe UI",
78
+ Roboto,
79
+ "Helvetica Neue",
80
+ sans-serif;
81
+ font-size: 15px;
82
+ line-height: 1.6;
83
+ }
84
+
85
+ a {
86
+ color: inherit;
87
+ text-decoration: none;
88
+ }
89
+
90
+ code,
91
+ pre {
92
+ font-family:
93
+ ui-monospace,
94
+ "SFMono-Regular",
95
+ Menlo,
96
+ Consolas,
97
+ "Liberation Mono",
98
+ monospace;
99
+ }
100
+
101
+ p code,
102
+ li code,
103
+ td code {
104
+ border-radius: 5px;
105
+ padding: 1px 5px;
106
+ background: var(--surface-2);
107
+ font-size: 0.92em;
108
+ }
109
+
110
+ /* ---------- shell ---------- */
111
+
112
+ .shell {
113
+ display: grid;
114
+ min-height: 100vh;
115
+ grid-template-columns: 264px minmax(0, 1fr);
116
+ }
117
+
118
+ .sidebar {
119
+ position: sticky;
120
+ top: 0;
121
+ display: flex;
122
+ flex-direction: column;
123
+ height: 100vh;
124
+ border-right: 1px solid var(--sidebar-line);
125
+ background: var(--sidebar-bg);
126
+ color: var(--sidebar-ink);
127
+ overflow-y: auto;
128
+ }
129
+
130
+ .brand {
131
+ display: flex;
132
+ align-items: baseline;
133
+ gap: 10px;
134
+ padding: 26px 22px 6px;
135
+ }
136
+
137
+ .brand h1 {
138
+ margin: 0;
139
+ font-size: 22px;
140
+ line-height: 1;
141
+ letter-spacing: -0.01em;
142
+ }
143
+
144
+ .brand .version {
145
+ border-radius: 999px;
146
+ padding: 2px 8px;
147
+ background: rgba(52, 196, 150, 0.18);
148
+ color: #7fe0c0;
149
+ font-size: 11px;
150
+ font-weight: 700;
151
+ }
152
+
153
+ .brand-tagline {
154
+ margin: 0;
155
+ padding: 0 22px 18px;
156
+ border-bottom: 1px solid var(--sidebar-line);
157
+ color: var(--sidebar-muted);
158
+ font-size: 12.5px;
159
+ line-height: 1.5;
160
+ }
161
+
162
+ .search {
163
+ padding: 16px 16px 8px;
164
+ }
165
+
166
+ .search input {
167
+ width: 100%;
168
+ min-height: 36px;
169
+ border: 1px solid var(--sidebar-line);
170
+ border-radius: 8px;
171
+ padding: 0 12px;
172
+ background: rgba(255, 255, 255, 0.06);
173
+ color: var(--sidebar-ink);
174
+ font: inherit;
175
+ font-size: 13px;
176
+ outline: none;
177
+ }
178
+
179
+ .search input:focus {
180
+ border-color: #46b48f;
181
+ }
182
+
183
+ .search input::placeholder {
184
+ color: var(--sidebar-muted);
185
+ }
186
+
187
+ .nav {
188
+ flex: 1;
189
+ padding: 6px 12px 18px;
190
+ }
191
+
192
+ .nav-group {
193
+ margin: 14px 0 4px;
194
+ padding: 0 12px;
195
+ color: var(--sidebar-muted);
196
+ font-size: 11px;
197
+ font-weight: 700;
198
+ letter-spacing: 0.08em;
199
+ text-transform: uppercase;
200
+ }
201
+
202
+ .nav a {
203
+ display: flex;
204
+ align-items: center;
205
+ min-height: 33px;
206
+ border-left: 2px solid transparent;
207
+ border-radius: 0 7px 7px 0;
208
+ margin: 1px 0;
209
+ padding: 5px 12px;
210
+ color: var(--sidebar-ink);
211
+ opacity: 0.82;
212
+ font-size: 13.5px;
213
+ }
214
+
215
+ .nav a:hover,
216
+ .nav a:focus {
217
+ background: rgba(255, 255, 255, 0.07);
218
+ opacity: 1;
219
+ }
220
+
221
+ .nav a.active {
222
+ border-left-color: #34c496;
223
+ background: rgba(52, 196, 150, 0.1);
224
+ color: #9ce8cd;
225
+ opacity: 1;
226
+ }
227
+
228
+ .sidebar-foot {
229
+ padding: 14px 22px 20px;
230
+ border-top: 1px solid var(--sidebar-line);
231
+ color: var(--sidebar-muted);
232
+ font-size: 12px;
233
+ }
234
+
235
+ /* ---------- content ---------- */
236
+
237
+ .content {
238
+ min-width: 0;
239
+ }
240
+
241
+ .topbar {
242
+ position: sticky;
243
+ top: 0;
244
+ z-index: 5;
245
+ display: flex;
246
+ align-items: center;
247
+ justify-content: space-between;
248
+ gap: 16px;
249
+ min-height: 56px;
250
+ border-bottom: 1px solid var(--line);
251
+ padding: 0 34px;
252
+ background: color-mix(in srgb, var(--bg) 90%, transparent);
253
+ backdrop-filter: blur(10px);
254
+ }
255
+
256
+ .topbar-crumb {
257
+ color: var(--muted);
258
+ font-size: 13px;
259
+ }
260
+
261
+ .topbar-crumb strong {
262
+ color: var(--ink);
263
+ font-weight: 650;
264
+ }
265
+
266
+ .topbar-links {
267
+ display: flex;
268
+ flex-wrap: wrap;
269
+ gap: 8px;
270
+ }
271
+
272
+ .topbar-links a {
273
+ border: 1px solid var(--line);
274
+ border-radius: 7px;
275
+ padding: 5px 11px;
276
+ background: var(--surface);
277
+ color: var(--ink);
278
+ font-size: 12.5px;
279
+ }
280
+
281
+ .topbar-links a:hover {
282
+ border-color: var(--accent);
283
+ color: var(--accent-ink);
284
+ }
285
+
286
+ main {
287
+ max-width: 880px;
288
+ margin: 0 auto;
289
+ padding: 40px 34px 80px;
290
+ }
291
+
292
+ section {
293
+ padding: 30px 0 34px;
294
+ border-bottom: 1px solid var(--line);
295
+ scroll-margin-top: 72px;
296
+ }
297
+
298
+ section:first-child {
299
+ padding-top: 0;
300
+ }
301
+
302
+ section:last-child {
303
+ border-bottom: 0;
304
+ }
305
+
306
+ .eyebrow {
307
+ margin: 0 0 6px;
308
+ color: var(--accent);
309
+ font-size: 12px;
310
+ font-weight: 750;
311
+ letter-spacing: 0.07em;
312
+ text-transform: uppercase;
313
+ }
314
+
315
+ h2 {
316
+ margin: 0 0 10px;
317
+ font-size: 25px;
318
+ line-height: 1.2;
319
+ letter-spacing: -0.01em;
320
+ }
321
+
322
+ h3 {
323
+ margin: 0 0 8px;
324
+ font-size: 16px;
325
+ line-height: 1.3;
326
+ }
327
+
328
+ p {
329
+ margin: 0 0 12px;
330
+ }
331
+
332
+ .lede {
333
+ max-width: 720px;
334
+ margin-bottom: 16px;
335
+ color: var(--muted);
336
+ font-size: 15.5px;
337
+ }
338
+
339
+ /* ---------- components ---------- */
340
+
341
+ .hero {
342
+ display: grid;
343
+ grid-template-columns: minmax(0, 1fr) 300px;
344
+ gap: 28px;
345
+ align-items: start;
346
+ }
347
+
348
+ .checklist {
349
+ display: grid;
350
+ gap: 8px;
351
+ margin: 16px 0 0;
352
+ padding: 0;
353
+ list-style: none;
354
+ }
355
+
356
+ .checklist li {
357
+ position: relative;
358
+ padding-left: 24px;
359
+ color: var(--muted);
360
+ font-size: 14px;
361
+ }
362
+
363
+ .checklist li::before {
364
+ position: absolute;
365
+ left: 0;
366
+ top: 1px;
367
+ color: var(--accent);
368
+ font-weight: 700;
369
+ content: "✓";
370
+ }
371
+
372
+ .checklist li strong {
373
+ color: var(--ink);
374
+ font-weight: 600;
375
+ }
376
+
377
+ .status-panel {
378
+ border: 1px solid var(--line);
379
+ border-radius: 10px;
380
+ background: var(--surface);
381
+ box-shadow: var(--shadow);
382
+ overflow: hidden;
383
+ }
384
+
385
+ .status-panel header {
386
+ border-bottom: 1px solid var(--line);
387
+ padding: 11px 16px;
388
+ background: var(--surface-2);
389
+ font-size: 13px;
390
+ font-weight: 700;
391
+ }
392
+
393
+ .status-row {
394
+ display: flex;
395
+ align-items: center;
396
+ justify-content: space-between;
397
+ gap: 12px;
398
+ min-height: 40px;
399
+ border-bottom: 1px solid var(--line);
400
+ padding: 8px 16px;
401
+ font-size: 13.5px;
402
+ }
403
+
404
+ .status-row:last-child {
405
+ border-bottom: 0;
406
+ }
407
+
408
+ .pill {
409
+ display: inline-flex;
410
+ align-items: center;
411
+ border-radius: 999px;
412
+ padding: 2px 9px;
413
+ font-size: 11.5px;
414
+ font-weight: 700;
415
+ white-space: nowrap;
416
+ }
417
+
418
+ .pill.green {
419
+ background: var(--accent-soft);
420
+ color: var(--accent-ink);
421
+ }
422
+
423
+ .pill.amber {
424
+ background: var(--amber-soft);
425
+ color: var(--amber);
426
+ }
427
+
428
+ .pill.violet {
429
+ background: var(--violet-soft);
430
+ color: var(--violet);
431
+ }
432
+
433
+ .callout {
434
+ display: grid;
435
+ grid-template-columns: auto minmax(0, 1fr);
436
+ gap: 10px;
437
+ margin: 16px 0 0;
438
+ border: 1px solid var(--line);
439
+ border-left: 3px solid var(--accent);
440
+ border-radius: 8px;
441
+ padding: 12px 14px;
442
+ background: var(--surface);
443
+ font-size: 13.5px;
444
+ }
445
+
446
+ .callout.warn {
447
+ border-left-color: var(--amber);
448
+ }
449
+
450
+ .callout .icon {
451
+ font-size: 15px;
452
+ line-height: 1.5;
453
+ }
454
+
455
+ .callout p {
456
+ margin: 0;
457
+ color: var(--muted);
458
+ }
459
+
460
+ .callout strong {
461
+ color: var(--ink);
462
+ }
463
+
464
+ .code-block {
465
+ margin: 16px 0 0;
466
+ border-radius: 10px;
467
+ overflow-x: auto;
468
+ background: var(--code-bg);
469
+ color: var(--code-ink);
470
+ }
471
+
472
+ .code-block pre {
473
+ margin: 0;
474
+ padding: 16px 18px;
475
+ font-size: 13px;
476
+ line-height: 1.6;
477
+ }
478
+
479
+ .code-block .cm {
480
+ color: var(--code-comment);
481
+ }
482
+
483
+ .grid {
484
+ display: grid;
485
+ grid-template-columns: repeat(3, minmax(0, 1fr));
486
+ gap: 12px;
487
+ margin-top: 16px;
488
+ }
489
+
490
+ .grid.two {
491
+ grid-template-columns: repeat(2, minmax(0, 1fr));
492
+ }
493
+
494
+ .tile {
495
+ border: 1px solid var(--line);
496
+ border-radius: 10px;
497
+ padding: 15px 16px;
498
+ background: var(--surface);
499
+ }
500
+
501
+ .tile p {
502
+ margin: 0 0 8px;
503
+ color: var(--muted);
504
+ font-size: 13px;
505
+ }
506
+
507
+ .tile > code,
508
+ .tile code a {
509
+ display: inline-block;
510
+ border-radius: 6px;
511
+ padding: 2px 7px;
512
+ background: var(--surface-2);
513
+ color: var(--accent-ink);
514
+ font-size: 12.5px;
515
+ }
516
+
517
+ .tile h3 {
518
+ font-size: 14.5px;
519
+ }
520
+
521
+ .pipeline {
522
+ display: grid;
523
+ grid-template-columns: repeat(5, minmax(0, 1fr));
524
+ gap: 10px;
525
+ margin-top: 18px;
526
+ counter-reset: stage;
527
+ }
528
+
529
+ .stage {
530
+ position: relative;
531
+ border: 1px solid var(--line);
532
+ border-top: 3px solid var(--accent);
533
+ border-radius: 9px;
534
+ padding: 12px 13px 11px;
535
+ background: var(--surface);
536
+ counter-increment: stage;
537
+ }
538
+
539
+ .stage.alt {
540
+ border-top-color: var(--violet);
541
+ }
542
+
543
+ .stage::before {
544
+ display: block;
545
+ margin-bottom: 4px;
546
+ color: var(--muted);
547
+ font-size: 10.5px;
548
+ font-weight: 700;
549
+ letter-spacing: 0.06em;
550
+ content: "STEP " counter(stage);
551
+ }
552
+
553
+ .stage strong {
554
+ display: block;
555
+ margin-bottom: 4px;
556
+ font-size: 13.5px;
557
+ }
558
+
559
+ .stage span {
560
+ color: var(--muted);
561
+ font-size: 12px;
562
+ line-height: 1.5;
563
+ display: block;
564
+ }
565
+
566
+ .consumers {
567
+ display: grid;
568
+ grid-template-columns: repeat(3, minmax(0, 1fr));
569
+ gap: 12px;
570
+ margin-top: 12px;
571
+ }
572
+
573
+ .table-wrap {
574
+ margin-top: 16px;
575
+ border: 1px solid var(--line);
576
+ border-radius: 10px;
577
+ background: var(--surface);
578
+ overflow-x: auto;
579
+ }
580
+
581
+ table {
582
+ width: 100%;
583
+ border-collapse: collapse;
584
+ font-size: 13.5px;
585
+ }
586
+
587
+ th,
588
+ td {
589
+ border-bottom: 1px solid var(--line);
590
+ padding: 10px 14px;
591
+ text-align: left;
592
+ vertical-align: top;
593
+ }
594
+
595
+ th {
596
+ background: var(--surface-2);
597
+ font-size: 12px;
598
+ font-weight: 700;
599
+ letter-spacing: 0.03em;
600
+ text-transform: uppercase;
601
+ color: var(--muted);
602
+ white-space: nowrap;
603
+ }
604
+
605
+ tr:last-child td {
606
+ border-bottom: 0;
607
+ }
608
+
609
+ td.num {
610
+ font-variant-numeric: tabular-nums;
611
+ text-align: right;
612
+ white-space: nowrap;
613
+ }
614
+
615
+ th.num {
616
+ text-align: right;
617
+ }
618
+
619
+ td .best {
620
+ color: var(--accent-ink);
621
+ font-weight: 700;
622
+ }
623
+
624
+ .footnote {
625
+ margin-top: 10px;
626
+ color: var(--muted);
627
+ font-size: 12.5px;
628
+ }
629
+
630
+ .hidden {
631
+ display: none;
632
+ }
633
+
634
+ /* ---------- responsive ---------- */
635
+
636
+ @media (max-width: 960px) {
637
+ .shell {
638
+ grid-template-columns: 1fr;
639
+ }
640
+
641
+ .sidebar {
642
+ position: static;
643
+ height: auto;
644
+ }
645
+
646
+ .hero {
647
+ grid-template-columns: 1fr;
648
+ }
649
+
650
+ .grid,
651
+ .consumers {
652
+ grid-template-columns: repeat(2, minmax(0, 1fr));
653
+ }
654
+
655
+ .pipeline {
656
+ grid-template-columns: repeat(2, minmax(0, 1fr));
657
+ }
658
+ }
659
+
660
+ @media (max-width: 620px) {
661
+ .topbar {
662
+ position: static;
663
+ flex-direction: column;
664
+ align-items: flex-start;
665
+ padding: 12px 18px;
666
+ }
667
+
668
+ main {
669
+ padding: 28px 18px 56px;
670
+ }
671
+
672
+ h2 {
673
+ font-size: 22px;
674
+ }
675
+
676
+ .grid,
677
+ .grid.two,
678
+ .consumers,
679
+ .pipeline {
680
+ grid-template-columns: 1fr;
681
+ }
682
+ }
683
+ </style>
684
+ </head>
685
+ <body>
686
+ <div class="shell">
687
+ <aside class="sidebar" aria-label="Documentation navigation">
688
+ <div class="brand">
689
+ <h1>TypeSea</h1>
690
+ <span class="version">v0.1.0</span>
691
+ </div>
692
+ <p class="brand-tagline">
693
+ Zero-dependency runtime narrowing for TypeScript.
694
+ ESM-only &middot; Node &ge; 20.19 &middot; MIT
695
+ </p>
696
+ <div class="search">
697
+ <input data-search type="search" placeholder="Filter sections&hellip;" aria-label="Filter documentation sections">
698
+ </div>
699
+ <nav class="nav">
700
+ <p class="nav-group">Guide</p>
701
+ <a href="#overview">Overview</a>
702
+ <a href="#quick-start">Quick start</a>
703
+ <a href="#semantics">Semantics</a>
704
+ <p class="nav-group">Internals</p>
705
+ <a href="#architecture">Architecture</a>
706
+ <a href="#api">API map</a>
707
+ <a href="#adapters">Adapters</a>
708
+ <p class="nav-group">Quality</p>
709
+ <a href="#benchmarks">Benchmarks</a>
710
+ <a href="#release">Release gate</a>
711
+ <a href="#files">Reference files</a>
712
+ </nav>
713
+ <p class="sidebar-foot">MIT License &middot; zero runtime dependencies</p>
714
+ </aside>
715
+
716
+ <div class="content">
717
+ <div class="topbar">
718
+ <span class="topbar-crumb"><strong>TypeSea</strong> / Documentation</span>
719
+ <div class="topbar-links">
720
+ <a href="https://github.com/Feralthedogg/TypeSea">GitHub</a>
721
+ <a href="https://github.com/Feralthedogg/TypeSea/blob/main/docs/api.md">API reference</a>
722
+ <a href="https://github.com/Feralthedogg/TypeSea/blob/main/docs/engine-notes.md">Engine notes</a>
723
+ </div>
724
+ </div>
725
+
726
+ <main>
727
+ <section id="overview" data-doc-section data-title="overview contract zero dependency esm result frozen">
728
+ <div class="hero">
729
+ <div>
730
+ <p class="eyebrow">Overview</p>
731
+ <h2>Runtime typeguards shaped like a small compiler.</h2>
732
+ <p class="lede">
733
+ TypeSea treats validation schemas as frontend syntax. Each guard lowers into a
734
+ cached validation plan &mdash; a schema-specialized predicate kernel plus an
735
+ optimized graph &mdash; and executes through the plan, a runtime-compiled
736
+ validator, or a standalone AOT module.
737
+ </p>
738
+ <ul class="checklist">
739
+ <li><strong>Zero dependencies</strong> &mdash; no runtime, peer, optional, or bundled packages, enforced by policy.</li>
740
+ <li><strong>Hostile-input safe</strong> &mdash; descriptor reads mean user getters never execute.</li>
741
+ <li><strong>Result-first</strong> &mdash; expected failures return frozen <code>Result</code> values, never <code>throw</code>.</li>
742
+ <li><strong>Allocation-aware</strong> &mdash; successful <code>is()</code> avoids diagnostic allocation.</li>
743
+ <li><strong>No escape hatches</strong> &mdash; <code>any</code>, <code>try</code>, and <code>catch</code> are banned from the codebase.</li>
744
+ </ul>
745
+ </div>
746
+ <aside class="status-panel" aria-label="Package status">
747
+ <header>Package status</header>
748
+ <div class="status-row">
749
+ <span>Runtime dependencies</span>
750
+ <span class="pill green">zero</span>
751
+ </div>
752
+ <div class="status-row">
753
+ <span>Execution engines</span>
754
+ <span class="pill green">plan &middot; jit &middot; aot</span>
755
+ </div>
756
+ <div class="status-row">
757
+ <span>Module format</span>
758
+ <span class="pill violet">ESM-only</span>
759
+ </div>
760
+ <div class="status-row">
761
+ <span>Node.js</span>
762
+ <span class="pill green">&ge; 20.19</span>
763
+ </div>
764
+ <div class="status-row">
765
+ <span>Adapters</span>
766
+ <span class="pill amber">structural</span>
767
+ </div>
768
+ </aside>
769
+ </div>
770
+ </section>
771
+
772
+ <section id="quick-start" data-doc-section data-title="quick start install guard compile check json schema csp">
773
+ <p class="eyebrow">Quick start</p>
774
+ <h2>Define a guard once, then choose the execution path.</h2>
775
+ <p class="lede">
776
+ The same guard narrows through <code>is()</code>, returns immutable diagnostics
777
+ through <code>check()</code>, exports lossless JSON Schema, or compiles into a
778
+ generated validator.
779
+ </p>
780
+ <div class="code-block">
781
+ <pre><code>npm install typesea</code></pre>
782
+ </div>
783
+ <div class="code-block">
784
+ <pre><code>import { compile, t, toJsonSchema, type Infer } from "typesea";
785
+
786
+ const User = t.strictObject({
787
+ id: t.string.uuid(),
788
+ age: t.number.int().gte(0),
789
+ role: t.union(t.literal("admin"), t.literal("user"))
790
+ });
791
+
792
+ type User = Infer&lt;typeof User&gt;;
793
+
794
+ <span class="cm">// 1) Boolean narrowing &mdash; no diagnostic allocation on success</span>
795
+ if (User.is(input)) {
796
+ input.id; <span class="cm">// narrowed</span>
797
+ }
798
+
799
+ <span class="cm">// 2) Immutable diagnostics &mdash; frozen Result, never throws</span>
800
+ const checked = User.check(input);
801
+
802
+ <span class="cm">// 3) Hot path &mdash; generated validator code</span>
803
+ const FastUser = compile(User, { name: "isUser" });
804
+
805
+ <span class="cm">// 4) Interop &mdash; lossless-only JSON Schema export</span>
806
+ const schema = toJsonSchema(User);</code></pre>
807
+ </div>
808
+ <div class="callout warn">
809
+ <span class="icon">&#9888;</span>
810
+ <p>
811
+ <strong><code>compile()</code> uses <code>new Function</code></strong>, which throws under a
812
+ Content-Security-Policy that forbids <code>unsafe-eval</code>. In CSP-restricted
813
+ environments, emit validator source ahead of time with <code>emitAotModule()</code>.
814
+ </p>
815
+ </div>
816
+ </section>
817
+
818
+ <section id="semantics" data-doc-section data-title="semantics presence optional undefinedable nullable edge nan proto uuid strict">
819
+ <p class="eyebrow">Semantics</p>
820
+ <h2>Explicit presence, deliberate edge behavior.</h2>
821
+ <p class="lede">
822
+ Object presence is a first-class concept, and edge cases that break typical
823
+ validators are deliberate, documented decisions pinned by tests.
824
+ </p>
825
+ <div class="table-wrap">
826
+ <table>
827
+ <thead>
828
+ <tr>
829
+ <th>Wrapper</th>
830
+ <th>Key may be absent</th>
831
+ <th>Value may be <code>undefined</code></th>
832
+ <th>Inferred type</th>
833
+ </tr>
834
+ </thead>
835
+ <tbody>
836
+ <tr>
837
+ <td><code>t.optional(inner)</code></td>
838
+ <td>yes</td>
839
+ <td>no</td>
840
+ <td><code>key?: T</code></td>
841
+ </tr>
842
+ <tr>
843
+ <td><code>t.undefinedable(inner)</code></td>
844
+ <td>no</td>
845
+ <td>yes</td>
846
+ <td><code>key: T | undefined</code></td>
847
+ </tr>
848
+ <tr>
849
+ <td><code>t.nullable(inner)</code></td>
850
+ <td>&mdash;</td>
851
+ <td>value may be <code>null</code></td>
852
+ <td><code>key: T | null</code></td>
853
+ </tr>
854
+ </tbody>
855
+ </table>
856
+ </div>
857
+ <div class="table-wrap">
858
+ <table>
859
+ <thead>
860
+ <tr>
861
+ <th>Input</th>
862
+ <th>Behavior</th>
863
+ </tr>
864
+ </thead>
865
+ <tbody>
866
+ <tr>
867
+ <td><code>NaN</code>, <code>Infinity</code></td>
868
+ <td><code>t.number</code> accepts finite numbers only; <code>t.literal(NaN)</code> matches <code>NaN</code> via <code>Object.is</code>.</td>
869
+ </tr>
870
+ <tr>
871
+ <td>Getter-backed properties</td>
872
+ <td>Never executed &mdash; reads go through descriptors, accessors count as missing data.</td>
873
+ </tr>
874
+ <tr>
875
+ <td><code>__proto__</code>, <code>constructor</code> keys</td>
876
+ <td>Validated as plain own keys through null-prototype lookups; no pollution.</td>
877
+ </tr>
878
+ <tr>
879
+ <td>Strict-object extras</td>
880
+ <td>Rejected via <code>Reflect.ownKeys</code> &mdash; including symbol keys and non-enumerable properties.</td>
881
+ </tr>
882
+ <tr>
883
+ <td>Sparse array holes</td>
884
+ <td>Read as <code>undefined</code> without executing accessors.</td>
885
+ </tr>
886
+ <tr>
887
+ <td>Global-flag regexes</td>
888
+ <td>Cloned at construction; <code>lastIndex</code> reset before every test.</td>
889
+ </tr>
890
+ <tr>
891
+ <td>UUID strings</td>
892
+ <td>RFC 9562 versions 1&ndash;8 plus the nil UUID.</td>
893
+ </tr>
894
+ <tr>
895
+ <td>Cyclic input values</td>
896
+ <td>Validate finitely via (value &times; schema) active-pair tracking.</td>
897
+ </tr>
898
+ <tr>
899
+ <td>Nesting depth</td>
900
+ <td>Capped at 1024 frames &mdash; deep input fails instead of overflowing the stack.</td>
901
+ </tr>
902
+ </tbody>
903
+ </table>
904
+ </div>
905
+ </section>
906
+
907
+ <section id="architecture" data-doc-section data-title="architecture sea of nodes ir lower optimize plan kernel graph codegen">
908
+ <p class="eyebrow">Architecture</p>
909
+ <h2>Every schema lowers into a cached validation plan.</h2>
910
+ <p class="lede">
911
+ The public schema tree is kept for builder validation and diagnostics. Each schema
912
+ identity lowers once into the Sea-of-Nodes validation IR, is optimized, and is cached
913
+ as a validation plan owning both a schema-specialized predicate kernel and the
914
+ optimized graph consumed by generated validators.
915
+ </p>
916
+ <div class="pipeline" aria-label="TypeSea validation pipeline">
917
+ <div class="stage">
918
+ <strong>Builder</strong>
919
+ <span>Immutable guards validate construction inputs up front.</span>
920
+ </div>
921
+ <div class="stage">
922
+ <strong>Frozen schema</strong>
923
+ <span>The tree stores semantics and diagnostic structure.</span>
924
+ </div>
925
+ <div class="stage alt">
926
+ <strong>Sea-of-Nodes IR</strong>
927
+ <span>Lowering shares loads, predicates, keysets, and discriminant dispatch.</span>
928
+ </div>
929
+ <div class="stage alt">
930
+ <strong>Optimize</strong>
931
+ <span>Folding, reachability, and dense node ids keep invariants simple.</span>
932
+ </div>
933
+ <div class="stage">
934
+ <strong>Validation plan</strong>
935
+ <span>Cached per schema identity: predicate kernel + optimized graph.</span>
936
+ </div>
937
+ </div>
938
+ <div class="consumers">
939
+ <div class="tile">
940
+ <h3>Plan kernel</h3>
941
+ <p>Drives <code>is()</code> and the <code>check()</code> verdict preflight without per-node interpreter dispatch.</p>
942
+ <code>guard.is()</code>
943
+ </div>
944
+ <div class="tile">
945
+ <h3>Optimized graph</h3>
946
+ <p>Source of truth for runtime-compiled and AOT-emitted predicates, and for introspection.</p>
947
+ <code>compile() &middot; emitAotModule() &middot; graph()</code>
948
+ </div>
949
+ <div class="tile">
950
+ <h3>Diagnostic collector</h3>
951
+ <p>Failed <code>check()</code> calls replay the schema-aware collector for issue paths and codes.</p>
952
+ <code>guard.check()</code>
953
+ </div>
954
+ </div>
955
+ <div class="callout">
956
+ <span class="icon">&#128274;</span>
957
+ <p>
958
+ <strong>Injection-safe codegen:</strong> user-controlled literals, regexps, object
959
+ keys, keysets, and dynamic schema fallbacks live in side tables referenced by
960
+ numeric index. Hostile property names cannot escape into generated source &mdash;
961
+ pinned by dedicated injection-audit tests.
962
+ </p>
963
+ </div>
964
+ </section>
965
+
966
+ <section id="api" data-doc-section data-title="api builders decoder async messages json schema execution">
967
+ <p class="eyebrow">API map</p>
968
+ <h2>Small public surface, strict contracts.</h2>
969
+ <p class="lede">
970
+ Every entry point is exported from the package root; builders are also grouped under
971
+ the <code>t</code> table. The full signatures live in the
972
+ <a href="https://github.com/Feralthedogg/TypeSea/blob/main/docs/api.md"><code>API reference</code></a>.
973
+ </p>
974
+ <div class="grid">
975
+ <article class="tile">
976
+ <h3>Builders</h3>
977
+ <p>Scalars, literals, arrays, tuples, records, unions, intersections, and lazy recursion.</p>
978
+ <code>t.strictObject</code>
979
+ </article>
980
+ <article class="tile">
981
+ <h3>Object combinators</h3>
982
+ <p>Shape-preserving <code>extend</code>, <code>pick</code>, <code>omit</code>, and <code>partial</code>.</p>
983
+ <code>guard.extend</code>
984
+ </article>
985
+ <article class="tile">
986
+ <h3>Presence wrappers</h3>
987
+ <p>Explicit key-absence vs undefined-value vs null-value contracts.</p>
988
+ <code>t.optional</code>
989
+ </article>
990
+ <article class="tile">
991
+ <h3>Decoders</h3>
992
+ <p>Result-returning transform, pipe, and coercion; async variants keep expected failures in <code>Result</code>.</p>
993
+ <code>t.pipe</code>
994
+ </article>
995
+ <article class="tile">
996
+ <h3>Execution</h3>
997
+ <p>Runtime-compiled validators and standalone AOT module emission from the optimized graph.</p>
998
+ <code>compile</code>
999
+ </article>
1000
+ <article class="tile">
1001
+ <h3>Messages &amp; export</h3>
1002
+ <p>Locale-aware issue formatting (English and Korean built in) and lossless JSON Schema export.</p>
1003
+ <code>toJsonSchema</code>
1004
+ </article>
1005
+ </div>
1006
+ </section>
1007
+
1008
+ <section id="adapters" data-doc-section data-title="adapters trpc fastify react hook form resolver">
1009
+ <p class="eyebrow">Ecosystem adapters</p>
1010
+ <h2>Structural adapters without importing frameworks.</h2>
1011
+ <p class="lede">
1012
+ Adapter functions return objects or functions shaped for the target ecosystem.
1013
+ TypeSea does not import tRPC, Fastify, or React Hook Form at runtime.
1014
+ </p>
1015
+ <div class="table-wrap">
1016
+ <table>
1017
+ <thead>
1018
+ <tr>
1019
+ <th>Target</th>
1020
+ <th>Export</th>
1021
+ <th>Behavior</th>
1022
+ </tr>
1023
+ </thead>
1024
+ <tbody>
1025
+ <tr>
1026
+ <td>tRPC</td>
1027
+ <td><code>toTrpcParser</code> / <code>toAsyncTrpcParser</code></td>
1028
+ <td>Parser objects that return decoded values or throw <code>TypeSeaAssertionError</code>.</td>
1029
+ </tr>
1030
+ <tr>
1031
+ <td>Fastify</td>
1032
+ <td><code>toFastifyRouteSchema</code></td>
1033
+ <td>Lossless JSON Schema fragments for body, querystring, params, or headers.</td>
1034
+ </tr>
1035
+ <tr>
1036
+ <td>Fastify</td>
1037
+ <td><code>toFastifyValidatorCompiler</code></td>
1038
+ <td>Route validators dispatched by <code>httpPart</code>, producing <code>{ value }</code> or <code>{ error }</code>.</td>
1039
+ </tr>
1040
+ <tr>
1041
+ <td>React Hook Form</td>
1042
+ <td><code>toReactHookFormResolver</code></td>
1043
+ <td>Async resolver returning a nested field-error tree that RHF traverses by path.</td>
1044
+ </tr>
1045
+ </tbody>
1046
+ </table>
1047
+ </div>
1048
+ </section>
1049
+
1050
+ <section id="benchmarks" data-doc-section data-title="benchmarks performance zod valibot ajv compiled interpreted">
1051
+ <p class="eyebrow">Benchmarks</p>
1052
+ <h2>Measured honestly, gated on every release.</h2>
1053
+ <p class="lede">
1054
+ The suite compares the runtime plan against compiled TypeSea, and both against
1055
+ Zod, Valibot, and Ajv over one JSON-compatible strict-object contract. Comparison
1056
+ packages are development-only measurement tools, and diagnostic-path
1057
+ (<code>check()</code> vs <code>safeParse</code>) rows keep the numbers
1058
+ apples-to-apples.
1059
+ </p>
1060
+ <div class="table-wrap">
1061
+ <table>
1062
+ <thead>
1063
+ <tr>
1064
+ <th>Valid object path</th>
1065
+ <th class="num">ops/sec</th>
1066
+ </tr>
1067
+ </thead>
1068
+ <tbody>
1069
+ <tr>
1070
+ <td>TypeSea runtime plan <code>is()</code></td>
1071
+ <td class="num">496,270</td>
1072
+ </tr>
1073
+ <tr>
1074
+ <td>TypeSea compiled <code>is()</code></td>
1075
+ <td class="num"><span class="best">4,237,892</span></td>
1076
+ </tr>
1077
+ <tr>
1078
+ <td>Zod <code>safeParse</code></td>
1079
+ <td class="num">1,363,792</td>
1080
+ </tr>
1081
+ <tr>
1082
+ <td>Valibot <code>safeParse</code></td>
1083
+ <td class="num">1,384,892</td>
1084
+ </tr>
1085
+ <tr>
1086
+ <td>Ajv compiled</td>
1087
+ <td class="num">4,312,174</td>
1088
+ </tr>
1089
+ </tbody>
1090
+ </table>
1091
+ </div>
1092
+ <div class="table-wrap">
1093
+ <table>
1094
+ <thead>
1095
+ <tr>
1096
+ <th>Invalid object path</th>
1097
+ <th class="num">ops/sec</th>
1098
+ </tr>
1099
+ </thead>
1100
+ <tbody>
1101
+ <tr>
1102
+ <td>TypeSea runtime plan <code>is()</code></td>
1103
+ <td class="num">3,422,416</td>
1104
+ </tr>
1105
+ <tr>
1106
+ <td>TypeSea compiled <code>is()</code></td>
1107
+ <td class="num"><span class="best">27,125,445</span></td>
1108
+ </tr>
1109
+ <tr>
1110
+ <td>Zod <code>safeParse</code></td>
1111
+ <td class="num">83,501</td>
1112
+ </tr>
1113
+ <tr>
1114
+ <td>Valibot <code>safeParse</code></td>
1115
+ <td class="num">902,616</td>
1116
+ </tr>
1117
+ <tr>
1118
+ <td>Ajv compiled</td>
1119
+ <td class="num">28,953,501</td>
1120
+ </tr>
1121
+ </tbody>
1122
+ </table>
1123
+ </div>
1124
+ <p class="footnote">
1125
+ Local release smoke, 2026-07-04 KST, single machine &mdash; regression telemetry,
1126
+ not throughput guarantees. The compiled path stays at Ajv-level speed while keeping
1127
+ descriptor-based reads, strict symbol/non-enumerable key rejection, and immutable
1128
+ diagnostics.
1129
+ </p>
1130
+ <div class="code-block">
1131
+ <pre><code>npm run bench -- --run</code></pre>
1132
+ </div>
1133
+ </section>
1134
+
1135
+ <section id="release" data-doc-section data-title="release gate policy typecheck lint test dist api pack consumer provenance">
1136
+ <p class="eyebrow">Release gate</p>
1137
+ <h2>Publishing requires the full local gate.</h2>
1138
+ <p class="lede">
1139
+ One script runs everything CI runs: source policy, docs smoke, typecheck, lint,
1140
+ tests, build, dist policy, public API snapshot, package contents, clean consumer
1141
+ install, benchmark smoke, and pack dry run. CI executes the same gate on
1142
+ Node 20.19, 22, and 24; releases publish with npm provenance.
1143
+ </p>
1144
+ <div class="code-block">
1145
+ <pre><code>npm run release:check</code></pre>
1146
+ </div>
1147
+ <div class="callout">
1148
+ <span class="icon">&#128737;</span>
1149
+ <p>
1150
+ <strong><code>prepack</code> re-runs the full check</strong>, so even a bare
1151
+ <code>npm publish</code> cannot skip the gate. Package policy rejects any runtime
1152
+ dependency fields before the tarball is accepted.
1153
+ </p>
1154
+ </div>
1155
+ </section>
1156
+
1157
+ <section id="files" data-doc-section data-title="reference files api engine notes github">
1158
+ <p class="eyebrow">Reference files</p>
1159
+ <h2>Detailed contracts live in focused documents.</h2>
1160
+ <div class="grid two">
1161
+ <article class="tile">
1162
+ <h3>API reference</h3>
1163
+ <p>Guard, decoder, AOT, adapter, graph, and JSON Schema behavior with edge semantics.</p>
1164
+ <code><a href="https://github.com/Feralthedogg/TypeSea/blob/main/docs/api.md">docs/api.md</a></code>
1165
+ </article>
1166
+ <article class="tile">
1167
+ <h3>Engine notes</h3>
1168
+ <p>V8-facing implementation rules and Sea-of-Nodes validation IR semantics.</p>
1169
+ <code><a href="https://github.com/Feralthedogg/TypeSea/blob/main/docs/engine-notes.md">docs/engine-notes.md</a></code>
1170
+ </article>
1171
+ </div>
1172
+ </section>
1173
+ </main>
1174
+ </div>
1175
+ </div>
1176
+
1177
+ <script>
1178
+ const search = document.querySelector("[data-search]");
1179
+ const sections = Array.from(document.querySelectorAll("[data-doc-section]"));
1180
+ const links = Array.from(document.querySelectorAll(".nav a"));
1181
+ const groups = Array.from(document.querySelectorAll(".nav-group"));
1182
+
1183
+ if (search instanceof HTMLInputElement) {
1184
+ search.addEventListener("input", () => {
1185
+ const query = search.value.trim().toLowerCase();
1186
+ for (const section of sections) {
1187
+ const title = section.getAttribute("data-title") ?? "";
1188
+ const text = section.textContent?.toLowerCase() ?? "";
1189
+ const visible = query === "" || title.includes(query) || text.includes(query);
1190
+ section.classList.toggle("hidden", !visible);
1191
+ }
1192
+ for (const link of links) {
1193
+ const target = link.getAttribute("href") ?? "";
1194
+ const section = target.startsWith("#")
1195
+ ? document.getElementById(target.slice(1))
1196
+ : null;
1197
+ const visible = section === null || !section.classList.contains("hidden");
1198
+ link.classList.toggle("hidden", !visible);
1199
+ }
1200
+ for (const group of groups) {
1201
+ let sibling = group.nextElementSibling;
1202
+ let anyVisible = false;
1203
+ while (sibling !== null && !sibling.classList.contains("nav-group")) {
1204
+ if (sibling.matches("a") && !sibling.classList.contains("hidden")) {
1205
+ anyVisible = true;
1206
+ }
1207
+ sibling = sibling.nextElementSibling;
1208
+ }
1209
+ group.classList.toggle("hidden", !anyVisible);
1210
+ }
1211
+ });
1212
+ }
1213
+
1214
+ const linkById = new Map(
1215
+ links
1216
+ .map((link) => [link.getAttribute("href")?.slice(1) ?? "", link])
1217
+ .filter(([id]) => id !== "")
1218
+ );
1219
+
1220
+ if ("IntersectionObserver" in window) {
1221
+ const observer = new IntersectionObserver(
1222
+ (entries) => {
1223
+ for (const entry of entries) {
1224
+ if (entry.isIntersecting) {
1225
+ for (const link of links) {
1226
+ link.classList.toggle(
1227
+ "active",
1228
+ link === linkById.get(entry.target.id)
1229
+ );
1230
+ }
1231
+ }
1232
+ }
1233
+ },
1234
+ { rootMargin: "-20% 0px -70% 0px" }
1235
+ );
1236
+ for (const section of sections) {
1237
+ observer.observe(section);
1238
+ }
1239
+ }
1240
+ </script>
1241
+ </body>
1242
+ </html>