@ignex/nova 0.1.1 → 0.1.5

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 (120) hide show
  1. package/README.md +136 -33
  2. package/docs/ai/LOCAL_DEV.md +81 -0
  3. package/docs/ai/TREE.md +292 -0
  4. package/docs/architecture.md +101 -28
  5. package/docs/events.md +252 -0
  6. package/docs/generic-bindings.md +207 -0
  7. package/docs/publishing.md +2 -2
  8. package/docs/wire-format.md +74 -20
  9. package/index.ts +75 -27
  10. package/package.json +13 -2
  11. package/prebuilds/linux-x64/libignex_ffi.so +0 -0
  12. package/public/bindings.ts +24 -0
  13. package/public/client.ts +5 -1
  14. package/public/events.ts +71 -0
  15. package/public/generate.ts +510 -0
  16. package/public/internal.ts +16 -0
  17. package/public/nats.ts +9 -5
  18. package/public/server.ts +52 -16
  19. package/rust/src/ffi.rs +10 -0
  20. package/rust/src/generated/backend.rs +503 -0
  21. package/rust/src/transcode/generated.rs +377 -17
  22. package/src/bindings/assemble.ts +73 -0
  23. package/src/bindings/default.ts +65 -0
  24. package/src/bindings/types.ts +113 -0
  25. package/src/bridge/nats/inbound.ts +46 -0
  26. package/src/bridge/nats/index.ts +131 -0
  27. package/src/bridge/nats/real-transport.ts +133 -0
  28. package/src/bridge/nats/types.ts +80 -0
  29. package/src/bridge/subjects.ts +3 -0
  30. package/src/codegen/constants.ts +28 -0
  31. package/src/codegen/direct-gen.ts +564 -0
  32. package/src/codegen/fingerprint.ts +44 -0
  33. package/src/codegen/hash.ts +25 -0
  34. package/src/codegen/registry-gen.ts +246 -0
  35. package/src/codegen/rust-glue-gen.ts +552 -0
  36. package/src/codegen/schema-model.ts +363 -0
  37. package/src/codegen/ts-ser-gen.ts +230 -0
  38. package/src/codegen/typebox-to-fbs.ts +60 -0
  39. package/src/core/auth.ts +67 -5
  40. package/src/core/client-heartbeat.ts +2 -1
  41. package/src/core/client-reconnect.ts +9 -2
  42. package/src/core/client-rpc.ts +75 -0
  43. package/src/core/client-state.ts +63 -8
  44. package/src/core/client-wire.ts +148 -15
  45. package/src/core/client.ts +105 -31
  46. package/src/core/groups.ts +8 -0
  47. package/src/core/metrics.ts +42 -21
  48. package/src/core/outbound.ts +62 -11
  49. package/src/core/rate-limit.ts +69 -0
  50. package/src/core/replay.ts +41 -1
  51. package/src/core/resume.ts +181 -0
  52. package/src/core/rooms.ts +10 -3
  53. package/src/core/routing.ts +144 -12
  54. package/src/core/server/client-info.ts +37 -0
  55. package/src/core/server/http-routes.ts +59 -0
  56. package/src/core/server/index.ts +360 -0
  57. package/src/core/server/metrics-view.ts +53 -0
  58. package/src/core/server/socket-lifecycle.ts +57 -0
  59. package/src/core/state.ts +124 -14
  60. package/src/core/topic-log.ts +86 -0
  61. package/src/events/clients.ts +174 -0
  62. package/src/events/cluster/dedupe.ts +43 -0
  63. package/src/events/cluster/envelope.ts +149 -0
  64. package/src/events/cluster/index.ts +50 -0
  65. package/src/events/cluster/keys.ts +33 -0
  66. package/src/events/cluster/kinds.ts +32 -0
  67. package/src/events/cluster/presence-table.ts +99 -0
  68. package/src/events/cluster/presence.ts +53 -0
  69. package/src/events/cluster/redis-client.ts +50 -0
  70. package/src/events/cluster/store-memory.ts +67 -0
  71. package/src/events/cluster/store-redis.ts +44 -0
  72. package/src/events/cluster/subjects.ts +30 -0
  73. package/src/events/cluster/sync.ts +476 -0
  74. package/src/events/cluster/transport-nats.ts +24 -0
  75. package/src/events/cluster/transport-redis.ts +120 -0
  76. package/src/events/cluster-rpc.ts +196 -0
  77. package/src/events/data.ts +38 -0
  78. package/src/events/delivery.ts +83 -0
  79. package/src/events/emit.ts +173 -0
  80. package/src/events/global.ts +117 -0
  81. package/src/events/groups.ts +118 -0
  82. package/src/events/hub/context-factory.ts +79 -0
  83. package/src/events/hub/dispatch.ts +86 -0
  84. package/src/events/hub/index.ts +536 -0
  85. package/src/events/hub/internal.ts +31 -0
  86. package/src/events/hub/metrics-snapshot.ts +84 -0
  87. package/src/events/hub/resolve-cluster.ts +49 -0
  88. package/src/events/index.ts +61 -0
  89. package/src/events/queue.ts +123 -0
  90. package/src/events/registry.ts +214 -0
  91. package/src/events/schedule.ts +73 -0
  92. package/src/events/trace.ts +283 -0
  93. package/src/events/types/client.ts +68 -0
  94. package/src/events/types/cluster.ts +40 -0
  95. package/src/events/types/context.ts +50 -0
  96. package/src/events/types/emit-target.ts +29 -0
  97. package/src/events/types/groups.ts +35 -0
  98. package/src/events/types/hub.ts +124 -0
  99. package/src/events/types/index.ts +30 -0
  100. package/src/events/types/metrics.ts +52 -0
  101. package/src/events/types/options.ts +62 -0
  102. package/src/generated/direct-ser.ts +148 -60
  103. package/src/generated/fbs/backend.fbs +24 -1
  104. package/src/generated/registry.ts +94 -33
  105. package/src/generated/rust/backend_generated.rs +503 -0
  106. package/src/generated/ts/backend.ts +4 -0
  107. package/src/generated/ts/resume.ts +74 -0
  108. package/src/generated/ts/resumed.ts +88 -0
  109. package/src/generated/ts/rpc-call.ts +112 -0
  110. package/src/generated/ts/rpc-result.ts +126 -0
  111. package/src/generated/ts/snapshot-request.ts +19 -5
  112. package/src/generated/ts-ser.ts +110 -17
  113. package/src/generated/wire-registry.json +7 -2
  114. package/src/native/ffi.ts +85 -28
  115. package/src/schema/index.ts +49 -2
  116. package/src/server.ts +7 -3
  117. package/src/transport/transport.ts +200 -79
  118. package/src/bridge/nats.ts +0 -269
  119. package/src/core/server.ts +0 -294
  120. package/src/transport/stats.ts +0 -44
