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
@@ -1,227 +0,0 @@
1
- import * as native from "../baseline";
2
- import { rust, rustBatch } from "../rust-ffi";
3
- import { decoder } from "../shared/bytes";
4
- import { pairsToObject, readHttpPacked, readPairsPacked } from "../shared/packed";
5
- import { assertDeepEqual, assertEqual, parseJsonBytes } from "./assert";
6
- import type { BenchFixtures, ComplexFixtures } from "./fixtures";
7
-
8
- export function runCorrectnessChecks(f: BenchFixtures): void {
9
-
10
- assertDeepEqual(
11
- readHttpPacked(native.nativeHttpParseRequestPacked(f.httpRaw)),
12
- readHttpPacked(rust.httpParseRequestPacked(f.httpRaw)),
13
- "http parse packed native writer",
14
- );
15
-
16
- assertDeepEqual(
17
- pairsToObject(readPairsPacked(native.nativeQueryParsePacked(f.queryStr))),
18
- pairsToObject(readPairsPacked(rust.queryParsePacked(f.queryStr))),
19
- "query parse packed native writer",
20
- );
21
-
22
- assertDeepEqual(
23
- pairsToObject(readPairsPacked(native.nativeCookieParsePacked(f.cookieStr))),
24
- pairsToObject(readPairsPacked(rust.cookieParsePacked(f.cookieStr))),
25
- "cookie parse packed native writer",
26
- );
27
-
28
- assertEqual(
29
- native.nativeJsonSum(f.jsonPayload),
30
- rust.jsonSumIds(f.jsonPayload),
31
- "json sum",
32
- );
33
-
34
-
35
- assertEqual(
36
- decoder.decode(native.nativeWsAcceptKey(f.wsKey)),
37
- decoder.decode(rust.wsAcceptKey(f.wsKeyBytes)),
38
- "ws accept key",
39
- );
40
-
41
- assertDeepEqual(
42
- parseJsonBytes(native.nativeJsonPatch(f.jsonDoc, f.jsonPatch)),
43
- parseJsonBytes(rust.jsonPatch(f.jsonDoc, f.jsonPatch)),
44
- "json patch",
45
- );
46
-
47
- assertEqual(
48
- decoder.decode(f.hmacSig),
49
- decoder.decode(rust.hmacSha256(f.hmacKey, f.hmacData)),
50
- "hmac sha256",
51
- );
52
-
53
- assertEqual(
54
- native.nativeHmacSha256Verify(f.hmacKey, f.hmacData, f.hmacSig),
55
- rust.hmacSha256Verify(f.hmacKey, f.hmacData, f.hmacSig),
56
- "hmac verify",
57
- );
58
-
59
- assertEqual(
60
- native.nativeValidateEmail(f.emailOk),
61
- rust.validateEmail(f.emailOk),
62
- "email valid",
63
- );
64
-
65
- assertEqual(
66
- native.nativeValidateUuid(f.uuidOk),
67
- rust.validateUuid(f.uuidOk),
68
- "uuid valid",
69
- );
70
-
71
- assertEqual(
72
- native.nativeValidateIpv4(f.ipv4Ok),
73
- rust.validateIpv4(f.ipv4Ok),
74
- "ipv4 valid",
75
- );
76
-
77
- assertEqual(
78
- native.nativeValidateIpv6(f.ipv6Ok),
79
- rust.validateIpv6(f.ipv6Ok),
80
- "ipv6 valid",
81
- );
82
-
83
- assertEqual(
84
- native.nativeCrc32(f.crcInput),
85
- rust.crc32(f.crcInput),
86
- "crc32",
87
- );
88
-
89
- assertEqual(
90
- native.nativeFnv1a64(f.crcInput),
91
- rust.fnv1a64(f.crcInput),
92
- "fnv1a64",
93
- );
94
-
95
- assertEqual(
96
- native.nativeJsonValid(f.jsonPayload),
97
- rust.jsonValid(f.jsonPayload),
98
- "json valid",
99
- );
100
-
101
-
102
- assertEqual(
103
- native.nativeMimeFromExtension("json"),
104
- decoder.decode(rust.mimeFromExtension(f.mimeExt)),
105
- "mime",
106
- );
107
-
108
- assertEqual(
109
- native.nativeUrlEncode("hello world & foo=bar"),
110
- decoder.decode(rust.urlEncode(f.urlEncodeInput)),
111
- "url encode",
112
- );
113
-
114
- assertEqual(
115
- native.nativeUrlDecode("hello%20world%20%26%20foo%3Dbar"),
116
- decoder.decode(rust.urlDecode(f.urlDecodeInput)),
117
- "url decode",
118
- );
119
-
120
- console.log("Practical correctness checks passed. ✓");
121
- }
122
-
123
- export function runComplexCorrectnessChecks(
124
- _f: BenchFixtures,
125
- c: ComplexFixtures,
126
- ): void {
127
- // Batch JSON validation
128
- const nativeBatch = c.batchJsonDocs.reduce(
129
- (acc, doc) => acc + (native.nativeJsonValid(doc) ? 1 : 0),
130
- 0,
131
- );
132
- const rustBatchTest = c.batchJsonDocs.reduce(
133
- (acc, doc) => acc + rust.jsonValid(doc),
134
- 0,
135
- );
136
- assertEqual(nativeBatch, rustBatchTest, "batch json valid");
137
-
138
- // Batch email validation
139
- const nativeEmails = c.batchEmails.reduce(
140
- (acc, e) => acc + (native.nativeValidateEmail(e) ? 1 : 0),
141
- 0,
142
- );
143
- const rustEmails = c.batchEmails.reduce(
144
- (acc, e) => acc + rust.validateEmail(e),
145
- 0,
146
- );
147
- assertEqual(nativeEmails, rustEmails, "batch email valid");
148
-
149
- // Batch UUID validation
150
- const nativeUuids = c.batchUuids.reduce(
151
- (acc, u) => acc + (native.nativeValidateUuid(u) ? 1 : 0),
152
- 0,
153
- );
154
- const rustUuids = c.batchUuids.reduce(
155
- (acc, u) => acc + rust.validateUuid(u),
156
- 0,
157
- );
158
- assertEqual(nativeUuids, rustUuids, "batch uuid valid");
159
-
160
- // Batch IPv4 validation
161
- const nativeIps = c.batchIpv4s.reduce(
162
- (acc, ip) => acc + (native.nativeValidateIpv4(ip) ? 1 : 0),
163
- 0,
164
- );
165
- const rustIps = c.batchIpv4s.reduce(
166
- (acc, ip) => acc + rust.validateIpv4(ip),
167
- 0,
168
- );
169
- assertEqual(nativeIps, rustIps, "batch ipv4 valid");
170
-
171
-
172
-
173
- // Large JSON validation
174
- assertEqual(
175
- native.nativeJsonValid(c.jsonLarge),
176
- rust.jsonValid(c.jsonLarge),
177
- "large json valid",
178
- );
179
-
180
- // Huge JSON validation
181
- assertEqual(
182
- native.nativeJsonValid(c.jsonHuge),
183
- rust.jsonValid(c.jsonHuge),
184
- "huge json valid",
185
- );
186
-
187
- // Deep nested JSON validation
188
- assertEqual(
189
- native.nativeJsonValid(c.jsonNestedDeep),
190
- rust.jsonValid(c.jsonNestedDeep),
191
- "deep json valid",
192
- );
193
-
194
-
195
- const rustBatchJson = rustBatch
196
- .jsonValid(c.batchJsonDocs)
197
- .reduce((acc, b) => acc + b, 0);
198
- assertEqual(nativeBatch, rustBatchJson, "batch json valid packed");
199
-
200
- const rustBatchEmails = rustBatch
201
- .validateEmail(c.batchEmails)
202
- .reduce((acc, b) => acc + b, 0);
203
- assertEqual(nativeEmails, rustBatchEmails, "batch email valid packed");
204
-
205
- const rustBatchUuids = rustBatch
206
- .validateUuid(c.batchUuids)
207
- .reduce((acc, b) => acc + b, 0);
208
- assertEqual(nativeUuids, rustBatchUuids, "batch uuid valid packed");
209
-
210
- const rustBatchIpv4s = rustBatch
211
- .validateIpv4(c.batchIpv4s)
212
- .reduce((acc, b) => acc + b, 0);
213
- assertEqual(nativeIps, rustBatchIpv4s, "batch ipv4 valid packed");
214
-
215
- const nativeQueryCount = c.batchQueries.reduce(
216
- (acc, q) => acc + readPairsPacked(native.nativeQueryParsePacked(q)).length,
217
- 0,
218
- );
219
-
220
- const rustQueryCount = rustBatch
221
- .queryParse(c.batchQueries)
222
- .reduce((acc, bytes) => acc + readPairsPacked(bytes).length, 0);
223
-
224
- assertEqual(nativeQueryCount, rustQueryCount, "batch query packed count");
225
-
226
- console.log("Complex correctness checks passed. ✓");
227
- }
@@ -1,27 +0,0 @@
1
- export function checksumValue(value: unknown): bigint {
2
- if (typeof value === "bigint") {
3
- return value;
4
- }
5
-
6
- if (typeof value === "number") {
7
- return Number.isFinite(value) ? BigInt(Math.trunc(value)) : 0n;
8
- }
9
-
10
- if (typeof value === "boolean") {
11
- return value ? 1n : 0n;
12
- }
13
-
14
- if (typeof value === "string") {
15
- return BigInt(value.length);
16
- }
17
-
18
- if (value instanceof Uint8Array) {
19
- return BigInt(value.byteLength) + BigInt(value[0] ?? 0);
20
- }
21
-
22
- if (value != null) {
23
- return 1n;
24
- }
25
-
26
- return 0n;
27
- }
@@ -1,70 +0,0 @@
1
- import type { ComparisonReport } from "./types";
2
-
3
- export const comparisonReports: ComparisonReport[] = [
4
- // ── Original sequential benchmarks ──
5
- { label: "JSON valid", nativeName: "native:json_valid", rustName: "rust:json_valid" },
6
- { label: "JSON sum", nativeName: "native:json_sum", rustName: "rust:json_sum" },
7
- { label: "HTTP parse", nativeName: "native:http_parse", rustName: "rust:http_parse" },
8
- { label: "Query parse", nativeName: "native:query_parse", rustName: "rust:query_parse" },
9
- { label: "Cookie parse", nativeName: "native:cookie_parse", rustName: "rust:cookie_parse" },
10
- { label: "Random token", nativeName: "native:random_token", rustName: "rust:random_token" },
11
- { label: "WebSocket accept", nativeName: "native:ws_accept_key", rustName: "rust:ws_accept_key" },
12
- { label: "JSON Patch", nativeName: "native:json_patch", rustName: "rust:json_patch" },
13
- { label: "HMAC sign", nativeName: "native:hmac_sha256", rustName: "rust:hmac_sha256" },
14
- { label: "HMAC verify", nativeName: "native:hmac_verify", rustName: "rust:hmac_verify" },
15
- { label: "Email validation", nativeName: "native:validate_email", rustName: "rust:validate_email" },
16
- { label: "UUID validation", nativeName: "native:validate_uuid", rustName: "rust:validate_uuid" },
17
- { label: "IPv4 validation", nativeName: "native:validate_ipv4", rustName: "rust:validate_ipv4" },
18
- { label: "IPv6 validation", nativeName: "native:validate_ipv6", rustName: "rust:validate_ipv6" },
19
- { label: "CRC32", nativeName: "native:crc32", rustName: "rust:crc32" },
20
- { label: "FNV-1a 64", nativeName: "native:fnv1a64", rustName: "rust:fnv1a64" },
21
- { label: "MIME lookup", nativeName: "native:mime", rustName: "rust:mime" },
22
- { label: "URL encode", nativeName: "native:url_encode", rustName: "rust:url_encode" },
23
- { label: "URL decode", nativeName: "native:url_decode", rustName: "rust:url_decode" },
24
-
25
- // ── Complex payload benchmarks ──
26
- { label: "JSON valid (50k rows)", nativeName: "native:json_valid_large", rustName: "rust:json_valid_large" },
27
- { label: "JSON valid (100k rows)", nativeName: "native:json_valid_huge", rustName: "rust:json_valid_huge" },
28
- { label: "JSON valid (deep nested)", nativeName: "native:json_valid_deep", rustName: "rust:json_valid_deep" },
29
- { label: "JSON sum (50k rows)", nativeName: "native:json_sum_large", rustName: "rust:json_sum_large" },
30
- { label: "HTTP parse (complex)", nativeName: "native:http_parse_complex", rustName: "rust:http_parse_complex" },
31
- { label: "HTTP parse (huge)", nativeName: "native:http_parse_huge", rustName: "rust:http_parse_huge" },
32
- { label: "Cookie parse (large)", nativeName: "native:cookie_parse_large", rustName: "rust:cookie_parse_large" },
33
- { label: "Query parse (complex)", nativeName: "native:query_parse_complex", rustName: "rust:query_parse_complex" },
34
- { label: "URL encode (large)", nativeName: "native:url_encode_large", rustName: "rust:url_encode_large" },
35
- { label: "URL decode (large)", nativeName: "native:url_decode_large", rustName: "rust:url_decode_large" },
36
- { label: "JSON valid (batch 100)", nativeName: "native:json_valid_batch", rustName: "rust:json_valid_batch" },
37
- { label: "Email validate (batch 100)", nativeName: "native:validate_email_batch", rustName: "rust:validate_email_batch" },
38
- { label: "UUID validate (batch 100)", nativeName: "native:validate_uuid_batch", rustName: "rust:validate_uuid_batch" },
39
- { label: "IPv4 validate (batch 100)", nativeName: "native:validate_ipv4_batch", rustName: "rust:validate_ipv4_batch" },
40
- { label: "Query parse (batch 100)", nativeName: "native:query_parse_batch", rustName: "rust:query_parse_batch" },
41
-
42
- // ── Concurrent burst benchmarks ──
43
- { label: "JSON valid concurrent (10x50)", nativeName: "native:json_valid_concurrent_10", rustName: "rust:json_valid_concurrent_10" },
44
- { label: "JSON valid concurrent (50x20)", nativeName: "native:json_valid_concurrent_50", rustName: "rust:json_valid_concurrent_50" },
45
- { label: "HTTP parse concurrent (20x50)", nativeName: "native:http_parse_concurrent_20", rustName: "rust:http_parse_concurrent_20" },
46
- { label: "HMAC concurrent (20x30)", nativeName: "native:hmac_sha256_concurrent_20", rustName: "rust:hmac_sha256_concurrent_20" },
47
- { label: "Email validate concurrent (50x40)", nativeName: "native:validate_email_concurrent_50", rustName: "rust:validate_email_concurrent_50" },
48
- { label: "UUID validate concurrent (50x40)", nativeName: "native:validate_uuid_concurrent_50", rustName: "rust:validate_uuid_concurrent_50" },
49
- { label: "Query parse concurrent (20x50)", nativeName: "native:query_parse_concurrent_20", rustName: "rust:query_parse_concurrent_20" },
50
- { label: "Cookie parse concurrent (20x50)", nativeName: "native:cookie_parse_concurrent_20", rustName: "rust:cookie_parse_concurrent_20" },
51
- { label: "CRC32 concurrent (20x100)", nativeName: "native:crc32_concurrent_20", rustName: "rust:crc32_concurrent_20" },
52
- { label: "JSON sum concurrent (20x20)", nativeName: "native:json_sum_concurrent_20", rustName: "rust:json_sum_concurrent_20" },
53
-
54
- // ── Stress benchmarks (2s) ──
55
- { label: "JSON valid stress (2s)", nativeName: "native:json_valid_stress", rustName: "rust:json_valid_stress" },
56
- { label: "HTTP parse stress (2s)", nativeName: "native:http_parse_stress", rustName: "rust:http_parse_stress" },
57
- { label: "HMAC stress (2s)", nativeName: "native:hmac_sha256_stress", rustName: "rust:hmac_sha256_stress" },
58
- { label: "CRC32 stress (2s)", nativeName: "native:crc32_stress", rustName: "rust:crc32_stress" },
59
- { label: "Query parse stress (2s)", nativeName: "native:query_parse_stress", rustName: "rust:query_parse_stress" },
60
- { label: "JSON sum stress (2s)", nativeName: "native:json_sum_stress", rustName: "rust:json_sum_stress" },
61
- { label: "Email validate stress (2s)", nativeName: "native:validate_email_stress", rustName: "rust:validate_email_stress" },
62
- { label: "Cookie parse stress (2s)", nativeName: "native:cookie_parse_stress", rustName: "rust:cookie_parse_stress" },
63
- { label: "UUID validate stress (2s)", nativeName: "native:validate_uuid_stress", rustName: "rust:validate_uuid_stress" },
64
- { label: "WebSocket accept stress (2s)", nativeName: "native:ws_accept_key_stress", rustName: "rust:ws_accept_key_stress" },
65
-
66
-
67
- { label: "HTTP parse pipeline", nativeName: "native:http_parse_pipeline", rustName: "rust:http_parse_pipeline" },
68
- { label: "Query parse pipeline", nativeName: "native:query_parse_pipeline", rustName: "rust:query_parse_pipeline" },
69
- { label: "Cookie parse pipeline", nativeName: "native:cookie_parse_pipeline", rustName: "rust:cookie_parse_pipeline" },
70
- ];
@@ -1,135 +0,0 @@
1
- import * as native from "../baseline";
2
- import { rust, rustBatch } from "../rust-ffi";
3
- import { checksumValue } from "./checksum";
4
-
5
- type HmacPayload = {
6
- key: Uint8Array;
7
- data: Uint8Array;
8
- };
9
-
10
- let currentOp = "";
11
- let currentPayload: unknown;
12
-
13
- function runOnce(op: string, payload: unknown): unknown {
14
- switch (op) {
15
- case "native:json_valid":
16
- return native.nativeJsonValid(payload as Uint8Array) ? 1 : 0;
17
- case "rust:json_valid":
18
- return rust.jsonValid(payload as Uint8Array);
19
-
20
- case "native:http_parse":
21
- return native.nativeHttpParseRequestPacked(payload as Uint8Array).byteLength;
22
- case "rust:http_parse":
23
- return rust.httpParseRequestPacked(payload as Uint8Array).byteLength;
24
-
25
- case "native:hmac_sha256": {
26
- const p = payload as HmacPayload;
27
- return native.nativeHmacSha256(p.key, p.data).byteLength;
28
- }
29
- case "rust:hmac_sha256": {
30
- const p = payload as HmacPayload;
31
- return rust.hmacSha256(p.key, p.data).byteLength;
32
- }
33
-
34
- case "native:validate_email":
35
- return native.nativeValidateEmail(payload as Uint8Array) ? 1 : 0;
36
- case "rust:validate_email":
37
- return rust.validateEmail(payload as Uint8Array);
38
-
39
- case "native:validate_uuid":
40
- return native.nativeValidateUuid(payload as Uint8Array) ? 1 : 0;
41
- case "rust:validate_uuid":
42
- return rust.validateUuid(payload as Uint8Array);
43
-
44
- case "native:validate_ipv4":
45
- return native.nativeValidateIpv4(payload as Uint8Array) ? 1 : 0;
46
- case "rust:validate_ipv4":
47
- return rust.validateIpv4(payload as Uint8Array);
48
-
49
- case "native:validate_ipv6":
50
- return native.nativeValidateIpv6(payload as Uint8Array) ? 1 : 0;
51
- case "rust:validate_ipv6":
52
- return rust.validateIpv6(payload as Uint8Array);
53
-
54
- case "native:query_parse":
55
- return native.nativeQueryParsePacked(payload as Uint8Array).byteLength;
56
- case "rust:query_parse":
57
- return rust.queryParsePacked(payload as Uint8Array).byteLength;
58
-
59
- case "native:cookie_parse":
60
- return native.nativeCookieParsePacked(payload as Uint8Array).byteLength;
61
- case "rust:cookie_parse":
62
- return rust.cookieParsePacked(payload as Uint8Array).byteLength;
63
-
64
- case "native:crc32":
65
- return native.nativeCrc32(payload as Uint8Array);
66
- case "rust:crc32":
67
- return rust.crc32(payload as Uint8Array);
68
-
69
- case "native:json_sum":
70
- return native.nativeJsonSum(payload as Uint8Array);
71
- case "rust:json_sum":
72
- return rust.jsonSumIds(payload as Uint8Array);
73
-
74
- case "native:json_valid_batch": {
75
- const items = payload as Uint8Array[];
76
- let count = 0;
77
- for (const item of items) {
78
- if (native.nativeJsonValid(item)) count += 1;
79
- }
80
- return count;
81
- }
82
-
83
- case "rust:json_valid_batch_packed": {
84
- const items = payload as Uint8Array[];
85
- const bits = rustBatch.jsonValid(items);
86
- let count = 0;
87
- for (const bit of bits) count += bit;
88
- return count;
89
- }
90
-
91
- default:
92
- throw new Error(`Unknown concurrent op: ${op}`);
93
- }
94
- }
95
-
96
- const ctx = globalThis as any;
97
-
98
- ctx.onmessage = (event: any) => {
99
- const msg = event.data;
100
-
101
- try {
102
- if (msg?.type === "init") {
103
- currentOp = msg.op as string;
104
- currentPayload = msg.payload;
105
-
106
- const warmup = Math.max(0, Number(msg.warmup ?? 0));
107
- for (let i = 0; i < warmup; i++) {
108
- checksumValue(runOnce(currentOp, currentPayload));
109
- }
110
-
111
- ctx.postMessage({ type: "ready" });
112
- return;
113
- }
114
-
115
- if (msg?.type === "run") {
116
- const iterations = Math.max(1, Number(msg.iterations ?? 1));
117
- let checksum = 0n;
118
-
119
- for (let i = 0; i < iterations; i++) {
120
- checksum += checksumValue(runOnce(currentOp, currentPayload));
121
- }
122
-
123
- ctx.postMessage({
124
- type: "result",
125
- checksum: checksum.toString(),
126
- });
127
- return;
128
- }
129
- } catch (err) {
130
- ctx.postMessage({
131
- type: "error",
132
- message: err instanceof Error ? err.message : String(err),
133
- });
134
- }
135
- };
@@ -1,233 +0,0 @@
1
- import { nativeHmacSha256 } from "../baseline/tasks/hmac";
2
- import { jsonRowsBytes } from "../data/json-rows";
3
- import { encoder } from "../shared/bytes";
4
-
5
- export interface BenchFixtures {
6
- jsonPayload: Uint8Array;
7
- httpRaw: Uint8Array;
8
- queryStr: Uint8Array;
9
- cookieStr: Uint8Array;
10
- hmacKey: Uint8Array;
11
- hmacData: Uint8Array;
12
- hmacSig: Uint8Array;
13
- wsKey: string;
14
- wsKeyBytes: Uint8Array;
15
- jsonDoc: Uint8Array;
16
- jsonPatch: Uint8Array;
17
- emailOk: Uint8Array;
18
- uuidOk: Uint8Array;
19
- ipv4Ok: Uint8Array;
20
- ipv6Ok: Uint8Array;
21
- crcInput: Uint8Array;
22
- mimeExt: Uint8Array;
23
- urlEncodeInput: Uint8Array;
24
- urlDecodeInput: Uint8Array;
25
- }
26
-
27
- export interface ComplexFixtures {
28
- jsonLarge: Uint8Array;
29
- jsonHuge: Uint8Array;
30
- jsonNestedDeep: Uint8Array;
31
- httpComplex: Uint8Array;
32
- httpHuge: Uint8Array;
33
- cookieLarge: Uint8Array;
34
- queryComplex: Uint8Array;
35
- urlLarge: Uint8Array;
36
- batchJsonDocs: Uint8Array[];
37
- batchEmails: Uint8Array[];
38
- batchUuids: Uint8Array[];
39
- batchIpv4s: Uint8Array[];
40
- batchQueries: Uint8Array[];
41
- }
42
-
43
- export function createFixtures(): BenchFixtures {
44
- const jsonPayload = jsonRowsBytes(5_000);
45
-
46
- const httpRaw = encoder.encode(
47
- "GET /api/users?page=1&limit=20 HTTP/1.1\r\n" +
48
- "Host: example.com\r\n" +
49
- "Accept: application/json\r\n" +
50
- "Authorization: Bearer token\r\n" +
51
- "Cookie: sid=abc; theme=dark\r\n" +
52
- "\r\n",
53
- );
54
-
55
- const queryStr = encoder.encode(
56
- "name=John+Doe&age=30&tags[]=a&tags[]=b&empty=&enc=%20hi%20",
57
- );
58
-
59
- const cookieStr = encoder.encode("session=abc123; theme=dark; lang=en-US");
60
-
61
- const hmacKey = encoder.encode("super-secret-key-2026");
62
- const hmacData = encoder.encode("message to sign with HMAC-SHA256");
63
- const hmacSig = nativeHmacSha256(hmacKey, hmacData);
64
-
65
- const wsKey = "dGhlIHNhbXBsZSBub25jZQ==";
66
- const wsKeyBytes = encoder.encode(wsKey);
67
-
68
- const jsonDoc = encoder.encode(JSON.stringify({ a: 1, b: { c: 2 } }));
69
- const jsonPatch = encoder.encode(
70
- JSON.stringify([{ op: "replace", path: "/a", value: 42 }]),
71
- );
72
-
73
- const emailOk = encoder.encode("user@example.com");
74
- const uuidOk = encoder.encode("550e8400-e29b-41d4-a716-446655440000");
75
- const ipv4Ok = encoder.encode("192.168.1.100");
76
- const ipv6Ok = encoder.encode("2001:db8::1");
77
-
78
- const crcInput = encoder.encode(
79
- "Hello, practical CRC32 checksum test data!",
80
- );
81
-
82
- const mimeExt = encoder.encode("json");
83
-
84
- const urlEncodeInput = encoder.encode("hello world & foo=bar");
85
- const urlDecodeInput = encoder.encode(
86
- "hello%20world%20%26%20foo%3Dbar",
87
- );
88
-
89
- return {
90
- jsonPayload,
91
- httpRaw,
92
- queryStr,
93
- cookieStr,
94
- hmacKey,
95
- hmacData,
96
- hmacSig,
97
- wsKey,
98
- wsKeyBytes,
99
- jsonDoc,
100
- jsonPatch,
101
- emailOk,
102
- uuidOk,
103
- ipv4Ok,
104
- ipv6Ok,
105
- crcInput,
106
- mimeExt,
107
- urlEncodeInput,
108
- urlDecodeInput,
109
- };
110
- }
111
-
112
- export function createComplexFixtures(): ComplexFixtures {
113
- const jsonLarge = jsonRowsBytes(50_000);
114
- const jsonHuge = jsonRowsBytes(100_000);
115
-
116
- const jsonNestedDeep = encoder.encode(
117
- JSON.stringify({
118
- level1: {
119
- level2: {
120
- level3: {
121
- level4: {
122
- level5: {
123
- data: Array.from({ length: 1000 }, (_, i) => ({
124
- id: i,
125
- value: `item_${i}`,
126
- tags: ["alpha", "beta", "gamma"],
127
- })),
128
- meta: { created: "2026-01-01", updated: "2026-07-24", version: 42 },
129
- },
130
- },
131
- },
132
- },
133
- },
134
- }),
135
- );
136
-
137
- const httpComplex = encoder.encode(
138
- "POST /api/v1/users/123/orders?include=items,payments&expand=shipping HTTP/1.1\r\n" +
139
- "Host: api.example.com\r\n" +
140
- "Content-Type: application/json\r\n" +
141
- "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c\r\n" +
142
- "X-Request-ID: 550e8400-e29b-41d4-a716-446655440000\r\n" +
143
- "X-Trace-ID: abcdef1234567890\r\n" +
144
- "X-Client-Version: 2.5.1\r\n" +
145
- "Accept: application/json, text/plain, */*\r\n" +
146
- "Accept-Language: en-US,en;q=0.9\r\n" +
147
- "Accept-Encoding: gzip, deflate, br\r\n" +
148
- "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\r\n" +
149
- "Cookie: session=abc123; theme=dark; lang=en-US; prefs=compact; tracking=0\r\n" +
150
- "Content-Length: 256\r\n" +
151
- "Connection: keep-alive\r\n" +
152
- "Cache-Control: no-cache\r\n" +
153
- "Pragma: no-cache\r\n" +
154
- "\r\n",
155
- );
156
-
157
- const httpHuge = encoder.encode(
158
- "GET /api/search?q=" +
159
- "a".repeat(4000) +
160
- " HTTP/1.1\r\n" +
161
- "Host: example.com\r\n" +
162
- Array.from(
163
- { length: 50 },
164
- (_, i) => `X-Custom-Header-${i}: value-${i}\r\n`,
165
- ).join("") +
166
- "\r\n",
167
- );
168
-
169
- const cookieLarge = encoder.encode(
170
- Array.from(
171
- { length: 50 },
172
- (_, i) => `cookie_${i}=value_${i}_with_some_extra_data_${i}`,
173
- ).join("; "),
174
- );
175
-
176
- const queryComplex = encoder.encode(
177
- Array.from(
178
- { length: 100 },
179
- (_, i) => `param${i}=value${i}&arr[]=${i}a&arr[]=${i}b`,
180
- ).join("&"),
181
- );
182
-
183
- const urlLarge = encoder.encode(
184
- "https://example.com/path/to/resource?search=" +
185
- encodeURIComponent("hello world & foo=bar " + "x".repeat(2000)),
186
- );
187
-
188
- const batchJsonDocs = Array.from({ length: 100 }, (_, i) =>
189
- encoder.encode(
190
- JSON.stringify({
191
- id: i,
192
- action: "update",
193
- payload: { count: i * 2, name: `item_${i}` },
194
- }),
195
- ),
196
- );
197
-
198
- const batchEmails = Array.from({ length: 100 }, (_, i) =>
199
- encoder.encode(`user${i}@subdomain${i}.example.com`),
200
- );
201
-
202
- const batchUuids = Array.from({ length: 100 }, (_, i) =>
203
- encoder.encode(
204
- `550e8400-e29b-41d4-a716-${String(i).padStart(12, "0")}`,
205
- ),
206
- );
207
-
208
- const batchIpv4s = Array.from({ length: 100 }, (_, i) =>
209
- encoder.encode(`192.168.${Math.floor(i / 256)}.${i % 256}`),
210
- );
211
-
212
- const batchQueries = Array.from({ length: 100 }, (_, i) =>
213
- encoder.encode(
214
- `id=${i}&name=user${i}&active=${i % 2 === 0}&tags[]=${i}a&tags[]=${i}b`,
215
- ),
216
- );
217
-
218
- return {
219
- jsonLarge,
220
- jsonHuge,
221
- jsonNestedDeep,
222
- httpComplex,
223
- httpHuge,
224
- cookieLarge,
225
- queryComplex,
226
- urlLarge,
227
- batchJsonDocs,
228
- batchEmails,
229
- batchUuids,
230
- batchIpv4s,
231
- batchQueries,
232
- };
233
- }
@@ -1,2 +0,0 @@
1
- export { runBenchmark } from "./run";
2
- export * from "./types";