starpc 0.52.0 → 0.52.2

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 (152) hide show
  1. package/README.md +37 -8
  2. package/dist/echo/client-test.d.ts +1 -1
  3. package/dist/echo/client-test.js +110 -2
  4. package/dist/integration/cross-language/tcp-packet-stream.d.ts +3 -0
  5. package/dist/integration/cross-language/tcp-packet-stream.js +112 -0
  6. package/dist/integration/cross-language/tcp-packet-stream.test.d.ts +1 -0
  7. package/dist/integration/cross-language/tcp-packet-stream.test.js +121 -0
  8. package/dist/integration/cross-language/ts-client.js +50 -37
  9. package/dist/integration/cross-language/ts-server.js +1 -36
  10. package/dist/rpcstream/rpcstream.d.ts +5 -1
  11. package/dist/rpcstream/rpcstream.js +75 -28
  12. package/dist/rpcstream/rpcstream.test.d.ts +1 -0
  13. package/dist/rpcstream/rpcstream.test.js +92 -0
  14. package/dist/srpc/client-rpc.d.ts +1 -0
  15. package/dist/srpc/client-rpc.js +9 -0
  16. package/dist/srpc/client-rpc.test.d.ts +1 -0
  17. package/dist/srpc/client-rpc.test.js +50 -0
  18. package/dist/srpc/client.js +18 -4
  19. package/dist/srpc/common-rpc.d.ts +5 -0
  20. package/dist/srpc/common-rpc.js +37 -8
  21. package/dist/srpc/common-rpc.test.js +2 -0
  22. package/dist/srpc/errors.d.ts +2 -0
  23. package/dist/srpc/errors.js +14 -0
  24. package/dist/srpc/index.d.ts +1 -1
  25. package/dist/srpc/index.js +1 -1
  26. package/dist/srpc/packet-codec.test.d.ts +1 -0
  27. package/dist/srpc/packet-codec.test.js +75 -0
  28. package/dist/srpc/packet.d.ts +1 -1
  29. package/dist/srpc/packet.js +11 -1
  30. package/dist/srpc/server.js +19 -6
  31. package/dist/srpc/server.test.js +43 -0
  32. package/dist/srpc/stream.d.ts +4 -1
  33. package/dist/srpc/stream.js +62 -3
  34. package/dist/srpc/stream.test.js +110 -1
  35. package/dist/srpc/termination.d.ts +27 -0
  36. package/dist/srpc/termination.js +56 -0
  37. package/dist/srpc/termination.test.d.ts +1 -0
  38. package/dist/srpc/termination.test.js +24 -0
  39. package/dist/testdata/packet-codec-vectors.json +64 -0
  40. package/echo/Cargo.toml +8 -0
  41. package/echo/client-test.ts +124 -2
  42. package/echo/echo_e2e_test.cpp +542 -985
  43. package/echo/echo_pb2.py +40 -0
  44. package/echo/echo_pb2.pyi +13 -0
  45. package/echo/echo_srpc.pb.cpp +3 -5
  46. package/echo/echo_srpc.pb.go +6 -9
  47. package/echo/echo_srpc.pb.hpp +23 -3
  48. package/echo/echo_srpc.pb.rs +61 -26
  49. package/echo/echo_srpc.py +309 -0
  50. package/echo/echo_srpc.pyi +85 -0
  51. package/echo/half_close_test.rs +178 -0
  52. package/echo/integration_server.rs +14 -21
  53. package/echo/main.rs +28 -48
  54. package/go.mod +3 -3
  55. package/go.sum +6 -8
  56. package/integration/cross-language/cpp-client.cpp +446 -402
  57. package/integration/cross-language/cpp-pipe-server.cpp +139 -0
  58. package/integration/cross-language/cpp-pipe_test.go +114 -0
  59. package/integration/cross-language/cpp-server.cpp +222 -186
  60. package/integration/cross-language/go-client/main.go +79 -3
  61. package/integration/cross-language/python-client.py +146 -0
  62. package/integration/cross-language/python-server.py +140 -0
  63. package/integration/cross-language/run.bash +190 -65
  64. package/integration/cross-language/tcp-packet-stream.test.ts +154 -0
  65. package/integration/cross-language/tcp-packet-stream.ts +121 -0
  66. package/integration/cross-language/ts-client.ts +62 -40
  67. package/integration/cross-language/ts-server.ts +1 -45
  68. package/mock/mock_pb2.py +38 -0
  69. package/mock/mock_pb2.pyi +11 -0
  70. package/mock/mock_srpc.pb.cpp +1 -1
  71. package/mock/mock_srpc.pb.hpp +1 -1
  72. package/mock/mock_srpc.pb.rs +10 -9
  73. package/mock/mock_srpc.py +71 -0
  74. package/mock/mock_srpc.pyi +27 -0
  75. package/package.json +19 -5
  76. package/srpc/CMakeLists.txt +3 -58
  77. package/srpc/README-cpp.md +69 -0
  78. package/srpc/__init__.py +0 -0
  79. package/srpc/accept.go +10 -4
  80. package/srpc/accept_test.go +25 -0
  81. package/srpc/build.rs +129 -34
  82. package/srpc/client-half-close_test.go +152 -0
  83. package/srpc/client-invoker.go +32 -42
  84. package/srpc/client-invoker_test.go +53 -0
  85. package/srpc/client-rpc.cpp +65 -80
  86. package/srpc/client-rpc.go +32 -33
  87. package/srpc/client-rpc.hpp +52 -38
  88. package/srpc/client-rpc.test.ts +67 -0
  89. package/srpc/client-rpc.ts +10 -0
  90. package/srpc/client-rpc_test.go +76 -0
  91. package/srpc/client.cpp +99 -87
  92. package/srpc/client.hpp +46 -35
  93. package/srpc/client.rs +78 -38
  94. package/srpc/client.ts +20 -4
  95. package/srpc/client_half_close_test.cc +331 -0
  96. package/srpc/client_invoker.rs +75 -0
  97. package/srpc/codec.rs +6 -0
  98. package/srpc/common-rpc.cpp +186 -146
  99. package/srpc/common-rpc.go +5 -4
  100. package/srpc/common-rpc.hpp +119 -89
  101. package/srpc/common-rpc.test.ts +2 -0
  102. package/srpc/common-rpc.ts +43 -8
  103. package/srpc/common-rpc_test.go +23 -0
  104. package/srpc/error.rs +19 -2
  105. package/srpc/errors.hpp +80 -50
  106. package/srpc/errors.ts +16 -0
  107. package/srpc/handler.hpp +9 -7
  108. package/srpc/handler.rs +7 -45
  109. package/srpc/index.ts +2 -0
  110. package/srpc/invoker.hpp +82 -55
  111. package/srpc/invoker.rs +14 -52
  112. package/srpc/lib.rs +2 -0
  113. package/srpc/message.hpp +17 -12
  114. package/srpc/msg-stream.go +1 -0
  115. package/srpc/msg-stream.hpp +108 -61
  116. package/srpc/mux.cpp +84 -84
  117. package/srpc/mux.hpp +48 -38
  118. package/srpc/mux.rs +4 -4
  119. package/srpc/net.go +12 -3
  120. package/srpc/packet-codec-vectors_test.go +195 -0
  121. package/srpc/packet-codec.test.ts +139 -0
  122. package/srpc/packet-rw.go +9 -2
  123. package/srpc/packet.cpp +60 -58
  124. package/srpc/packet.hpp +35 -20
  125. package/srpc/packet.rs +8 -27
  126. package/srpc/packet.ts +15 -2
  127. package/srpc/py.typed +0 -0
  128. package/srpc/rpc.rs +332 -115
  129. package/srpc/rpc_lifecycle_test.cc +333 -0
  130. package/srpc/rpcproto_pb2.py +40 -0
  131. package/srpc/rpcproto_pb2.pyi +40 -0
  132. package/srpc/server-cancel_test.go +39 -0
  133. package/srpc/server-rpc.cpp +83 -73
  134. package/srpc/server-rpc.go +21 -19
  135. package/srpc/server-rpc.hpp +56 -37
  136. package/srpc/server.rs +76 -131
  137. package/srpc/server.test.ts +50 -0
  138. package/srpc/server.ts +22 -6
  139. package/srpc/starpc.hpp +4 -2
  140. package/srpc/stream.go +4 -0
  141. package/srpc/stream.hpp +95 -34
  142. package/srpc/stream.rs +7 -2
  143. package/srpc/stream.test.ts +132 -1
  144. package/srpc/stream.ts +65 -9
  145. package/srpc/termination.test.ts +30 -0
  146. package/srpc/termination.ts +70 -0
  147. package/srpc/testing.rs +11 -66
  148. package/srpc/transport.rs +21 -71
  149. package/srpc/websocket.rs +106 -57
  150. package/srpc/writer.hpp +46 -32
  151. package/srpc/yamux.rs +82 -26
  152. package/srpc/tests/integration_test.rs +0 -495
