@ignex/nova 0.1.3 → 0.1.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/README.md +4 -1
- package/docs/ai/TREE.md +69 -9
- package/docs/architecture.md +75 -27
- package/docs/events.md +83 -1
- package/docs/generic-bindings.md +10 -0
- package/docs/wire-format.md +65 -18
- package/package.json +2 -1
- package/prebuilds/linux-x64/libignex_ffi.so +0 -0
- package/public/generate.ts +97 -3
- package/public/server.ts +10 -0
- package/rust/src/generated/backend.rs +503 -0
- package/rust/src/transcode/generated.rs +376 -17
- package/src/bridge/nats/inbound.ts +46 -0
- package/src/bridge/nats/index.ts +131 -0
- package/src/bridge/nats/real-transport.ts +133 -0
- package/src/bridge/nats/types.ts +80 -0
- package/src/codegen/constants.ts +14 -4
- package/src/codegen/direct-gen.ts +20 -6
- package/src/codegen/registry-gen.ts +10 -6
- package/src/codegen/rust-glue-gen.ts +10 -3
- package/src/codegen/schema-model.ts +28 -3
- package/src/codegen/ts-ser-gen.ts +12 -3
- package/src/core/auth.ts +65 -4
- package/src/core/client-rpc.ts +75 -0
- package/src/core/client-state.ts +53 -0
- package/src/core/client-wire.ts +183 -8
- package/src/core/client.ts +84 -4
- package/src/core/groups.ts +5 -0
- package/src/core/metrics.ts +38 -21
- package/src/core/outbound.ts +50 -6
- package/src/core/rate-limit.ts +69 -0
- package/src/core/replay.ts +41 -1
- package/src/core/resume.ts +181 -0
- package/src/core/rooms.ts +10 -3
- package/src/core/routing.ts +128 -5
- package/src/core/server/client-info.ts +37 -0
- package/src/core/server/http-routes.ts +59 -0
- package/src/core/{server.ts → server/index.ts} +112 -120
- package/src/core/server/metrics-view.ts +53 -0
- package/src/core/server/socket-lifecycle.ts +57 -0
- package/src/core/state.ts +73 -1
- package/src/core/topic-log.ts +86 -0
- package/src/events/clients.ts +18 -0
- package/src/events/cluster/dedupe.ts +43 -0
- package/src/events/cluster/envelope.ts +149 -0
- package/src/events/cluster/index.ts +50 -0
- package/src/events/cluster/keys.ts +33 -0
- package/src/events/cluster/kinds.ts +32 -0
- package/src/events/cluster/presence-table.ts +99 -0
- package/src/events/cluster/presence.ts +53 -0
- package/src/events/cluster/redis-client.ts +50 -0
- package/src/events/cluster/store-memory.ts +67 -0
- package/src/events/cluster/store-redis.ts +44 -0
- package/src/events/cluster/subjects.ts +30 -0
- package/src/events/cluster/sync.ts +476 -0
- package/src/events/cluster/transport-nats.ts +24 -0
- package/src/events/cluster/transport-redis.ts +120 -0
- package/src/events/cluster-rpc.ts +196 -0
- package/src/events/delivery.ts +83 -0
- package/src/events/emit.ts +57 -11
- package/src/events/hub/context-factory.ts +79 -0
- package/src/events/hub/dispatch.ts +86 -0
- package/src/events/hub/index.ts +536 -0
- package/src/events/hub/internal.ts +31 -0
- package/src/events/hub/metrics-snapshot.ts +84 -0
- package/src/events/hub/resolve-cluster.ts +49 -0
- package/src/events/queue.ts +36 -9
- package/src/events/registry.ts +90 -54
- package/src/events/schedule.ts +73 -0
- package/src/events/trace.ts +283 -0
- package/src/events/types/client.ts +68 -0
- package/src/events/types/cluster.ts +40 -0
- package/src/events/types/context.ts +50 -0
- package/src/events/types/emit-target.ts +29 -0
- package/src/events/types/groups.ts +35 -0
- package/src/events/types/hub.ts +124 -0
- package/src/events/types/index.ts +30 -0
- package/src/events/types/metrics.ts +52 -0
- package/src/events/types/options.ts +62 -0
- package/src/generated/direct-ser.ts +146 -59
- package/src/generated/fbs/backend.fbs +23 -0
- package/src/generated/registry.ts +92 -33
- package/src/generated/rust/backend_generated.rs +503 -0
- package/src/generated/ts/backend.ts +4 -0
- package/src/generated/ts/resume.ts +74 -0
- package/src/generated/ts/resumed.ts +88 -0
- package/src/generated/ts/rpc-call.ts +112 -0
- package/src/generated/ts/rpc-result.ts +126 -0
- package/src/generated/ts/snapshot-request.ts +19 -5
- package/src/generated/ts-ser.ts +109 -16
- package/src/generated/wire-registry.json +7 -3
- package/src/schema/index.ts +45 -1
- package/src/transport/transport.ts +117 -77
- package/src/bridge/nats.ts +0 -309
- package/src/events/cluster.ts +0 -732
- package/src/events/hub.ts +0 -481
- package/src/events/types.ts +0 -378
- package/src/transport/stats.ts +0 -48
|
@@ -9,9 +9,9 @@ use std::os::raw::c_char;
|
|
|
9
9
|
use serde::Deserialize;
|
|
10
10
|
use crate::generated::backend;
|
|
11
11
|
|
|
12
|
-
pub const WIRE_VERSION: u8 =
|
|
13
|
-
pub const WIRE_HEADER_LEN: usize =
|
|
14
|
-
pub const SCHEMA_FINGERPRINT: u64 =
|
|
12
|
+
pub const WIRE_VERSION: u8 = 2;
|
|
13
|
+
pub const WIRE_HEADER_LEN: usize = 14; // [version:1][event_id:u32 LE][flags:1][seq:u64 LE]
|
|
14
|
+
pub const SCHEMA_FINGERPRINT: u64 = 3647747841; // fnv1a32(canonical model)
|
|
15
15
|
|
|
16
16
|
thread_local! {
|
|
17
17
|
static FBB: RefCell<flatbuffers::FlatBufferBuilder<'static>> =
|
|
@@ -473,12 +473,15 @@ pub fn build_leave_group<'a>(fbb: &mut flatbuffers::FlatBufferBuilder<'a>, j: &L
|
|
|
473
473
|
pub struct SnapshotRequestJson {
|
|
474
474
|
#[serde(default)]
|
|
475
475
|
pub topic: String,
|
|
476
|
+
#[serde(default, deserialize_with = "de_i64")]
|
|
477
|
+
pub from_seq: i64,
|
|
476
478
|
}
|
|
477
479
|
|
|
478
480
|
pub fn build_snapshot_request<'a>(fbb: &mut flatbuffers::FlatBufferBuilder<'a>, j: &SnapshotRequestJson) -> flatbuffers::WIPOffset<backend::SnapshotRequest<'a>> {
|
|
479
481
|
let topic = fbb.create_string(&j.topic);
|
|
480
482
|
backend::SnapshotRequest::create(fbb, &backend::SnapshotRequestArgs {
|
|
481
483
|
topic: Some(topic),
|
|
484
|
+
from_seq: j.from_seq,
|
|
482
485
|
..Default::default()
|
|
483
486
|
})
|
|
484
487
|
}
|
|
@@ -513,6 +516,88 @@ pub fn build_pong<'a>(fbb: &mut flatbuffers::FlatBufferBuilder<'a>, j: &PongJson
|
|
|
513
516
|
})
|
|
514
517
|
}
|
|
515
518
|
|
|
519
|
+
#[derive(Deserialize, Default)]
|
|
520
|
+
#[serde(rename_all = "camelCase")]
|
|
521
|
+
pub struct ResumeJson {
|
|
522
|
+
#[serde(default, deserialize_with = "de_i64")]
|
|
523
|
+
pub last_seq: i64,
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
pub fn build_resume<'a>(fbb: &mut flatbuffers::FlatBufferBuilder<'a>, j: &ResumeJson) -> flatbuffers::WIPOffset<backend::Resume<'a>> {
|
|
527
|
+
|
|
528
|
+
backend::Resume::create(fbb, &backend::ResumeArgs {
|
|
529
|
+
last_seq: j.last_seq,
|
|
530
|
+
..Default::default()
|
|
531
|
+
})
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
#[derive(Deserialize, Default)]
|
|
535
|
+
#[serde(rename_all = "camelCase")]
|
|
536
|
+
pub struct ResumedJson {
|
|
537
|
+
#[serde(default)]
|
|
538
|
+
pub ok: bool,
|
|
539
|
+
#[serde(default, deserialize_with = "de_i64")]
|
|
540
|
+
pub from: i64,
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
pub fn build_resumed<'a>(fbb: &mut flatbuffers::FlatBufferBuilder<'a>, j: &ResumedJson) -> flatbuffers::WIPOffset<backend::Resumed<'a>> {
|
|
544
|
+
|
|
545
|
+
backend::Resumed::create(fbb, &backend::ResumedArgs {
|
|
546
|
+
ok: j.ok,
|
|
547
|
+
from: j.from,
|
|
548
|
+
..Default::default()
|
|
549
|
+
})
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
#[derive(Deserialize, Default)]
|
|
553
|
+
#[serde(rename_all = "camelCase")]
|
|
554
|
+
pub struct RpcCallJson {
|
|
555
|
+
#[serde(default)]
|
|
556
|
+
pub id: String,
|
|
557
|
+
#[serde(default)]
|
|
558
|
+
pub name: String,
|
|
559
|
+
#[serde(default)]
|
|
560
|
+
pub payload_b64: String,
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
pub fn build_rpc_call<'a>(fbb: &mut flatbuffers::FlatBufferBuilder<'a>, j: &RpcCallJson) -> flatbuffers::WIPOffset<backend::RpcCall<'a>> {
|
|
564
|
+
let id = fbb.create_string(&j.id);
|
|
565
|
+
let name = fbb.create_string(&j.name);
|
|
566
|
+
let payload_b64 = fbb.create_string(&j.payload_b64);
|
|
567
|
+
backend::RpcCall::create(fbb, &backend::RpcCallArgs {
|
|
568
|
+
id: Some(id),
|
|
569
|
+
name: Some(name),
|
|
570
|
+
payload_b64: Some(payload_b64),
|
|
571
|
+
..Default::default()
|
|
572
|
+
})
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
#[derive(Deserialize, Default)]
|
|
576
|
+
#[serde(rename_all = "camelCase")]
|
|
577
|
+
pub struct RpcResultJson {
|
|
578
|
+
#[serde(default)]
|
|
579
|
+
pub id: String,
|
|
580
|
+
#[serde(default)]
|
|
581
|
+
pub ok: bool,
|
|
582
|
+
#[serde(default)]
|
|
583
|
+
pub err: String,
|
|
584
|
+
#[serde(default)]
|
|
585
|
+
pub payload_b64: String,
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
pub fn build_rpc_result<'a>(fbb: &mut flatbuffers::FlatBufferBuilder<'a>, j: &RpcResultJson) -> flatbuffers::WIPOffset<backend::RpcResult<'a>> {
|
|
589
|
+
let id = fbb.create_string(&j.id);
|
|
590
|
+
let err = fbb.create_string(&j.err);
|
|
591
|
+
let payload_b64 = fbb.create_string(&j.payload_b64);
|
|
592
|
+
backend::RpcResult::create(fbb, &backend::RpcResultArgs {
|
|
593
|
+
id: Some(id),
|
|
594
|
+
ok: j.ok,
|
|
595
|
+
err: Some(err),
|
|
596
|
+
payload_b64: Some(payload_b64),
|
|
597
|
+
..Default::default()
|
|
598
|
+
})
|
|
599
|
+
}
|
|
600
|
+
|
|
516
601
|
pub fn serialize_quote(json: &[u8], out: &mut [u8]) -> Result<usize, TranscodeError> {
|
|
517
602
|
let j: QuoteJson = serde_json::from_slice(json).map_err(|_| TranscodeError::Parse)?;
|
|
518
603
|
copy_finished(out, |fbb| build_quote(fbb, &j))
|
|
@@ -588,6 +673,26 @@ pub fn serialize_pong(json: &[u8], out: &mut [u8]) -> Result<usize, TranscodeErr
|
|
|
588
673
|
copy_finished(out, |fbb| build_pong(fbb, &j))
|
|
589
674
|
}
|
|
590
675
|
|
|
676
|
+
pub fn serialize_resume(json: &[u8], out: &mut [u8]) -> Result<usize, TranscodeError> {
|
|
677
|
+
let j: ResumeJson = serde_json::from_slice(json).map_err(|_| TranscodeError::Parse)?;
|
|
678
|
+
copy_finished(out, |fbb| build_resume(fbb, &j))
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
pub fn serialize_resumed(json: &[u8], out: &mut [u8]) -> Result<usize, TranscodeError> {
|
|
682
|
+
let j: ResumedJson = serde_json::from_slice(json).map_err(|_| TranscodeError::Parse)?;
|
|
683
|
+
copy_finished(out, |fbb| build_resumed(fbb, &j))
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
pub fn serialize_rpc_call(json: &[u8], out: &mut [u8]) -> Result<usize, TranscodeError> {
|
|
687
|
+
let j: RpcCallJson = serde_json::from_slice(json).map_err(|_| TranscodeError::Parse)?;
|
|
688
|
+
copy_finished(out, |fbb| build_rpc_call(fbb, &j))
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
pub fn serialize_rpc_result(json: &[u8], out: &mut [u8]) -> Result<usize, TranscodeError> {
|
|
692
|
+
let j: RpcResultJson = serde_json::from_slice(json).map_err(|_| TranscodeError::Parse)?;
|
|
693
|
+
copy_finished(out, |fbb| build_rpc_result(fbb, &j))
|
|
694
|
+
}
|
|
695
|
+
|
|
591
696
|
fn read_u32(b: &[u8], off: &mut usize) -> u32 {
|
|
592
697
|
let v = u32::from_le_bytes([b[*off], b[*off + 1], b[*off + 2], b[*off + 3]]);
|
|
593
698
|
*off += 4;
|
|
@@ -713,7 +818,7 @@ fn read_packed_welcome_groups<'a>(fbb: &mut flatbuffers::FlatBufferBuilder<'a>,
|
|
|
713
818
|
}
|
|
714
819
|
|
|
715
820
|
|
|
716
|
-
#[
|
|
821
|
+
#[export_name = "fb_quote_serialize"]
|
|
717
822
|
pub unsafe extern "C" fn fb_quote_serialize(
|
|
718
823
|
symbol: *const c_char,
|
|
719
824
|
bid: f64,
|
|
@@ -753,6 +858,10 @@ pub unsafe extern "C" fn fb_quote_serialize(
|
|
|
753
858
|
*out.add(0) = WIRE_VERSION;
|
|
754
859
|
let id_bytes = 2995289047u32.to_le_bytes();
|
|
755
860
|
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
861
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
862
|
+
// server stamps per-destination delivery seqs on send.
|
|
863
|
+
*out.add(5) = 0;
|
|
864
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
756
865
|
}
|
|
757
866
|
needed
|
|
758
867
|
}
|
|
@@ -762,7 +871,7 @@ pub unsafe extern "C" fn fb_quote_serialize(
|
|
|
762
871
|
.unwrap_or(0)
|
|
763
872
|
}
|
|
764
873
|
|
|
765
|
-
#[
|
|
874
|
+
#[export_name = "fb_trade_serialize"]
|
|
766
875
|
pub unsafe extern "C" fn fb_trade_serialize(
|
|
767
876
|
symbol: *const c_char,
|
|
768
877
|
price: f64,
|
|
@@ -801,6 +910,10 @@ pub unsafe extern "C" fn fb_trade_serialize(
|
|
|
801
910
|
*out.add(0) = WIRE_VERSION;
|
|
802
911
|
let id_bytes = 1362521689u32.to_le_bytes();
|
|
803
912
|
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
913
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
914
|
+
// server stamps per-destination delivery seqs on send.
|
|
915
|
+
*out.add(5) = 0;
|
|
916
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
804
917
|
}
|
|
805
918
|
needed
|
|
806
919
|
}
|
|
@@ -810,7 +923,7 @@ pub unsafe extern "C" fn fb_trade_serialize(
|
|
|
810
923
|
.unwrap_or(0)
|
|
811
924
|
}
|
|
812
925
|
|
|
813
|
-
#[
|
|
926
|
+
#[export_name = "fb_portfolio_serialize"]
|
|
814
927
|
pub unsafe extern "C" fn fb_portfolio_serialize(
|
|
815
928
|
account_id: *const c_char,
|
|
816
929
|
positions_ptr: *const u8,
|
|
@@ -854,6 +967,10 @@ pub unsafe extern "C" fn fb_portfolio_serialize(
|
|
|
854
967
|
*out.add(0) = WIRE_VERSION;
|
|
855
968
|
let id_bytes = 464274147u32.to_le_bytes();
|
|
856
969
|
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
970
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
971
|
+
// server stamps per-destination delivery seqs on send.
|
|
972
|
+
*out.add(5) = 0;
|
|
973
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
857
974
|
}
|
|
858
975
|
needed
|
|
859
976
|
}
|
|
@@ -863,7 +980,7 @@ pub unsafe extern "C" fn fb_portfolio_serialize(
|
|
|
863
980
|
.unwrap_or(0)
|
|
864
981
|
}
|
|
865
982
|
|
|
866
|
-
#[
|
|
983
|
+
#[export_name = "fb_complex_serialize"]
|
|
867
984
|
pub unsafe extern "C" fn fb_complex_serialize(
|
|
868
985
|
id: *const c_char,
|
|
869
986
|
names_ptr: *const u8,
|
|
@@ -919,6 +1036,10 @@ pub unsafe extern "C" fn fb_complex_serialize(
|
|
|
919
1036
|
*out.add(0) = WIRE_VERSION;
|
|
920
1037
|
let id_bytes = 2318166199u32.to_le_bytes();
|
|
921
1038
|
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1039
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1040
|
+
// server stamps per-destination delivery seqs on send.
|
|
1041
|
+
*out.add(5) = 0;
|
|
1042
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
922
1043
|
}
|
|
923
1044
|
needed
|
|
924
1045
|
}
|
|
@@ -928,7 +1049,7 @@ pub unsafe extern "C" fn fb_complex_serialize(
|
|
|
928
1049
|
.unwrap_or(0)
|
|
929
1050
|
}
|
|
930
1051
|
|
|
931
|
-
#[
|
|
1052
|
+
#[export_name = "fb_big_val_serialize"]
|
|
932
1053
|
pub unsafe extern "C" fn fb_big_val_serialize(
|
|
933
1054
|
id: *const c_char,
|
|
934
1055
|
seq: i64,
|
|
@@ -962,6 +1083,10 @@ pub unsafe extern "C" fn fb_big_val_serialize(
|
|
|
962
1083
|
*out.add(0) = WIRE_VERSION;
|
|
963
1084
|
let id_bytes = 3211729064u32.to_le_bytes();
|
|
964
1085
|
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1086
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1087
|
+
// server stamps per-destination delivery seqs on send.
|
|
1088
|
+
*out.add(5) = 0;
|
|
1089
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
965
1090
|
}
|
|
966
1091
|
needed
|
|
967
1092
|
}
|
|
@@ -971,7 +1096,7 @@ pub unsafe extern "C" fn fb_big_val_serialize(
|
|
|
971
1096
|
.unwrap_or(0)
|
|
972
1097
|
}
|
|
973
1098
|
|
|
974
|
-
#[
|
|
1099
|
+
#[export_name = "fb_hello_serialize"]
|
|
975
1100
|
pub unsafe extern "C" fn fb_hello_serialize(
|
|
976
1101
|
version: i64,
|
|
977
1102
|
caps_ptr: *const u8,
|
|
@@ -1006,6 +1131,10 @@ pub unsafe extern "C" fn fb_hello_serialize(
|
|
|
1006
1131
|
*out.add(0) = WIRE_VERSION;
|
|
1007
1132
|
let id_bytes = 1335831723u32.to_le_bytes();
|
|
1008
1133
|
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1134
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1135
|
+
// server stamps per-destination delivery seqs on send.
|
|
1136
|
+
*out.add(5) = 0;
|
|
1137
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
1009
1138
|
}
|
|
1010
1139
|
needed
|
|
1011
1140
|
}
|
|
@@ -1015,7 +1144,7 @@ pub unsafe extern "C" fn fb_hello_serialize(
|
|
|
1015
1144
|
.unwrap_or(0)
|
|
1016
1145
|
}
|
|
1017
1146
|
|
|
1018
|
-
#[
|
|
1147
|
+
#[export_name = "fb_welcome_serialize"]
|
|
1019
1148
|
pub unsafe extern "C" fn fb_welcome_serialize(
|
|
1020
1149
|
client_id: *const c_char,
|
|
1021
1150
|
groups_ptr: *const u8,
|
|
@@ -1049,6 +1178,10 @@ pub unsafe extern "C" fn fb_welcome_serialize(
|
|
|
1049
1178
|
*out.add(0) = WIRE_VERSION;
|
|
1050
1179
|
let id_bytes = 669089267u32.to_le_bytes();
|
|
1051
1180
|
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1181
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1182
|
+
// server stamps per-destination delivery seqs on send.
|
|
1183
|
+
*out.add(5) = 0;
|
|
1184
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
1052
1185
|
}
|
|
1053
1186
|
needed
|
|
1054
1187
|
}
|
|
@@ -1058,7 +1191,7 @@ pub unsafe extern "C" fn fb_welcome_serialize(
|
|
|
1058
1191
|
.unwrap_or(0)
|
|
1059
1192
|
}
|
|
1060
1193
|
|
|
1061
|
-
#[
|
|
1194
|
+
#[export_name = "fb_subscribe_serialize"]
|
|
1062
1195
|
pub unsafe extern "C" fn fb_subscribe_serialize(
|
|
1063
1196
|
topic: *const c_char,
|
|
1064
1197
|
out: *mut u8,
|
|
@@ -1088,6 +1221,10 @@ pub unsafe extern "C" fn fb_subscribe_serialize(
|
|
|
1088
1221
|
*out.add(0) = WIRE_VERSION;
|
|
1089
1222
|
let id_bytes = 2946386435u32.to_le_bytes();
|
|
1090
1223
|
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1224
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1225
|
+
// server stamps per-destination delivery seqs on send.
|
|
1226
|
+
*out.add(5) = 0;
|
|
1227
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
1091
1228
|
}
|
|
1092
1229
|
needed
|
|
1093
1230
|
}
|
|
@@ -1097,7 +1234,7 @@ pub unsafe extern "C" fn fb_subscribe_serialize(
|
|
|
1097
1234
|
.unwrap_or(0)
|
|
1098
1235
|
}
|
|
1099
1236
|
|
|
1100
|
-
#[
|
|
1237
|
+
#[export_name = "fb_unsubscribe_serialize"]
|
|
1101
1238
|
pub unsafe extern "C" fn fb_unsubscribe_serialize(
|
|
1102
1239
|
topic: *const c_char,
|
|
1103
1240
|
out: *mut u8,
|
|
@@ -1127,6 +1264,10 @@ pub unsafe extern "C" fn fb_unsubscribe_serialize(
|
|
|
1127
1264
|
*out.add(0) = WIRE_VERSION;
|
|
1128
1265
|
let id_bytes = 4190043798u32.to_le_bytes();
|
|
1129
1266
|
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1267
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1268
|
+
// server stamps per-destination delivery seqs on send.
|
|
1269
|
+
*out.add(5) = 0;
|
|
1270
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
1130
1271
|
}
|
|
1131
1272
|
needed
|
|
1132
1273
|
}
|
|
@@ -1136,7 +1277,7 @@ pub unsafe extern "C" fn fb_unsubscribe_serialize(
|
|
|
1136
1277
|
.unwrap_or(0)
|
|
1137
1278
|
}
|
|
1138
1279
|
|
|
1139
|
-
#[
|
|
1280
|
+
#[export_name = "fb_join_group_serialize"]
|
|
1140
1281
|
pub unsafe extern "C" fn fb_join_group_serialize(
|
|
1141
1282
|
group: *const c_char,
|
|
1142
1283
|
out: *mut u8,
|
|
@@ -1166,6 +1307,10 @@ pub unsafe extern "C" fn fb_join_group_serialize(
|
|
|
1166
1307
|
*out.add(0) = WIRE_VERSION;
|
|
1167
1308
|
let id_bytes = 3026600144u32.to_le_bytes();
|
|
1168
1309
|
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1310
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1311
|
+
// server stamps per-destination delivery seqs on send.
|
|
1312
|
+
*out.add(5) = 0;
|
|
1313
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
1169
1314
|
}
|
|
1170
1315
|
needed
|
|
1171
1316
|
}
|
|
@@ -1175,7 +1320,7 @@ pub unsafe extern "C" fn fb_join_group_serialize(
|
|
|
1175
1320
|
.unwrap_or(0)
|
|
1176
1321
|
}
|
|
1177
1322
|
|
|
1178
|
-
#[
|
|
1323
|
+
#[export_name = "fb_leave_group_serialize"]
|
|
1179
1324
|
pub unsafe extern "C" fn fb_leave_group_serialize(
|
|
1180
1325
|
group: *const c_char,
|
|
1181
1326
|
out: *mut u8,
|
|
@@ -1205,6 +1350,10 @@ pub unsafe extern "C" fn fb_leave_group_serialize(
|
|
|
1205
1350
|
*out.add(0) = WIRE_VERSION;
|
|
1206
1351
|
let id_bytes = 3755061443u32.to_le_bytes();
|
|
1207
1352
|
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1353
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1354
|
+
// server stamps per-destination delivery seqs on send.
|
|
1355
|
+
*out.add(5) = 0;
|
|
1356
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
1208
1357
|
}
|
|
1209
1358
|
needed
|
|
1210
1359
|
}
|
|
@@ -1214,9 +1363,10 @@ pub unsafe extern "C" fn fb_leave_group_serialize(
|
|
|
1214
1363
|
.unwrap_or(0)
|
|
1215
1364
|
}
|
|
1216
1365
|
|
|
1217
|
-
#[
|
|
1366
|
+
#[export_name = "fb_snapshot_request_serialize"]
|
|
1218
1367
|
pub unsafe extern "C" fn fb_snapshot_request_serialize(
|
|
1219
1368
|
topic: *const c_char,
|
|
1369
|
+
from_seq: i64,
|
|
1220
1370
|
out: *mut u8,
|
|
1221
1371
|
out_cap: usize,
|
|
1222
1372
|
) -> usize {
|
|
@@ -1235,6 +1385,7 @@ pub unsafe extern "C" fn fb_snapshot_request_serialize(
|
|
|
1235
1385
|
let topic = fbb.create_string(topic);
|
|
1236
1386
|
backend::SnapshotRequest::create(fbb, &backend::SnapshotRequestArgs {
|
|
1237
1387
|
topic: Some(topic),
|
|
1388
|
+
from_seq: from_seq,
|
|
1238
1389
|
..Default::default()
|
|
1239
1390
|
})
|
|
1240
1391
|
}) {
|
|
@@ -1244,6 +1395,10 @@ pub unsafe extern "C" fn fb_snapshot_request_serialize(
|
|
|
1244
1395
|
*out.add(0) = WIRE_VERSION;
|
|
1245
1396
|
let id_bytes = 1249175018u32.to_le_bytes();
|
|
1246
1397
|
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1398
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1399
|
+
// server stamps per-destination delivery seqs on send.
|
|
1400
|
+
*out.add(5) = 0;
|
|
1401
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
1247
1402
|
}
|
|
1248
1403
|
needed
|
|
1249
1404
|
}
|
|
@@ -1253,7 +1408,7 @@ pub unsafe extern "C" fn fb_snapshot_request_serialize(
|
|
|
1253
1408
|
.unwrap_or(0)
|
|
1254
1409
|
}
|
|
1255
1410
|
|
|
1256
|
-
#[
|
|
1411
|
+
#[export_name = "fb_ping_serialize"]
|
|
1257
1412
|
pub unsafe extern "C" fn fb_ping_serialize(
|
|
1258
1413
|
ts: i64,
|
|
1259
1414
|
out: *mut u8,
|
|
@@ -1283,6 +1438,10 @@ pub unsafe extern "C" fn fb_ping_serialize(
|
|
|
1283
1438
|
*out.add(0) = WIRE_VERSION;
|
|
1284
1439
|
let id_bytes = 375255177u32.to_le_bytes();
|
|
1285
1440
|
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1441
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1442
|
+
// server stamps per-destination delivery seqs on send.
|
|
1443
|
+
*out.add(5) = 0;
|
|
1444
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
1286
1445
|
}
|
|
1287
1446
|
needed
|
|
1288
1447
|
}
|
|
@@ -1292,7 +1451,7 @@ pub unsafe extern "C" fn fb_ping_serialize(
|
|
|
1292
1451
|
.unwrap_or(0)
|
|
1293
1452
|
}
|
|
1294
1453
|
|
|
1295
|
-
#[
|
|
1454
|
+
#[export_name = "fb_pong_serialize"]
|
|
1296
1455
|
pub unsafe extern "C" fn fb_pong_serialize(
|
|
1297
1456
|
ts: i64,
|
|
1298
1457
|
out: *mut u8,
|
|
@@ -1322,6 +1481,202 @@ pub unsafe extern "C" fn fb_pong_serialize(
|
|
|
1322
1481
|
*out.add(0) = WIRE_VERSION;
|
|
1323
1482
|
let id_bytes = 2061178551u32.to_le_bytes();
|
|
1324
1483
|
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1484
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1485
|
+
// server stamps per-destination delivery seqs on send.
|
|
1486
|
+
*out.add(5) = 0;
|
|
1487
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
1488
|
+
}
|
|
1489
|
+
needed
|
|
1490
|
+
}
|
|
1491
|
+
Err(_) => 0,
|
|
1492
|
+
}
|
|
1493
|
+
}))
|
|
1494
|
+
.unwrap_or(0)
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
#[export_name = "fb_resume_serialize"]
|
|
1498
|
+
pub unsafe extern "C" fn fb_resume_serialize(
|
|
1499
|
+
last_seq: i64,
|
|
1500
|
+
out: *mut u8,
|
|
1501
|
+
out_cap: usize,
|
|
1502
|
+
) -> usize {
|
|
1503
|
+
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
|
1504
|
+
if out.is_null() && out_cap != 0 {
|
|
1505
|
+
return 0;
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
// envelope = [WIRE_VERSION:1][event_id:u32 LE]; flatbuffer payload follows
|
|
1509
|
+
let payload: &mut [u8] = if out_cap < WIRE_HEADER_LEN {
|
|
1510
|
+
&mut []
|
|
1511
|
+
} else {
|
|
1512
|
+
std::slice::from_raw_parts_mut(out.add(WIRE_HEADER_LEN), out_cap - WIRE_HEADER_LEN)
|
|
1513
|
+
};
|
|
1514
|
+
match copy_finished(payload, |fbb| {
|
|
1515
|
+
|
|
1516
|
+
backend::Resume::create(fbb, &backend::ResumeArgs {
|
|
1517
|
+
last_seq: last_seq,
|
|
1518
|
+
..Default::default()
|
|
1519
|
+
})
|
|
1520
|
+
}) {
|
|
1521
|
+
Ok(written) => {
|
|
1522
|
+
let needed = written + WIRE_HEADER_LEN;
|
|
1523
|
+
if needed <= out_cap {
|
|
1524
|
+
*out.add(0) = WIRE_VERSION;
|
|
1525
|
+
let id_bytes = 4281967466u32.to_le_bytes();
|
|
1526
|
+
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1527
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1528
|
+
// server stamps per-destination delivery seqs on send.
|
|
1529
|
+
*out.add(5) = 0;
|
|
1530
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
1531
|
+
}
|
|
1532
|
+
needed
|
|
1533
|
+
}
|
|
1534
|
+
Err(_) => 0,
|
|
1535
|
+
}
|
|
1536
|
+
}))
|
|
1537
|
+
.unwrap_or(0)
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
#[export_name = "fb_resumed_serialize"]
|
|
1541
|
+
pub unsafe extern "C" fn fb_resumed_serialize(
|
|
1542
|
+
ok: u8,
|
|
1543
|
+
from: i64,
|
|
1544
|
+
out: *mut u8,
|
|
1545
|
+
out_cap: usize,
|
|
1546
|
+
) -> usize {
|
|
1547
|
+
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
|
1548
|
+
if out.is_null() && out_cap != 0 {
|
|
1549
|
+
return 0;
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
// envelope = [WIRE_VERSION:1][event_id:u32 LE]; flatbuffer payload follows
|
|
1553
|
+
let payload: &mut [u8] = if out_cap < WIRE_HEADER_LEN {
|
|
1554
|
+
&mut []
|
|
1555
|
+
} else {
|
|
1556
|
+
std::slice::from_raw_parts_mut(out.add(WIRE_HEADER_LEN), out_cap - WIRE_HEADER_LEN)
|
|
1557
|
+
};
|
|
1558
|
+
match copy_finished(payload, |fbb| {
|
|
1559
|
+
|
|
1560
|
+
backend::Resumed::create(fbb, &backend::ResumedArgs {
|
|
1561
|
+
ok: ok != 0,
|
|
1562
|
+
from: from,
|
|
1563
|
+
..Default::default()
|
|
1564
|
+
})
|
|
1565
|
+
}) {
|
|
1566
|
+
Ok(written) => {
|
|
1567
|
+
let needed = written + WIRE_HEADER_LEN;
|
|
1568
|
+
if needed <= out_cap {
|
|
1569
|
+
*out.add(0) = WIRE_VERSION;
|
|
1570
|
+
let id_bytes = 3585847050u32.to_le_bytes();
|
|
1571
|
+
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1572
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1573
|
+
// server stamps per-destination delivery seqs on send.
|
|
1574
|
+
*out.add(5) = 0;
|
|
1575
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
1576
|
+
}
|
|
1577
|
+
needed
|
|
1578
|
+
}
|
|
1579
|
+
Err(_) => 0,
|
|
1580
|
+
}
|
|
1581
|
+
}))
|
|
1582
|
+
.unwrap_or(0)
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
#[export_name = "fb_rpc_call_serialize"]
|
|
1586
|
+
pub unsafe extern "C" fn fb_rpc_call_serialize(
|
|
1587
|
+
id: *const c_char,
|
|
1588
|
+
name: *const c_char,
|
|
1589
|
+
payload_b64: *const c_char,
|
|
1590
|
+
out: *mut u8,
|
|
1591
|
+
out_cap: usize,
|
|
1592
|
+
) -> usize {
|
|
1593
|
+
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
|
1594
|
+
if out.is_null() && out_cap != 0 {
|
|
1595
|
+
return 0;
|
|
1596
|
+
}
|
|
1597
|
+
let id = if id.is_null() { "" } else { std::str::from_utf8_unchecked(CStr::from_ptr(id).to_bytes()) };
|
|
1598
|
+
let name = if name.is_null() { "" } else { std::str::from_utf8_unchecked(CStr::from_ptr(name).to_bytes()) };
|
|
1599
|
+
let payload_b64 = if payload_b64.is_null() { "" } else { std::str::from_utf8_unchecked(CStr::from_ptr(payload_b64).to_bytes()) };
|
|
1600
|
+
// envelope = [WIRE_VERSION:1][event_id:u32 LE]; flatbuffer payload follows
|
|
1601
|
+
let payload: &mut [u8] = if out_cap < WIRE_HEADER_LEN {
|
|
1602
|
+
&mut []
|
|
1603
|
+
} else {
|
|
1604
|
+
std::slice::from_raw_parts_mut(out.add(WIRE_HEADER_LEN), out_cap - WIRE_HEADER_LEN)
|
|
1605
|
+
};
|
|
1606
|
+
match copy_finished(payload, |fbb| {
|
|
1607
|
+
let id = fbb.create_string(id);
|
|
1608
|
+
let name = fbb.create_string(name);
|
|
1609
|
+
let payload_b64 = fbb.create_string(payload_b64);
|
|
1610
|
+
backend::RpcCall::create(fbb, &backend::RpcCallArgs {
|
|
1611
|
+
id: Some(id),
|
|
1612
|
+
name: Some(name),
|
|
1613
|
+
payload_b64: Some(payload_b64),
|
|
1614
|
+
..Default::default()
|
|
1615
|
+
})
|
|
1616
|
+
}) {
|
|
1617
|
+
Ok(written) => {
|
|
1618
|
+
let needed = written + WIRE_HEADER_LEN;
|
|
1619
|
+
if needed <= out_cap {
|
|
1620
|
+
*out.add(0) = WIRE_VERSION;
|
|
1621
|
+
let id_bytes = 986404564u32.to_le_bytes();
|
|
1622
|
+
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1623
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1624
|
+
// server stamps per-destination delivery seqs on send.
|
|
1625
|
+
*out.add(5) = 0;
|
|
1626
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
1627
|
+
}
|
|
1628
|
+
needed
|
|
1629
|
+
}
|
|
1630
|
+
Err(_) => 0,
|
|
1631
|
+
}
|
|
1632
|
+
}))
|
|
1633
|
+
.unwrap_or(0)
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
#[export_name = "fb_rpc_result_serialize"]
|
|
1637
|
+
pub unsafe extern "C" fn fb_rpc_result_serialize(
|
|
1638
|
+
id: *const c_char,
|
|
1639
|
+
ok: u8,
|
|
1640
|
+
err: *const c_char,
|
|
1641
|
+
payload_b64: *const c_char,
|
|
1642
|
+
out: *mut u8,
|
|
1643
|
+
out_cap: usize,
|
|
1644
|
+
) -> usize {
|
|
1645
|
+
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
|
1646
|
+
if out.is_null() && out_cap != 0 {
|
|
1647
|
+
return 0;
|
|
1648
|
+
}
|
|
1649
|
+
let id = if id.is_null() { "" } else { std::str::from_utf8_unchecked(CStr::from_ptr(id).to_bytes()) };
|
|
1650
|
+
let err = if err.is_null() { "" } else { std::str::from_utf8_unchecked(CStr::from_ptr(err).to_bytes()) };
|
|
1651
|
+
let payload_b64 = if payload_b64.is_null() { "" } else { std::str::from_utf8_unchecked(CStr::from_ptr(payload_b64).to_bytes()) };
|
|
1652
|
+
// envelope = [WIRE_VERSION:1][event_id:u32 LE]; flatbuffer payload follows
|
|
1653
|
+
let payload: &mut [u8] = if out_cap < WIRE_HEADER_LEN {
|
|
1654
|
+
&mut []
|
|
1655
|
+
} else {
|
|
1656
|
+
std::slice::from_raw_parts_mut(out.add(WIRE_HEADER_LEN), out_cap - WIRE_HEADER_LEN)
|
|
1657
|
+
};
|
|
1658
|
+
match copy_finished(payload, |fbb| {
|
|
1659
|
+
let id = fbb.create_string(id);
|
|
1660
|
+
let err = fbb.create_string(err);
|
|
1661
|
+
let payload_b64 = fbb.create_string(payload_b64);
|
|
1662
|
+
backend::RpcResult::create(fbb, &backend::RpcResultArgs {
|
|
1663
|
+
id: Some(id),
|
|
1664
|
+
ok: ok != 0,
|
|
1665
|
+
err: Some(err),
|
|
1666
|
+
payload_b64: Some(payload_b64),
|
|
1667
|
+
..Default::default()
|
|
1668
|
+
})
|
|
1669
|
+
}) {
|
|
1670
|
+
Ok(written) => {
|
|
1671
|
+
let needed = written + WIRE_HEADER_LEN;
|
|
1672
|
+
if needed <= out_cap {
|
|
1673
|
+
*out.add(0) = WIRE_VERSION;
|
|
1674
|
+
let id_bytes = 648609069u32.to_le_bytes();
|
|
1675
|
+
std::ptr::copy_nonoverlapping(id_bytes.as_ptr(), out.add(1), 4);
|
|
1676
|
+
// [flags:1][seq:u64 LE] — pristine (flags=0, seq=0); the
|
|
1677
|
+
// server stamps per-destination delivery seqs on send.
|
|
1678
|
+
*out.add(5) = 0;
|
|
1679
|
+
std::ptr::write_bytes(out.add(6), 0, 8);
|
|
1325
1680
|
}
|
|
1326
1681
|
needed
|
|
1327
1682
|
}
|
|
@@ -1348,6 +1703,10 @@ pub fn serialize_event(event_id: u32, json: &[u8], out: &mut [u8]) -> Result<usi
|
|
|
1348
1703
|
1249175018 => serialize_snapshot_request(json, out),
|
|
1349
1704
|
375255177 => serialize_ping(json, out),
|
|
1350
1705
|
2061178551 => serialize_pong(json, out),
|
|
1706
|
+
4281967466 => serialize_resume(json, out),
|
|
1707
|
+
3585847050 => serialize_resumed(json, out),
|
|
1708
|
+
986404564 => serialize_rpc_call(json, out),
|
|
1709
|
+
648609069 => serialize_rpc_result(json, out),
|
|
1351
1710
|
_ => Err(TranscodeError::UnknownEvent),
|
|
1352
1711
|
}
|
|
1353
1712
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inbound pipeline — the bridge's NATS→clients forward. Subscribes a subject
|
|
3
|
+
* and, for each arriving frame: reads the envelope header (cheap), rejects
|
|
4
|
+
* transport-internal control frames and non-allowlisted events, then decodes
|
|
5
|
+
* the payload and hands `{name, payload}` to the wired `onInbound` callback.
|
|
6
|
+
*
|
|
7
|
+
* Decode failures are counted in `stats.bridgeInboundErrors`, never thrown —
|
|
8
|
+
* the WS hot path must not depend on broker input being well-formed.
|
|
9
|
+
*/
|
|
10
|
+
import type { Bindings } from "../../bindings/types";
|
|
11
|
+
import type { NatsBridgeStats, NatsTransport } from "./types";
|
|
12
|
+
|
|
13
|
+
export function subscribeInboundSubject(deps: {
|
|
14
|
+
transport: NatsTransport;
|
|
15
|
+
bindings: Bindings;
|
|
16
|
+
stats: NatsBridgeStats;
|
|
17
|
+
subject: string;
|
|
18
|
+
/** allowlist; `null` = forward every app event */
|
|
19
|
+
allowlist: Set<string> | null;
|
|
20
|
+
/** set once by the server (the fan-out-to-clients callback) */
|
|
21
|
+
getOnInbound(): ((name: string, payload: unknown) => void) | null;
|
|
22
|
+
}): () => void {
|
|
23
|
+
const { transport, bindings, stats, subject, allowlist } = deps;
|
|
24
|
+
return transport.subscribe(subject, (data) => {
|
|
25
|
+
// header-first: reject junk/control frames before any payload decode
|
|
26
|
+
const header = bindings.readFrameHeader(data);
|
|
27
|
+
if (!header) {
|
|
28
|
+
stats.bridgeInboundErrors++;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (bindings.isControlId(header.id)) {
|
|
32
|
+
stats.bridgeInboundErrors++; // never forward transport-internal frames
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (allowlist && !allowlist.has(header.name)) return;
|
|
36
|
+
let payload: unknown;
|
|
37
|
+
try {
|
|
38
|
+
payload = bindings.decodePayload(header.id, data);
|
|
39
|
+
} catch {
|
|
40
|
+
stats.bridgeInboundErrors++;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
stats.bridgeInbound++;
|
|
44
|
+
deps.getOnInbound()?.(header.name, payload);
|
|
45
|
+
});
|
|
46
|
+
}
|