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,177 +0,0 @@
1
- import { checksumValue } from "./checksum";
2
- import { nowMs } from "./now";
3
- import type {
4
- BenchResult,
5
- ConcurrentBenchTask,
6
- ConcurrentBenchResult,
7
- StressBenchResult,
8
- } from "./types";
9
-
10
- const concurrentWorkerUrl = new URL("./concurrent-worker.ts", import.meta.url);
11
-
12
- export function bench(
13
- name: string,
14
- fn: () => unknown,
15
- iterations = 100,
16
- warmup = 10,
17
- ): BenchResult {
18
- const safeIterations = Math.max(1, iterations);
19
- const safeWarmup = Math.max(0, warmup);
20
-
21
- let checksum = 0n;
22
-
23
- for (let i = 0; i < safeWarmup; i++) {
24
- checksum += checksumValue(fn());
25
- }
26
-
27
- const samples: number[] = new Array(safeIterations);
28
-
29
- for (let i = 0; i < safeIterations; i++) {
30
- const start = nowMs();
31
- checksum += checksumValue(fn());
32
- samples[i] = nowMs() - start;
33
- }
34
-
35
- samples.sort((a, b) => a - b);
36
-
37
- const total = samples.reduce((a, b) => a + b, 0);
38
- const avg = total / safeIterations;
39
-
40
- return {
41
- name,
42
- iterations: safeIterations,
43
- avgMs: avg,
44
- p50Ms: samples[Math.floor(safeIterations * 0.5)] ?? 0,
45
- p95Ms: samples[Math.floor(safeIterations * 0.95)] ?? 0,
46
- opsPerSec: 1000 / Math.max(avg, 1e-9),
47
- checksum: checksum.toString(),
48
- };
49
- }
50
-
51
- export async function benchConcurrent(
52
- task: ConcurrentBenchTask,
53
- ): Promise<ConcurrentBenchResult> {
54
- const concurrency = Math.max(1, task.concurrency);
55
- const iterations = Math.max(1, task.iterationsPerSlot);
56
- const warmup = Math.max(0, task.warmupPerSlot);
57
-
58
- const workers: Worker[] = [];
59
-
60
- try {
61
- await Promise.all(
62
- Array.from({ length: concurrency }, async () => {
63
- const worker = new Worker(concurrentWorkerUrl, { type: "module" });
64
- workers.push(worker);
65
-
66
- await new Promise<void>((resolve, reject) => {
67
- worker.onmessage = (e: any) => {
68
- const msg = e.data;
69
- if (msg?.type === "ready") {
70
- resolve();
71
- } else if (msg?.type === "error") {
72
- reject(new Error(msg.message ?? "worker init error"));
73
- }
74
- };
75
-
76
- worker.onerror = (e: any) => {
77
- reject(new Error(e?.message ?? "worker error"));
78
- };
79
-
80
- worker.postMessage({
81
- type: "init",
82
- op: task.op,
83
- payload: task.payload,
84
- warmup,
85
- });
86
- });
87
- }),
88
- );
89
-
90
- const resultPromises = workers.map(
91
- (worker) =>
92
- new Promise<bigint>((resolve, reject) => {
93
- worker.onmessage = (e: any) => {
94
- const msg = e.data;
95
- if (msg?.type === "result") {
96
- resolve(BigInt(msg.checksum ?? "0"));
97
- } else if (msg?.type === "error") {
98
- reject(new Error(msg.message ?? "worker runtime error"));
99
- }
100
- };
101
-
102
- worker.onerror = (e: any) => {
103
- reject(new Error(e?.message ?? "worker error"));
104
- };
105
- }),
106
- );
107
-
108
- const start = nowMs();
109
-
110
- for (const worker of workers) {
111
- worker.postMessage({
112
- type: "run",
113
- iterations,
114
- });
115
- }
116
-
117
- const checksums = await Promise.all(resultPromises);
118
- const totalMs = nowMs() - start;
119
-
120
- const checksum = checksums.reduce((a, b) => a + b, 0n);
121
- const totalOps = concurrency * iterations;
122
-
123
- return {
124
- name: task.name,
125
- iterations,
126
- concurrency,
127
- totalOps,
128
- totalMs,
129
- avgMs: totalMs / Math.max(totalOps, 1),
130
- p50Ms: 0,
131
- p95Ms: 0,
132
- opsPerSec: (totalOps / Math.max(totalMs, 1e-9)) * 1000,
133
- checksum: checksum.toString(),
134
- };
135
- } finally {
136
- for (const worker of workers) {
137
- worker.terminate();
138
- }
139
- }
140
- }
141
-
142
- export function benchStress(
143
- name: string,
144
- fn: () => unknown,
145
- durationMs: number,
146
- warmupMs = 100,
147
- ): StressBenchResult {
148
- const safeDuration = Math.max(100, durationMs);
149
- const safeWarmup = Math.max(0, warmupMs);
150
-
151
- const warmupEnd = nowMs() + safeWarmup;
152
- while (nowMs() < warmupEnd) {
153
- checksumValue(fn());
154
- }
155
-
156
- let checksum = 0n;
157
- let ops = 0;
158
-
159
- const start = nowMs();
160
- const end = start + safeDuration;
161
-
162
- while (nowMs() < end) {
163
- checksum += checksumValue(fn());
164
- ops++;
165
- }
166
-
167
- const elapsed = nowMs() - start;
168
-
169
- return {
170
- name,
171
- durationMs: elapsed,
172
- totalOps: ops,
173
- opsPerSec: (ops / Math.max(elapsed, 1e-9)) * 1000,
174
- avgMs: elapsed / Math.max(ops, 1),
175
- checksum: checksum.toString(),
176
- };
177
- }
package/src/bench/now.ts DELETED
@@ -1,3 +0,0 @@
1
- export function nowMs(): number {
2
- return Bun.nanoseconds() / 1_000_000;
3
- }
@@ -1,79 +0,0 @@
1
- import type { BenchResult, ComparisonReport, ConcurrentBenchResult, StressBenchResult } from "./types";
2
-
3
- export function printResults(results: BenchResult[]): void {
4
- console.table(
5
- results.map((r) => ({
6
- name: r.name,
7
- iters: r.iterations,
8
- "avg ms": r.avgMs.toFixed(4),
9
- "p50 ms": r.p50Ms.toFixed(4),
10
- "p95 ms": r.p95Ms.toFixed(4),
11
- "ops/s": r.opsPerSec.toFixed(1),
12
- checksum:
13
- r.checksum.length > 16 ? `${r.checksum.slice(0, 16)}…` : r.checksum,
14
- })),
15
- );
16
- }
17
-
18
- export function printConcurrentResults(results: ConcurrentBenchResult[]): void {
19
- console.table(
20
- results.map((r) => ({
21
- name: r.name,
22
- concurrency: r.concurrency,
23
- "ops/slot": r.iterations,
24
- "total ops": r.totalOps,
25
- "total ms": r.totalMs.toFixed(2),
26
- "avg ms/op": r.avgMs.toFixed(6),
27
- "ops/s": r.opsPerSec.toFixed(1),
28
- checksum: r.checksum.length > 16 ? `${r.checksum.slice(0, 16)}…` : r.checksum,
29
- })),
30
- );
31
- }
32
-
33
- export function printStressResults(results: StressBenchResult[]): void {
34
- console.table(
35
- results.map((r) => ({
36
- name: r.name,
37
- "duration ms": r.durationMs.toFixed(0),
38
- "total ops": r.totalOps,
39
- "ops/s": r.opsPerSec.toFixed(1),
40
- "avg ms": r.avgMs.toFixed(6),
41
- checksum: r.checksum.length > 16 ? `${r.checksum.slice(0, 16)}…` : r.checksum,
42
- })),
43
- );
44
- }
45
-
46
- function printComparison(
47
- results: (BenchResult | ConcurrentBenchResult | StressBenchResult)[],
48
- report: ComparisonReport,
49
- ): void {
50
- const n = results.find((x) => x.name === report.nativeName);
51
- const r = results.find((x) => x.name === report.rustName);
52
-
53
- if (!n || !r) {
54
- return;
55
- }
56
-
57
- const nAvg = n.avgMs;
58
- const rAvg = r.avgMs;
59
- const ratio = nAvg / Math.max(rAvg, 1e-9);
60
-
61
- if (ratio >= 1) {
62
- console.log(
63
- `${report.label}: Rust ${rAvg.toFixed(4)}ms vs Native ${nAvg.toFixed(4)}ms → Rust ${ratio.toFixed(2)}x faster`,
64
- );
65
- } else {
66
- console.log(
67
- `${report.label}: Rust ${rAvg.toFixed(4)}ms vs Native ${nAvg.toFixed(4)}ms → Native ${(1 / ratio).toFixed(2)}x faster`,
68
- );
69
- }
70
- }
71
-
72
- export function printSummary(
73
- results: (BenchResult | ConcurrentBenchResult | StressBenchResult)[],
74
- reports: ComparisonReport[],
75
- ): void {
76
- for (const report of reports) {
77
- printComparison(results, report);
78
- }
79
- }
package/src/bench/run.ts DELETED
@@ -1,57 +0,0 @@
1
- import { runCorrectnessChecks, runComplexCorrectnessChecks } from "./checks";
2
- import { comparisonReports } from "./comparisons";
3
- import { createFixtures, createComplexFixtures } from "./fixtures";
4
- import { bench, benchConcurrent, benchStress } from "./measure";
5
- import { printResults, printConcurrentResults, printStressResults, printSummary } from "./report";
6
- import { createAllTasks, createComplexTasks, createConcurrentTasks, createStressTasks } from "./tasks";
7
-
8
- export async function runBenchmark(): Promise<void> {
9
- const fixtures = createFixtures();
10
- const complexFixtures = createComplexFixtures();
11
-
12
- runCorrectnessChecks(fixtures);
13
- runComplexCorrectnessChecks(fixtures, complexFixtures);
14
-
15
- // ── Standard sequential benchmarks ──
16
- console.log("\n═══ Standard Benchmarks ═══");
17
- const tasks = createAllTasks(fixtures);
18
- const results = tasks.map((task) =>
19
- bench(task.name, task.run, task.iterations, task.warmup),
20
- );
21
- printResults(results);
22
-
23
- // ── Complex payload benchmarks ──
24
- console.log("\n═══ Complex Payload Benchmarks ═══");
25
- const complexTasks = createComplexTasks(complexFixtures);
26
- const complexResults = complexTasks.map((task) =>
27
- bench(task.name, task.run, task.iterations, task.warmup),
28
- );
29
- printResults(complexResults);
30
-
31
- // ── Concurrent burst benchmarks ──
32
- console.log("\n═══ Concurrent Burst Benchmarks ═══");
33
- const concurrentTasks = createConcurrentTasks(fixtures, complexFixtures);
34
- const concurrentResults: import("./types").ConcurrentBenchResult[] = [];
35
- for (const task of concurrentTasks) {
36
- concurrentResults.push(await benchConcurrent(task));
37
- }
38
- printConcurrentResults(concurrentResults);
39
-
40
- // ── Stress benchmarks (fixed duration) ──
41
- console.log("\n═══ Stress Benchmarks (2s each) ═══");
42
- const stressTasksList = createStressTasks(fixtures, complexFixtures);
43
- const stressResults: import("./types").StressBenchResult[] = [];
44
- for (const task of stressTasksList) {
45
- stressResults.push(
46
- benchStress(task.name, task.run, task.durationMs, task.warmupMs),
47
- );
48
- }
49
- printStressResults(stressResults);
50
-
51
- // ── Combined summary ──
52
- console.log("\n═══ Practical Summary ═══");
53
- printSummary(
54
- [...results, ...complexResults, ...concurrentResults, ...stressResults],
55
- comparisonReports,
56
- );
57
- }
@@ -1,232 +0,0 @@
1
- import * as native from "../../baseline";
2
- import { rust, rustBatch } from "../../rust-ffi";
3
- import type { ComplexFixtures } from "../fixtures";
4
- import type { BenchTask } from "../types";
5
-
6
- export function complexTasks(c: ComplexFixtures): BenchTask[] {
7
- return [
8
- // ── Large JSON payloads ──
9
- {
10
- name: "native:json_valid_large",
11
- run: () => native.nativeJsonValid(c.jsonLarge),
12
- iterations: 20,
13
- warmup: 5,
14
- },
15
- {
16
- name: "rust:json_valid_large",
17
- run: () => rust.jsonValid(c.jsonLarge),
18
- iterations: 20,
19
- warmup: 5,
20
- },
21
- {
22
- name: "native:json_sum_large",
23
- run: () => native.nativeJsonSum(c.jsonLarge),
24
- iterations: 20,
25
- warmup: 5,
26
- },
27
- {
28
- name: "rust:json_sum_large",
29
- run: () => rust.jsonSumIds(c.jsonLarge),
30
- iterations: 20,
31
- warmup: 5,
32
- },
33
-
34
- // ── Huge JSON payloads ──
35
- {
36
- name: "native:json_valid_huge",
37
- run: () => native.nativeJsonValid(c.jsonHuge),
38
- iterations: 10,
39
- warmup: 3,
40
- },
41
- {
42
- name: "rust:json_valid_huge",
43
- run: () => rust.jsonValid(c.jsonHuge),
44
- iterations: 10,
45
- warmup: 3,
46
- },
47
-
48
- // ── Deep nested JSON ──
49
- {
50
- name: "native:json_valid_deep",
51
- run: () => native.nativeJsonValid(c.jsonNestedDeep),
52
- iterations: 100,
53
- warmup: 20,
54
- },
55
- {
56
- name: "rust:json_valid_deep",
57
- run: () => rust.jsonValid(c.jsonNestedDeep),
58
- iterations: 100,
59
- warmup: 20,
60
- },
61
-
62
- // ── Complex HTTP ──
63
- {
64
- name: "native:http_parse_complex",
65
- run: () => native.nativeHttpParseRequestPacked(c.httpComplex).byteLength,
66
- iterations: 200,
67
- warmup: 50,
68
- },
69
- {
70
- name: "rust:http_parse_complex",
71
- run: () => rust.httpParseRequestPacked(c.httpComplex).byteLength,
72
- iterations: 200,
73
- warmup: 50,
74
- },
75
-
76
- // ── Huge HTTP ──
77
- {
78
- name: "native:http_parse_huge",
79
- run: () => native.nativeHttpParseRequestPacked(c.httpHuge).byteLength,
80
- iterations: 100,
81
- warmup: 20,
82
- },
83
- {
84
- name: "rust:http_parse_huge",
85
- run: () => rust.httpParseRequestPacked(c.httpHuge).byteLength,
86
- iterations: 100,
87
- warmup: 20,
88
- },
89
-
90
- // ── Large cookie string ──
91
- {
92
- name: "native:cookie_parse_large",
93
- run: () => native.nativeCookieParsePacked(c.cookieLarge).byteLength,
94
- iterations: 200,
95
- warmup: 50,
96
- },
97
- {
98
- name: "rust:cookie_parse_large",
99
- run: () => rust.cookieParsePacked(c.cookieLarge).byteLength,
100
- iterations: 200,
101
- warmup: 50,
102
- },
103
-
104
- // ── Complex query string ──
105
- {
106
- name: "native:query_parse_complex",
107
- run: () => native.nativeQueryParsePacked(c.queryComplex).byteLength,
108
- iterations: 100,
109
- warmup: 20,
110
- },
111
- {
112
- name: "rust:query_parse_complex",
113
- run: () => rust.queryParsePacked(c.queryComplex).byteLength,
114
- iterations: 100,
115
- warmup: 20,
116
- },
117
-
118
- // ── Large URL encode/decode ──
119
- {
120
- name: "native:url_encode_large",
121
- run: () => native.nativeUrlEncode(c.urlLarge).length,
122
- iterations: 100,
123
- warmup: 20,
124
- },
125
- {
126
- name: "rust:url_encode_large",
127
- run: () => rust.urlEncode(c.urlLarge).byteLength,
128
- iterations: 100,
129
- warmup: 20,
130
- },
131
- {
132
- name: "native:url_decode_large",
133
- run: () => native.nativeUrlDecode(c.urlLarge).length,
134
- iterations: 100,
135
- warmup: 20,
136
- },
137
- {
138
- name: "rust:url_decode_large",
139
- run: () => rust.urlDecode(c.urlLarge).byteLength,
140
- iterations: 100,
141
- warmup: 20,
142
- },
143
-
144
- // ── Batch operations ──
145
- {
146
- name: "native:json_valid_batch",
147
- run: () =>
148
- c.batchJsonDocs.reduce(
149
- (acc, doc) => acc + (native.nativeJsonValid(doc) ? 1 : 0),
150
- 0,
151
- ),
152
- iterations: 50,
153
- warmup: 10,
154
- },
155
- {
156
- name: "rust:json_valid_batch",
157
- run: () => rustBatch.jsonValid(c.batchJsonDocs).reduce((acc, b) => acc + b, 0),
158
- iterations: 50,
159
- warmup: 10,
160
- },
161
- {
162
- name: "native:validate_email_batch",
163
- run: () =>
164
- c.batchEmails.reduce(
165
- (acc, e) => acc + (native.nativeValidateEmail(e) ? 1 : 0),
166
- 0,
167
- ),
168
- iterations: 50,
169
- warmup: 10,
170
- },
171
- {
172
- name: "rust:validate_email_batch",
173
- run: () =>
174
- rustBatch.validateEmail(c.batchEmails).reduce((acc, b) => acc + b, 0),
175
- iterations: 50,
176
- warmup: 10,
177
- },
178
- {
179
- name: "native:validate_uuid_batch",
180
- run: () =>
181
- c.batchUuids.reduce(
182
- (acc, u) => acc + (native.nativeValidateUuid(u) ? 1 : 0),
183
- 0,
184
- ),
185
- iterations: 50,
186
- warmup: 10,
187
- },
188
- {
189
- name: "rust:validate_uuid_batch",
190
- run: () =>
191
- rustBatch.validateUuid(c.batchUuids).reduce((acc, b) => acc + b, 0),
192
- iterations: 50,
193
- warmup: 10,
194
- },
195
- {
196
- name: "native:validate_ipv4_batch",
197
- run: () =>
198
- c.batchIpv4s.reduce(
199
- (acc, ip) => acc + (native.nativeValidateIpv4(ip) ? 1 : 0),
200
- 0,
201
- ),
202
- iterations: 50,
203
- warmup: 10,
204
- },
205
- {
206
- name: "rust:validate_ipv4_batch",
207
- run: () =>
208
- rustBatch.validateIpv4(c.batchIpv4s).reduce((acc, b) => acc + b, 0),
209
- iterations: 50,
210
- warmup: 10,
211
- },
212
- {
213
- name: "native:query_parse_batch",
214
- run: () =>
215
- c.batchQueries.reduce(
216
- (acc, q) => acc + native.nativeQueryParsePacked(q).byteLength,
217
- 0,
218
- ),
219
- iterations: 30,
220
- warmup: 5,
221
- },
222
- {
223
- name: "rust:query_parse_batch",
224
- run: () =>
225
- rustBatch
226
- .queryParse(c.batchQueries)
227
- .reduce((acc, bytes) => acc + bytes.byteLength, 0),
228
- iterations: 30,
229
- warmup: 5,
230
- },
231
- ];
232
- }