castrum 0.9.0 → 0.9.2
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.
- package/README.md +153 -630
- package/castrum.linux-x64-gnu.node +0 -0
- package/dist/index.d.ts +1653 -1817
- package/dist/index.js +6172 -4294
- package/docs/API.md +337 -0
- package/docs/ARCHITECTURE.md +111 -17
- package/docs/BENCHMARKS.md +117 -49
- package/docs/CASE_STUDY.md +243 -0
- package/docs/ENVIRONMENT.md +24 -7
- package/docs/FFI_BUN_GUIDE.md +335 -0
- package/docs/GETTING_STARTED.md +18 -34
- package/docs/HOW_TO_ADD_AN_OP.md +180 -0
- package/docs/INGRESS-ROUTER.md +82 -0
- package/docs/INGRESS.md +11 -7
- package/docs/NATIVE-ROUTE.md +77 -0
- package/docs/REPO_MAP.md +103 -53
- package/docs/adr/0001-two-wire-formats.md +1 -1
- package/docs/adr/0003-bun-builtins-delegation.md +6 -5
- package/docs/ai/LOCAL_DEV.md +81 -0
- package/docs/ai/TREE.md +1070 -0
- package/docs/bun-builtins-decision-matrix.md +25 -18
- package/index.ts +9 -16
- package/package.json +41 -28
- package/src/ingress/body.ts +167 -27
- package/src/ingress/decode/result-base.ts +10 -2
- package/src/ingress/handlers.ts +116 -285
- package/src/ingress/headers/security.ts +41 -0
- package/src/ingress/health.ts +1 -0
- package/src/ingress/index.ts +45 -169
- package/src/ingress/native-route.ts +182 -0
- package/src/ingress/packing/gather-raw-headers.ts +110 -22
- package/src/ingress/packing/header-packing.ts +5 -5
- package/src/ingress/packing/input-packer.ts +17 -3
- package/src/ingress/packing/route-wire.ts +197 -0
- package/src/ingress/packing/select-headers.ts +20 -7
- package/src/ingress/path-matcher.ts +115 -0
- package/src/ingress/response/baked-response.ts +302 -0
- package/src/ingress/router.ts +277 -0
- package/src/ingress/routes/common.ts +50 -1
- package/src/ingress/routes/fallback.ts +2 -2
- package/src/ingress/routes/head.ts +3 -13
- package/src/ingress/routes/index.ts +5 -4
- package/src/ingress/routes/json-write.ts +26 -47
- package/src/ingress/routes/native.ts +130 -0
- package/src/ingress/routes/options.ts +2 -12
- package/src/ingress/routes/read.ts +3 -13
- package/src/ingress/routes/responder.ts +159 -0
- package/src/ingress/server-node.ts +7 -7
- package/src/ingress/server.ts +83 -112
- package/src/ingress/sync.ts +151 -0
- package/src/ingress/types.ts +44 -1
- package/src/integration/pipeline.ts +3 -0
- package/src/integration/streaming.ts +2 -3
- package/src/integration/websocket.ts +4 -3
- package/src/loader/batch.ts +4 -0
- package/src/loader/cost.ts +1 -0
- package/src/loader/index.ts +43 -228
- package/src/loader/state.ts +84 -0
- package/src/loader/types.ts +145 -0
- package/src/native/ffi/build/codecs.ts +736 -0
- package/src/native/ffi/build/compress.ts +248 -0
- package/src/native/ffi/build/instances.ts +598 -0
- package/src/native/ffi/build/parse.ts +539 -0
- package/src/native/ffi/build/util.ts +140 -0
- package/src/native/ffi/build.ts +94 -0
- package/src/native/ffi/constants.ts +58 -0
- package/src/native/ffi/selftest.ts +22 -0
- package/src/native/ffi/types.ts +499 -0
- package/src/native/ffi.ts +307 -1357
- package/src/native/loader.ts +52 -6
- package/src/native/types/instances.ts +279 -0
- package/src/native/types.ts +41 -238
- package/src/runtime/builtins.ts +131 -0
- package/src/runtime/codec.ts +147 -0
- package/src/runtime/detect.ts +36 -0
- package/src/runtime/index.ts +28 -0
- package/src/runtime/native.ts +35 -0
- package/src/runtime/server.ts +31 -0
- package/src/runtime/transport.ts +64 -0
- package/src/runtime/types.ts +173 -0
- package/src/runtime/uuid.ts +45 -0
- package/src/runtime/websocket.ts +30 -0
- package/src/rust-ffi/addon.ts +1 -1
- package/src/rust-ffi/batch/build.ts +155 -0
- package/src/rust-ffi/batch/index.ts +8 -0
- package/src/rust-ffi/batch/types.ts +92 -0
- package/src/rust-ffi/client.ts +5 -6
- package/src/rust-ffi/context.ts +39 -10
- package/src/rust-ffi/index.ts +28 -17
- package/src/rust-ffi/into.ts +21 -0
- package/src/rust-ffi/options.ts +1 -1
- package/src/rust-ffi/packed.ts +40 -2
- package/src/rust-ffi/proven.ts +16 -30
- package/src/rust-ffi/scalar/crypto.ts +188 -107
- package/src/rust-ffi/scalar/factories.ts +257 -27
- package/src/rust-ffi/scalar/hashing.ts +43 -41
- package/src/rust-ffi/scalar/http.ts +208 -77
- package/src/rust-ffi/scalar/index.ts +3 -3
- package/src/rust-ffi/scalar/interface.ts +88 -213
- package/src/rust-ffi/scalar/json-packed.ts +175 -0
- package/src/rust-ffi/scalar/json.ts +28 -12
- package/src/rust-ffi/scalar/payload.ts +159 -42
- package/src/rust-ffi/text.ts +31 -5
- package/src/selection.ts +27 -31
- package/src/shared/adaptive.ts +1 -2
- package/src/shared/buffer-pool.ts +72 -17
- package/src/shared/bytes.ts +75 -6
- package/src/shared/codec.ts +78 -0
- package/src/shared/env.ts +4 -4
- package/src/shared/log.ts +1 -0
- package/src/shared/packed/index.ts +10 -0
- package/src/shared/packed/parsers.ts +31 -0
- package/src/shared/packed/schema.ts +23 -0
- package/src/shared/{packed.ts → packed/wire.ts} +31 -39
- package/src/shared/proven.ts +189 -496
- package/src/shared/runtime.ts +20 -25
- package/src/shared/uuid.ts +12 -28
- package/src/data/json-rows.ts +0 -33
- package/src/rust-ffi/batch.ts +0 -431
- package/src/shared/bench-classify.ts +0 -209
package/src/shared/proven.ts
CHANGED
|
@@ -1,596 +1,289 @@
|
|
|
1
|
-
// src/shared/proven.ts —
|
|
1
|
+
// src/shared/proven.ts — baked "proven selection" registry (PURE DATA, no addon).
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// `bench/results/cpu/latest.json`):
|
|
3
|
+
// The proven selection answers: "for op X, which implementation is the
|
|
4
|
+
// benchmark-proven winner, and is that what we wire as the default?"
|
|
6
5
|
//
|
|
7
|
-
// -
|
|
8
|
-
// -
|
|
9
|
-
// -
|
|
10
|
-
//
|
|
11
|
-
// like Bun's JSON.parse).
|
|
12
|
-
// - "unmeasured" No direct comparison task exists (infra/config only).
|
|
6
|
+
// - 'native' → the rust addon wins (bun:ffi on Bun / napi on Node)
|
|
7
|
+
// - 'js' → the pure-TS implementation wins
|
|
8
|
+
// - 'bun' → a Bun built-in wins UNDER BUN and is delegated there
|
|
9
|
+
// (see src/runtime/builtins.ts)
|
|
13
10
|
//
|
|
14
|
-
// This
|
|
15
|
-
//
|
|
16
|
-
// the
|
|
11
|
+
// This is BAKED (committed), benchmark-derived data — the winners were
|
|
12
|
+
// measured by `scripts/select-native.ts` (the `nativeRatio` in
|
|
13
|
+
// `src/selection.json`) and the Bun built-in decision matrix
|
|
14
|
+
// (`docs/bun-builtins-decision-matrix.md`). It is PURE DATA: no addon import,
|
|
15
|
+
// no dlopen, no live benchmark audit. That live audit was the friction of the
|
|
16
|
+
// old `check:proven`/`check:annotate` machinery (flaky on noisy hosts) — it
|
|
17
|
+
// is intentionally NOT re-added. Instead `test/unit/shared/proven.test.ts`
|
|
18
|
+
// verifies every entry is wired to the impl it claims (`opImpl`, the Bun
|
|
19
|
+
// built-in registry, and the addon's embedded selection.json), so drift is
|
|
20
|
+
// caught deterministically instead of by re-running benchmarks.
|
|
21
|
+
//
|
|
22
|
+
// `typicalRatio` is the addon-vs-pure-TS-baseline ratio (rust faster = >1) for
|
|
23
|
+
// native/js entries, and the Bun-built-in-vs-addon ratio for 'bun' entries
|
|
24
|
+
// (higher = the built-in wins by more).
|
|
25
|
+
|
|
26
|
+
/** The benchmark-proven default implementation for an op. */
|
|
27
|
+
export type ProvenImpl = 'native' | 'js' | 'bun'
|
|
17
28
|
|
|
18
|
-
|
|
29
|
+
/** How decisive the baked winner is. */
|
|
30
|
+
export type ProvenStatus = 'proven' | 'parity' | 'unmeasured'
|
|
19
31
|
|
|
32
|
+
/** One entry in the baked proven-selection registry. */
|
|
20
33
|
export interface ProvenEntry {
|
|
21
|
-
/**
|
|
34
|
+
/** Selection op name (matches `opImpl(op)` / `src/selection.json` keys). */
|
|
22
35
|
name: string
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
rustTask: string
|
|
29
|
-
status: PerformanceStatus
|
|
30
|
-
/** Typical rust-vs-baseline ratio from release/perf builds (rust faster = >1). */
|
|
36
|
+
/** The baked default implementation: the benchmark-proven winner. */
|
|
37
|
+
impl: ProvenImpl
|
|
38
|
+
/** `proven` = decisive win, `parity` = borderline, `unmeasured` = pinned by policy. */
|
|
39
|
+
status: ProvenStatus
|
|
40
|
+
/** Measured ratio behind the decision (see module doc for the axis). */
|
|
31
41
|
typicalRatio?: number
|
|
32
42
|
/** Why this classification. */
|
|
33
43
|
note?: string
|
|
34
44
|
}
|
|
35
45
|
|
|
36
46
|
/**
|
|
37
|
-
*
|
|
38
|
-
* (
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* `as const satisfies` keeps the literal `name`/`status` types so the
|
|
43
|
-
* `ProvenKey` type (below) can be derived at the type level.
|
|
47
|
+
* Baked proven-winner registry. Covering the FULL selection surface
|
|
48
|
+
* (`src/selection.json` ops + every Bun built-in delegation) so nothing can be
|
|
49
|
+
* silently dropped. Classifications are based on release/perf-build results;
|
|
50
|
+
* `test/unit/shared/proven.test.ts` re-checks them against the LIVE wiring.
|
|
44
51
|
*/
|
|
45
|
-
export const
|
|
46
|
-
// ──
|
|
47
|
-
{
|
|
48
|
-
name: 'fnv1a64',
|
|
49
|
-
label: 'FNV-1a 64',
|
|
50
|
-
nativeTask: 'native:fnv1a64',
|
|
51
|
-
rustTask: 'rust:fnv1a64',
|
|
52
|
-
status: 'proven',
|
|
53
|
-
typicalRatio: 11,
|
|
54
|
-
},
|
|
52
|
+
export const PROVEN_SELECTION: readonly ProvenEntry[] = [
|
|
53
|
+
// ── Bun built-in delegation — 'bun' (wins under Bun; consumer binding = 'js') ──
|
|
55
54
|
{
|
|
56
|
-
name: '
|
|
57
|
-
|
|
58
|
-
nativeTask: 'native:json_valid',
|
|
59
|
-
rustTask: 'rust:json_valid',
|
|
60
|
-
status: 'proven',
|
|
61
|
-
typicalRatio: 3,
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
name: 'jsonSumIds',
|
|
65
|
-
label: 'JSON sum',
|
|
66
|
-
nativeTask: 'native:json_sum',
|
|
67
|
-
rustTask: 'rust:json_sum',
|
|
68
|
-
status: 'proven',
|
|
69
|
-
typicalRatio: 3,
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
name: 'httpParseRequestPacked',
|
|
73
|
-
label: 'HTTP parse',
|
|
74
|
-
nativeTask: 'native:http_parse',
|
|
75
|
-
rustTask: 'rust:http_parse',
|
|
76
|
-
status: 'proven',
|
|
77
|
-
typicalRatio: 4,
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
name: 'queryParsePacked',
|
|
81
|
-
label: 'Query parse',
|
|
82
|
-
nativeTask: 'native:query_parse',
|
|
83
|
-
rustTask: 'rust:query_parse',
|
|
55
|
+
name: 'crc32',
|
|
56
|
+
impl: 'bun',
|
|
84
57
|
status: 'proven',
|
|
85
58
|
typicalRatio: 4,
|
|
59
|
+
note: 'Bun.hash.crc32 wins 2.8–8.4×; selection.json records js (0.659)',
|
|
86
60
|
},
|
|
87
61
|
{
|
|
88
|
-
name: '
|
|
89
|
-
|
|
90
|
-
nativeTask: 'native:cookie_parse',
|
|
91
|
-
rustTask: 'rust:cookie_parse',
|
|
92
|
-
status: 'proven',
|
|
93
|
-
typicalRatio: 2.5,
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
name: 'wsAcceptKey',
|
|
97
|
-
label: 'WebSocket accept',
|
|
98
|
-
nativeTask: 'native:ws_accept_key',
|
|
99
|
-
rustTask: 'rust:ws_accept_key',
|
|
100
|
-
status: 'proven',
|
|
101
|
-
typicalRatio: 1.6,
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
name: 'jsonPatch',
|
|
105
|
-
label: 'JSON Patch',
|
|
106
|
-
nativeTask: 'native:json_patch',
|
|
107
|
-
rustTask: 'rust:json_patch',
|
|
62
|
+
name: 'xxh3',
|
|
63
|
+
impl: 'bun',
|
|
108
64
|
status: 'proven',
|
|
109
|
-
typicalRatio:
|
|
110
|
-
note: '
|
|
65
|
+
typicalRatio: 4.15,
|
|
66
|
+
note: 'Bun.hash.xxHash3 ~4.15×; addon kept as the Node / non-Bun path',
|
|
111
67
|
},
|
|
112
68
|
{
|
|
113
69
|
name: 'hmacSha256',
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
typicalRatio: 1.5,
|
|
119
|
-
note: 'Classification vs the node:crypto baseline. Under Bun the public rust.hmacSha256 delegates to Bun.CryptoHasher (BUN_WINS — hex re-encoded to the same contract); this row measures the raw addon (see src/bench/raw-native.ts).',
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
name: 'hmacSha256Verify',
|
|
123
|
-
label: 'HMAC verify',
|
|
124
|
-
nativeTask: 'native:hmac_verify',
|
|
125
|
-
rustTask: 'rust:hmac_verify',
|
|
126
|
-
status: 'proven',
|
|
127
|
-
typicalRatio: 2.4,
|
|
70
|
+
impl: 'bun',
|
|
71
|
+
status: 'parity',
|
|
72
|
+
typicalRatio: 1.2,
|
|
73
|
+
note: 'Bun.CryptoHasher mild 1.1–1.4×; the addon still beats the pure-JS baseline (1.212)',
|
|
128
74
|
},
|
|
129
75
|
{
|
|
130
|
-
name: '
|
|
131
|
-
|
|
132
|
-
nativeTask: 'native:validate_email',
|
|
133
|
-
rustTask: 'rust:validate_email',
|
|
76
|
+
name: 'randomToken',
|
|
77
|
+
impl: 'bun',
|
|
134
78
|
status: 'proven',
|
|
135
|
-
typicalRatio:
|
|
79
|
+
typicalRatio: 1.62,
|
|
80
|
+
note: 'Bun.randomUUIDv7 / crypto.getRandomValues for token-sized output',
|
|
136
81
|
},
|
|
137
82
|
{
|
|
138
|
-
name: '
|
|
139
|
-
|
|
140
|
-
nativeTask: 'native:validate_ipv6',
|
|
141
|
-
rustTask: 'rust:validate_ipv6',
|
|
83
|
+
name: 'gzipCompress',
|
|
84
|
+
impl: 'bun',
|
|
142
85
|
status: 'proven',
|
|
143
|
-
typicalRatio:
|
|
86
|
+
typicalRatio: 2.02,
|
|
87
|
+
note: 'Bun.gzipSync ~2×; gzipDecompress deliberately NOT delegated (64 MiB bomb cap)',
|
|
144
88
|
},
|
|
145
89
|
{
|
|
146
90
|
name: 'urlEncode',
|
|
147
|
-
|
|
148
|
-
nativeTask: 'native:url_encode',
|
|
149
|
-
rustTask: 'rust:url_encode',
|
|
150
|
-
status: 'not-competitive',
|
|
151
|
-
note: 'Public rust.urlEncode delegates to encodeURIComponent under Bun (BUN_WINS — ~3-4x faster than the FFI crossing; skips the C-ABI call). The rust: column measures the RAW addon (src/bench/raw-native.ts): the small-input FFI crossing loses (~0.58x), but LARGE inputs win (rust:url_encode_large ~1.45x) — the honest report no longer self-compares the built-in. Rust addon remains the Node path. Byte parity pinned by test/unit/features/url.test.ts + test/unit/features/wiring.test.ts.',
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
name: 'urlDecode',
|
|
155
|
-
label: 'URL decode',
|
|
156
|
-
nativeTask: 'native:url_decode',
|
|
157
|
-
rustTask: 'rust:url_decode',
|
|
158
|
-
status: 'not-competitive',
|
|
159
|
-
note: 'Public rust.urlDecode delegates to decodeURIComponent under Bun (BUN_WINS — ~4-8x faster than the FFI crossing; strict UTF-8 semantics match: both throw on malformed/invalid). The rust: column measures the RAW addon (src/bench/raw-native.ts): the small-input FFI crossing loses (~0.55x), but LARGE inputs win (rust:url_decode_large ~3.45x) — the honest report no longer self-compares the built-in. Rust addon remains the Node path and the raw-bytes urlDecodeBytes stays native. Parity pinned by test/unit/features/url.test.ts + test/unit/features/wiring.test.ts.',
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
name: 'jwtVerify',
|
|
163
|
-
label: 'JWT verify',
|
|
164
|
-
nativeTask: 'native:jwt_verify',
|
|
165
|
-
rustTask: 'rust:jwt_verify',
|
|
166
|
-
status: 'proven',
|
|
167
|
-
typicalRatio: 1.4,
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
name: 'passwordHash',
|
|
171
|
-
label: 'Password hash',
|
|
172
|
-
nativeTask: 'native:password_hash',
|
|
173
|
-
rustTask: 'rust:password_hash',
|
|
91
|
+
impl: 'bun',
|
|
174
92
|
status: 'proven',
|
|
175
|
-
typicalRatio:
|
|
176
|
-
note: '
|
|
93
|
+
typicalRatio: 11.5,
|
|
94
|
+
note: 'encodeURIComponent ~11.5×, zero alloc',
|
|
177
95
|
},
|
|
178
96
|
{
|
|
179
|
-
name: '
|
|
180
|
-
|
|
181
|
-
nativeTask: 'native:aead_encrypt',
|
|
182
|
-
rustTask: 'rust:aead_encrypt',
|
|
97
|
+
name: 'urlDecode',
|
|
98
|
+
impl: 'bun',
|
|
183
99
|
status: 'proven',
|
|
184
|
-
typicalRatio:
|
|
100
|
+
typicalRatio: 6,
|
|
101
|
+
note: 'decodeURIComponent ~4–8×',
|
|
185
102
|
},
|
|
186
103
|
{
|
|
187
|
-
name: '
|
|
188
|
-
|
|
189
|
-
nativeTask: 'native:aead_decrypt',
|
|
190
|
-
rustTask: 'rust:aead_decrypt',
|
|
104
|
+
name: 'base64Encode',
|
|
105
|
+
impl: 'bun',
|
|
191
106
|
status: 'proven',
|
|
192
107
|
typicalRatio: 2,
|
|
108
|
+
note: 'Buffer.toString("base64") ~2×; url-safe / unpadded fall through to native',
|
|
193
109
|
},
|
|
194
110
|
{
|
|
195
|
-
name: '
|
|
196
|
-
|
|
197
|
-
nativeTask: 'native:gzip_decompress',
|
|
198
|
-
rustTask: 'rust:gzip_decompress',
|
|
199
|
-
status: 'proven',
|
|
200
|
-
typicalRatio: 1.4,
|
|
201
|
-
note: "zlib-rs vs node zlib; swings 1.0-1.4x run-to-run. Deliberately NOT delegated to Bun.gunzipSync under Bun (NOT in BUN_WINS): Bun's decompressor has no output-size bound, and the native path keeps the 64 MiB decompression-bomb cap.",
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
name: 'brotliDecompress',
|
|
205
|
-
label: 'Brotli decompress',
|
|
206
|
-
nativeTask: 'native:brotli_decompress',
|
|
207
|
-
rustTask: 'rust:brotli_decompress',
|
|
208
|
-
status: 'proven',
|
|
209
|
-
typicalRatio: 1.9,
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
name: 'multipartParse',
|
|
213
|
-
label: 'Multipart parse',
|
|
214
|
-
nativeTask: 'native:multipart_parse',
|
|
215
|
-
rustTask: 'rust:multipart_parse',
|
|
216
|
-
status: 'proven',
|
|
217
|
-
typicalRatio: 2.3,
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
name: 'wsFrameEncode',
|
|
221
|
-
label: 'WS frame encode',
|
|
222
|
-
nativeTask: 'native:ws_frame_encode',
|
|
223
|
-
rustTask: 'rust:ws_frame_encode',
|
|
224
|
-
status: 'proven',
|
|
225
|
-
typicalRatio: 1.8,
|
|
226
|
-
},
|
|
227
|
-
{
|
|
228
|
-
name: 'wsFrameDecode',
|
|
229
|
-
label: 'WS frame decode',
|
|
230
|
-
nativeTask: 'native:ws_frame_decode',
|
|
231
|
-
rustTask: 'rust:ws_frame_decode',
|
|
111
|
+
name: 'base64UrlEncode',
|
|
112
|
+
impl: 'bun',
|
|
232
113
|
status: 'proven',
|
|
233
114
|
typicalRatio: 2,
|
|
115
|
+
note: 'Buffer.toString("base64url")',
|
|
234
116
|
},
|
|
235
117
|
{
|
|
236
|
-
name: '
|
|
237
|
-
|
|
238
|
-
nativeTask: 'native:json_schema_validate',
|
|
239
|
-
rustTask: 'rust:json_schema_validate',
|
|
240
|
-
status: 'proven',
|
|
241
|
-
note: 'Zero-DOM fast path validates raw bytes for the common keyword subset (scalar ~1.2-2.4x, batch ~1.0-1.56x vs ajv); unsupported keywords fall back to the jsonschema crate.',
|
|
242
|
-
},
|
|
243
|
-
|
|
244
|
-
// ── Parity (no clear win) ──
|
|
245
|
-
{
|
|
246
|
-
name: 'crc32',
|
|
247
|
-
label: 'CRC32',
|
|
248
|
-
nativeTask: 'native:crc32',
|
|
249
|
-
rustTask: 'rust:crc32',
|
|
250
|
-
status: 'not-competitive',
|
|
251
|
-
note: 'Raw addon vs the same-engine JS crc-32 loop (~0.23-0.44x across runs). Under Bun the public rust.crc32 delegates to Bun.hash.crc32 (BUN_WINS, ~2.8-8.4x) — this row measures the raw addon (src/bench/raw-native.ts).',
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
name: 'xxh3',
|
|
255
|
-
label: 'XXH3-64',
|
|
256
|
-
nativeTask: 'diag:bun_hash_xxh3',
|
|
257
|
-
rustTask: 'diag:xxh3',
|
|
258
|
-
status: 'not-competitive',
|
|
259
|
-
note: 'Bun.hash.xxHash3 wins ~4x (in-process C++ beats the FFI crossing). The public rust.xxh3 now DELEGATES to Bun.hash.xxHash3 under Bun (BUN_WINS); the addon remains the Node/non-Bun fast path. See docs/bun-builtins-decision-matrix.md.',
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
name: 'randomToken',
|
|
263
|
-
label: 'Random token',
|
|
264
|
-
nativeTask: 'native:random_token',
|
|
265
|
-
rustTask: 'rust:random_token',
|
|
266
|
-
status: 'parity',
|
|
267
|
-
typicalRatio: 1.1,
|
|
268
|
-
note: 'Raw addon vs crypto.getRandomValues baseline. Under Bun the public rust.randomToken delegates to crypto.getRandomValues + native hex (BUN_WINS, same 2n-hex format + 16 MiB guard) — this row measures the raw addon (src/bench/raw-native.ts).',
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
name: 'validateUuid',
|
|
272
|
-
label: 'UUID validation',
|
|
273
|
-
nativeTask: 'native:validate_uuid',
|
|
274
|
-
rustTask: 'rust:validate_uuid',
|
|
275
|
-
status: 'parity',
|
|
276
|
-
typicalRatio: 1,
|
|
277
|
-
},
|
|
278
|
-
{
|
|
279
|
-
name: 'validateIpv4',
|
|
280
|
-
label: 'IPv4 validation',
|
|
281
|
-
nativeTask: 'native:validate_ipv4',
|
|
282
|
-
rustTask: 'rust:validate_ipv4',
|
|
283
|
-
status: 'parity',
|
|
284
|
-
typicalRatio: 1.05,
|
|
285
|
-
},
|
|
286
|
-
{
|
|
287
|
-
name: 'mimeFromExtension',
|
|
288
|
-
label: 'MIME lookup',
|
|
289
|
-
nativeTask: 'native:mime',
|
|
290
|
-
rustTask: 'rust:mime',
|
|
291
|
-
status: 'parity',
|
|
292
|
-
typicalRatio: 1.4,
|
|
293
|
-
note: 'Consistently ~1.38-1.44x rust after the 2026-08-12 marshal reduction (cachedMime no longer per-call slices; text.mimeFromExtension memoizes the decoded string). phf table lookup.',
|
|
294
|
-
},
|
|
295
|
-
{
|
|
296
|
-
name: 'gzipCompress',
|
|
297
|
-
label: 'Gzip compress',
|
|
298
|
-
nativeTask: 'native:gzip_compress',
|
|
299
|
-
rustTask: 'rust:gzip_compress',
|
|
300
|
-
status: 'parity',
|
|
301
|
-
typicalRatio: 1,
|
|
302
|
-
note: 'Raw addon vs node zlib baseline. Under Bun the public rust.gzipCompress delegates to Bun.gzipSync (BUN_WINS, ~2x; decompression-parity with the addon — only the header OS byte differs) — this row measures the raw addon (src/bench/raw-native.ts).',
|
|
303
|
-
},
|
|
304
|
-
{
|
|
305
|
-
name: 'sseEncodeEvent',
|
|
306
|
-
label: 'SSE encode',
|
|
307
|
-
nativeTask: 'native:sse_encode',
|
|
308
|
-
rustTask: 'rust:sse_encode',
|
|
309
|
-
status: 'parity',
|
|
310
|
-
typicalRatio: 1.1,
|
|
311
|
-
},
|
|
312
|
-
|
|
313
|
-
// ── New primitives (2026-08-11; measured vs Bun built-ins / node:crypto) ──
|
|
314
|
-
{
|
|
315
|
-
name: 'passwordHashBcrypt',
|
|
316
|
-
label: 'Password hash (bcrypt)',
|
|
317
|
-
nativeTask: 'diag:bun_password_bcrypt_hash',
|
|
318
|
-
rustTask: 'diag:bcrypt_hash',
|
|
319
|
-
status: 'parity',
|
|
320
|
-
note: 'Bun.password.bcrypt ~1.24x faster at cost 10 (noisy KDF); rust is self-contained and non-Bun. See docs/bun-builtins-decision-matrix.md.',
|
|
321
|
-
},
|
|
322
|
-
{
|
|
323
|
-
name: 'passwordVerifyBcrypt',
|
|
324
|
-
label: 'Password verify (bcrypt)',
|
|
325
|
-
nativeTask: 'diag:bun_password_bcrypt_verify',
|
|
326
|
-
rustTask: 'diag:bcrypt_verify',
|
|
327
|
-
status: 'parity',
|
|
328
|
-
note: 'Rust ~1.49x vs Bun.password.verify at cost 10; KDF timings noisy — parity for gate stability.',
|
|
329
|
-
},
|
|
330
|
-
{
|
|
331
|
-
name: 'pbkdf2Sha256',
|
|
332
|
-
label: 'PBKDF2-HMAC-SHA256',
|
|
333
|
-
nativeTask: 'diag:pbkdf2_sha256',
|
|
334
|
-
rustTask: 'diag:pbkdf2_sha256_rust',
|
|
335
|
-
status: 'parity',
|
|
336
|
-
note: '~1.08x vs node:crypto pbkdf2Sync at 100k rounds (parity); Bun has no synchronous PBKDF2.',
|
|
337
|
-
},
|
|
338
|
-
|
|
339
|
-
// ── Not competitive (JS baseline wins) ──
|
|
340
|
-
{
|
|
341
|
-
name: 'jsonParse',
|
|
342
|
-
label: 'JSON parse',
|
|
343
|
-
nativeTask: 'native:json_parse',
|
|
344
|
-
rustTask: 'rust:json_parse',
|
|
345
|
-
status: 'not-competitive',
|
|
346
|
-
note: "Bun's JSON.parse beats the native DOM + napi marshaling path (~5x).",
|
|
347
|
-
},
|
|
348
|
-
{
|
|
349
|
-
name: 'jwtSign',
|
|
350
|
-
label: 'JWT sign',
|
|
351
|
-
nativeTask: 'native:jwt_sign',
|
|
352
|
-
rustTask: 'rust:jwt_sign',
|
|
353
|
-
status: 'not-competitive',
|
|
354
|
-
note: 'Base64 + claims DOM marshal overhead. Use jwtSignBytes (claims as JSON bytes) which skips the napi Value marshal and flips to a ~1.07x win.',
|
|
355
|
-
},
|
|
356
|
-
{
|
|
357
|
-
name: 'jwtSignBytes',
|
|
358
|
-
label: 'JWT sign (bytes)',
|
|
359
|
-
nativeTask: 'native:jwt_sign',
|
|
360
|
-
rustTask: 'rust:jwt_sign_bytes',
|
|
361
|
-
status: 'parity',
|
|
362
|
-
note: 'Byte-JSON claims overload avoids the napi serde_json::Value DOM marshal; flips jwtSign from a ~1.3x loss to ~1.07x (parity).',
|
|
363
|
-
},
|
|
364
|
-
{
|
|
365
|
-
name: 'brotliCompress',
|
|
366
|
-
label: 'Brotli compress',
|
|
367
|
-
nativeTask: 'native:brotli_compress',
|
|
368
|
-
rustTask: 'rust:brotli_compress',
|
|
369
|
-
status: 'not-competitive',
|
|
370
|
-
note: 'The native brotli baseline wins for small inputs.',
|
|
371
|
-
},
|
|
372
|
-
{
|
|
373
|
-
name: 'templateRender',
|
|
374
|
-
label: 'Template render',
|
|
375
|
-
nativeTask: 'native:template_render',
|
|
376
|
-
rustTask: 'rust:template_render',
|
|
377
|
-
status: 'not-competitive',
|
|
378
|
-
note: 'The allocating render marshals the context via napi DOM (~1.5x loss). Use TemplateRenderer.renderBytes (JSON-bytes context) which avoids it and wins ~1.37x.',
|
|
379
|
-
},
|
|
380
|
-
|
|
381
|
-
// ── Framework actions (2026-08-07; release-build numbers) ──
|
|
382
|
-
{
|
|
383
|
-
name: 'formParsePacked',
|
|
384
|
-
label: 'Form parse',
|
|
385
|
-
nativeTask: 'native:form_parse',
|
|
386
|
-
rustTask: 'rust:form_parse',
|
|
118
|
+
name: 'hexEncode',
|
|
119
|
+
impl: 'bun',
|
|
387
120
|
status: 'proven',
|
|
388
|
-
typicalRatio:
|
|
389
|
-
note: '
|
|
390
|
-
},
|
|
391
|
-
{
|
|
392
|
-
name: 'parseMediaType',
|
|
393
|
-
label: 'Media type parse',
|
|
394
|
-
nativeTask: 'native:media_type_parse',
|
|
395
|
-
rustTask: 'rust:media_type_parse',
|
|
396
|
-
status: 'not-competitive',
|
|
397
|
-
note: 'Consistent ~0.71-0.81x (sub-µs FFI crossing vs the JS baseline); use MediaTypeMatcher (precompiled expected) for the zero-alloc match path.',
|
|
398
|
-
},
|
|
399
|
-
{
|
|
400
|
-
name: 'etag',
|
|
401
|
-
label: 'ETag',
|
|
402
|
-
nativeTask: 'native:etag',
|
|
403
|
-
rustTask: 'rust:etag',
|
|
404
|
-
status: 'parity',
|
|
405
|
-
typicalRatio: 1.06,
|
|
121
|
+
typicalRatio: 1.35,
|
|
122
|
+
note: 'Buffer.toString("hex")',
|
|
406
123
|
},
|
|
407
124
|
{
|
|
408
125
|
name: 'httpDate',
|
|
409
|
-
|
|
410
|
-
nativeTask: 'native:http_date',
|
|
411
|
-
rustTask: 'rust:http_date',
|
|
412
|
-
status: 'not-competitive',
|
|
413
|
-
note: 'Delegates to Date.toUTCString() under Bun (BUN_WINS — ~3.7x faster than the FFI crossing; byte-identical RFC 1123 for HTTP timestamps, incl. leap years/epoch). Rust addon remains the Node path; pooled httpDateInto stays native.',
|
|
414
|
-
},
|
|
415
|
-
{
|
|
416
|
-
name: 'createConditionalRequest',
|
|
417
|
-
label: 'Conditional request',
|
|
418
|
-
nativeTask: 'native:conditional',
|
|
419
|
-
rustTask: 'rust:conditional',
|
|
126
|
+
impl: 'bun',
|
|
420
127
|
status: 'proven',
|
|
421
|
-
typicalRatio:
|
|
128
|
+
typicalRatio: 3.7,
|
|
129
|
+
note: 'Date.toUTCString() ~3.7×',
|
|
422
130
|
},
|
|
131
|
+
|
|
132
|
+
// ── Native winners — 'native' (addon beats the pure-TS baseline) ──
|
|
133
|
+
{ name: 'fnv1a64', impl: 'native', status: 'proven', typicalRatio: 12.603 },
|
|
134
|
+
{ name: 'hmacSha256Verify', impl: 'native', status: 'proven', typicalRatio: 9.028 },
|
|
135
|
+
{ name: 'signCookie', impl: 'native', status: 'proven', typicalRatio: 3.64 },
|
|
136
|
+
{ name: 'verifyCookie', impl: 'native', status: 'proven', typicalRatio: 1.772 },
|
|
137
|
+
{ name: 'csrfToken', impl: 'native', status: 'proven', typicalRatio: 12.671 },
|
|
138
|
+
{ name: 'csrfVerify', impl: 'native', status: 'proven', typicalRatio: 12.458 },
|
|
423
139
|
{
|
|
424
|
-
name: '
|
|
425
|
-
|
|
426
|
-
nativeTask: 'native:accept_negotiate',
|
|
427
|
-
rustTask: 'rust:accept_negotiate',
|
|
140
|
+
name: 'passwordHash',
|
|
141
|
+
impl: 'native',
|
|
428
142
|
status: 'proven',
|
|
429
|
-
typicalRatio:
|
|
143
|
+
typicalRatio: 1.657,
|
|
144
|
+
note: 'argon2id — rust ~1.83× vs Bun.password at equal cost; never delegate',
|
|
430
145
|
},
|
|
431
146
|
{
|
|
432
|
-
name: '
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
note: 'Delegates to Buffer base64 under Bun for the standard padded, non-url-safe case (BUN_WINS — ~2x faster than the FFI crossing); url-safe/unpadded falls through to native. Rust addon remains the Node path. Parity pinned by test/unit/features/encoding.test.ts.',
|
|
438
|
-
},
|
|
439
|
-
{
|
|
440
|
-
name: 'base64Decode',
|
|
441
|
-
label: 'Base64 decode',
|
|
442
|
-
nativeTask: 'native:base64_decode',
|
|
443
|
-
rustTask: 'rust:base64_decode',
|
|
444
|
-
status: 'parity',
|
|
445
|
-
typicalRatio: 1.17,
|
|
446
|
-
},
|
|
447
|
-
{
|
|
448
|
-
name: 'hexEncode',
|
|
449
|
-
label: 'Hex encode',
|
|
450
|
-
nativeTask: 'native:hex_encode',
|
|
451
|
-
rustTask: 'rust:hex_encode',
|
|
452
|
-
status: 'not-competitive',
|
|
453
|
-
note: "Buffer.toString('hex') is native SIMD; pooled hexEncodeInto cuts the loss from ~2.2x to ~1.35x.",
|
|
147
|
+
name: 'passwordVerify',
|
|
148
|
+
impl: 'native',
|
|
149
|
+
status: 'proven',
|
|
150
|
+
typicalRatio: 1.88,
|
|
151
|
+
note: 'argon2id verify — rust wins; no representative pure-TS baseline (pinned)',
|
|
454
152
|
},
|
|
153
|
+
{ name: 'aeadEncrypt', impl: 'native', status: 'proven', typicalRatio: 1.288 },
|
|
455
154
|
{
|
|
456
|
-
name: '
|
|
457
|
-
|
|
458
|
-
nativeTask: 'native:hex_decode',
|
|
459
|
-
rustTask: 'rust:hex_decode',
|
|
155
|
+
name: 'aeadDecrypt',
|
|
156
|
+
impl: 'native',
|
|
460
157
|
status: 'parity',
|
|
461
|
-
typicalRatio:
|
|
462
|
-
note: '
|
|
463
|
-
},
|
|
464
|
-
{
|
|
465
|
-
name: 'signCookie',
|
|
466
|
-
label: 'Cookie sign',
|
|
467
|
-
nativeTask: 'native:cookie_sign',
|
|
468
|
-
rustTask: 'rust:cookie_sign',
|
|
469
|
-
status: 'proven',
|
|
470
|
-
typicalRatio: 9,
|
|
158
|
+
typicalRatio: 1.108,
|
|
159
|
+
note: 'borderline — kept native',
|
|
471
160
|
},
|
|
161
|
+
{ name: 'createAcceptNegotiator', impl: 'native', status: 'proven', typicalRatio: 2.01 },
|
|
472
162
|
{
|
|
473
|
-
name: '
|
|
474
|
-
|
|
475
|
-
nativeTask: 'native:cookie_verify',
|
|
476
|
-
rustTask: 'rust:cookie_verify',
|
|
163
|
+
name: 'gzipDecompress',
|
|
164
|
+
impl: 'native',
|
|
477
165
|
status: 'proven',
|
|
478
|
-
typicalRatio:
|
|
166
|
+
typicalRatio: 61.039,
|
|
167
|
+
note: 'deliberately NOT delegated — Bun.gunzipSync has no bomb cap; native 64 MiB cap kept',
|
|
479
168
|
},
|
|
480
169
|
{
|
|
481
|
-
name: '
|
|
482
|
-
|
|
483
|
-
nativeTask: 'native:csrf_create',
|
|
484
|
-
rustTask: 'rust:csrf_create',
|
|
170
|
+
name: 'brotliCompress',
|
|
171
|
+
impl: 'native',
|
|
485
172
|
status: 'proven',
|
|
486
|
-
typicalRatio:
|
|
173
|
+
typicalRatio: 9.983,
|
|
174
|
+
note: 'no synchronous Bun API',
|
|
487
175
|
},
|
|
488
176
|
{
|
|
489
|
-
name: '
|
|
490
|
-
|
|
491
|
-
nativeTask: 'native:csrf_verify',
|
|
492
|
-
rustTask: 'rust:csrf_verify',
|
|
177
|
+
name: 'brotliDecompress',
|
|
178
|
+
impl: 'native',
|
|
493
179
|
status: 'proven',
|
|
494
|
-
typicalRatio:
|
|
180
|
+
typicalRatio: 33.327,
|
|
181
|
+
note: 'no synchronous Bun API',
|
|
495
182
|
},
|
|
496
183
|
{
|
|
497
|
-
name: '
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
status: 'parity',
|
|
502
|
-
typicalRatio: 1.11,
|
|
503
|
-
note: 'Noisy ~1.5µs op; swings 0.74-1.03x run-to-run. UrlBuilder reuses the parsed base.',
|
|
184
|
+
name: 'jwtSign',
|
|
185
|
+
impl: 'native',
|
|
186
|
+
status: 'unmeasured',
|
|
187
|
+
note: 'pinned native — constant-time canonical (not pure-perf)',
|
|
504
188
|
},
|
|
505
189
|
{
|
|
506
|
-
name: '
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
status: 'not-competitive',
|
|
511
|
-
note: 'encodeURIComponent baseline wins (~1.2-1.35x).',
|
|
190
|
+
name: 'jwtVerify',
|
|
191
|
+
impl: 'native',
|
|
192
|
+
status: 'unmeasured',
|
|
193
|
+
note: 'pinned native — constant-time canonical',
|
|
512
194
|
},
|
|
513
|
-
|
|
514
|
-
// ── Unmeasured (no direct comparison task) ──
|
|
515
195
|
{
|
|
516
|
-
name: '
|
|
517
|
-
|
|
518
|
-
nativeTask: '',
|
|
519
|
-
rustTask: '',
|
|
196
|
+
name: 'createTemplate',
|
|
197
|
+
impl: 'native',
|
|
520
198
|
status: 'unmeasured',
|
|
521
|
-
note: '
|
|
199
|
+
note: 'pinned native — compiled-once instance',
|
|
522
200
|
},
|
|
523
201
|
{
|
|
524
|
-
name: '
|
|
525
|
-
|
|
526
|
-
nativeTask: '',
|
|
527
|
-
rustTask: '',
|
|
202
|
+
name: 'createSchemaValidator',
|
|
203
|
+
impl: 'native',
|
|
528
204
|
status: 'unmeasured',
|
|
205
|
+
note: 'pinned native — compiled-once instance',
|
|
529
206
|
},
|
|
207
|
+
|
|
208
|
+
// ── JS winners — 'js' (pure-TS beats the addon) ──
|
|
209
|
+
{ name: 'queryPairs', impl: 'js', status: 'proven', typicalRatio: 0.279 },
|
|
210
|
+
{ name: 'cookiePairs', impl: 'js', status: 'proven', typicalRatio: 0.105 },
|
|
211
|
+
{ name: 'formPairs', impl: 'js', status: 'proven', typicalRatio: 0.328 },
|
|
212
|
+
{ name: 'etag', impl: 'js', status: 'proven', typicalRatio: 0.187 },
|
|
213
|
+
{ name: 'parseMediaType', impl: 'js', status: 'proven', typicalRatio: 0.378 },
|
|
214
|
+
{ name: 'parseAcceptEncoding', impl: 'js', status: 'proven', typicalRatio: 0.367 },
|
|
215
|
+
{ name: 'createConditionalRequest', impl: 'js', status: 'proven', typicalRatio: 0.275 },
|
|
530
216
|
{
|
|
531
|
-
name: '
|
|
532
|
-
|
|
533
|
-
nativeTask: '',
|
|
534
|
-
rustTask: '',
|
|
217
|
+
name: 'multipartParse',
|
|
218
|
+
impl: 'js',
|
|
535
219
|
status: 'unmeasured',
|
|
536
|
-
note: '
|
|
220
|
+
note: 'no ratio recorded — JS baseline kept',
|
|
537
221
|
},
|
|
538
222
|
{
|
|
539
|
-
name: '
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
note: 'Runtime setup only.',
|
|
223
|
+
name: 'jsonValid',
|
|
224
|
+
impl: 'js',
|
|
225
|
+
status: 'parity',
|
|
226
|
+
typicalRatio: 0.749,
|
|
227
|
+
note: 'borderline — JSON.parse wins',
|
|
545
228
|
},
|
|
546
229
|
{
|
|
547
|
-
name: '
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
note: 'Introspection only.',
|
|
230
|
+
name: 'jsonPatch',
|
|
231
|
+
impl: 'js',
|
|
232
|
+
status: 'proven',
|
|
233
|
+
typicalRatio: 0.014,
|
|
234
|
+
note: 'custom JSON.patch beats the addon at small sizes',
|
|
553
235
|
},
|
|
236
|
+
{ name: 'sseEncode', impl: 'js', status: 'proven', typicalRatio: 0.586 },
|
|
237
|
+
{ name: 'wsFrameEncode', impl: 'js', status: 'proven', typicalRatio: 0.152 },
|
|
238
|
+
{
|
|
239
|
+
name: 'wsFrameDecode',
|
|
240
|
+
impl: 'js',
|
|
241
|
+
status: 'parity',
|
|
242
|
+
typicalRatio: 0.988,
|
|
243
|
+
note: 'parity boundary — JS baseline kept',
|
|
244
|
+
},
|
|
245
|
+
{ name: 'wsAcceptKey', impl: 'js', status: 'parity', typicalRatio: 0.939 },
|
|
246
|
+
{ name: 'validateEmail', impl: 'js', status: 'proven', typicalRatio: 0.007 },
|
|
247
|
+
{ name: 'validateUuid', impl: 'js', status: 'proven', typicalRatio: 0.008 },
|
|
248
|
+
{ name: 'validateIpv4', impl: 'js', status: 'proven', typicalRatio: 0.012 },
|
|
249
|
+
{ name: 'validateIpv6', impl: 'js', status: 'proven', typicalRatio: 0.078 },
|
|
250
|
+
{ name: 'createRateLimiter', impl: 'js', status: 'proven', typicalRatio: 0.061 },
|
|
251
|
+
{ name: 'renderTemplate', impl: 'js', status: 'proven', typicalRatio: 0.141 },
|
|
554
252
|
] as const satisfies readonly ProvenEntry[]
|
|
555
253
|
|
|
556
|
-
|
|
557
|
-
type ProvenEntryOf<S extends PerformanceStatus> = Extract<
|
|
558
|
-
(typeof PROVEN_SURFACE)[number],
|
|
559
|
-
{ status: S }
|
|
560
|
-
>
|
|
254
|
+
const INDEX = new Map<string, ProvenEntry>(PROVEN_SELECTION.map((e) => [e.name, e]))
|
|
561
255
|
|
|
562
256
|
/**
|
|
563
|
-
* The
|
|
564
|
-
*
|
|
565
|
-
* from the data.
|
|
257
|
+
* The baked {@link ProvenEntry} for `op`, or `undefined` for unknown ops.
|
|
258
|
+
* Pure data — never dlopens the addon.
|
|
566
259
|
*/
|
|
567
|
-
export
|
|
260
|
+
export function provenEntry(op: string): ProvenEntry | undefined {
|
|
261
|
+
return INDEX.get(op)
|
|
262
|
+
}
|
|
568
263
|
|
|
569
|
-
|
|
264
|
+
/** The baked default implementation for `op` (`native` / `js` / `bun`), or `null`. */
|
|
265
|
+
export function provenImpl(op: string): ProvenImpl | null {
|
|
266
|
+
return INDEX.get(op)?.impl ?? null
|
|
267
|
+
}
|
|
570
268
|
|
|
571
|
-
/**
|
|
572
|
-
export function provenStatus(
|
|
573
|
-
return
|
|
269
|
+
/** The baked status for `op`, or `null` for unknown ops. */
|
|
270
|
+
export function provenStatus(op: string): ProvenStatus | null {
|
|
271
|
+
return INDEX.get(op)?.status ?? null
|
|
574
272
|
}
|
|
575
273
|
|
|
576
|
-
/** Whether
|
|
577
|
-
export function isProven(
|
|
578
|
-
return
|
|
274
|
+
/** Whether the op's baked winner is a decisive (`proven`) win. */
|
|
275
|
+
export function isProven(op: string): boolean {
|
|
276
|
+
return INDEX.get(op)?.status === 'proven'
|
|
579
277
|
}
|
|
580
278
|
|
|
581
|
-
/** The
|
|
582
|
-
export function provenSurface(): ProvenEntry[] {
|
|
583
|
-
return
|
|
279
|
+
/** The full baked registry (same array as {@link PROVEN_SELECTION}). */
|
|
280
|
+
export function provenSurface(): readonly ProvenEntry[] {
|
|
281
|
+
return PROVEN_SELECTION
|
|
584
282
|
}
|
|
585
283
|
|
|
586
|
-
/**
|
|
587
|
-
export function provenSummary():
|
|
588
|
-
const
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
'not-competitive': 0,
|
|
592
|
-
unmeasured: 0,
|
|
593
|
-
}
|
|
594
|
-
for (const e of PROVEN_SURFACE) out[e.status] += 1
|
|
595
|
-
return out
|
|
284
|
+
/** A one-line summary of the baked selection (counts per implementation). */
|
|
285
|
+
export function provenSummary(): string {
|
|
286
|
+
const byImpl = { native: 0, js: 0, bun: 0 }
|
|
287
|
+
for (const e of PROVEN_SELECTION) byImpl[e.impl] += 1
|
|
288
|
+
return `proven selection: ${byImpl.native} native, ${byImpl.js} js, ${byImpl.bun} bun built-in (${PROVEN_SELECTION.length} ops)`
|
|
596
289
|
}
|