castrum 0.7.0 → 0.9.1

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 (207) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -368
  3. package/castrum.linux-x64-gnu.node +0 -0
  4. package/dist/index.d.ts +2763 -0
  5. package/dist/index.js +8707 -0
  6. package/docs/API.md +337 -0
  7. package/docs/ARCHITECTURE.md +507 -0
  8. package/docs/BENCHMARKS.md +343 -0
  9. package/docs/CASE_STUDY.md +240 -0
  10. package/docs/ENVIRONMENT.md +81 -0
  11. package/docs/FFI_BUN_GUIDE.md +327 -0
  12. package/docs/GETTING_STARTED.md +192 -0
  13. package/docs/INGRESS-ROUTER.md +81 -0
  14. package/docs/INGRESS.md +746 -0
  15. package/docs/NATIVE-ROUTE.md +53 -0
  16. package/docs/REPO_MAP.md +279 -0
  17. package/docs/adr/0001-two-wire-formats.md +39 -0
  18. package/docs/adr/0002-zero-dom-fast-schema.md +38 -0
  19. package/docs/adr/0003-bun-builtins-delegation.md +43 -0
  20. package/docs/bun-builtins-decision-matrix.md +115 -0
  21. package/index.ts +44 -8
  22. package/package.json +98 -33
  23. package/src/ingress/body.ts +289 -0
  24. package/src/ingress/constants.ts +220 -48
  25. package/src/ingress/context.ts +136 -0
  26. package/src/ingress/decode/baked-result.ts +121 -0
  27. package/src/ingress/decode/fast-result.ts +160 -0
  28. package/src/ingress/decode/packed-sections.ts +56 -0
  29. package/src/ingress/decode/result-base.ts +172 -0
  30. package/src/ingress/errors.ts +72 -0
  31. package/src/ingress/fast.ts +152 -1021
  32. package/src/ingress/handlers.ts +639 -1001
  33. package/src/ingress/headers/baked-templates.ts +102 -0
  34. package/src/ingress/headers/cors.ts +44 -0
  35. package/src/ingress/headers/fast-templates.ts +238 -0
  36. package/src/ingress/headers/hsts.ts +83 -0
  37. package/src/ingress/health.ts +68 -0
  38. package/src/ingress/index.ts +142 -405
  39. package/src/ingress/metrics.ts +132 -0
  40. package/src/ingress/options.ts +197 -0
  41. package/src/ingress/packing/gather-raw-headers.ts +139 -0
  42. package/src/ingress/packing/header-packing.ts +75 -0
  43. package/src/ingress/packing/input-packer.ts +164 -0
  44. package/src/ingress/packing/scratch.ts +50 -0
  45. package/src/ingress/packing/select-headers.ts +102 -0
  46. package/src/ingress/response/error-bodies.ts +75 -0
  47. package/src/ingress/response/terminal.ts +59 -0
  48. package/src/ingress/router.ts +237 -0
  49. package/src/ingress/routes/common.ts +79 -0
  50. package/src/ingress/routes/delete.ts +14 -0
  51. package/src/ingress/routes/echo.ts +107 -0
  52. package/src/ingress/routes/fallback.ts +23 -0
  53. package/src/ingress/routes/head.ts +27 -0
  54. package/src/ingress/routes/index.ts +11 -0
  55. package/src/ingress/routes/json-write.ts +129 -0
  56. package/src/ingress/routes/options.ts +26 -0
  57. package/src/ingress/routes/read.ts +35 -0
  58. package/src/ingress/routes/responder.ts +159 -0
  59. package/src/ingress/server-node.ts +376 -0
  60. package/src/ingress/server.ts +475 -0
  61. package/src/ingress/shared.ts +132 -0
  62. package/src/ingress/status.ts +97 -0
  63. package/src/ingress/types.ts +191 -0
  64. package/src/integration/batch.ts +58 -0
  65. package/src/integration/index.ts +29 -0
  66. package/src/integration/pipeline.ts +220 -0
  67. package/src/integration/streaming.ts +78 -0
  68. package/src/integration/websocket.ts +93 -0
  69. package/src/loader/batch.ts +137 -0
  70. package/src/loader/cost.ts +105 -0
  71. package/src/loader/index.ts +745 -0
  72. package/src/loader/ops.ts +657 -0
  73. package/src/loader/state.ts +84 -0
  74. package/src/loader/types.ts +145 -0
  75. package/src/native/ffi/constants.ts +58 -0
  76. package/src/native/ffi/selftest.ts +729 -0
  77. package/src/native/ffi/types.ts +474 -0
  78. package/src/native/ffi.ts +1775 -0
  79. package/src/native/index.ts +8 -207
  80. package/src/native/loader.ts +240 -0
  81. package/src/native/types/instances.ts +274 -0
  82. package/src/native/types.ts +401 -0
  83. package/src/runtime/builtins.ts +131 -0
  84. package/src/runtime/codec.ts +147 -0
  85. package/src/runtime/detect.ts +36 -0
  86. package/src/runtime/index.ts +28 -0
  87. package/src/runtime/native.ts +35 -0
  88. package/src/runtime/server.ts +31 -0
  89. package/src/runtime/transport.ts +64 -0
  90. package/src/runtime/types.ts +173 -0
  91. package/src/runtime/uuid.ts +45 -0
  92. package/src/runtime/websocket.ts +30 -0
  93. package/src/rust-ffi/addon.ts +10 -0
  94. package/src/rust-ffi/batch/build.ts +155 -0
  95. package/src/rust-ffi/batch/index.ts +8 -0
  96. package/src/rust-ffi/batch/types.ts +92 -0
  97. package/src/rust-ffi/client.ts +87 -0
  98. package/src/rust-ffi/context.ts +193 -0
  99. package/src/rust-ffi/index.ts +51 -541
  100. package/src/rust-ffi/into.ts +21 -0
  101. package/src/rust-ffi/options.ts +113 -0
  102. package/src/rust-ffi/packed.ts +253 -0
  103. package/src/rust-ffi/proven.ts +28 -0
  104. package/src/rust-ffi/scalar/crypto.ts +346 -0
  105. package/src/rust-ffi/scalar/factories.ts +459 -0
  106. package/src/rust-ffi/scalar/hashing.ts +74 -0
  107. package/src/rust-ffi/scalar/http.ts +337 -0
  108. package/src/rust-ffi/scalar/index.ts +31 -0
  109. package/src/rust-ffi/scalar/interface.ts +325 -0
  110. package/src/rust-ffi/scalar/json-packed.ts +175 -0
  111. package/src/rust-ffi/scalar/json.ts +61 -0
  112. package/src/rust-ffi/scalar/payload.ts +241 -0
  113. package/src/rust-ffi/text.ts +121 -0
  114. package/src/selection.json +194 -0
  115. package/src/selection.ts +73 -0
  116. package/src/shared/adaptive.ts +67 -0
  117. package/src/shared/buffer-pool.ts +264 -0
  118. package/src/shared/bytes.ts +108 -9
  119. package/src/shared/codec.ts +78 -0
  120. package/src/shared/env.ts +20 -0
  121. package/src/shared/log.ts +75 -0
  122. package/src/shared/metrics.ts +247 -0
  123. package/src/shared/packed/index.ts +10 -0
  124. package/src/shared/packed/parsers.ts +31 -0
  125. package/src/shared/packed/schema.ts +23 -0
  126. package/src/shared/packed/wire.ts +504 -0
  127. package/src/shared/proven.ts +289 -0
  128. package/src/shared/request-id.ts +67 -0
  129. package/src/shared/response.ts +104 -0
  130. package/src/shared/runtime.ts +29 -0
  131. package/src/shared/trace.ts +81 -0
  132. package/src/shared/uuid.ts +15 -0
  133. package/Cargo.toml +0 -73
  134. package/bench.ts +0 -3
  135. package/rust/batch.rs +0 -195
  136. package/rust/cookie_parser.rs +0 -70
  137. package/rust/cors.rs +0 -263
  138. package/rust/hashing.rs +0 -164
  139. package/rust/headers.rs +0 -234
  140. package/rust/hmac_sha256.rs +0 -113
  141. package/rust/http_parser.rs +0 -132
  142. package/rust/ingress.rs +0 -616
  143. package/rust/ingress_constants.rs +0 -89
  144. package/rust/ip_trust.rs +0 -185
  145. package/rust/json_ops.rs +0 -66
  146. package/rust/json_patch_ops.rs +0 -25
  147. package/rust/json_schema.rs +0 -151
  148. package/rust/json_ser.rs +0 -429
  149. package/rust/lib.rs +0 -48
  150. package/rust/method.rs +0 -141
  151. package/rust/mime_lookup.rs +0 -76
  152. package/rust/output.rs +0 -238
  153. package/rust/proxy.rs +0 -90
  154. package/rust/query_parser.rs +0 -141
  155. package/rust/random_token.rs +0 -52
  156. package/rust/rate_limit.rs +0 -203
  157. package/rust/terminal.rs +0 -95
  158. package/rust/unit_tests.rs +0 -843
  159. package/rust/url_codec.rs +0 -133
  160. package/rust/util.rs +0 -537
  161. package/rust/validation.rs +0 -107
  162. package/rust/websocket.rs +0 -23
  163. package/src/baseline/index.ts +0 -12
  164. package/src/baseline/tasks/cookie.ts +0 -22
  165. package/src/baseline/tasks/hashing.ts +0 -18
  166. package/src/baseline/tasks/hmac.ts +0 -38
  167. package/src/baseline/tasks/http.ts +0 -62
  168. package/src/baseline/tasks/json-patch.ts +0 -12
  169. package/src/baseline/tasks/json.ts +0 -50
  170. package/src/baseline/tasks/mime.ts +0 -5
  171. package/src/baseline/tasks/query.ts +0 -14
  172. package/src/baseline/tasks/token.ts +0 -15
  173. package/src/baseline/tasks/url.ts +0 -11
  174. package/src/baseline/tasks/validation.ts +0 -19
  175. package/src/baseline/tasks/websocket.ts +0 -14
  176. package/src/bench/assert.ts +0 -70
  177. package/src/bench/checks.ts +0 -227
  178. package/src/bench/checksum.ts +0 -27
  179. package/src/bench/comparisons.ts +0 -70
  180. package/src/bench/concurrent-worker.ts +0 -135
  181. package/src/bench/fixtures.ts +0 -233
  182. package/src/bench/index.ts +0 -2
  183. package/src/bench/measure.ts +0 -177
  184. package/src/bench/now.ts +0 -3
  185. package/src/bench/report.ts +0 -79
  186. package/src/bench/run.ts +0 -57
  187. package/src/bench/tasks/complex.ts +0 -232
  188. package/src/bench/tasks/concurrent.ts +0 -213
  189. package/src/bench/tasks/cookie.ts +0 -44
  190. package/src/bench/tasks/hashing.ts +0 -33
  191. package/src/bench/tasks/hmac.ts +0 -36
  192. package/src/bench/tasks/http.ts +0 -50
  193. package/src/bench/tasks/index.ts +0 -52
  194. package/src/bench/tasks/json-patch.ts +0 -21
  195. package/src/bench/tasks/json.ts +0 -33
  196. package/src/bench/tasks/mime.ts +0 -21
  197. package/src/bench/tasks/query.ts +0 -44
  198. package/src/bench/tasks/stress.ts +0 -142
  199. package/src/bench/tasks/token.ts +0 -20
  200. package/src/bench/tasks/url.ts +0 -34
  201. package/src/bench/tasks/validation.ts +0 -57
  202. package/src/bench/tasks/websocket.ts +0 -21
  203. package/src/bench/types.ts +0 -60
  204. package/src/data/json-rows.ts +0 -33
  205. package/src/ingress/packed-input.ts +0 -59
  206. package/src/shared/json.ts +0 -18
  207. package/src/shared/packed.ts +0 -316