package/srpc/packet.rs CHANGED
@@ -10,10 +10,8 @@ use bytes::Bytes;
10
10
 
11
11
  /// Creates a new CallStart packet.
12
12
  ///
13
- /// # Arguments
14
- /// * `service` - The service ID
15
- /// * `method` - The method ID
16
- /// * `data` - Optional initial data (None = no data, Some(empty) = empty data)
13
+ /// `None` data sends no payload; `Some(empty)` sends empty data with the
14
+ /// `data_is_zero` flag set.
17
15
  pub fn new_call_start(
18
16
  service: impl Into<String>,
19
17
  method: impl Into<String>,
@@ -31,10 +29,7 @@ pub fn new_call_start(
31
29
  }
32
30
  }
33
31
 
34
- /// Creates a new CallData packet with data.
35
- ///
36
- /// # Arguments
37
- /// * `data` - The data to send (can be empty)
32
+ /// Creates a new CallData packet carrying `data`, which may be empty.
38
33
  pub fn new_call_data(data: Vec<u8>) -> Packet {
39
34
  let data_is_zero = data.is_empty();
40
35
  Packet {
@@ -49,16 +44,9 @@ pub fn new_call_data(data: Vec<u8>) -> Packet {
49
44
 
50
45
  /// Creates a new CallData packet with optional data and flags.
51
46
  ///
52
- /// # Arguments
53
- /// * `data` - Optional data bytes
54
- /// * `data_is_zero` - True if empty data should be sent
55
- /// * `complete` - True if this completes the stream
56
- /// * `error` - Optional error message
57
- pub fn new_call_data_full(
58
- data: Option<Bytes>,
59
- complete: bool,
60
- error: Option<String>,
61
- ) -> Packet {
47
+ /// Sets `complete` when either `complete` or `error` is set, so an error
48
+ /// always ends the call.
49
+ pub fn new_call_data_full(data: Option<Bytes>, complete: bool, error: Option<String>) -> Packet {
62
50
  let (data_bytes, data_is_zero) = encode_optional_data(data);
63
51
 
64
52
  Packet {
@@ -83,10 +71,7 @@ pub fn new_call_complete() -> Packet {
83
71
  }
84
72
  }
85
73
 
86
- /// Creates a new CallData packet with an error.
87
- ///
88
- /// # Arguments
89
- /// * `error` - The error message
74
+ /// Creates a new CallData packet carrying an error message.
90
75
  pub fn new_call_error(error: impl Into<String>) -> Packet {
91
76
  Packet {
92
77
  body: Some(Body::CallData(CallData {
@@ -154,11 +139,7 @@ impl Validate for CallData {
154
139
  // - data_is_zero flag set (indicating intentionally empty data)
155
140
  // - complete flag set
156
141
  // - error message
157
- if self.data.is_empty()
158
- && !self.data_is_zero
159
- && !self.complete
160
- && self.error.is_empty()
161
- {
142
+ if self.data.is_empty() && !self.data_is_zero && !self.complete && self.error.is_empty() {
162
143
  return Err(Error::EmptyPacket);
163
144
  }
164
145
  Ok(())
package/srpc/packet.ts CHANGED
@@ -7,6 +7,8 @@ import {
7
7
  buildEncodeMessageTransform,
8
8
  } from './message.js'
9
9
 
10
+ const MAX_MESSAGE_SIZE = 10_000_000
11
+
10
12
  // decodePacketSource decodes packets from a binary data stream.
11
13
  export const decodePacketSource = buildDecodeMessageTransform<Packet>(Packet)
12
14
 
@@ -39,6 +41,9 @@ export async function* lengthPrefixEncode(
39
41
  for await (const chunk of source) {
40
42
  // Encode the length of the chunk.
41
43
  const length = chunk instanceof Uint8Array ? chunk.length : chunk.byteLength
44
+ if (length === 0 || length > MAX_MESSAGE_SIZE) {
45
+ throw RangeError(`invalid packet length: ${length}`)
46
+ }
42
47
  const lengthEncoded = lengthEncoder(length)
43
48
 
44
49
  // Concatenate the length prefix and the data.
@@ -50,7 +55,7 @@ export async function* lengthPrefixEncode(
50
55
  export async function* lengthPrefixDecode(
51
56
  source: Source<Uint8Array | Uint8ArrayList>,
52
57
  lengthDecoder: typeof uint32LEDecode,
53
- ) {
58
+ ): AsyncGenerator<Uint8ArrayList> {
54
59
  const buffer = new Uint8ArrayList()
55
60
 
56
61
  for await (const chunk of source) {
@@ -59,18 +64,26 @@ export async function* lengthPrefixDecode(
59
64
  // Continue extracting messages while buffer contains enough data for decoding.
60
65
  while (buffer.length >= lengthDecoder.bytes) {
61
66
  const messageLength = lengthDecoder(buffer)
67
+ if (messageLength === 0 || messageLength > MAX_MESSAGE_SIZE) {
68
+ throw RangeError(`invalid packet length: ${messageLength}`)
69
+ }
62
70
  const totalLength = lengthDecoder.bytes + messageLength
63
71
 
64
72
  if (buffer.length < totalLength) break // Wait for more data if the full message hasn't arrived.
65
73
 
66
74
  // Extract the message excluding the length prefix.
67
- const message = buffer.sublist(lengthDecoder.bytes, totalLength)
75
+ const message = new Uint8ArrayList(
76
+ buffer.slice(lengthDecoder.bytes, totalLength),
77
+ )
68
78
  yield message
69
79
 
70
80
  // Remove the processed message from the buffer.
71
81
  buffer.consume(totalLength)
72
82
  }
73
83
  }
84
+ if (buffer.length !== 0) {
85
+ throw new RangeError('truncated packet frame')
86
+ }
74
87
  }
75
88
 
76
89
  // prependLengthPrefixTransform adds a length prefix to a message source.
package/srpc/py.typed ADDED
File without changes