castrum 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +322 -59
  3. package/castrum.linux-x64-gnu.node +0 -0
  4. package/dist/index.d.ts +3161 -0
  5. package/dist/index.js +7306 -0
  6. package/docs/ARCHITECTURE.md +415 -0
  7. package/docs/BENCHMARKS.md +307 -0
  8. package/docs/ENVIRONMENT.md +79 -0
  9. package/docs/GETTING_STARTED.md +209 -0
  10. package/docs/INGRESS.md +745 -0
  11. package/docs/REPO_MAP.md +259 -0
  12. package/docs/adr/0001-two-wire-formats.md +39 -0
  13. package/docs/adr/0002-zero-dom-fast-schema.md +38 -0
  14. package/docs/adr/0003-bun-builtins-delegation.md +42 -0
  15. package/docs/bun-builtins-decision-matrix.md +108 -0
  16. package/index.ts +51 -8
  17. package/package.json +73 -20
  18. package/src/data/json-rows.ts +13 -13
  19. package/src/ingress/body.ts +149 -0
  20. package/src/ingress/constants.ts +220 -48
  21. package/src/ingress/context.ts +136 -0
  22. package/src/ingress/decode/baked-result.ts +121 -0
  23. package/src/ingress/decode/fast-result.ts +160 -0
  24. package/src/ingress/decode/packed-sections.ts +56 -0
  25. package/src/ingress/decode/result-base.ts +172 -0
  26. package/src/ingress/errors.ts +72 -0
  27. package/src/ingress/fast.ts +152 -1021
  28. package/src/ingress/handlers.ts +563 -1001
  29. package/src/ingress/headers/baked-templates.ts +102 -0
  30. package/src/ingress/headers/cors.ts +44 -0
  31. package/src/ingress/headers/fast-templates.ts +238 -0
  32. package/src/ingress/headers/hsts.ts +83 -0
  33. package/src/ingress/health.ts +67 -0
  34. package/src/ingress/index.ts +130 -405
  35. package/src/ingress/metrics.ts +132 -0
  36. package/src/ingress/options.ts +197 -0
  37. package/src/ingress/packing/gather-raw-headers.ts +75 -0
  38. package/src/ingress/packing/header-packing.ts +75 -0
  39. package/src/ingress/packing/input-packer.ts +150 -0
  40. package/src/ingress/packing/scratch.ts +50 -0
  41. package/src/ingress/packing/select-headers.ts +96 -0
  42. package/src/ingress/response/error-bodies.ts +75 -0
  43. package/src/ingress/response/terminal.ts +59 -0
  44. package/src/ingress/routes/common.ts +38 -0
  45. package/src/ingress/routes/delete.ts +14 -0
  46. package/src/ingress/routes/echo.ts +107 -0
  47. package/src/ingress/routes/fallback.ts +23 -0
  48. package/src/ingress/routes/head.ts +37 -0
  49. package/src/ingress/routes/index.ts +10 -0
  50. package/src/ingress/routes/json-write.ts +153 -0
  51. package/src/ingress/routes/options.ts +36 -0
  52. package/src/ingress/routes/read.ts +45 -0
  53. package/src/ingress/server-node.ts +376 -0
  54. package/src/ingress/server.ts +443 -0
  55. package/src/ingress/shared.ts +132 -0
  56. package/src/ingress/status.ts +97 -0
  57. package/src/ingress/types.ts +157 -0
  58. package/src/integration/batch.ts +58 -0
  59. package/src/integration/index.ts +29 -0
  60. package/src/integration/pipeline.ts +217 -0
  61. package/src/integration/streaming.ts +79 -0
  62. package/src/integration/websocket.ts +92 -0
  63. package/src/loader/batch.ts +133 -0
  64. package/src/loader/cost.ts +104 -0
  65. package/src/loader/index.ts +930 -0
  66. package/src/loader/ops.ts +657 -0
  67. package/src/native/ffi.ts +1541 -0
  68. package/src/native/index.ts +8 -207
  69. package/src/native/loader.ts +194 -0
  70. package/src/native/types.ts +598 -0
  71. package/src/rust-ffi/addon.ts +10 -0
  72. package/src/rust-ffi/batch.ts +431 -0
  73. package/src/rust-ffi/client.ts +88 -0
  74. package/src/rust-ffi/context.ts +164 -0
  75. package/src/rust-ffi/index.ts +40 -541
  76. package/src/rust-ffi/options.ts +113 -0
  77. package/src/rust-ffi/packed.ts +253 -0
  78. package/src/rust-ffi/proven.ts +42 -0
  79. package/src/rust-ffi/scalar/crypto.ts +265 -0
  80. package/src/rust-ffi/scalar/factories.ts +233 -0
  81. package/src/rust-ffi/scalar/hashing.ts +72 -0
  82. package/src/rust-ffi/scalar/http.ts +206 -0
  83. package/src/rust-ffi/scalar/index.ts +31 -0
  84. package/src/rust-ffi/scalar/interface.ts +450 -0
  85. package/src/rust-ffi/scalar/json.ts +45 -0
  86. package/src/rust-ffi/scalar/payload.ts +124 -0
  87. package/src/rust-ffi/text.ts +95 -0
  88. package/src/selection.json +194 -0
  89. package/src/selection.ts +77 -0
  90. package/src/shared/adaptive.ts +68 -0
  91. package/src/shared/bench-classify.ts +209 -0
  92. package/src/shared/buffer-pool.ts +209 -0
  93. package/src/shared/bytes.ts +35 -5
  94. package/src/shared/env.ts +20 -0
  95. package/src/shared/log.ts +74 -0
  96. package/src/shared/metrics.ts +247 -0
  97. package/src/shared/packed.ts +350 -154
  98. package/src/shared/proven.ts +596 -0
  99. package/src/shared/request-id.ts +67 -0
  100. package/src/shared/response.ts +104 -0
  101. package/src/shared/runtime.ts +34 -0
  102. package/src/shared/trace.ts +81 -0
  103. package/src/shared/uuid.ts +31 -0
  104. package/Cargo.toml +0 -73
  105. package/bench.ts +0 -3
  106. package/rust/batch.rs +0 -195
  107. package/rust/cookie_parser.rs +0 -70
  108. package/rust/cors.rs +0 -263
  109. package/rust/hashing.rs +0 -164
  110. package/rust/headers.rs +0 -234
  111. package/rust/hmac_sha256.rs +0 -113
  112. package/rust/http_parser.rs +0 -132
  113. package/rust/ingress.rs +0 -616
  114. package/rust/ingress_constants.rs +0 -89
  115. package/rust/ip_trust.rs +0 -185
  116. package/rust/json_ops.rs +0 -66
  117. package/rust/json_patch_ops.rs +0 -25
  118. package/rust/json_schema.rs +0 -151
  119. package/rust/json_ser.rs +0 -429
  120. package/rust/lib.rs +0 -48
  121. package/rust/method.rs +0 -141
  122. package/rust/mime_lookup.rs +0 -76
  123. package/rust/output.rs +0 -238
  124. package/rust/proxy.rs +0 -90
  125. package/rust/query_parser.rs +0 -141
  126. package/rust/random_token.rs +0 -52
  127. package/rust/rate_limit.rs +0 -203
  128. package/rust/terminal.rs +0 -95
  129. package/rust/unit_tests.rs +0 -843
  130. package/rust/url_codec.rs +0 -133
  131. package/rust/util.rs +0 -537
  132. package/rust/validation.rs +0 -107
  133. package/rust/websocket.rs +0 -23
  134. package/src/baseline/index.ts +0 -12
  135. package/src/baseline/tasks/cookie.ts +0 -22
  136. package/src/baseline/tasks/hashing.ts +0 -18
  137. package/src/baseline/tasks/hmac.ts +0 -38
  138. package/src/baseline/tasks/http.ts +0 -62
  139. package/src/baseline/tasks/json-patch.ts +0 -12
  140. package/src/baseline/tasks/json.ts +0 -50
  141. package/src/baseline/tasks/mime.ts +0 -5
  142. package/src/baseline/tasks/query.ts +0 -14
  143. package/src/baseline/tasks/token.ts +0 -15
  144. package/src/baseline/tasks/url.ts +0 -11
  145. package/src/baseline/tasks/validation.ts +0 -19
  146. package/src/baseline/tasks/websocket.ts +0 -14
  147. package/src/bench/assert.ts +0 -70
  148. package/src/bench/checks.ts +0 -227
  149. package/src/bench/checksum.ts +0 -27
  150. package/src/bench/comparisons.ts +0 -70
  151. package/src/bench/concurrent-worker.ts +0 -135
  152. package/src/bench/fixtures.ts +0 -233
  153. package/src/bench/index.ts +0 -2
  154. package/src/bench/measure.ts +0 -177
  155. package/src/bench/now.ts +0 -3
  156. package/src/bench/report.ts +0 -79
  157. package/src/bench/run.ts +0 -57
  158. package/src/bench/tasks/complex.ts +0 -232
  159. package/src/bench/tasks/concurrent.ts +0 -213
  160. package/src/bench/tasks/cookie.ts +0 -44
  161. package/src/bench/tasks/hashing.ts +0 -33
  162. package/src/bench/tasks/hmac.ts +0 -36
  163. package/src/bench/tasks/http.ts +0 -50
  164. package/src/bench/tasks/index.ts +0 -52
  165. package/src/bench/tasks/json-patch.ts +0 -21
  166. package/src/bench/tasks/json.ts +0 -33
  167. package/src/bench/tasks/mime.ts +0 -21
  168. package/src/bench/tasks/query.ts +0 -44
  169. package/src/bench/tasks/stress.ts +0 -142
  170. package/src/bench/tasks/token.ts +0 -20
  171. package/src/bench/tasks/url.ts +0 -34
  172. package/src/bench/tasks/validation.ts +0 -57
  173. package/src/bench/tasks/websocket.ts +0 -21
  174. package/src/bench/types.ts +0 -60
  175. package/src/ingress/packed-input.ts +0 -59
  176. package/src/shared/json.ts +0 -18
@@ -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
- }