castrum 0.9.3 → 0.9.4

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 (184) hide show
  1. package/Cargo.lock +2259 -0
  2. package/Cargo.toml +138 -0
  3. package/README.md +6 -0
  4. package/build.rs +5 -0
  5. package/castrum.linux-x64-gnu.node +0 -0
  6. package/dist/index.d.ts +1348 -1295
  7. package/dist/index.js +4307 -3776
  8. package/docs/API.md +1 -1
  9. package/docs/ARCHITECTURE.md +3 -2
  10. package/docs/CASE_STUDY.md +2 -2
  11. package/docs/ENVIRONMENT.md +16 -0
  12. package/docs/FFI_BUN_GUIDE.md +89 -6
  13. package/docs/REPO_MAP.md +2 -2
  14. package/index.ts +19 -25
  15. package/package.json +9 -1
  16. package/rust/crypto/aead.rs +378 -0
  17. package/rust/crypto/argon2.rs +265 -0
  18. package/rust/crypto/base64.rs +420 -0
  19. package/rust/crypto/bcrypt.rs +89 -0
  20. package/rust/crypto/cookie_sign.rs +169 -0
  21. package/rust/crypto/csrf.rs +106 -0
  22. package/rust/crypto/ed25519.rs +215 -0
  23. package/rust/crypto/hashing.rs +140 -0
  24. package/rust/crypto/hmac_sha256.rs +88 -0
  25. package/rust/crypto/jwt/api.rs +286 -0
  26. package/rust/crypto/jwt/mod.rs +22 -0
  27. package/rust/crypto/jwt/tests.rs +312 -0
  28. package/rust/crypto/jwt/token.rs +360 -0
  29. package/rust/crypto/mod.rs +27 -0
  30. package/rust/crypto/pbkdf2.rs +96 -0
  31. package/rust/crypto/random_token.rs +85 -0
  32. package/rust/crypto/session.rs +222 -0
  33. package/rust/ffi/crypto.rs +708 -0
  34. package/rust/ffi/hashing.rs +285 -0
  35. package/rust/ffi/http.rs +752 -0
  36. package/rust/ffi/ingress.rs +303 -0
  37. package/rust/ffi/json.rs +517 -0
  38. package/rust/ffi/jwt.rs +419 -0
  39. package/rust/ffi/metrics.rs +373 -0
  40. package/rust/ffi/mod.rs +68 -0
  41. package/rust/ffi/payload.rs +275 -0
  42. package/rust/ffi/probe.rs +60 -0
  43. package/rust/ffi/rate_limit.rs +77 -0
  44. package/rust/ffi/route.rs +85 -0
  45. package/rust/ffi/tests.rs +2333 -0
  46. package/rust/ffi/util.rs +152 -0
  47. package/rust/ffi/validators.rs +123 -0
  48. package/rust/http/accept.rs +606 -0
  49. package/rust/http/cookie_parser.rs +140 -0
  50. package/rust/http/etag.rs +289 -0
  51. package/rust/http/form.rs +132 -0
  52. package/rust/http/headers.rs +267 -0
  53. package/rust/http/http_date.rs +286 -0
  54. package/rust/http/http_parser.rs +252 -0
  55. package/rust/http/media_type.rs +355 -0
  56. package/rust/http/method.rs +200 -0
  57. package/rust/http/mime_lookup.rs +130 -0
  58. package/rust/http/mod.rs +32 -0
  59. package/rust/http/multipart.rs +685 -0
  60. package/rust/http/query_parser.rs +180 -0
  61. package/rust/http/url_codec.rs +296 -0
  62. package/rust/http/url_join.rs +324 -0
  63. package/rust/ingress/api.rs +355 -0
  64. package/rust/ingress/cors.rs +403 -0
  65. package/rust/ingress/ingress_constants.rs +209 -0
  66. package/rust/ingress/ip_trust.rs +312 -0
  67. package/rust/ingress/mod.rs +48 -0
  68. package/rust/ingress/native_route.rs +779 -0
  69. package/rust/ingress/options.rs +176 -0
  70. package/rust/ingress/output.rs +406 -0
  71. package/rust/ingress/packed.rs +191 -0
  72. package/rust/ingress/pipeline.rs +534 -0
  73. package/rust/ingress/proxy.rs +138 -0
  74. package/rust/ingress/rate_limit.rs +538 -0
  75. package/rust/ingress/terminal.rs +114 -0
  76. package/rust/ingress/tests.rs +566 -0
  77. package/rust/ingress/time.rs +70 -0
  78. package/rust/json/fast_schema/capture.rs +336 -0
  79. package/rust/json/fast_schema/compile.rs +556 -0
  80. package/rust/json/fast_schema/cursor.rs +368 -0
  81. package/rust/json/fast_schema/email.rs +282 -0
  82. package/rust/json/fast_schema/errors.rs +247 -0
  83. package/rust/json/fast_schema/mod.rs +57 -0
  84. package/rust/json/fast_schema/tests.rs +1143 -0
  85. package/rust/json/fast_schema/types.rs +140 -0
  86. package/rust/json/fast_schema/validate.rs +931 -0
  87. package/rust/json/json_ops.rs +121 -0
  88. package/rust/json/json_schema.rs +837 -0
  89. package/rust/json/json_ser.rs +881 -0
  90. package/rust/json/mod.rs +19 -0
  91. package/rust/json/napi_marshal.rs +318 -0
  92. package/rust/json/patch/api.rs +60 -0
  93. package/rust/json/patch/engine.rs +153 -0
  94. package/rust/json/patch/mod.rs +47 -0
  95. package/rust/json/patch/ops.rs +270 -0
  96. package/rust/json/patch/pointer.rs +49 -0
  97. package/rust/json/patch/tests.rs +499 -0
  98. package/rust/lib.rs +72 -0
  99. package/rust/metrics/api.rs +148 -0
  100. package/rust/metrics/mod.rs +21 -0
  101. package/rust/metrics/registry.rs +961 -0
  102. package/rust/panic_safety.rs +40 -0
  103. package/rust/payload/compress.rs +512 -0
  104. package/rust/payload/mod.rs +13 -0
  105. package/rust/payload/sse.rs +214 -0
  106. package/rust/payload/template.rs +253 -0
  107. package/rust/payload/websocket.rs +69 -0
  108. package/rust/payload/ws_frames.rs +354 -0
  109. package/rust/proptest_suite.rs +139 -0
  110. package/rust/selection.rs +95 -0
  111. package/rust/src/bin/native-bench.rs +495 -0
  112. package/rust/test_support.rs +71 -0
  113. package/rust/util/batch/api.rs +266 -0
  114. package/rust/util/batch/core.rs +473 -0
  115. package/rust/util/batch/mod.rs +23 -0
  116. package/rust/util/batch/tests.rs +445 -0
  117. package/rust/util/batch_core.rs +184 -0
  118. package/rust/util/bytes.rs +407 -0
  119. package/rust/util/mod.rs +34 -0
  120. package/rust/util/packed.rs +473 -0
  121. package/rust/util/text.rs +130 -0
  122. package/rust/util/threadpool.rs +128 -0
  123. package/rust/util/validation.rs +419 -0
  124. package/rust-toolchain.toml +17 -0
  125. package/scripts/postinstall.mjs +199 -0
  126. package/src/ingress/constants.ts +1 -1
  127. package/src/ingress/context.ts +2 -2
  128. package/src/ingress/decode/baked-result.ts +13 -13
  129. package/src/ingress/decode/fast-result.ts +17 -17
  130. package/src/ingress/errors.ts +7 -7
  131. package/src/ingress/headers/baked-templates.ts +1 -1
  132. package/src/ingress/headers/fast-templates.ts +3 -3
  133. package/src/ingress/index.ts +1 -1
  134. package/src/ingress/native-route.ts +9 -5
  135. package/src/ingress/options.ts +1 -1
  136. package/src/ingress/packing/gather-raw-headers.ts +1 -1
  137. package/src/ingress/packing/route-wire.ts +1 -5
  138. package/src/ingress/response/error-bodies.ts +5 -5
  139. package/src/ingress/response/terminal.ts +1 -1
  140. package/src/ingress/routes/echo.ts +4 -4
  141. package/src/ingress/routes/fallback.ts +2 -2
  142. package/src/ingress/routes/head.ts +2 -2
  143. package/src/ingress/routes/native.ts +2 -1
  144. package/src/ingress/routes/options.ts +1 -1
  145. package/src/ingress/routes/read.ts +2 -2
  146. package/src/ingress/server.ts +10 -6
  147. package/src/ingress/status.ts +7 -7
  148. package/src/integration/batch.ts +1 -1
  149. package/src/integration/index.ts +9 -9
  150. package/src/integration/pipeline.ts +6 -6
  151. package/src/integration/websocket.ts +2 -2
  152. package/src/loader/index.ts +1 -5
  153. package/src/loader/ops.ts +1 -1
  154. package/src/native/ffi/build/codecs.ts +104 -8
  155. package/src/native/ffi/build/compress.ts +14 -10
  156. package/src/native/ffi/build/instances.ts +40 -3
  157. package/src/native/ffi/build/metrics.ts +224 -0
  158. package/src/native/ffi/build/parse.ts +59 -23
  159. package/src/native/ffi/build/util.ts +14 -1
  160. package/src/native/ffi/build.ts +2 -0
  161. package/src/native/ffi/selftest.ts +10 -3
  162. package/src/native/ffi/types.ts +111 -9
  163. package/src/native/ffi.ts +87 -1
  164. package/src/native/index.ts +1 -1
  165. package/src/native/loader.ts +2 -2
  166. package/src/native/types/instances.ts +34 -0
  167. package/src/native/types.ts +11 -0
  168. package/src/runtime/codec.ts +53 -9
  169. package/src/runtime/types.ts +7 -0
  170. package/src/rust-ffi/batch/build.ts +16 -9
  171. package/src/rust-ffi/index.ts +7 -6
  172. package/src/rust-ffi/options.ts +1 -3
  173. package/src/rust-ffi/proven.ts +3 -3
  174. package/src/rust-ffi/scalar/crypto.ts +1 -1
  175. package/src/rust-ffi/scalar/factories.ts +73 -0
  176. package/src/rust-ffi/scalar/hashing.ts +1 -1
  177. package/src/rust-ffi/scalar/http.ts +17 -11
  178. package/src/rust-ffi/scalar/index.ts +2 -0
  179. package/src/rust-ffi/scalar/interface.ts +20 -0
  180. package/src/rust-ffi/scalar/payload.ts +11 -3
  181. package/src/rust-ffi/scalar/validation.ts +121 -0
  182. package/src/selection.ts +1 -1
  183. package/src/shared/bytes.ts +5 -4
  184. package/src/shared/codec.ts +18 -3
