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