starpc 0.50.0 → 0.52.0

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 (100) hide show
  1. package/cmd/protoc-gen-es-starpc/typescript.ts +37 -0
  2. package/dist/cmd/protoc-gen-es-starpc/typescript.js +24 -0
  3. package/dist/echo/echo_srpc.pb.d.ts +44 -1
  4. package/dist/echo/server.d.ts +9 -8
  5. package/dist/echo/server.js +6 -6
  6. package/dist/integration/cross-language/ts-client.js +5 -79
  7. package/dist/integration/cross-language/ts-server.js +4 -100
  8. package/dist/mock/mock_srpc.pb.d.ts +14 -1
  9. package/dist/srpc/channel.js +6 -3
  10. package/dist/srpc/channel.test.js +20 -1
  11. package/dist/srpc/client.d.ts +1 -3
  12. package/dist/srpc/client.js +2 -22
  13. package/dist/srpc/common-rpc.d.ts +1 -9
  14. package/dist/srpc/common-rpc.js +4 -62
  15. package/dist/srpc/handler.d.ts +12 -4
  16. package/dist/srpc/index.d.ts +2 -4
  17. package/dist/srpc/index.js +1 -3
  18. package/dist/srpc/invoker.d.ts +2 -2
  19. package/dist/srpc/invoker.js +2 -2
  20. package/dist/srpc/rpcproto.pb.d.ts +0 -44
  21. package/dist/srpc/rpcproto.pb.js +0 -53
  22. package/dist/srpc/server-context.d.ts +11 -0
  23. package/dist/srpc/server-context.js +28 -0
  24. package/dist/srpc/server-rpc.js +3 -3
  25. package/dist/srpc/server.test.js +65 -2
  26. package/dist/srpc/watchdog.test.js +1 -0
  27. package/echo/echo.go +8 -8
  28. package/echo/echo.pb.go +12 -36
  29. package/echo/echo_srpc.pb.cpp +1 -1
  30. package/echo/echo_srpc.pb.go +1 -1
  31. package/echo/echo_srpc.pb.hpp +1 -1
  32. package/echo/echo_srpc.pb.rs +1 -1
  33. package/echo/echo_srpc.pb.ts +74 -0
  34. package/echo/server.go +1 -1
  35. package/echo/server.ts +24 -5
  36. package/go.mod +1 -1
  37. package/go.sum +2 -0
  38. package/integration/cross-language/go-client/main.go +4 -142
  39. package/integration/cross-language/go-server/main.go +2 -170
  40. package/integration/cross-language/run.bash +5 -105
  41. package/integration/cross-language/ts-client.ts +5 -90
  42. package/integration/cross-language/ts-server.ts +4 -112
  43. package/mock/mock.go +1 -1
  44. package/mock/mock.pb.go +12 -36
  45. package/mock/mock_srpc.pb.cpp +1 -1
  46. package/mock/mock_srpc.pb.go +1 -1
  47. package/mock/mock_srpc.pb.hpp +1 -1
  48. package/mock/mock_srpc.pb.rs +1 -1
  49. package/mock/mock_srpc.pb.ts +19 -1
  50. package/package.json +2 -2
  51. package/srpc/channel.test.ts +21 -1
  52. package/srpc/channel.ts +7 -3
  53. package/srpc/client-prefix.go +1 -1
  54. package/srpc/client-set.go +1 -1
  55. package/srpc/client.go +1 -1
  56. package/srpc/client.ts +4 -31
  57. package/srpc/common-rpc.go +15 -69
  58. package/srpc/common-rpc.ts +4 -77
  59. package/srpc/common-rpc_test.go +81 -0
  60. package/srpc/errors.go +26 -1
  61. package/srpc/handler.ts +54 -5
  62. package/srpc/index.ts +7 -4
  63. package/srpc/invoker-prefix.go +1 -1
  64. package/srpc/invoker.go +2 -2
  65. package/srpc/invoker.ts +20 -7
  66. package/srpc/message.go +1 -1
  67. package/srpc/msg-stream.go +1 -9
  68. package/srpc/mux-verbose.go +1 -1
  69. package/srpc/mux.go +1 -1
  70. package/srpc/rpcproto.pb.cc +4 -15
  71. package/srpc/rpcproto.pb.go +102 -419
  72. package/srpc/rpcproto.pb.h +0 -59
  73. package/srpc/rpcproto.pb.rs +0 -45
  74. package/srpc/rpcproto.pb.ts +0 -62
  75. package/srpc/rpcproto.proto +0 -16
  76. package/srpc/server-context.ts +55 -0
  77. package/srpc/server-rpc.go +1 -1
  78. package/srpc/server-rpc.ts +4 -6
  79. package/srpc/server.test.ts +94 -1
  80. package/srpc/stream-pipe.go +1 -1
  81. package/srpc/stream-rwc.go +1 -1
  82. package/srpc/stream.go +0 -20
  83. package/srpc/watchdog.test.ts +1 -0
  84. package/dist/rpcstream/receipt.test.d.ts +0 -1
  85. package/dist/rpcstream/receipt.test.js +0 -41
  86. package/dist/srpc/call-receipt.d.ts +0 -17
  87. package/dist/srpc/call-receipt.js +0 -106
  88. package/dist/srpc/call-receipt.test.d.ts +0 -1
  89. package/dist/srpc/call-receipt.test.js +0 -375
  90. package/dist/srpc/server-invocation.d.ts +0 -17
  91. package/dist/srpc/server-invocation.js +0 -37
  92. package/integration/cross-language/go-server/fixture-owner_test.go +0 -127
  93. package/srpc/call-receipt-e2e_test.go +0 -111
  94. package/srpc/call-receipt.go +0 -112
  95. package/srpc/call-receipt.test.ts +0 -441
  96. package/srpc/call-receipt.ts +0 -131
  97. package/srpc/call-receipt_test.go +0 -536
  98. package/srpc/schema-ownership_test.go +0 -115
  99. package/srpc/server-invocation.go +0 -40
  100. package/srpc/server-invocation.ts +0 -76
