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,20 +0,0 @@
1
- import * as native from "../../baseline";
2
- import { rust } from "../../rust-ffi";
3
- import type { BenchTask } from "../types";
4
-
5
- export function tokenTasks(): BenchTask[] {
6
- return [
7
- {
8
- name: "native:random_token",
9
- run: () => native.nativeRandomToken(32).byteLength,
10
- iterations: 1000,
11
- warmup: 100,
12
- },
13
- {
14
- name: "rust:random_token",
15
- run: () => rust.randomToken(32).byteLength,
16
- iterations: 1000,
17
- warmup: 100,
18
- },
19
- ];
20
- }
@@ -1,34 +0,0 @@
1
- import * as native from "../../baseline";
2
- import { rust } from "../../rust-ffi";
3
- import type { BenchFixtures } from "../fixtures";
4
- import type { BenchTask } from "../types";
5
-
6
- export function urlTasks(f: BenchFixtures): BenchTask[] {
7
- return [
8
- {
9
- name: "native:url_encode",
10
- run: () => native.nativeUrlEncode("hello world & foo=bar").length,
11
- iterations: 1000,
12
- warmup: 100,
13
- },
14
- {
15
- name: "rust:url_encode",
16
- run: () => rust.urlEncode(f.urlEncodeInput).byteLength,
17
- iterations: 1000,
18
- warmup: 100,
19
- },
20
- {
21
- name: "native:url_decode",
22
- run: () =>
23
- native.nativeUrlDecode("hello%20world%20%26%20foo%3Dbar").length,
24
- iterations: 1000,
25
- warmup: 100,
26
- },
27
- {
28
- name: "rust:url_decode",
29
- run: () => rust.urlDecode(f.urlDecodeInput).byteLength,
30
- iterations: 1000,
31
- warmup: 100,
32
- },
33
- ];
34
- }
@@ -1,57 +0,0 @@
1
- import * as native from "../../baseline";
2
- import { rust } from "../../rust-ffi";
3
- import type { BenchFixtures } from "../fixtures";
4
- import type { BenchTask } from "../types";
5
-
6
- export function validationTasks(f: BenchFixtures): BenchTask[] {
7
- return [
8
- {
9
- name: "native:validate_email",
10
- run: () => (native.nativeValidateEmail(f.emailOk) ? 1 : 0),
11
- iterations: 1000,
12
- warmup: 100,
13
- },
14
- {
15
- name: "rust:validate_email",
16
- run: () => rust.validateEmail(f.emailOk),
17
- iterations: 1000,
18
- warmup: 100,
19
- },
20
- {
21
- name: "native:validate_uuid",
22
- run: () => (native.nativeValidateUuid(f.uuidOk) ? 1 : 0),
23
- iterations: 1000,
24
- warmup: 100,
25
- },
26
- {
27
- name: "rust:validate_uuid",
28
- run: () => rust.validateUuid(f.uuidOk),
29
- iterations: 1000,
30
- warmup: 100,
31
- },
32
- {
33
- name: "native:validate_ipv4",
34
- run: () => (native.nativeValidateIpv4(f.ipv4Ok) ? 1 : 0),
35
- iterations: 1000,
36
- warmup: 100,
37
- },
38
- {
39
- name: "rust:validate_ipv4",
40
- run: () => rust.validateIpv4(f.ipv4Ok),
41
- iterations: 1000,
42
- warmup: 100,
43
- },
44
- {
45
- name: "native:validate_ipv6",
46
- run: () => (native.nativeValidateIpv6(f.ipv6Ok) ? 1 : 0),
47
- iterations: 1000,
48
- warmup: 100,
49
- },
50
- {
51
- name: "rust:validate_ipv6",
52
- run: () => rust.validateIpv6(f.ipv6Ok),
53
- iterations: 1000,
54
- warmup: 100,
55
- },
56
- ];
57
- }
@@ -1,21 +0,0 @@
1
- import * as native from "../../baseline";
2
- import { rust } from "../../rust-ffi";
3
- import type { BenchFixtures } from "../fixtures";
4
- import type { BenchTask } from "../types";
5
-
6
- export function websocketTasks(f: BenchFixtures): BenchTask[] {
7
- return [
8
- {
9
- name: "native:ws_accept_key",
10
- run: () => native.nativeWsAcceptKey(f.wsKey).byteLength,
11
- iterations: 1000,
12
- warmup: 100,
13
- },
14
- {
15
- name: "rust:ws_accept_key",
16
- run: () => rust.wsAcceptKey(f.wsKeyBytes).byteLength,
17
- iterations: 1000,
18
- warmup: 100,
19
- },
20
- ];
21
- }
@@ -1,60 +0,0 @@
1
- export interface BenchResult {
2
- name: string;
3
- iterations: number;
4
- avgMs: number;
5
- p50Ms: number;
6
- p95Ms: number;
7
- opsPerSec: number;
8
- checksum: string;
9
- }
10
-
11
- export interface ConcurrentBenchResult {
12
- name: string;
13
- iterations: number;
14
- concurrency: number;
15
- totalOps: number;
16
- totalMs: number;
17
- avgMs: number;
18
- p50Ms: number;
19
- p95Ms: number;
20
- opsPerSec: number;
21
- checksum: string;
22
- }
23
-
24
- export interface StressBenchResult {
25
- name: string;
26
- durationMs: number;
27
- totalOps: number;
28
- opsPerSec: number;
29
- avgMs: number;
30
- checksum: string;
31
- }
32
-
33
- export interface BenchTask {
34
- name: string;
35
- run: () => unknown;
36
- iterations: number;
37
- warmup: number;
38
- }
39
-
40
- export interface ConcurrentBenchTask {
41
- name: string;
42
- op: string;
43
- payload: unknown;
44
- concurrency: number;
45
- iterationsPerSlot: number;
46
- warmupPerSlot: number;
47
- }
48
-
49
- export interface StressBenchTask {
50
- name: string;
51
- run: () => unknown;
52
- durationMs: number;
53
- warmupMs: number;
54
- }
55
-
56
- export interface ComparisonReport {
57
- label: string;
58
- nativeName: string;
59
- rustName: string;
60
- }
@@ -1,59 +0,0 @@
1
- export class IngressInputPacker {
2
- private buf: Uint8Array;
3
- private view: DataView;
4
- private pos = 0;
5
-
6
- constructor(initialSize = 65536) {
7
- this.buf = new Uint8Array(Math.max(1024, initialSize));
8
- this.view = new DataView(this.buf.buffer);
9
- }
10
-
11
- private ensure(additional: number): void {
12
- const needed = this.pos + additional;
13
- if (needed <= this.buf.byteLength) return;
14
-
15
- let nextSize = this.buf.byteLength * 2;
16
- while (nextSize < needed) {
17
- nextSize *= 2;
18
- }
19
-
20
- const next = new Uint8Array(nextSize);
21
- next.set(this.buf.subarray(0, this.pos));
22
-
23
- this.buf = next;
24
- this.view = new DataView(next.buffer);
25
- }
26
-
27
- private writeU8(value: number): void {
28
- this.ensure(1);
29
- this.buf[this.pos++] = value & 0xff;
30
- }
31
-
32
- private writeLenPrefixed(bytes: Uint8Array): void {
33
- this.ensure(4 + bytes.byteLength);
34
-
35
- this.view.setUint32(this.pos, bytes.byteLength, true);
36
- this.pos += 4;
37
-
38
- this.buf.set(bytes, this.pos);
39
- this.pos += bytes.byteLength;
40
- }
41
-
42
- pack(
43
- methodKind: number,
44
- urlBytes: Uint8Array,
45
- ipBytes: Uint8Array,
46
- requestIdBytes: Uint8Array,
47
- headers: Uint8Array,
48
- ): Uint8Array {
49
- this.pos = 0;
50
-
51
- this.writeU8(methodKind);
52
- this.writeLenPrefixed(urlBytes);
53
- this.writeLenPrefixed(ipBytes);
54
- this.writeLenPrefixed(requestIdBytes);
55
- this.writeLenPrefixed(headers);
56
-
57
- return this.buf.subarray(0, this.pos);
58
- }
59
- }
@@ -1,18 +0,0 @@
1
- export function sortKeys(value: unknown): unknown {
2
- if (value === null || typeof value !== "object") {
3
- return value;
4
- }
5
-
6
- if (Array.isArray(value)) {
7
- return value.map(sortKeys);
8
- }
9
-
10
- const record = value as Record<string, unknown>;
11
- const sorted: Record<string, unknown> = {};
12
-
13
- for (const key of Object.keys(record).sort()) {
14
- sorted[key] = sortKeys(record[key]);
15
- }
16
-
17
- return sorted;
18
- }