@@ -1,4 +1,4 @@
1
- // @generated by scripts/rust-glue-gen.ts — DO NOT EDIT
1
+ // @generated by src/codegen/rust-glue-gen.ts — DO NOT EDIT
2
2
  #![allow(clippy::all)]
3
3
  #![allow(dead_code)]
4
4
  #![allow(unused_imports)]
@@ -9,8 +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 = 1;
13
- pub const WIRE_HEADER_LEN: usize = 5; // [version:1][event_id:u32 LE]
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)
14
15
 
15
16
  thread_local! {
16
17
  static FBB: RefCell<flatbuffers::FlatBufferBuilder<'static>> =
@@ -472,12 +473,15 @@ pub fn build_leave_group<'a>(fbb: &mut flatbuffers::FlatBufferBuilder<'a>, j: &L
472
473
  pub struct SnapshotRequestJson {
473
474
  #[serde(default)]
474
475
  pub topic: String,
476
+ #[serde(default, deserialize_with = "de_i64")]
477
+ pub from_seq: i64,
475
478
  }
476
479
 
477
480
  pub fn build_snapshot_request<'a>(fbb: &mut flatbuffers::FlatBufferBuilder<'a>, j: &SnapshotRequestJson) -> flatbuffers::WIPOffset<backend::SnapshotRequest<'a>> {
478
481
  let topic = fbb.create_string(&j.topic);
479
482
  backend::SnapshotRequest::create(fbb, &backend::SnapshotRequestArgs {
480
483
  topic: Some(topic),
484
+ from_seq: j.from_seq,
481
485
  ..Default::default()
482
486
  })
483
487
  }