@@ -111,27 +111,6 @@ stop_server() {
111
111
 
112
112
  # run_pair <test_name> <server_args...> -- <client_args...>
113
113
  # The client receives $SERVER_ADDR as its last argument.
114
- # check_receipt_events verifies terminal markers after the receipt server
115
- # naturally completes, so receipt synchronization is event/process-backed.
116
- check_receipt_events() {
117
- local expected="$1"
118
- local event_log="$2"
119
- awk -v expected="$expected" '
120
- $0 == "SERVER_RECEIPT_TERMINAL " expected { terminal = NR; next }
121
- $0 == "SERVER_RECEIPT_ACK_WRITE " expected { ack_write = NR; next }
122
- $0 == "CLIENT_RECEIPT_RESOLVED " expected { client = NR; next }
123
- END {
124
- if (!terminal || !client) {
125
- exit 1
126
- }
127
- if (expected == "committed" &&
128
- (!ack_write || terminal >= ack_write || ack_write >= client)) {
129
- exit 1
130
- }
131
- }
132
- ' "$event_log"
133
- }
134
-
135
114
  run_pair() {
136
115
  local test_name="$1"
137
116
  shift
@@ -140,7 +119,6 @@ run_pair() {
140
119
  return
141
120
  fi
142
121
 
143
- # Split args on "--".
144
122
  local srv_args=()
145
123
  local cli_args=()
146
124
  local in_client=false
@@ -156,103 +134,33 @@ run_pair() {
156
134
  fi
157
135
  done
158
136
 
159
- local expected_terminal=""
160
- case "$test_name" in
161
- *"receipt commit") expected_terminal="committed" ;;
162
- *"receipt abort") expected_terminal="canceled" ;;
163
- *"receipt loss") expected_terminal="transportLost" ;;
164
- *"receipt bare-close") expected_terminal="closed" ;;
165
- esac
166
-
167
137
  echo -n " ${test_name}... "
168
-
169
- local event_fifo=""
170
- local event_log=""
171
- local event_reader=""
172
- if [ -n "$expected_terminal" ]; then
173
- event_fifo=$(mktemp)
174
- rm -f "$event_fifo"
175
- mkfifo "$event_fifo"
176
- event_log=$(mktemp)
177
- exec 3<>"$event_fifo"
178
- (
179
- exec 3>&-
180
- cat "$event_fifo" > "$event_log"
181
- ) &
182
- event_reader=$!
183
- export RECEIPT_EVENT_FIFO="$event_fifo"
184
- else
185
- unset RECEIPT_EVENT_FIFO
186
- fi
187
-
188
138
  if ! start_server "${srv_args[@]}"; then
189
139
  echo "FAILED (server start)"
190
140
  FAILED=$((FAILED + 1))