@@ -0,0 +1,113 @@
1
+ // src/rust-ffi/options.ts — Client options + input-normalization helpers.
2
+ //
3
+ // Holds the `RustOptions` contract, the rayon thread-count resolution, and the
4
+ // small coercion helpers (bigint/number/ext normalization) used across the FFI
5
+ // namespaces.
6
+
7
+ import { availableParallelism, cpus } from 'node:os'
8
+ import { decoder } from '../shared/bytes'
9
+ import { resolveEnvVar } from '../shared/env'
10
+
11
+ /** Options accepted by `createRust` / `rust.configure`. */
12
+ export interface RustOptions {
13
+ /**
14
+ * Rayon thread pool size.
15
+ *
16
+ * The rayon pool is process-wide and initialized **once** (native
17
+ * `OnceLock`) — the first initialization wins. Importing this module
18
+ * initializes the pool with defaults, so this option only takes effect when
19
+ * the pool has not yet been created. For reliable control set
20
+ * `CASTRUM_RAYON_THREADS` / `RUST_RAYON_THREADS` before import.
21
+ * Default: max(1, hardwareConcurrency - 1).
22
+ */
23
+ rayonThreads?: number
24
+ /** Cache MIME lookups keyed by normalized extension. Default: true. */
25
+ mimeCache?: boolean
26
+ /** Reuse HMAC signers keyed by key-buffer identity. Default: true. */
27
+ hmacCache?: boolean
28
+ }
29
+
30
+ const FALLBACK_CORES = 4
31
+
32
+ /**
33
+ * Resolve the CPU count without relying on `navigator.hardwareConcurrency`,
34
+ * which throws a ReferenceError under Node.js < 21. `os.availableParallelism`
35
+ * exists in Bun and Node >= 18.14; older Node falls back to `os.cpus().length`.
36
+ */
37
+ function hardwareConcurrency(): number {
38
+ if (typeof availableParallelism === 'function') {
39
+ return availableParallelism()
40
+ }
41
+ const count = cpus()?.length
42
+ return count && count > 0 ? count : FALLBACK_CORES
43
+ }
44
+
45
+ /** Resolve the effective rayon thread count from explicit/env/default. */
46
+ export function resolveRayonThreads(explicit?: number): number {
47
+ const cores = hardwareConcurrency()
48
+
49
+ if (explicit !== undefined && Number.isFinite(explicit) && explicit > 0) {
50
+ return Math.max(1, Math.min(cores, Math.floor(explicit)))
51
+ }
52
+
53
+ const envThreads = Number(
54
+ resolveEnvVar('CASTRUM_RAYON_THREADS'),
55
+ )
56
+
57
+ if (Number.isFinite(envThreads) && envThreads > 0) {
58
+ return Math.max(1, Math.min(cores, Math.floor(envThreads)))
59
+ }
60
+
61
+ return Math.max(1, cores - 1)
62
+ }
63
+
64
+ /** Coerce a value to bigint (accepts bigint/number/string). */
65
+ export function asBigInt(value: unknown): bigint {
66
+ if (typeof value === 'bigint') {
67
+ return value
68
+ }
69
+
70
+ if (typeof value === 'number' && Number.isFinite(value)) {
71
+ return BigInt(Math.trunc(value))
72
+ }
73
+
74
+ if (typeof value === 'string' && value.trim().length > 0) {
75
+ return BigInt(value)
76
+ }
77
+
78
+ throw new TypeError(`Expected bigint-compatible value, got ${typeof value}: ${String(value)}`)
79
+ }
80
+
81
+ /** Coerce a value to number (accepts number/bigint/string). */
82
+ export function asNumber(value: unknown): number {
83
+ if (typeof value === 'number') {
84
+ return value
85
+ }
86
+
87
+ if (typeof value === 'bigint') {
88
+ return Number(value)
89
+ }
90
+
91
+ if (typeof value === 'string' && value.trim().length > 0) {
92
+ return Number(value)
93
+ }
94
+
95
+ return 0
96
+ }
97
+
98
+ /** Normalize a file-extension byte slice to a lowercase string w/o a dot. */
99
+ export function normalizeExt(ext: Uint8Array): string {
100
+ let s: string
101
+
102
+ try {
103
+ s = decoder.decode(ext)
104
+ } catch {
105
+ return ''
106
+ }
107
+
108
+ if (s.charCodeAt(0) === 46) {
109
+ s = s.slice(1)
110
+ }
111
+
112
+ return s.toLowerCase()
113
+ }
@@ -0,0 +1,253 @@
1
+ // src/rust-ffi/packed.ts — Raw packed-wire FFI namespace.
2
+ //
3
+ // `rust.packed.*` is the zero-copy API: callers pass already-packed buffers and
4
+ // receive the raw packed output, plus the batch metadata/count helpers.
5
+
6
+ import type { PasswordHashOptions } from '../native'
7
+ import { type RustClientContext, resolvePoolNative } from './context'
8
+ import { asNumber } from './options'
9
+
10
+ /** Raw packed-wire FFI namespace. */
11
+ export interface RustPacked {
12
+ // ── Sync batch (packed in → packed out) ──
13
+ crc32BatchPacked(input: Uint8Array): Uint8Array
14
+ jsonValidBatchPacked(input: Uint8Array): Uint8Array
15
+ validateEmailBatchPacked(input: Uint8Array): Uint8Array
16
+ validateUuidBatchPacked(input: Uint8Array): Uint8Array
17
+ validateIpv4BatchPacked(input: Uint8Array): Uint8Array
18
+ validateIpv6BatchPacked(input: Uint8Array): Uint8Array
19
+ jsonSumBatchPacked(input: Uint8Array): Uint8Array
20
+ queryParseBatchPacked(input: Uint8Array): Uint8Array
21
+ cookieParseBatchPacked(input: Uint8Array): Uint8Array
22
+ httpParseRequestBatchPacked(input: Uint8Array): Uint8Array
23
+ /** Batch RFC 6902 JSON Patch (two packed lists, zipped) → packed results. */
24
+ jsonPatchBatchPacked(docs: Uint8Array, patches: Uint8Array): Uint8Array
25
+ /** Packed FNV-1a 64 batch (i64 per item). */
26
+ fnv1A64BatchPacked(input: Uint8Array): Uint8Array
27
+ /** Packed ETag batch (10 strong / 12 weak bytes per item). */
28
+ etagBatchPacked(input: Uint8Array, weak?: boolean | null): Uint8Array
29
+ urlEncodeBatchPacked(input: Uint8Array): Uint8Array
30
+ urlDecodeBatchPacked(input: Uint8Array): Uint8Array
31
+ urlDecodeBytesBatchPacked(input: Uint8Array): Uint8Array
32
+ mimeFromExtensionBatchPacked(input: Uint8Array): Uint8Array
33
+ wsAcceptKeyBatchPacked(input: Uint8Array): Uint8Array
34
+
35
+ // ── Batch metadata / counts ──
36
+ jsonValidBatchCountPacked(input: Uint8Array): number
37
+ validateEmailBatchCountPacked(input: Uint8Array): number
38
+ validateUuidBatchCountPacked(input: Uint8Array): number
39
+ validateIpv4BatchCountPacked(input: Uint8Array): number
40
+ validateIpv6BatchCountPacked(input: Uint8Array): number
41
+ jsonSumBatchTotalPacked(input: Uint8Array): number
42
+ queryParseBatchTotalLenPacked(input: Uint8Array): number
43
+ cookieParseBatchTotalLenPacked(input: Uint8Array): number
44
+ httpParseRequestBatchTotalLenPacked(input: Uint8Array): number
45
+
46
+ // ── Backend-framework features ──
47
+ passwordHashBatchPacked(
48
+ input: Uint8Array,
49
+ salt: Uint8Array,
50
+ options?: PasswordHashOptions | null,
51
+ ): Uint8Array
52
+ /** Packed password-verify batch (two packed lists, zipped) → bitset. */
53
+ passwordVerifyBatchPacked(passwords: Uint8Array, phcs: Uint8Array): Uint8Array
54
+ /** Packed URL-resolve batch (two packed lists, zipped) → packed results. */
55
+ urlResolveBatchPacked(bases: Uint8Array, references: Uint8Array): Uint8Array
56
+ aeadEncryptBatchPacked(
57
+ input: Uint8Array,
58
+ key: Uint8Array,
59
+ nonce: Uint8Array,
60
+ algorithm?: string | null,
61
+ ): Uint8Array
62
+ aeadDecryptBatchPacked(
63
+ input: Uint8Array,
64
+ key: Uint8Array,
65
+ nonce: Uint8Array,
66
+ algorithm?: string | null,
67
+ ): Uint8Array
68
+ gzipCompressBatchPacked(input: Uint8Array, level?: number | null): Uint8Array
69
+ gzipDecompressBatchPacked(input: Uint8Array): Uint8Array
70
+ brotliCompressBatchPacked(input: Uint8Array, quality?: number | null): Uint8Array
71
+ brotliDecompressBatchPacked(input: Uint8Array): Uint8Array
72
+ jwtSignBatchPacked(
73
+ input: Uint8Array,
74
+ secret: Uint8Array,
75
+ ttlSeconds: number | null,
76
+ nowSeconds: number,
77
+ ): Uint8Array
78
+ jwtVerifyBatchPacked(input: Uint8Array, secret: Uint8Array, nowSeconds: number): Uint8Array
79
+ /** Batch HMAC-SHA256 sign (packed in → hex-signature byte results). */
80
+ hmacSha256BatchPacked(input: Uint8Array, key: Uint8Array): Uint8Array
81
+ /** Batch HMAC-SHA256 verify (two packed lists: data + hex sigs, zipped) → bitset. */
82
+ hmacSha256VerifyBatchPacked(input: Uint8Array, sigs: Uint8Array, key: Uint8Array): Uint8Array
83
+ multipartParseBatchPacked(input: Uint8Array, boundary: Uint8Array): Uint8Array
84
+ templateRenderBatchPacked(input: Uint8Array, source: string): Uint8Array
85
+ sseEncodeBatchPacked(
86
+ input: Uint8Array,
87
+ event: string | null,
88
+ id: string | null,
89
+ retry: number | null,
90
+ ): Uint8Array
91
+ wsFrameEncodeBatchPacked(
92
+ input: Uint8Array,
93
+ opcode: number,
94
+ mask: boolean,
95
+ fin: boolean,
96
+ ): Uint8Array
97
+ wsFrameDecodeBatchPacked(input: Uint8Array): Uint8Array
98
+ }
99
+
100
+ /** Build the `packed` namespace for a client context. */
101
+ export function buildPacked(ctx: RustClientContext): RustPacked {
102
+ // Packed ops are rayon-backed NAPI calls (no C ABI). Resolve each native fn
103
+ // on first use — ensuring the process-wide pool initializes at that point so
104
+ // `rust.configure({ rayonThreads })` still takes effect — and cache it via
105
+ // `resolvePoolNative` (shared with `resolveNative`/batch, context.ts). This
106
+ // removes BOTH the lazy-addon Proxy `get` and the old `withPoolInit`
107
+ // per-access Proxy from the packed hot path. The object keeps the
108
+ // `NativeAddon` type so the method bodies below typecheck unchanged.
109
+ const addon = new Proxy(ctx.addon, {
110
+ get: (_target, name) => resolvePoolNative(ctx, String(name)),
111
+ }) as typeof ctx.addon
112
+
113
+ return {
114
+ crc32BatchPacked(input) {
115
+ return addon.crc32BatchPacked(input)
116
+ },
117
+ jsonValidBatchPacked(input) {
118
+ return addon.jsonValidBatchPacked(input)
119
+ },
120
+ validateEmailBatchPacked(input) {
121
+ return addon.validateEmailBatchPacked(input)
122
+ },
123
+ validateUuidBatchPacked(input) {
124
+ return addon.validateUuidBatchPacked(input)
125
+ },
126
+ validateIpv4BatchPacked(input) {
127
+ return addon.validateIpv4BatchPacked(input)
128
+ },
129
+ validateIpv6BatchPacked(input) {
130
+ return addon.validateIpv6BatchPacked(input)
131
+ },
132
+ jsonSumBatchPacked(input) {
133
+ return addon.jsonSumBatchPacked(input)
134
+ },
135
+ queryParseBatchPacked(input) {
136
+ return addon.queryParseBatchPacked(input)
137
+ },
138
+ cookieParseBatchPacked(input) {
139
+ return addon.cookieParseBatchPacked(input)
140
+ },
141
+ httpParseRequestBatchPacked(input) {
142
+ return addon.httpParseRequestBatchPacked(input)
143
+ },
144
+ jsonPatchBatchPacked(docs, patches) {
145
+ return addon.jsonPatchBatchPacked(docs, patches)
146
+ },
147
+ fnv1A64BatchPacked(input) {
148
+ return addon.fnv1A64BatchPacked(input)
149
+ },
150
+ etagBatchPacked(input, weak) {
151
+ return addon.etagBatchPacked(input, weak ?? null)
152
+ },
153
+ urlEncodeBatchPacked(input) {
154
+ return addon.urlEncodeBatchPacked(input)
155
+ },
156
+ urlDecodeBatchPacked(input) {
157
+ return addon.urlDecodeBatchPacked(input)
158
+ },
159
+ urlDecodeBytesBatchPacked(input) {
160
+ return addon.urlDecodeBytesBatchPacked(input)
161
+ },
162
+ mimeFromExtensionBatchPacked(input) {
163
+ return addon.mimeFromExtensionBatchPacked(input)
164
+ },
165
+ wsAcceptKeyBatchPacked(input) {
166
+ return addon.wsAcceptKeyBatchPacked(input)
167
+ },
168
+
169
+ jsonValidBatchCountPacked(input) {
170
+ return asNumber(addon.jsonValidBatchCountPacked(input))
171
+ },
172
+ validateEmailBatchCountPacked(input) {
173
+ return asNumber(addon.validateEmailBatchCountPacked(input))
174
+ },
175
+ validateUuidBatchCountPacked(input) {
176
+ return asNumber(addon.validateUuidBatchCountPacked(input))
177
+ },
178
+ validateIpv4BatchCountPacked(input) {
179
+ return asNumber(addon.validateIpv4BatchCountPacked(input))
180
+ },
181
+ validateIpv6BatchCountPacked(input) {
182
+ return asNumber(addon.validateIpv6BatchCountPacked(input))
183
+ },
184
+ jsonSumBatchTotalPacked(input) {
185
+ return asNumber(addon.jsonSumBatchTotalPacked(input))
186
+ },
187
+ queryParseBatchTotalLenPacked(input) {
188
+ return asNumber(addon.queryParseBatchTotalLenPacked(input))
189
+ },
190
+ cookieParseBatchTotalLenPacked(input) {
191
+ return asNumber(addon.cookieParseBatchTotalLenPacked(input))
192
+ },
193
+ httpParseRequestBatchTotalLenPacked(input) {
194
+ return asNumber(addon.httpParseRequestBatchTotalLenPacked(input))
195
+ },
196
+
197
+ // ── Backend-framework features ──
198
+ passwordHashBatchPacked(input, salt, options) {
199
+ return addon.passwordHashBatchPacked(input, salt, options ?? null)
200
+ },
201
+ passwordVerifyBatchPacked(passwords, phcs) {
202
+ return addon.passwordVerifyBatchPacked(passwords, phcs)
203
+ },
204
+ urlResolveBatchPacked(bases, references) {
205
+ return addon.urlResolveBatchPacked(bases, references)
206
+ },
207
+ aeadEncryptBatchPacked(input, key, nonce, algorithm) {
208
+ return addon.aeadEncryptBatchPacked(input, key, nonce, algorithm ?? null)
209
+ },
210
+ aeadDecryptBatchPacked(input, key, nonce, algorithm) {
211
+ return addon.aeadDecryptBatchPacked(input, key, nonce, algorithm ?? null)
212
+ },
213
+ gzipCompressBatchPacked(input, level) {
214
+ return addon.gzipCompressBatchPacked(input, level ?? null)
215
+ },
216
+ gzipDecompressBatchPacked(input) {
217
+ return addon.gzipDecompressBatchPacked(input)
218
+ },
219
+ brotliCompressBatchPacked(input, quality) {
220
+ return addon.brotliCompressBatchPacked(input, quality ?? null)
221
+ },
222
+ brotliDecompressBatchPacked(input) {
223
+ return addon.brotliDecompressBatchPacked(input)
224
+ },
225
+ jwtSignBatchPacked(input, secret, ttlSeconds, nowSeconds) {
226
+ return addon.jwtSignBatchPacked(input, secret, ttlSeconds ?? null, nowSeconds)
227
+ },
228
+ jwtVerifyBatchPacked(input, secret, nowSeconds) {
229
+ return addon.jwtVerifyBatchPacked(input, secret, nowSeconds)
230
+ },
231
+ hmacSha256BatchPacked(input, key) {
232
+ return addon.hmacSha256BatchPacked(input, key)
233
+ },
234
+ hmacSha256VerifyBatchPacked(input, sigs, key) {
235
+ return addon.hmacSha256VerifyBatchPacked(input, sigs, key)
236
+ },
237
+ multipartParseBatchPacked(input, boundary) {
238
+ return addon.multipartParseBatchPacked(input, boundary)
239
+ },
240
+ templateRenderBatchPacked(input, source) {
241
+ return addon.templateRenderBatchPacked(input, source)
242
+ },
243
+ sseEncodeBatchPacked(input, event, id, retry) {
244
+ return addon.sseEncodeBatchPacked(input, event ?? null, id ?? null, retry ?? null)
245
+ },
246
+ wsFrameEncodeBatchPacked(input, opcode, mask, fin) {
247
+ return addon.wsFrameEncodeBatchPacked(input, opcode, mask, fin)
248
+ },
249
+ wsFrameDecodeBatchPacked(input) {
250
+ return addon.wsFrameDecodeBatchPacked(input)
251
+ },
252
+ }
253
+ }
@@ -0,0 +1,28 @@
1
+ // src/rust-ffi/proven.ts — the baked "proven selection" surface.
2
+ //
3
+ // `proven` re-exposes the FULL `rust.*` surface (identical object) alongside
4
+ // the pure-data registry (`src/shared/proven.ts`) that states which
5
+ // implementation is the benchmark-proven winner for every op: 'native',
6
+ // 'js', or 'bun' (Bun built-in delegation). The winners are BAKED (committed,
7
+ // benchmark-derived) and verified by `test/unit/shared/proven.test.ts` — no
8
+ // live benchmark audit and no `@deprecated` JSDoc machinery (the old
9
+ // `check:proven` / `check:annotate` friction, intentionally not re-added).
10
+
11
+ import { rust, type RustClient } from './client'
12
+
13
+ /** The full `rust.*` surface — identical to `rust`; the proven wiring is baked (see {@link ../shared/proven}). */
14
+ export type ProvenClient = RustClient
15
+
16
+ /** The full `rust.*` surface, exposed for audit. Same object as `rust`. */
17
+ export const proven: ProvenClient = rust
18
+
19
+ export {
20
+ PROVEN_SELECTION,
21
+ isProven,
22
+ provenEntry,
23
+ provenImpl,
24
+ provenStatus,
25
+ provenSummary,
26
+ provenSurface,
27
+ } from '../shared/proven'
28
+ export type { ProvenEntry, ProvenImpl, ProvenStatus } from '../shared/proven'