@@ -512,6 +516,88 @@ pub fn build_pong<'a>(fbb: &mut flatbuffers::FlatBufferBuilder<'a>, j: &PongJson
512
516
  })
513
517
  }
514
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
+
515
601
  pub fn serialize_quote(json: &[u8], out: &mut [u8]) -> Result<usize, TranscodeError> {
516
602
  let j: QuoteJson = serde_json::from_slice(json).map_err(|_| TranscodeError::Parse)?;
517
603
  copy_finished(out, |fbb| build_quote(fbb, &j))
@@ -587,6 +673,26 @@ pub fn serialize_pong(json: &[u8], out: &mut [u8]) -> Result<usize, TranscodeErr
587
673
  copy_finished(out, |fbb| build_pong(fbb, &j))
588
674
  }
589
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
+
590
696
  fn read_u32(b: &[u8], off: &mut usize) -> u32 {
591
697
  let v = u32::from_le_bytes([b[*off], b[*off + 1], b[*off + 2], b[*off + 3]]);
592
698
  *off += 4;
@@ -712,7 +818,7 @@ fn read_packed_welcome_groups<'a>(fbb: &mut flatbuffers::FlatBufferBuilder<'a>,
712
818
  }
713
819
 
714
820
 
715
- #[no_mangle]
821
+ #[export_name = "fb_quote_serialize"]
716
822
  pub unsafe extern "C" fn fb_quote_serialize(
717
823
  symbol: *const c_char,
718
824
  bid: f64,
@@ -752,6 +858,10 @@ pub unsafe extern "C" fn fb_quote_serialize(
752
858
  *out.add(0) = WIRE_VERSION;
753
859
  let id_bytes = 2995289047u32.to_le_bytes();
754
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);
755
865
  }
756
866
  needed
757
867
  }
@@ -761,7 +871,7 @@ pub unsafe extern "C" fn fb_quote_serialize(
761
871
  .unwrap_or(0)
762
872
  }
763
873
 
764
- #[no_mangle]
874
+ #[export_name = "fb_trade_serialize"]
765
875
  pub unsafe extern "C" fn fb_trade_serialize(
766
876
  symbol: *const c_char,
767
877
  price: f64,
@@ -800,6 +910,10 @@ pub unsafe extern "C" fn fb_trade_serialize(
800
910
  *out.add(0) = WIRE_VERSION;
801
911
  let id_bytes = 1362521689u32.to_le_bytes();
802
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);
803
917
  }
804
918
  needed
805
919
  }
@@ -809,7 +923,7 @@ pub unsafe extern "C" fn fb_trade_serialize(
809
923
  .unwrap_or(0)
810
924
  }
811
925
 
812
- #[no_mangle]
926
+ #[export_name = "fb_portfolio_serialize"]
813
927
  pub unsafe extern "C" fn fb_portfolio_serialize(
814
928
  account_id: *const c_char,
815
929
  positions_ptr: *const u8,
@@ -853,6 +967,10 @@ pub unsafe extern "C" fn fb_portfolio_serialize(
853
967
  *out.add(0) = WIRE_VERSION;
854
968
  let id_bytes = 464274147u32.to_le_bytes();
855
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);
856
974
  }
857
975
  needed
858
976
  }
@@ -862,7 +980,7 @@ pub unsafe extern "C" fn fb_portfolio_serialize(
862
980
  .unwrap_or(0)
863
981
  }
864
982
 
865
- #[no_mangle]
983
+ #[export_name = "fb_complex_serialize"]
866
984
  pub unsafe extern "C" fn fb_complex_serialize(
867
985
  id: *const c_char,
868
986
  names_ptr: *const u8,
@@ -918,6 +1036,10 @@ pub unsafe extern "C" fn fb_complex_serialize(
918
1036
  *out.add(0) = WIRE_VERSION;
919
1037
  let id_bytes = 2318166199u32.to_le_bytes();
920
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);
921
1043
  }
922
1044
  needed
923
1045
  }
@@ -927,7 +1049,7 @@ pub unsafe extern "C" fn fb_complex_serialize(
927
1049
  .unwrap_or(0)
928
1050
  }
929
1051
 