191
141
  ERRORS="${ERRORS}\n ${test_name} (server start failed)"
192
- if [ -n "$event_reader" ]; then
193
- exec 3>&-
194
- kill "$event_reader" 2>/dev/null || true
195
- wait "$event_reader" 2>/dev/null || true
196
- rm -f "$event_fifo" "$event_log"
197
- fi
198
- unset RECEIPT_EVENT_FIFO
199
142
  return
200
143
  fi
201
144
 
202
145
  local client_out
203
146
  client_out=$(mktemp)
204
147
  local client_ok=false
205
- local server_ok=true
206
148
  if "${cli_args[@]}" "$SERVER_ADDR" > "$client_out" 2>&1; then
207
149
  client_ok=true
208
150
  fi
151
+ stop_server
209
152
 
210
- if [ -n "$event_reader" ]; then
211
- if $client_ok; then
212
- if ! wait "$SERVER_PID"; then
213
- server_ok=false
214
- fi
215
- else
216
- stop_server
217
- wait "$SERVER_PID" 2>/dev/null || true
218
- server_ok=false
219
- fi
220
- exec 3>&-
221
- wait "$event_reader" 2>/dev/null || true
222
- else
223
- stop_server
224
- fi
225
- unset RECEIPT_EVENT_FIFO
226
-
227
- local terminal_ok=true
228
- if [ -n "$expected_terminal" ] &&
229
- ! check_receipt_events "$expected_terminal" "$event_log"; then
230
- terminal_ok=false
231
- fi
232
-
233
- if $client_ok && $server_ok && $terminal_ok; then
153
+ if $client_ok; then
234
154
  echo "PASSED"
235
- if [ -n "$expected_terminal" ]; then
236
- echo " receipt events:"
237
- sed 's/^/ /' "$event_log"
238
- fi
239
155
  PASSED=$((PASSED + 1))
240
156
  else
241
157
  echo "FAILED"
242
158
  FAILED=$((FAILED + 1))
243
159
  ERRORS="${ERRORS}\n ${test_name}"
244
- if ! $client_ok; then
245
- echo " client output:"
246
- sed 's/^/ /' "$client_out"
247
- fi
248
- if ! $terminal_ok; then
249
- echo " receipt events:"
250
- sed 's/^/ /' "$event_log"
251
- echo " server output:"
252
- sed 's/^/ /' "$SERVER_LOG"
253
- fi
160
+ echo " client output:"
161
+ sed 's/^/ /' "$client_out"
254
162
  fi
255
- rm -f "$client_out" "$SERVER_LOG" "$event_fifo" "$event_log"
163
+ rm -f "$client_out" "$SERVER_LOG"
256
164
  SERVER_LOG=""
257
165
  }
258
166
 
@@ -264,10 +172,6 @@ echo ""
264
172
  run_pair "go-server + go-client" "$GO_SERVER" -- "$GO_CLIENT"
265
173
  run_pair "go-server + rust-client" "$GO_SERVER" -- "$RUST_CLIENT"
266
174
  run_pair "go-server + ts-client" "$GO_SERVER" -- node "$TS_CLIENT"
267
- run_pair "go-server + ts-client receipt commit" "$GO_SERVER" receipt commit -- node "$TS_CLIENT" receipt commit
268
- run_pair "go-server + ts-client receipt abort" "$GO_SERVER" receipt abort -- node "$TS_CLIENT" receipt abort
269
- run_pair "go-server + ts-client receipt loss" "$GO_SERVER" receipt loss -- node "$TS_CLIENT" receipt loss
270
- run_pair "go-server + ts-client receipt bare-close" "$GO_SERVER" receipt bare-close -- node "$TS_CLIENT" receipt bare-close
271
175
  run_pair "go-server + cpp-client" "$GO_SERVER" -- "$CPP_CLIENT"
272
176
 
273
177
  # Rust server combinations
@@ -278,10 +182,6 @@ run_pair "rust-server + cpp-client" "$RUST_SERVER" -- "$CPP_CLIENT"
278
182
 
279
183
  # TypeScript server combinations
280
184
  run_pair "ts-server + go-client" node "$TS_SERVER" -- "$GO_CLIENT"