package/Cargo.toml ADDED
@@ -0,0 +1,138 @@
1
+ [package]
2
+ name = "castrum"
3
+ # Keep in sync with package.json "version" (single source of truth: the npm package).
4
+ version = "0.9.4"
5
+ edition = "2021"
6
+
7
+ [lib]
8
+ name = "castrum"
9
+ crate-type = ["cdylib", "rlib"]
10
+ path = "rust/lib.rs"
11
+
12
+ # Native-only benchmark binary: times the pure-Rust cores (crc32, hashing,
13
+ # hex/base64/url, validators, packed parsers, gzip/brotli, ...) with NO JS / FFI
14
+ # boundary, so bench/ffi-margin.ts can compare them against the same ops called
15
+ # through bun:ffi and pinpoint exactly where the crossing cost is. Diagnostic
16
+ # only — never shipped; NOT part of the addon surface.
17
+ [[bin]]
18
+ name = "native-bench"
19
+ path = "rust/src/bin/native-bench.rs"
20
+
21
+ [dependencies]
22
+ napi = { version = "3", features = ["napi10", "serde-json"] }
23
+ napi-derive = "3"
24
+
25
+ serde = { version = "1", features = ["derive"] }
26
+ # preserve_order: IndexMap for serde_json::Value objects -> faster DOM build + O(1)
27
+ # object lookups during jsonschema validation (BTreeMap default is O(log n)).
28
+ # Key order becomes insertion order; correctness checks are order-insensitive.
29
+ serde_json = { version = "1", features = ["preserve_order"] }
30
+ # sort_keys: sonic's owned `Value` object backs mutable objects with
31
+ # AHashMap (non-deterministic iteration order) unless `sort_keys` is enabled,
32
+ # which swaps the owned map to BTreeMap → DETERMINISTIC sorted serialization.
33
+ # Determinism is a hard wire-format requirement: JWT sign (iat/exp injection)
34
+ # and the RFC 6902 patch engine must emit byte-identical output across the
35
+ # FFI/napi/scalar/bulk transports. Parsed (unmutated) values keep the shared
36
+ # Vec representation (insertion order) — only mutation switches to the map.
37
+ sonic-rs = { version = "0.5", features = ["sort_keys"] }
38
+
39
+ # default-features=false: drop resolve-http + tls-aws-lc-rs which pull in
40
+ # reqwest -> hyper/h2/tokio/rustls (large binary, attack surface). Format
41
+ # validators (email etc.) are built-in and NOT feature-gated in 0.48.
42
+ jsonschema = { version = "0.48", default-features = false, features = ["resolve-file"] }
43
+ aws-lc-rs = "1"
44
+ # NOTE: base64 0.23 enables SIMD (SSE/AVX) by default via the `simd-unsafe`
45
+ # feature (part of `default`); no explicit feature is needed.
46
+ base64 = "0.23"
47
+ crc32fast = "1"
48
+ httparse = "1"
49
+ mime_guess = "2"
50
+ phf = { version = "0.14", features = ["macros"] }
51
+ getrandom = "0.4"
52
+ memchr = "2"
53
+ simdutf8 = "0.1"
54
+ email_address = "0.2"
55
+ fast_chemail = { version = "0.9", optional = true }
56
+ # Replicate jsonschema 0.48.5's format:"email" hostname validation (punycode
57
+ # A-labels + RFC 5892 PVALID/contextual rules) on the zero-DOM fast path. Same
58
+ # crates/versions the jsonschema crate uses, so the fast path stays byte-parity.
59
+ idna = "1"
60
+ unicode-general-category = "1"
61
+ rayon = "1"
62
+ # mimalloc is set as the Rust #[global_allocator] (see rust/lib.rs). We DELIBERATELY
63
+ # do NOT enable the "override" feature: it interposes libc malloc/free at the
64
+ # process level, which is an embedding hazard when this cdylib is dlopen'd into
65
+ # Bun (which itself embeds mimalloc -> symbol clashes). The Rust-level global
66
+ # allocator keeps most of the allocation win without replacing the host malloc.
67
+ mimalloc = { version = "0.1", features = ["local_dynamic_tls"] }
68
+ core_affinity = "0.8"
69
+
70
+ parking_lot = "0.12"
71
+ xxhash-rust = { version = "0.8", features = ["xxh3"] }
72
+ ipnet = "2"
73
+ lru = "0.12"
74
+ # Zero-cost hashing for fast_schema object-key lookups (default SipHash is slow
75
+ # on short keys). Already a transitive dep, so no new download.
76
+ rustc-hash = "2"
77
+ # fast_schema extended-keyword parity: fancy-regex is the SAME regex engine the
78
+ # jsonschema crate uses for `pattern`/`patternProperties` (ECMA-262 semantics incl.
79
+ # lookahead/backrefs); fraction::BigFraction is the SAME exact-rational type used
80
+ # for `multipleOf` divisibility. Both are already transitive deps, so no new
81
+ # downloads — but they become direct deps so fast_schema can use them.
82
+ fancy-regex = "0.18"
83
+ fraction = "0.15"
84
+ # Exact cross-type number equality for enum/const/uniqueItems (same semantics
85
+ # jsonschema uses via jsonschema-value's cmp::equal). Already transitive.
86
+ num-cmp = "0.1"
87
+
88
+ # Backend-framework feature additions (Phase A/B/C)
89
+ # argon2id password hashing (password-hash/rand features are default-on).
90
+ argon2 = "0.5"
91
+ # bcrypt password hashing (pure-Rust, Blowfish-based).
92
+ bcrypt = "0.16"
93
+ # PBKDF2-HMAC-SHA256 (RustCrypto) — pure-Rust KDF.
94
+ pbkdf2 = "0.12"
95
+ sha2 = "0.10"
96
+ # HTML templating (fast, safe, no eval).
97
+ minijinja = "2"
98
+ # gzip via the memory-safe zlib-rs backend (pure Rust, no C).
99
+ flate2 = { version = "1", default-features = false, features = ["zlib-rs"] }
100
+ # brotli compression (pure Rust port).
101
+ brotli = "8"
102
+
103
+ [build-dependencies]
104
+ napi-build = "2"
105
+
106
+ [dev-dependencies]
107
+ # Property-based testing for the security-sensitive wire parsers (fuzz-style
108
+ # with automatic shrinking) — complements the deterministic xorshift corpus in
109
+ # rust/test_support.rs. Runs under `cargo test`; not part of the shipped addon.
110
+ proptest = "1"
111
+
112
+ [features]
113
+ default = ["fast-email"]
114
+ fast-email = ["dep:fast_chemail"]
115
+
116
+ # Codify the CI clippy gate (`cargo clippy --all-targets -- -D warnings`) so a
117
+ # bare local `cargo clippy` fails on the same lints — no flag drift between
118
+ # laptop and CI. Clippy-only lints: normal `cargo build`/`test` are unaffected.
119
+ [lints.clippy]
120
+ all = "deny"
121
+
122
+ [profile.release]
123
+ opt-level = 3
124
+ lto = "fat"
125
+ codegen-units = 1
126
+ strip = "symbols"
127
+ debug = 0
128
+ incremental = false
129
+ # Safety: this is an embedded cdylib loaded into the Bun process. panic = "unwind"
130
+ # (the default) lets napi's catch_unwind convert Rust panics into JS exceptions
131
+ # instead of aborting the host process. overflow-checks = true catches integer
132
+ # overflow in release; the cost is negligible relative to the safety gain.
133
+ overflow-checks = true
134
+ debug-assertions = false
135
+
136
+ [profile.release.package."*"]
137
+ opt-level = 3
138
+ codegen-units = 1
package/README.md CHANGED
@@ -34,6 +34,12 @@ bun install
34
34
  bun run build # compile the Rust addon (release)
35
35
  ```
36
36
 
37
+ > **Cross-platform install**: prebuilt addons ship for linux (x64/arm64,
38
+ > glibc + musl), macOS (x64/arm64), and Windows (x64 msvc) — built by CI on
39
+ > every push/PR and published on a `v*` tag. When no prebuilt matches your
40
+ > platform, the package `postinstall` hook compiles the addon from source in
41
+ > your `node_modules` (`cargo build --release`, needs a Rust toolchain).
42
+
37
43
  ### 2. Start a server
38
44
 
39
45
  ```ts
package/build.rs ADDED
@@ -0,0 +1,5 @@
1
+ extern crate napi_build;
2
+
3
+ fn main() {
4
+ napi_build::setup();
5
+ }
Binary file