930
- #[no_mangle]
1052
+ #[export_name = "fb_big_val_serialize"]
931
1053
  pub unsafe extern "C" fn fb_big_val_serialize(
932
1054
  id: *const c_char,
933
1055
  seq: i64,
@@ -961,6 +1083,10 @@ pub unsafe extern "C" fn fb_big_val_serialize(
961
1083
  *out.add(0) = WIRE_VERSION;
962
1084
  let id_bytes = 3211729064u32.to_le_bytes();
963
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);
964
1090
  }
965
1091
  needed
966
1092
  }
@@ -970,7 +1096,7 @@ pub unsafe extern "C" fn fb_big_val_serialize(
970
1096
  .unwrap_or(0)
971
1097
  }
972
1098
 
973
- #[no_mangle]
1099
+ #[export_name = "fb_hello_serialize"]
974
1100
  pub unsafe extern "C" fn fb_hello_serialize(
975
1101
  version: i64,
976
1102
  caps_ptr: *const u8,
@@ -1005,6 +1131,10 @@ pub unsafe extern "C" fn fb_hello_serialize(
1005
1131
  *out.add(0) = WIRE_VERSION;
1006
1132
  let id_bytes = 1335831723u32.to_le_bytes();
1007
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);
1008
1138
  }
1009
1139
  needed
1010
1140
  }
@@ -1014,7 +1144,7 @@ pub unsafe extern "C" fn fb_hello_serialize(
1014
1144
  .unwrap_or(0)
1015
1145
  }
1016
1146
 
1017
- #[no_mangle]
1147
+ #[export_name = "fb_welcome_serialize"]
1018
1148
  pub unsafe extern "C" fn fb_welcome_serialize(
1019
1149
  client_id: *const c_char,
1020
1150
  groups_ptr: *const u8,
@@ -1048,6 +1178,10 @@ pub unsafe extern "C" fn fb_welcome_serialize(
1048
1178
  *out.add(0) = WIRE_VERSION;
1049
1179
  let id_bytes = 669089267u32.to_le_bytes();
1050
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);
1051
1185
  }
1052
1186
  needed
1053
1187
  }
@@ -1057,7 +1191,7 @@ pub unsafe extern "C" fn fb_welcome_serialize(
1057
1191
  .unwrap_or(0)
1058
1192
  }
1059
1193
 
1060
- #[no_mangle]
1194
+ #[export_name = "fb_subscribe_serialize"]
1061
1195
  pub unsafe extern "C" fn fb_subscribe_serialize(
1062
1196
  topic: *const c_char,
1063
1197
  out: *mut u8,
@@ -1087,6 +1221,10 @@ pub unsafe extern "C" fn fb_subscribe_serialize(
1087
1221
  *out.add(0) = WIRE_VERSION;
1088
1222
  let id_bytes = 2946386435u32.to_le_bytes();
1089
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);
1090
1228
  }
1091
1229
  needed
1092
1230
  }
@@ -1096,7 +1234,7 @@ pub unsafe extern "C" fn fb_subscribe_serialize(
1096
1234
  .unwrap_or(0)
1097
1235
  }
1098
1236
 
1099
- #[no_mangle]
1237
+ #[export_name = "fb_unsubscribe_serialize"]
1100
1238
  pub unsafe extern "C" fn fb_unsubscribe_serialize(
1101
1239
  topic: *const c_char,
1102
1240
  out: *mut u8,
@@ -1126,6 +1264,10 @@ pub unsafe extern "C" fn fb_unsubscribe_serialize(
1126
1264
  *out.add(0) = WIRE_VERSION;
1127
1265
  let id_bytes = 4190043798u32.to_le_bytes();
1128
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);
1129
1271
  }
1130
1272
  needed
1131
1273
  }
@@ -1135,7 +1277,7 @@ pub unsafe extern "C" fn fb_unsubscribe_serialize(
1135
1277
  .unwrap_or(0)
1136
1278
  }
1137
1279
 
1138
- #[no_mangle]
1280
+ #[export_name = "fb_join_group_serialize"]
1139
1281
  pub unsafe extern "C" fn fb_join_group_serialize(
1140
1282
  group: *const c_char,
1141
1283
  out: *mut u8,
@@ -1165,6 +1307,10 @@ pub unsafe extern "C" fn fb_join_group_serialize(
1165
1307
  *out.add(0) = WIRE_VERSION;
1166
1308
  let id_bytes = 3026600144u32.to_le_bytes();
1167
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);
1168
1314
  }