281
- run_pair "ts-server + go-client receipt commit" node "$TS_SERVER" receipt commit -- "$GO_CLIENT" receipt commit
282
- run_pair "ts-server + go-client receipt abort" node "$TS_SERVER" receipt abort -- "$GO_CLIENT" receipt abort
283
- run_pair "ts-server + go-client receipt loss" node "$TS_SERVER" receipt loss -- "$GO_CLIENT" receipt loss
284
- run_pair "ts-server + go-client receipt bare-close" node "$TS_SERVER" receipt bare-close -- "$GO_CLIENT" receipt bare-close
285
185
  run_pair "ts-server + rust-client" node "$TS_SERVER" -- "$RUST_CLIENT"
286
186
  run_pair "ts-server + ts-client" node "$TS_SERVER" -- node "$TS_CLIENT"
287
187
  run_pair "ts-server + cpp-client" node "$TS_SERVER" -- "$CPP_CLIENT"
@@ -1,5 +1,4 @@
1
1
  import net from 'net'
2
- import { closeSync, openSync, writeSync } from 'node:fs'
3
2
  import { pipe } from 'it-pipe'
4
3
  import { pushable } from 'it-pushable'
5
4
  import { Client } from '../../srpc/client.js'
@@ -8,22 +7,9 @@ import {
8
7
  prependLengthPrefixTransform,
9
8
  } from '../../srpc/packet.js'
10
9
  import { combineUint8ArrayListTransform } from '../../srpc/array-list.js'
11
- import { EchoMsg, runClientTest } from '../../echo/index.js'
10
+ import { runClientTest } from '../../echo/index.js'
12
11
  import type { OpenStreamFunc, PacketStream } from '../../srpc/stream.js'
13
12
  import type { Source } from 'it-stream-types'
14
- function emitReceiptEvent(line: string): void {
15
- console.log(line)
16
- const fifo = process.env.RECEIPT_EVENT_FIFO
17
- if (!fifo) {
18
- return
19
- }
20
- const fd = openSync(fifo, 'w')
21
- try {
22
- writeSync(fd, `${line}\n`)
23
- } finally {
24
- closeSync(fd)
25
- }
26
- }
27
13
 
28
14
  // tcpSocketToPacketStream wraps a Node.js TCP socket into a PacketStream.
