castrum 0.9.2 → 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.
- package/Cargo.lock +2259 -0
- package/Cargo.toml +138 -0
- package/README.md +6 -0
- package/build.rs +5 -0
- package/castrum.linux-x64-gnu.node +0 -0
- package/dist/index.d.ts +1348 -1295
- package/dist/index.js +4307 -3776
- package/docs/API.md +1 -1
- package/docs/ARCHITECTURE.md +3 -2
- package/docs/CASE_STUDY.md +2 -2
- package/docs/ENVIRONMENT.md +16 -0
- package/docs/FFI_BUN_GUIDE.md +89 -6
- package/docs/REPO_MAP.md +2 -2
- package/index.ts +19 -25
- package/package.json +9 -1
- 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 +96 -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 +68 -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/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 +132 -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 +180 -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 +779 -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 +566 -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 +881 -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 +72 -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/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 +407 -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/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 +104 -8
- package/src/native/ffi/build/compress.ts +14 -10
- package/src/native/ffi/build/instances.ts +40 -3
- package/src/native/ffi/build/metrics.ts +224 -0
- package/src/native/ffi/build/parse.ts +59 -23
- package/src/native/ffi/build/util.ts +14 -1
- package/src/native/ffi/build.ts +2 -0
- package/src/native/ffi/selftest.ts +10 -3
- package/src/native/ffi/types.ts +111 -9
- package/src/native/ffi.ts +87 -1
- package/src/native/index.ts +1 -1
- package/src/native/loader.ts +2 -2
- 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 +17 -11
- 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/selection.ts +1 -1
- package/src/shared/bytes.ts +5 -4
- package/src/shared/codec.ts +18 -3
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// rust/json/json_ops.rs — zero-DOM JSON validation/sum + DOM parse.
|
|
2
|
+
//
|
|
3
|
+
// `json_valid_bytes` / `json_sum_ids_bytes` operate on raw bytes with no
|
|
4
|
+
// per-key heap `String` DOM; `json_parse` materializes a `serde_json::Value`
|
|
5
|
+
// when a caller needs the full DOM. Heavily inlined for the hot paths.
|
|
6
|
+
|
|
7
|
+
use napi::bindgen_prelude::*;
|
|
8
|
+
use napi_derive::napi;
|
|
9
|
+
use serde::de::{Deserializer, IgnoredAny, SeqAccess, Visitor};
|
|
10
|
+
use serde::Deserialize;
|
|
11
|
+
use std::fmt;
|
|
12
|
+
|
|
13
|
+
#[derive(Deserialize)]
|
|
14
|
+
struct IdRow {
|
|
15
|
+
#[serde(default)]
|
|
16
|
+
id: Option<i64>,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
struct IdSumVisitor;
|
|
20
|
+
|
|
21
|
+
impl<'de> Visitor<'de> for IdSumVisitor {
|
|
22
|
+
type Value = i64;
|
|
23
|
+
|
|
24
|
+
#[inline]
|
|
25
|
+
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
26
|
+
f.write_str("an array of objects with numeric ids")
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
#[inline]
|
|
30
|
+
fn visit_seq<A: SeqAccess<'de>>(
|
|
31
|
+
self,
|
|
32
|
+
mut seq: A,
|
|
33
|
+
) -> std::result::Result<Self::Value, A::Error> {
|
|
34
|
+
let mut sum = 0i64;
|
|
35
|
+
while let Some(row) = seq.next_element::<Option<IdRow>>()? {
|
|
36
|
+
if let Some(IdRow { id: Some(id) }) = row {
|
|
37
|
+
sum = sum.saturating_add(id);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
Ok(sum)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
struct IdSum(i64);
|
|
45
|
+
|
|
46
|
+
impl<'de> Deserialize<'de> for IdSum {
|
|
47
|
+
#[inline]
|
|
48
|
+
fn deserialize<D: Deserializer<'de>>(d: D) -> std::result::Result<Self, D::Error> {
|
|
49
|
+
d.deserialize_seq(IdSumVisitor).map(IdSum)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
#[inline(always)]
|
|
54
|
+
pub fn json_valid_bytes(input: &[u8]) -> bool {
|
|
55
|
+
// sonic-rs uses SIMD validation internally — already optimal.
|
|
56
|
+
sonic_rs::from_slice::<IgnoredAny>(input).is_ok()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
#[inline]
|
|
60
|
+
pub fn json_sum_ids_bytes(input: &[u8]) -> Result<i64> {
|
|
61
|
+
sonic_rs::from_slice::<IdSum>(input)
|
|
62
|
+
.map(|s| s.0)
|
|
63
|
+
.map_err(|e| Error::from_reason(e.to_string()))
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
#[napi]
|
|
67
|
+
pub fn json_valid(input: Uint8Array) -> bool {
|
|
68
|
+
json_valid_bytes(input.as_ref())
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/// Parse JSON into a JS value (sonic-rs → compact `sonic_rs::Value` → hand
|
|
72
|
+
/// written napi marshal). This replaces the old `serde_json::Value` DOM +
|
|
73
|
+
/// generic napi `serde-json` marshal — the sonic Value build is cheaper (no
|
|
74
|
+
/// per-key heap `String`) and the walker avoids serde trait dispatch. Number
|
|
75
|
+
/// marshaling stays byte-parity with the old path (PosInt → BigInt, NegInt/
|
|
76
|
+
/// Float → Number).
|
|
77
|
+
///
|
|
78
|
+
/// This is the "parse to a usable JS object" path — directly comparable to
|
|
79
|
+
/// `JSON.parse`. Throws on invalid JSON. Note: napi marshaling of the DOM has
|
|
80
|
+
/// real cost, so this is intentionally NOT a zero-copy / validation-only path.
|
|
81
|
+
#[napi]
|
|
82
|
+
pub fn json_parse(env: Env, input: Uint8Array) -> Result<Unknown<'static>> {
|
|
83
|
+
let value: sonic_rs::Value = sonic_rs::from_slice(input.as_ref())
|
|
84
|
+
.map_err(|e| Error::from_reason(format!("JSON parse error: {e}")))?;
|
|
85
|
+
crate::json::napi_marshal::sonic_value_to_js(&env, &value)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
#[napi]
|
|
89
|
+
pub fn json_sum_ids(input: Uint8Array) -> Result<i64> {
|
|
90
|
+
json_sum_ids_bytes(input.as_ref())
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
#[cfg(test)]
|
|
94
|
+
mod tests {
|
|
95
|
+
use super::*;
|
|
96
|
+
|
|
97
|
+
#[test]
|
|
98
|
+
fn json_parse_roundtrip() {
|
|
99
|
+
let v =
|
|
100
|
+
sonic_rs::from_slice::<serde_json::Value>(br#"{"a":1,"b":[true,null,"x"]}"#).unwrap();
|
|
101
|
+
assert_eq!(v["a"], 1);
|
|
102
|
+
assert_eq!(v["b"][0], true);
|
|
103
|
+
assert_eq!(v["b"][2], "x");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
#[test]
|
|
107
|
+
fn json_parse_rejects_invalid() {
|
|
108
|
+
assert!(sonic_rs::from_slice::<serde_json::Value>(b"{not json").is_err());
|
|
109
|
+
assert!(sonic_rs::from_slice::<serde_json::Value>(b"").is_err());
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
#[test]
|
|
113
|
+
fn json_valid_matches_parse() {
|
|
114
|
+
let good = br#"{"id":1,"name":"x"}"#;
|
|
115
|
+
assert!(json_valid_bytes(good));
|
|
116
|
+
assert!(sonic_rs::from_slice::<serde_json::Value>(good).is_ok());
|
|
117
|
+
let bad = b"nope";
|
|
118
|
+
assert!(!json_valid_bytes(bad));
|
|
119
|
+
assert!(sonic_rs::from_slice::<serde_json::Value>(bad).is_err());
|
|
120
|
+
}
|
|
121
|
+
}
|