1169
1315
  needed
1170
1316
  }
@@ -1174,7 +1320,7 @@ pub unsafe extern "C" fn fb_join_group_serialize(
1174
1320
  .unwrap_or(0)
1175
1321
  }
1176
1322
 
1177
- #[no_mangle]
1323
+ #[export_name = "fb_leave_group_serialize"]
1178
1324
  pub unsafe extern "C" fn fb_leave_group_serialize(
1179
1325
  group: *const c_char,
1180
1326
  out: *mut u8,
@@ -1204,6 +1350,10 @@ pub unsafe extern "C" fn fb_leave_group_serialize(
1204
1350
  *out.add(0) = WIRE_VERSION;
1205
1351
  let id_bytes = 3755061443u32.to_le_bytes();
1206
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);
1207
1357
  }
1208
1358
  needed
1209
1359
  }
@@ -1213,9 +1363,10 @@ pub unsafe extern "C" fn fb_leave_group_serialize(
1213
1363
  .unwrap_or(0)
1214
1364
  }
1215
1365
 
1216
- #[no_mangle]
1366
+ #[export_name = "fb_snapshot_request_serialize"]
1217
1367
  pub unsafe extern "C" fn fb_snapshot_request_serialize(
1218
1368
  topic: *const c_char,
1369
+ from_seq: i64,
1219
1370
  out: *mut u8,
1220
1371
  out_cap: usize,
1221
1372
  ) -> usize {
@@ -1234,6 +1385,7 @@ pub unsafe extern "C" fn fb_snapshot_request_serialize(
1234
1385
  let topic = fbb.create_string(topic);
1235
1386
  backend::SnapshotRequest::create(fbb, &backend::SnapshotRequestArgs {
1236
1387
  topic: Some(topic),
1388
+ from_seq: from_seq,
1237
1389
  ..Default::default()
1238
1390
  })
1239
1391
  }) {
@@ -1243,6 +1395,10 @@ pub unsafe extern "C" fn fb_snapshot_request_serialize(
1243
1395
  *out.add(0) = WIRE_VERSION;
1244
1396
  let id_bytes = 1249175018u32.to_le_bytes();
1245
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);
1246
1402
  }
1247
1403
  needed
1248
1404
  }
@@ -1252,7 +1408,7 @@ pub unsafe extern "C" fn fb_snapshot_request_serialize(
1252
1408
  .unwrap_or(0)
1253
1409
  }
1254
1410
 
1255
- #[no_mangle]
1411
+ #[export_name = "fb_ping_serialize"]
1256
1412
  pub unsafe extern "C" fn fb_ping_serialize(
1257
1413
  ts: i64,
1258
1414
  out: *mut u8,
@@ -1282,6 +1438,10 @@ pub unsafe extern "C" fn fb_ping_serialize(
1282
1438
  *out.add(0) = WIRE_VERSION;
1283
1439
  let id_bytes = 375255177u32.to_le_bytes();
1284
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);
1285
1445
  }
1286
1446
  needed
1287
1447
  }
@@ -1291,7 +1451,7 @@ pub unsafe extern "C" fn fb_ping_serialize(
1291
1451
  .unwrap_or(0)
1292
1452
  }
1293
1453
 
1294
- #[no_mangle]
1454
+ #[export_name = "fb_pong_serialize"]
1295
1455
  pub unsafe extern "C" fn fb_pong_serialize(
1296
1456
  ts: i64,
1297
1457
  out: *mut u8,
@@ -1321,6 +1481,202 @@ pub unsafe extern "C" fn fb_pong_serialize(
1321
1481
  *out.add(0) = WIRE_VERSION;
1322
1482
  let id_bytes = 2061178551u32.to_le_bytes();
1323
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);
1324
1680
  }
1325
1681
  needed
1326
1682
  }
@@ -1347,6 +1703,10 @@ pub fn serialize_event(event_id: u32, json: &[u8], out: &mut [u8]) -> Result<usi
1347
1703
  1249175018 => serialize_snapshot_request(json, out),
1348
1704
  375255177 => serialize_ping(json, out),
1349
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),
1350
1710
  _ => Err(TranscodeError::UnknownEvent),
1351
1711
  }
1352
1712
  }