29
15
  function tcpSocketToPacketStream(socket: net.Socket): PacketStream {
@@ -60,28 +46,17 @@ function tcpSocketToPacketStream(socket: net.Socket): PacketStream {
60
46
  }
61
47
 
62
48
  async function main() {
63
- const receiptMode = process.argv[2] === 'receipt'
64
- const receiptCase = receiptMode ? process.argv[3] : undefined
65
- const addr = receiptMode ? process.argv[4] : process.argv[2]
49
+ const addr = process.argv[2]
66
50
  if (!addr) {
67
- console.error('usage: ts-client [receipt <case>] <host:port>')
51
+ console.error('usage: ts-client <host:port>')
68
52
  process.exit(1)
69
53
  }
70
- if (
71
- receiptMode &&
72
- !['commit', 'abort', 'loss', 'bare-close'].includes(receiptCase ?? '')
73
- ) {
74
- throw new Error(`unknown receipt case: ${receiptCase}`)
75
- }
76
54
 
77
55
  const [host, portStr] = addr.split(':')
78
56
  const port = parseInt(portStr, 10)
79
- let activeSocket: net.Socket | undefined
80
-
81
57
  const openStream: OpenStreamFunc = async (): Promise<PacketStream> => {
82
58
  const { promise, resolve, reject } = Promise.withResolvers<PacketStream>()
83
59
  const socket = net.connect(port, host, () => {
84
- activeSocket = socket
85
60
  resolve(tcpSocketToPacketStream(socket))
86
61
  })
87
62
  socket.on('error', reject)
@@ -89,71 +64,11 @@ async function main() {
89
64
  }
90
65
 
91
66
  const client = new Client(openStream)
92
-
93
- if (receiptMode) {
94
- console.log(`Running held receipt test via TCP (${receiptCase})...`)
95
- const request = EchoMsg.create({ body: 'held receipt' })
96
- const held = await client.requestWithReceipt(
97
- 'echo.Echoer',
98
- 'Echo',
99
- EchoMsg.toBinary(request),
100
- )
101
- const result = EchoMsg.fromBinary(held.response)
102
- if (result.body !== request.body) {
103
- throw new Error(`expected ${request.body}, got ${result.body}`)
104
- }
105
- switch (receiptCase) {
106
- case 'commit':
107
- await held.receipt.commit()
108
- break
109
- case 'abort':
110
- await held.receipt.abort()
111
- break
112
- case 'loss':
113
- activeSocket?.resetAndDestroy()
114
- await expectReceiptFailure(held.receipt)
115
- break
116
- case 'bare-close':
117
- activeSocket?.end()
118
- await expectReceiptFailure(held.receipt)
119
- break
120
- }
121
- emitReceiptEvent(
122
- `CLIENT_RECEIPT_RESOLVED ${receiptTerminalName(receiptCase ?? '')}`,
123
- )
124
- } else {
125
- console.log('Running client test via TCP...')
126
- await runClientTest(client)
127
- }
67
+ console.log('Running client test via TCP...')
68
+ await runClientTest(client)
128
69
  console.log('All tests passed.')
129
70
  }
130
71
 
131
- function receiptTerminalName(receiptCase: string): string {
132
- switch (receiptCase) {
133
- case 'commit':
134
- return 'committed'
135
- case 'abort':
136
- return 'canceled'
137
- case 'loss':
138
- return 'transportLost'
139
- case 'bare-close':
140
- return 'closed'
141
- default:
142
- return 'unknown'
143
- }
144
- }
145
-
146
- async function expectReceiptFailure(receipt: {
147
- commit(): Promise<void>
148
- }): Promise<void> {
149
- try {
150
- await receipt.commit()
151
- } catch {
152
- return
153
- }
154
- throw new Error('receipt commit unexpectedly succeeded')
155
- }
156
-
157
72
  process.on('unhandledRejection', (ev) => {
158
73
  console.error('Unhandled rejection', ev)
159
74
  process.exit(1)
@@ -1,5 +1,4 @@
1
1
  import net from 'net'
2
- import { closeSync, openSync, writeSync } from 'node:fs'
3
2
  import { pipe } from 'it-pipe'
4
3
  import { pushable } from 'it-pushable'
5
4
  import type { Source } from 'it-stream-types'
@@ -10,25 +9,10 @@ import {
10
9
  prependLengthPrefixTransform,
11
10
  } from '../../srpc/packet.js'
12
11
  import { combineUint8ArrayListTransform } from '../../srpc/array-list.js'
13
- import { EchoerServer, EchoMsg } from '../../echo/index.js'
12
+ import { EchoerServer } from '../../echo/index.js'
14
13
  import { EchoerDefinition } from '../../echo/echo_srpc.pb.js'
15
- import { Packet, TerminalKind } from '../../srpc/rpcproto.pb.js'
16
14
  import type { PacketStream } from '../../srpc/stream.js'
17
15
 
18
- function emitReceiptEvent(line: string): void {
19
- console.log(line)
20
- const fifo = process.env.RECEIPT_EVENT_FIFO
21
- if (!fifo) {
22
- return
23
- }
24
- const fd = openSync(fifo, 'w')
25
- try {
26
- writeSync(fd, `${line}\n`)
27
- } finally {
28
- closeSync(fd)
29
- }
30
- }
31
-
32
16
  // tcpSocketToPacketStream wraps a Node.js TCP socket into a PacketStream.
33
17
  // Each Uint8Array in source/sink is one packet (no length prefix).
34
18
  function tcpSocketToPacketStream(socket: net.Socket): PacketStream {
@@ -53,25 +37,12 @@ function tcpSocketToPacketStream(socket: net.Socket): PacketStream {
53
37
  sink: async (source: Source<Uint8Array>): Promise<void> => {
54
38
  for await (const chunk of pipe(source, prependLengthPrefixTransform())) {
55
39
  const data = chunk instanceof Uint8Array ? chunk : chunk.subarray()
56
- const packet = Packet.fromBinary(data.subarray(4))
57
- const receiptCompletion =
58
- receiptMode &&
59
- packet.body?.case === 'callData' &&
60
- packet.body.value.complete &&
61
- !packet.body.value.error
62
- if (receiptCompletion) {
63
- emitReceiptEvent('SERVER_RECEIPT_ACK_WRITE committed')
64
- }
65
- const writeDone = new Promise<void>((resolve, reject) => {
40
+ await new Promise<void>((resolve, reject) => {
66
41
  socket.write(data, (err) => {
67
42
  if (err) reject(err)
68
43
  else resolve()
69
44
  })
70
45
  })
71
- await writeDone
72
- if (receiptCompletion) {
73
- finishReceiptServer()
74
- }
75
46
  }
76
47
  socket.end()
77
48
  },
@@ -79,82 +50,9 @@ function tcpSocketToPacketStream(socket: net.Socket): PacketStream {
79
50
  }
80
51
 
81
52
  const mux = createMux()
82
- const receiptMode = process.argv[2] === 'receipt'
83
- const receiptCase = receiptMode ? process.argv[3] : undefined
84
- if (
85
- receiptMode &&
86
- !['commit', 'abort', 'loss', 'bare-close'].includes(receiptCase ?? '')
87
- ) {
88
- console.error(`unknown receipt case: ${receiptCase}`)
89
- process.exit(1)
90
- }
91
-
92
- const receiptServerDone = Promise.withResolvers<void>()
93
- let receiptServerFinished = false
94
- function finishReceiptServer(): void {
95
- if (!receiptServerFinished) {
96
- receiptServerFinished = true
97
- receiptServerDone.resolve()
98
- }
99
- }
100
-
101
- if (receiptMode) {
102
- mux.registerLookupMethod(async (serviceID, methodID) => {
103
- if (serviceID !== 'echo.Echoer' || methodID !== 'Echo') {
104
- return null
105
- }
106
- return async (dataSource, dataSink, invocation) => {
107
- let requestData: Uint8Array | undefined
108
- for await (const data of dataSource) {
109
- requestData = data
110
- break
111
- }
112
- if (!requestData) {
113
- throw new Error('receipt request was empty')
114
- }
115
- const requestMsg = EchoMsg.fromBinary(requestData)
116
- await dataSink(
117
- (async function* () {
118
- yield EchoMsg.toBinary(requestMsg)
119
- if (!invocation) {
120
- throw new Error('receipt invocation was missing')
121
- }
122
- emitReceiptEvent('SERVER_RECEIPT_WAITING')
123
- const terminal = await invocation.waitTerminal(
124
- new AbortController().signal,
125
- )
126
- emitReceiptEvent(`SERVER_RECEIPT_TERMINAL ${terminalName(terminal)}`)
127
- if (terminal !== TerminalKind.COMMITTED) {
128
- finishReceiptServer()
129
- }
130
- })(),
131
- )
132
- }
133
- })
134
- }
135
-
136
- function terminalName(terminal: TerminalKind): string {
137
- switch (terminal) {
138
- case TerminalKind.COMMITTED:
139
- return 'committed'
140
- case TerminalKind.CANCELED:
141
- return 'canceled'
142
- case TerminalKind.TRANSPORT_LOST:
143
- return 'transportLost'
144
- case TerminalKind.CLOSED:
145
- return 'closed'
146
- case TerminalKind.ABANDONED:
147
- return 'abandoned'
148
- default:
149
- return 'unknown'
150
- }
151
- }
152
-
153
53
  const server = new Server(mux.lookupMethod)
154
- if (!receiptMode) {
155
- const echoer = new EchoerServer(server)
156
- mux.register(createHandler(EchoerDefinition, echoer))
157
- }
54
+ const echoer = new EchoerServer(server)
55
+ mux.register(createHandler(EchoerDefinition, echoer))
158
56
 
159
57
  const tcpServer = net.createServer((socket) => {
160
58
  const stream = tcpSocketToPacketStream(socket)
@@ -166,12 +64,6 @@ tcpServer.listen(0, '127.0.0.1', () => {
166
64
  console.log(`LISTENING ${addr.address}:${addr.port}`)
167
65
  })
168
66
 
169
- if (receiptMode) {
170
- void receiptServerDone.promise.then(() => {
171
- tcpServer.close()
172
- })
173
- }
174
-
175
67
  process.on('SIGINT', () => {
176
68
  tcpServer.close()
177
69
  process.exit(0)
package/mock/mock.go CHANGED
@@ -26,4 +26,4 @@ func (e *MockServer) MockRequest(ctx context.Context, msg *MockMsg) (*MockMsg, e
26
26
  }
27
27
 
28
28
  // _ is a type assertion
29
- var _ SRPCMockServer = ((*MockServer)(nil))
29
+ var _ SRPCMockServer = (*MockServer)(nil)
package/mock/mock.pb.go CHANGED
@@ -1,5 +1,5 @@
1
1
  // Code generated by protoc-gen-go-lite. DO NOT EDIT.
2
- // protoc-gen-go-lite version: v0.13.0
2
+ // protoc-gen-go-lite version: v0.16.0
3
3
  // source: github.com/aperturerobotics/starpc/mock/mock.proto
4
4
 
5
5
  package e2e_mock
@@ -8,8 +8,6 @@ import (
8
8
  fmt "fmt"
9
9
  io "io"
10
10
  slices "slices"
11
- strconv "strconv"
12
- strings "strings"
13
11
 
14
12
  protobuf_go_lite "github.com/aperturerobotics/protobuf-go-lite"
15
13
  json "github.com/aperturerobotics/protobuf-go-lite/json"
@@ -139,13 +137,10 @@ func (m *MockMsg) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
139
137
  var l int
140
138
  _ = l
141
139
  if m.unknownFields != nil {
142
- i -= len(m.unknownFields)
143
- copy(dAtA[i:], m.unknownFields)
140
+ i = protobuf_go_lite.EncodeRawBytes(dAtA, i, m.unknownFields)
144
141
  }
145
142
  if len(m.Body) > 0 {
146
- i -= len(m.Body)
147
- copy(dAtA[i:], m.Body)
148
- i = protobuf_go_lite.EncodeVarint(dAtA, i, uint64(len(m.Body)))
143
+ i = protobuf_go_lite.EncodeString(dAtA, i, m.Body)
149
144
  i--
150
145
  dAtA[i] = 0xa
151
146
  }
@@ -158,26 +153,19 @@ func (m *MockMsg) SizeVT() (n int) {
158
153
  }
159
154
  var l int
160
155
  _ = l
161
- l = len(m.Body)
162
- if l > 0 {
163
- n += 1 + l + protobuf_go_lite.SizeOfVarint(uint64(l))
164
- }
156
+ n += protobuf_go_lite.SizeStringNonEmpty(1, m.Body)
165
157
  n += len(m.unknownFields)
166
158
  return n
167
159
  }
168
160
 
169
161
  func (x *MockMsg) MarshalProtoText() string {
170
- var sb strings.Builder
171
- sb.WriteString("MockMsg {")
162
+ var sb protobuf_go_lite.TextBuilder
163
+ initialLen := protobuf_go_lite.TextStartMessage(&sb, "MockMsg")
172
164
  if x.Body != "" {
173
- if sb.Len() > 9 {
174
- sb.WriteString(" ")
175
- }
176
- sb.WriteString("body: ")
177
- sb.WriteString(strconv.Quote(x.Body))
165
+ protobuf_go_lite.TextWriteFieldPrefix(&sb, initialLen, "body")
166
+ protobuf_go_lite.TextWriteString(&sb, x.Body)
178
167
  }
179
- sb.WriteString("}")
180
- return sb.String()
168
+ return protobuf_go_lite.TextFinishMessage(&sb)
181
169
  }
182
170
 
183
171
  func (x *MockMsg) String() string {
@@ -208,24 +196,12 @@ func (m *MockMsg) UnmarshalVT(dAtA []byte) error {
208
196
  if wireType != 2 {
209
197
  return fmt.Errorf("proto: wrong wireType = %d for field Body", wireType)
210
198
  }
211
- var stringLen uint64
212
- stringLen, iNdEx, err = protobuf_go_lite.DecodeVarint(dAtA, iNdEx)
199
+ var v string
200
+ v, iNdEx, err = protobuf_go_lite.DecodeString(dAtA, iNdEx)
213
201
  if err != nil {
214
202
  return err
215
203
  }
216
- intStringLen := int(stringLen)
217
- if intStringLen < 0 {
218
- return protobuf_go_lite.ErrInvalidLength
219
- }
220
- postIndex := iNdEx + intStringLen
221
- if postIndex < 0 {
222
- return protobuf_go_lite.ErrInvalidLength
223
- }
224
- if postIndex > l {
225
- return io.ErrUnexpectedEOF
226
- }
227
- m.Body = string(dAtA[iNdEx:postIndex])
228
- iNdEx = postIndex
204
+ m.Body = v
229
205
  default:
230
206
  iNdEx = preIndex
231
207
  skippy, err := protobuf_go_lite.Skip(dAtA[iNdEx:])
@@ -1,7 +1,7 @@
1
1
  //go:build deps_only
2
2
 
3
3
  // Code generated by protoc-gen-starpc-cpp. DO NOT EDIT.
4
- // protoc-gen-starpc-cpp version: v0.49.7
4
+ // protoc-gen-starpc-cpp version: v0.49.21
5
5
  // source: github.com/aperturerobotics/starpc/mock/mock.proto
6
6
 
7
7
  #include "mock_srpc.pb.hpp"
@@ -1,5 +1,5 @@
1
1
  // Code generated by protoc-gen-srpc. DO NOT EDIT.
2
- // protoc-gen-srpc version: v0.49.7
2
+ // protoc-gen-srpc version: v0.49.21
3
3
  // source: github.com/aperturerobotics/starpc/mock/mock.proto
4
4
 
5
5
  package e2e_mock
@@ -1,7 +1,7 @@
1
1
  //go:build deps_only && cgo
2
2
 
3
3
  // Code generated by protoc-gen-starpc-cpp. DO NOT EDIT.
4
- // protoc-gen-starpc-cpp version: v0.49.7
4
+ // protoc-gen-starpc-cpp version: v0.49.21
5
5
  // source: github.com/aperturerobotics/starpc/mock/mock.proto
6
6
 
7
7
  #pragma once
@@ -1,5 +1,5 @@
1
1
  // Code generated by protoc-gen-starpc-rust. DO NOT EDIT.
2
- // protoc-gen-starpc-rust version: v0.49.7
2
+ // protoc-gen-starpc-rust version: v0.49.21
3
3
  // source: github.com/aperturerobotics/starpc/mock/mock.proto
4
4
 
5
5
  #[allow(unused_imports)]
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { MockMsg } from './mock.pb.js'
6
6
  import { MethodKind } from '@aptre/protobuf-es-lite'
7
- import { ProtoRpc } from 'starpc'
7
+ import { ProtoRpc, ServerContext } from 'starpc'
8
8
 
9
9
  /**
10
10
  * Mock service mocks some RPCs for the e2e tests.
@@ -42,6 +42,24 @@ export interface Mock {
42
42
  MockRequest(request: MockMsg, abortSignal?: AbortSignal): Promise<MockMsg>
43
43
  }
44
44
 
45
+ /**
46
+ * Mock service mocks some RPCs for the e2e tests.
47
+ *
48
+ * @generated from service e2e.mock.Mock
49
+ */
50
+ export interface MockHandler {
51
+ /**
52
+ * MockRequest runs a mock unary request.
53
+ *
54
+ * @generated from rpc e2e.mock.Mock.MockRequest
55
+ */
56
+ MockRequest(
57
+ request: MockMsg,
58
+ abortSignal: AbortSignal,
59
+ context: ServerContext,
60
+ ): Promise<MockMsg>
61
+ }
62
+
45
63
  export const MockServiceName = MockDefinition.typeName
46
64
 
47
65
  export class MockClient implements Mock {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starpc",
3
- "version": "0.50.0",
3
+ "version": "0.52.0",
4
4
  "description": "Streaming protobuf RPC service protocol over any two-way channel.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -114,7 +114,7 @@
114
114
  "happy-dom": "^20.9.0",
115
115
  "husky": "^9.1.7",
116
116
  "lint-staged": "^17.0.0",
117
- "oxfmt": "0.61.0",
117
+ "oxfmt": "0.62.0",
118
118
  "oxlint": "^1.76.0",
119
119
  "rimraf": "^6.1.3",
120
120
  "tsx": "^4.20.4",
@@ -1,9 +1,29 @@
1
- import { describe, expect, it } from 'vitest'
1
+ import { describe, expect, it, vi } from 'vitest'
2
2
  import { pushable } from 'it-pushable'
3
3
 
4
4
  import { ChannelStream } from './channel.js'
5
5
 
6
6
  describe('ChannelStream', () => {
7
+ it('recognizes MessagePort implementations from another realm', () => {
8
+ const port = {
9
+ close: vi.fn(),
10
+ onmessage: null,
11
+ postMessage: vi.fn(),
12
+ start: vi.fn(),
13
+ } as unknown as MessagePort
14
+
15
+ const stream = new ChannelStream<Uint8Array>('client', port)
16
+ try {
17
+ expect(port.start).toHaveBeenCalledOnce()
18
+ expect(port.postMessage).toHaveBeenCalledWith({
19
+ ack: true,
20
+ from: 'client',
21
+ })
22
+ } finally {
23
+ stream.close()
24
+ }
25
+ })
26
+
7
27
  it('keeps MessagePort peer writes open after local source completes normally', async () => {
8
28
  const { port1, port2 } = new MessageChannel()
9
29
  const client = new ChannelStream<Uint8Array>('client', port1)