starpc 0.49.20 → 0.50.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 (44) hide show
  1. package/dist/integration/cross-language/ts-server.js +22 -6
  2. package/dist/mock/index.d.ts +2 -2
  3. package/dist/mock/index.js +2 -2
  4. package/dist/rpcstream/receipt.test.d.ts +1 -0
  5. package/dist/rpcstream/receipt.test.js +41 -0
  6. package/dist/srpc/call-receipt.js +2 -1
  7. package/dist/srpc/call-receipt.test.js +15 -14
  8. package/dist/srpc/common-rpc.d.ts +1 -3
  9. package/dist/srpc/common-rpc.js +10 -13
  10. package/dist/srpc/index.d.ts +1 -1
  11. package/dist/srpc/index.js +1 -0
  12. package/dist/srpc/rpcproto.pb.d.ts +44 -0
  13. package/dist/srpc/rpcproto.pb.js +53 -0
  14. package/dist/srpc/server-invocation.d.ts +1 -1
  15. package/go.mod +13 -12
  16. package/go.sum +24 -24
  17. package/integration/cross-language/go-server/fixture-owner_test.go +127 -0
  18. package/integration/cross-language/go-server/main.go +64 -42
  19. package/integration/cross-language/run.bash +2 -2
  20. package/integration/cross-language/ts-server.ts +27 -7
  21. package/mock/index.ts +2 -2
  22. package/package.json +19 -26
  23. package/srpc/accept.go +1 -1
  24. package/srpc/call-receipt-e2e_test.go +2 -2
  25. package/srpc/call-receipt.go +1 -1
  26. package/srpc/call-receipt.test.ts +19 -16
  27. package/srpc/call-receipt.ts +2 -1
  28. package/srpc/call-receipt_test.go +19 -19
  29. package/srpc/common-rpc.go +6 -6
  30. package/srpc/common-rpc.ts +17 -16
  31. package/srpc/index.ts +1 -1
  32. package/srpc/muxed-conn.go +1 -1
  33. package/srpc/muxed-yamux.go +1 -1
  34. package/srpc/rpcproto.pb.cc +15 -4
  35. package/srpc/rpcproto.pb.go +96 -0
  36. package/srpc/rpcproto.pb.h +59 -0
  37. package/srpc/rpcproto.pb.rs +45 -0
  38. package/srpc/rpcproto.pb.ts +62 -0
  39. package/srpc/rpcproto.proto +16 -0
  40. package/srpc/schema-ownership_test.go +115 -0
  41. package/srpc/server-invocation.go +1 -19
  42. package/srpc/server-invocation.ts +1 -7
  43. package/srpc/stream-yamux.go +1 -1
  44. package/srpc/websocket.go +1 -1
@@ -7,7 +7,7 @@ import { parseLengthPrefixTransform, prependLengthPrefixTransform, } from '../..
7
7
  import { combineUint8ArrayListTransform } from '../../srpc/array-list.js';
8
8
  import { EchoerServer, EchoMsg } from '../../echo/index.js';
9
9
  import { EchoerDefinition } from '../../echo/echo_srpc.pb.js';
10
- import { Packet } from '../../srpc/rpcproto.pb.js';
10
+ import { Packet, TerminalKind } from '../../srpc/rpcproto.pb.js';
11
11
  function emitReceiptEvent(line) {
12
12
  console.log(line);
13
13
  const fifo = process.env.RECEIPT_EVENT_FIFO;
@@ -46,6 +46,9 @@ function tcpSocketToPacketStream(socket) {
46
46
  packet.body?.case === 'callData' &&
47
47
  packet.body.value.complete &&
48
48
  !packet.body.value.error;
49
+ if (receiptCompletion) {
50
+ emitReceiptEvent('SERVER_RECEIPT_ACK_WRITE committed');
51
+ }
49
52
  const writeDone = new Promise((resolve, reject) => {
50
53
  socket.write(data, (err) => {
51
54
  if (err)
@@ -54,9 +57,6 @@ function tcpSocketToPacketStream(socket) {
54
57
  resolve();
55
58
  });
56
59
  });
57
- if (receiptCompletion) {
58
- emitReceiptEvent('SERVER_RECEIPT_ACK committed');
59
- }
60
60
  await writeDone;
61
61
  if (receiptCompletion) {
62
62
  finishReceiptServer();
@@ -104,14 +104,30 @@ if (receiptMode) {
104
104
  }
105
105
  emitReceiptEvent('SERVER_RECEIPT_WAITING');
106
106
  const terminal = await invocation.waitTerminal(new AbortController().signal);
107
- emitReceiptEvent(`SERVER_RECEIPT_TERMINAL ${terminal}`);
108
- if (terminal !== 'committed') {
107
+ emitReceiptEvent(`SERVER_RECEIPT_TERMINAL ${terminalName(terminal)}`);
108
+ if (terminal !== TerminalKind.COMMITTED) {
109
109
  finishReceiptServer();
110
110
  }
111
111
  })());
112
112
  };
113
113
  });
114
114
  }
115
+ function terminalName(terminal) {
116
+ switch (terminal) {
117
+ case TerminalKind.COMMITTED:
118
+ return 'committed';
119
+ case TerminalKind.CANCELED:
120
+ return 'canceled';
121
+ case TerminalKind.TRANSPORT_LOST:
122
+ return 'transportLost';
123
+ case TerminalKind.CLOSED:
124
+ return 'closed';
125
+ case TerminalKind.ABANDONED:
126
+ return 'abandoned';
127
+ default:
128
+ return 'unknown';
129
+ }
130
+ }
115
131
  const server = new Server(mux.lookupMethod);
116
132
  if (!receiptMode) {
117
133
  const echoer = new EchoerServer(server);
@@ -1,2 +1,2 @@
1
- export * from "./mock.pb.js";
2
- export * from "./mock_srpc.pb.js";
1
+ export * from './mock.pb.js';
2
+ export * from './mock_srpc.pb.js';
@@ -1,2 +1,2 @@
1
- export * from "./mock.pb.js";
2
- export * from "./mock_srpc.pb.js";
1
+ export * from './mock.pb.js';
2
+ export * from './mock_srpc.pb.js';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,41 @@
1
+ /// <reference lib="es2024.promise" />
2
+ import { describe, expect, it } from 'vitest';
3
+ import { Client } from '../srpc/client.js';
4
+ import { Server } from '../srpc/server.js';
5
+ import { TerminalKind } from '../srpc/rpcproto.pb.js';
6
+ import { buildRpcStreamOpenStream, handleRpcStream } from './rpcstream.js';
7
+ const response = new Uint8Array([4, 5, 6]);
8
+ // This guard mirrors the Go rpcstream/receipt_test.go nested tunnel: an
9
+ // ExecCallReceipt-equivalent held unary call runs through a real handleRpcStream
10
+ // tunnel. The inner generated handler sends its single response, then the
11
+ // wrapping invocation synchronously holds on waitTerminal. The first response
12
+ // must be client-visible while the exact invocation stays open for commit.
13
+ describe('rpcstream held receipt tunnel', () => {
14
+ it('delivers the first inner response while the invocation stays held', async () => {
15
+ const terminal = Promise.withResolvers();
16
+ const innerServer = new Server(async () => {
17
+ return async (_source, dataSink, invocation) => {
18
+ await dataSink((async function* () {
19
+ yield response;
20
+ if (!invocation) {
21
+ throw new Error('missing invocation');
22
+ }
23
+ terminal.resolve(await invocation.waitTerminal(new AbortController().signal));
24
+ })());
25
+ };
26
+ });
27
+ const caller = (packetTx) => handleRpcStream(packetTx[Symbol.asyncIterator](), async () => innerServer.rpcStreamHandler);
28
+ const client = new Client(buildRpcStreamOpenStream('component-a', caller));
29
+ const held = await client.requestWithReceipt('test.Service', 'Unary', response);
30
+ // The first inner response is client-visible while the invocation is held.
31
+ expect(held.response).toEqual(response);
32
+ // The inner invocation must still be open: no terminal observed yet.
33
+ const raced = await Promise.race([
34
+ terminal.promise.then(() => 'terminal'),
35
+ Promise.resolve('pending'),
36
+ ]);
37
+ expect(raced).toBe('pending');
38
+ await expect(held.receipt.commit()).resolves.toBeUndefined();
39
+ await expect(terminal.promise).resolves.toBe(TerminalKind.COMMITTED);
40
+ });
41
+ });
@@ -1,5 +1,6 @@
1
1
  /// <reference lib="es2024.promise" />
2
2
  import { ERR_RPC_ABORT } from './errors.js';
3
+ import { TerminalKind } from './rpcproto.pb.js';
3
4
  // CallReceipt holds a unary call until it is committed or aborted.
4
5
  export class CallReceipt {
5
6
  #call;
@@ -28,7 +29,7 @@ export class CallReceipt {
28
29
  throw new Error('unexpected trailing response data');
29
30
  }
30
31
  const terminal = this.#call.getTerminalKind();
31
- if (terminal !== 'committed' ||
32
+ if (terminal !== TerminalKind.COMMITTED ||
32
33
  !this.#requestCommitted ||
33
34
  this.#terminal !== 'committed') {
34
35
  throw new Error('receipt closed before commit');
@@ -6,7 +6,7 @@ import { Client } from './client.js';
6
6
  import { ClientRPC } from './client-rpc.js';
7
7
  import { Server } from './server.js';
8
8
  import { CallReceipt } from './call-receipt.js';
9
- import { Packet } from './rpcproto.pb.js';
9
+ import { Packet, TerminalKind } from './rpcproto.pb.js';
10
10
  import { ServerRPC } from './server-rpc.js';
11
11
  const response = new Uint8Array([1, 2, 3]);
12
12
  describe('generated service compatibility', () => {
@@ -88,7 +88,7 @@ describe('held unary receipt', () => {
88
88
  });
89
89
  const held = await client.requestWithReceipt('test.Service', 'Unary', response);
90
90
  await expect(held.receipt.commit()).resolves.toBeUndefined();
91
- await expect(terminal.promise).resolves.toBe('committed');
91
+ await expect(terminal.promise).resolves.toBe(TerminalKind.COMMITTED);
92
92
  });
93
93
  it('rejects commit after a bare remote close', async () => {
94
94
  const call = new ClientRPC('test.Service', 'Unary');
@@ -235,12 +235,12 @@ describe('held unary receipt', () => {
235
235
  });
236
236
  describe('server invocation terminal', () => {
237
237
  it.each([
238
- ['explicit completion', 'committed'],
239
- ['cancel', 'canceled'],
240
- ['transport loss', 'transportLost'],
241
- ['remote error packet', 'transportLost'],
242
- ['bare close', 'closed'],
243
- ['remote error packet with completion', 'transportLost'],
238
+ ['explicit completion', TerminalKind.COMMITTED],
239
+ ['cancel', TerminalKind.CANCELED],
240
+ ['transport loss', TerminalKind.TRANSPORT_LOST],
241
+ ['remote error packet', TerminalKind.TRANSPORT_LOST],
242
+ ['bare close', TerminalKind.CLOSED],
243
+ ['remote error packet with completion', TerminalKind.TRANSPORT_LOST],
244
244
  ])('%s is classified distinctly', async (_name, expected) => {
245
245
  const captured = Promise.withResolvers();
246
246
  const owner = new AbortController();
@@ -261,13 +261,13 @@ describe('server invocation terminal', () => {
261
261
  dataIsZero: true,
262
262
  });
263
263
  const invocation = await captured.promise;
264
- if (expected === 'committed') {
264
+ if (expected === TerminalKind.COMMITTED) {
265
265
  await rpc.handleCallData({ complete: true });
266
266
  }
267
- else if (expected === 'canceled') {
267
+ else if (expected === TerminalKind.CANCELED) {
268
268
  await rpc.handleCallCancel();
269
269
  }
270
- else if (expected === 'transportLost') {
270
+ else if (expected === TerminalKind.TRANSPORT_LOST) {
271
271
  if (_name === 'remote error packet' ||
272
272
  _name === 'remote error packet with completion') {
273
273
  await rpc.handleCallData({
@@ -291,7 +291,8 @@ describe('server invocation terminal', () => {
291
291
  }
292
292
  expect(rpcState.remoteCompleted).toBe(false);
293
293
  }
294
- if (expected === 'closed' || expected === 'transportLost') {
294
+ if (expected === TerminalKind.CLOSED ||
295
+ expected === TerminalKind.TRANSPORT_LOST) {
295
296
  expect(invocation.signal.aborted).toBe(true);
296
297
  }
297
298
  });
@@ -321,7 +322,7 @@ describe('server invocation terminal', () => {
321
322
  else {
322
323
  await rpc.handleCallCancel();
323
324
  }
324
- await expect(invocation.waitTerminal(owner.signal)).resolves.toBe('committed');
325
+ await expect(invocation.waitTerminal(owner.signal)).resolves.toBe(TerminalKind.COMMITTED);
325
326
  owner.abort();
326
327
  });
327
328
  it('returns abandoned only for owner cancellation without a remote terminal', async () => {
@@ -344,7 +345,7 @@ describe('server invocation terminal', () => {
344
345
  });
345
346
  const invocation = await captured.promise;
346
347
  owner.abort();
347
- await expect(invocation.waitTerminal(owner.signal)).resolves.toBe('abandoned');
348
+ await expect(invocation.waitTerminal(owner.signal)).resolves.toBe(TerminalKind.ABANDONED);
348
349
  });
349
350
  });
350
351
  async function* responseSource(terminal) {
@@ -1,7 +1,5 @@
1
1
  import type { Sink, Source } from 'it-stream-types';
2
- import type { CallData, CallStart } from './rpcproto.pb.js';
3
- import { Packet } from './rpcproto.pb.js';
4
- import type { TerminalKind } from './server-invocation.js';
2
+ import { Packet, TerminalKind, type CallData, type CallStart } from './rpcproto.pb.js';
5
3
  export declare class CommonRPC {
6
4
  readonly sink: Sink<Source<Packet>>;
7
5
  readonly source: AsyncIterable<Packet>;
@@ -1,5 +1,5 @@
1
1
  import { pushable } from 'it-pushable';
2
- import { Packet } from './rpcproto.pb.js';
2
+ import { Packet, TerminalKind, } from './rpcproto.pb.js';
3
3
  import { ERR_RPC_ABORT, RemoteRPCError } from './errors.js';
4
4
  const maxBufferedOutgoingPackets = 1;
5
5
  // CommonRPC is common logic between server and client RPCs.
@@ -65,7 +65,7 @@ export class CommonRPC {
65
65
  for (;;) {
66
66
  const terminal = this.getTerminalKind();
67
67
  if (terminal !== undefined) {
68
- if (terminal === 'closed' &&
68
+ if (terminal === TerminalKind.CLOSED &&
69
69
  this.remoteSourceClosed &&
70
70
  !this.closed) {
71
71
  await this.close();
@@ -73,7 +73,7 @@ export class CommonRPC {
73
73
  return terminal;
74
74
  }
75
75
  if (ownerAborted) {
76
- return 'abandoned';
76
+ return TerminalKind.ABANDONED;
77
77
  }
78
78
  await Promise.race([this.terminalPromise, ownerDone]);
79
79
  ownerAborted = ownerSignal.aborted;
@@ -215,17 +215,17 @@ export class CommonRPC {
215
215
  throw new Error('call start must be sent before call data');
216
216
  }
217
217
  this.pushRpcData(packet.data, packet.dataIsZero);
218
- const remoteError = packet.error ?
219
- new RemoteRPCError(this.service, this.method, packet.error)
218
+ const remoteError = packet.error
219
+ ? new RemoteRPCError(this.service, this.method, packet.error)
220
220
  : undefined;
221
221
  if (remoteError) {
222
222
  this.remoteError ??= remoteError;
223
223
  this.invocationController.abort();
224
- this.recordRemoteTerminal('transportLost');
224
+ this.recordRemoteTerminal(TerminalKind.TRANSPORT_LOST);
225
225
  }
226
226
  if (packet.complete && !remoteError) {
227
227
  this.remoteCompleted = true;
228
- this.recordRemoteTerminal('committed');
228
+ this.recordRemoteTerminal(TerminalKind.COMMITTED);
229
229
  this._rpcDataSource.end(remoteError);
230
230
  }
231
231
  else if (remoteError) {
@@ -234,7 +234,7 @@ export class CommonRPC {
234
234
  }
235
235
  // handleCallCancel handles a CallCancel packet.
236
236
  async handleCallCancel() {
237
- this.recordRemoteTerminal('canceled');
237
+ this.recordRemoteTerminal(TerminalKind.CANCELED);
238
238
  await this.close(new Error(ERR_RPC_ABORT));
239
239
  }
240
240
  // close closes the call, optionally with an error.
@@ -246,7 +246,7 @@ export class CommonRPC {
246
246
  if (!this.remoteError && err) {
247
247
  this.remoteError = err;
248
248
  }
249
- this.recordRemoteTerminal(err ? 'transportLost' : 'closed');
249
+ this.recordRemoteTerminal(err ? TerminalKind.TRANSPORT_LOST : TerminalKind.CLOSED);
250
250
  this.invocationController.abort();
251
251
  // note: this does nothing if _source is already ended.
252
252
  if (err && err.message) {
@@ -259,24 +259,21 @@ export class CommonRPC {
259
259
  this._source.end();
260
260
  this._rpcDataSource.end(err);
261
261
  }
262
- // _createSink returns a value for the sink field.
263
262
  _createSink() {
264
263
  return async (source) => {
265
264
  try {
266
265
  if (Symbol.asyncIterator in source) {
267
- // Handle async source
268
266
  for await (const msg of source) {
269
267
  await this.handlePacket(msg);
270
268
  }
271
269
  }
272
270
  else {
273
- // Handle sync source
274
271
  for (const msg of source) {
275
272
  await this.handlePacket(msg);
276
273
  }
277
274
  }
278
275
  this.remoteSourceClosed = true;
279
- this.recordRemoteTerminal('closed');
276
+ this.recordRemoteTerminal(TerminalKind.CLOSED);
280
277
  }
281
278
  catch (err) {
282
279
  this.close(err);
@@ -3,7 +3,7 @@ export { Client } from './client.js';
3
3
  export { CallReceipt } from './call-receipt.js';
4
4
  export type { HeldCall, ReceiptRpc } from './call-receipt.js';
5
5
  export { ServerInvocation } from './server-invocation.js';
6
- export type { TerminalKind } from './server-invocation.js';
6
+ export { TerminalKind } from './rpcproto.pb.js';
7
7
  export { Server } from './server.js';
8
8
  export { StreamConn } from './conn.js';
9
9
  export type { StreamConnParams, StreamHandler } from './conn.js';
@@ -2,6 +2,7 @@ export { ERR_RPC_ABORT, isAbortError, ERR_STREAM_IDLE, isStreamIdleError, castTo
2
2
  export { Client } from './client.js';
3
3
  export { CallReceipt } from './call-receipt.js';
4
4
  export { ServerInvocation } from './server-invocation.js';
5
+ export { TerminalKind } from './rpcproto.pb.js';
5
6
  export { Server } from './server.js';
6
7
  export { StreamConn } from './conn.js';
7
8
  export { WebSocketConn } from './websocket.js';
@@ -1,5 +1,49 @@
1
1
  import type { MessageType } from '@aptre/protobuf-es-lite/message';
2
2
  export declare const protobufPackage = "srpc";
3
+ /**
4
+ * TerminalKind is the terminal state of a held unary invocation.
5
+ *
6
+ * @generated from enum srpc.TerminalKind
7
+ */
8
+ export declare enum TerminalKind {
9
+ /**
10
+ * TERMINAL_KIND_UNSPECIFIED is not a valid terminal state.
11
+ *
12
+ * @generated from enum value: TERMINAL_KIND_UNSPECIFIED = 0;
13
+ */
14
+ UNSPECIFIED = 0,
15
+ /**
16
+ * TERMINAL_KIND_COMMITTED identifies an explicit remote CallData completion.
17
+ *
18
+ * @generated from enum value: TERMINAL_KIND_COMMITTED = 1;
19
+ */
20
+ COMMITTED = 1,
21
+ /**
22
+ * TERMINAL_KIND_CANCELED identifies a remote CallCancel packet.
23
+ *
24
+ * @generated from enum value: TERMINAL_KIND_CANCELED = 2;
25
+ */
26
+ CANCELED = 2,
27
+ /**
28
+ * TERMINAL_KIND_TRANSPORT_LOST identifies a remote error or transport failure.
29
+ *
30
+ * @generated from enum value: TERMINAL_KIND_TRANSPORT_LOST = 3;
31
+ */
32
+ TRANSPORT_LOST = 3,
33
+ /**
34
+ * TERMINAL_KIND_CLOSED identifies a bare remote close without completion.
35
+ *
36
+ * @generated from enum value: TERMINAL_KIND_CLOSED = 4;
37
+ */
38
+ CLOSED = 4,
39
+ /**
40
+ * TERMINAL_KIND_ABANDONED identifies owner-context expiry without a remote terminal.
41
+ *
42
+ * @generated from enum value: TERMINAL_KIND_ABANDONED = 5;
43
+ */
44
+ ABANDONED = 5
45
+ }
46
+ export declare const TerminalKind_Enum: import("@aptre/protobuf-es-lite/enum").EnumType;
3
47
  /**
4
48
  * CallStart requests starting a new RPC call.
5
49
  *
@@ -1,9 +1,62 @@
1
1
  // @generated by protoc-gen-es-lite unknown with parameter "target=ts,ts_nocheck=false"
2
2
  // @generated from file github.com/aperturerobotics/starpc/srpc/rpcproto.proto (package srpc, syntax proto3)
3
3
  /* eslint-disable */
4
+ import { createEnumType } from '@aptre/protobuf-es-lite/enum';
4
5
  import { createMessageType } from '@aptre/protobuf-es-lite/message';
5
6
  import { ScalarType } from '@aptre/protobuf-es-lite/scalar';
6
7
  export const protobufPackage = 'srpc';
8
+ /**
9
+ * TerminalKind is the terminal state of a held unary invocation.
10
+ *
11
+ * @generated from enum srpc.TerminalKind
12
+ */
13
+ export var TerminalKind;
14
+ (function (TerminalKind) {
15
+ /**
16
+ * TERMINAL_KIND_UNSPECIFIED is not a valid terminal state.
17
+ *
18
+ * @generated from enum value: TERMINAL_KIND_UNSPECIFIED = 0;
19
+ */
20
+ TerminalKind[TerminalKind["UNSPECIFIED"] = 0] = "UNSPECIFIED";
21
+ /**
22
+ * TERMINAL_KIND_COMMITTED identifies an explicit remote CallData completion.
23
+ *
24
+ * @generated from enum value: TERMINAL_KIND_COMMITTED = 1;
25
+ */
26
+ TerminalKind[TerminalKind["COMMITTED"] = 1] = "COMMITTED";
27
+ /**
28
+ * TERMINAL_KIND_CANCELED identifies a remote CallCancel packet.
29
+ *
30
+ * @generated from enum value: TERMINAL_KIND_CANCELED = 2;
31
+ */
32
+ TerminalKind[TerminalKind["CANCELED"] = 2] = "CANCELED";
33
+ /**
34
+ * TERMINAL_KIND_TRANSPORT_LOST identifies a remote error or transport failure.
35
+ *
36
+ * @generated from enum value: TERMINAL_KIND_TRANSPORT_LOST = 3;
37
+ */
38
+ TerminalKind[TerminalKind["TRANSPORT_LOST"] = 3] = "TRANSPORT_LOST";
39
+ /**
40
+ * TERMINAL_KIND_CLOSED identifies a bare remote close without completion.
41
+ *
42
+ * @generated from enum value: TERMINAL_KIND_CLOSED = 4;
43
+ */
44
+ TerminalKind[TerminalKind["CLOSED"] = 4] = "CLOSED";
45
+ /**
46
+ * TERMINAL_KIND_ABANDONED identifies owner-context expiry without a remote terminal.
47
+ *
48
+ * @generated from enum value: TERMINAL_KIND_ABANDONED = 5;
49
+ */
50
+ TerminalKind[TerminalKind["ABANDONED"] = 5] = "ABANDONED";
51
+ })(TerminalKind || (TerminalKind = {}));
52
+ export const TerminalKind_Enum = /* @__PURE__ */ createEnumType('srpc.TerminalKind', [
53
+ [0, 'TERMINAL_KIND_UNSPECIFIED'],
54
+ [1, 'TERMINAL_KIND_COMMITTED'],
55
+ [2, 'TERMINAL_KIND_CANCELED'],
56
+ [3, 'TERMINAL_KIND_TRANSPORT_LOST'],
57
+ [4, 'TERMINAL_KIND_CLOSED'],
58
+ [5, 'TERMINAL_KIND_ABANDONED'],
59
+ ]);
7
60
  export const CallStart =
8
61
  /* @__PURE__ */ createMessageType({
9
62
  typeName: 'srpc.CallStart',
@@ -1,4 +1,4 @@
1
- export type TerminalKind = 'committed' | 'canceled' | 'transportLost' | 'closed' | 'abandoned';
1
+ import type { TerminalKind } from './rpcproto.pb.js';
2
2
  export declare class ServerInvocation implements AbortSignal {
3
3
  readonly signal: AbortSignal;
4
4
  private readonly waitFn;
package/go.mod CHANGED
@@ -3,31 +3,32 @@ module github.com/aperturerobotics/starpc
3
3
  go 1.25.0
4
4
 
5
5
  require (
6
- github.com/aperturerobotics/common v0.33.1-0.20260516193515-675cfc5a0c12 // latest
7
- github.com/aperturerobotics/protobuf-go-lite v0.13.0 // latest
8
- github.com/aperturerobotics/util v1.34.5 // latest
6
+ github.com/aperturerobotics/common v0.34.4 // latest
7
+ github.com/aperturerobotics/protobuf-go-lite v0.16.0 // latest
8
+ github.com/aperturerobotics/util v1.34.9 // latest
9
9
  )
10
10
 
11
11
  require (
12
12
  github.com/aperturerobotics/abseil-cpp v0.0.0-20260131110040-4bb56e2f9017 // aperture-2
13
13
  github.com/aperturerobotics/cli v1.1.0 // indirect
14
- github.com/aperturerobotics/go-protoc-gen-prost v0.0.0-20260329113538-218ccd8f20e0 // indirect
15
- github.com/aperturerobotics/go-protoc-wasi v0.0.0-20260329113540-600516012db3 // indirect
16
- github.com/aperturerobotics/go-websocket v1.8.15-0.20260329113544-74dbfb8f11c6 // master
17
- github.com/aperturerobotics/json-iterator-lite v1.0.1-0.20251104042408-0c9eb8a3f726 // indirect
14
+ github.com/aperturerobotics/go-protoc-gen-prost v0.0.0-20260705010911-9f53feac967b // indirect
15
+ github.com/aperturerobotics/go-protoc-wasi v0.0.0-20260712054757-d8078c296c17 // indirect
16
+ github.com/aperturerobotics/go-websocket v1.8.15-0.20260619192713-a096778f08c1 // master
17
+ github.com/aperturerobotics/json-iterator-lite v1.1.0 // indirect
18
18
  github.com/aperturerobotics/protobuf v0.0.0-20260203024654-8201686529c4 // wasi
19
19
  )
20
20
 
21
21
  require (
22
- github.com/libp2p/go-yamux/v4 v4.0.2 // latest
23
22
  github.com/pkg/errors v0.9.1 // latest
24
- github.com/sirupsen/logrus v1.9.5-0.20260508084601-d4a50659cfd6 // latest
23
+ github.com/sirupsen/logrus v1.9.5-0.20260629095817-a23d315dfebb // latest
25
24
  )
26
25
 
26
+ require github.com/libp2p/go-yamux/v5 v5.1.0
27
+
27
28
  require (
28
29
  github.com/libp2p/go-buffer-pool v0.1.0 // indirect
29
- github.com/tetratelabs/wazero v1.11.0 // indirect
30
+ github.com/tetratelabs/wazero v1.12.0 // indirect
30
31
  github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect
31
- golang.org/x/mod v0.35.0 // indirect
32
- golang.org/x/sys v0.44.0 // indirect
32
+ golang.org/x/mod v0.38.0 // indirect
33
+ golang.org/x/sys v0.47.0 // indirect
33
34
  )
package/go.sum CHANGED
@@ -2,46 +2,46 @@ github.com/aperturerobotics/abseil-cpp v0.0.0-20260131110040-4bb56e2f9017 h1:3U7
2
2
  github.com/aperturerobotics/abseil-cpp v0.0.0-20260131110040-4bb56e2f9017/go.mod h1:lNSJTKECIUFAnfeSqy01kXYTYe1BHubW7198jNX3nEw=
3
3
  github.com/aperturerobotics/cli v1.1.0 h1:7a+YRC+EY3npAnTzhHV5gLCiw91KS0Ts3XwLILGOsT8=
4
4
  github.com/aperturerobotics/cli v1.1.0/go.mod h1:M7BFP9wow5ytTzMyJQOOO991fGfsUqdTI7gGEsHfTQ8=
5
- github.com/aperturerobotics/common v0.33.1-0.20260516193515-675cfc5a0c12 h1:KQiFEDyu5//G8JZ3yTN92kF2P3F+LHjSKsQikgROncU=
6
- github.com/aperturerobotics/common v0.33.1-0.20260516193515-675cfc5a0c12/go.mod h1:pW7BhBpKzVrTxN8XIz6jb3MJERZ15GDxaGQ7jcIl0Xg=
7
- github.com/aperturerobotics/go-protoc-gen-prost v0.0.0-20260329113538-218ccd8f20e0 h1:6/3RSSlPEQ6LeidslB1ZCJkxW+MnfYDkvdWMDklDXw4=
8
- github.com/aperturerobotics/go-protoc-gen-prost v0.0.0-20260329113538-218ccd8f20e0/go.mod h1:OBb/beWmr/pDIZAUfi86j/4tBh2v5ctTxKMqSnh9c/4=
9
- github.com/aperturerobotics/go-protoc-wasi v0.0.0-20260329113540-600516012db3 h1:lp+V8RYcBwTX1p81swkpZn5fhw1wn2xLorzETIxRyZQ=
10
- github.com/aperturerobotics/go-protoc-wasi v0.0.0-20260329113540-600516012db3/go.mod h1:vEq8i7EKb32+KXGtIEZjjhNns+BdsL2dUMw4uhy3578=
11
- github.com/aperturerobotics/go-websocket v1.8.15-0.20260329113544-74dbfb8f11c6 h1:Utc1F7jdCc6/HrwwIikJFXt/hXxkWIWETLp/CsG6Gl0=
12
- github.com/aperturerobotics/go-websocket v1.8.15-0.20260329113544-74dbfb8f11c6/go.mod h1:9KnSGuqxSXbdB/Oi0I6vvfPLkclfJwMGAQaDDGVgGow=
13
- github.com/aperturerobotics/json-iterator-lite v1.0.1-0.20251104042408-0c9eb8a3f726 h1:4B1F0DzuqPzb6WqgCjWaqDD7JU9RDsevQG5OP0DFBgs=
14
- github.com/aperturerobotics/json-iterator-lite v1.0.1-0.20251104042408-0c9eb8a3f726/go.mod h1:SvGGBv3OVxUyqO0ZxA/nvs6z3cg7NIbZ64TnbV2OISo=
5
+ github.com/aperturerobotics/common v0.34.4 h1:RQTOm6LxEnucXkED/kruhKKAOL6tbaPzMgfHPKaES4k=
6
+ github.com/aperturerobotics/common v0.34.4/go.mod h1:xnb1VBRs3x2o1PaKg0OlP7SqDaC9Hmrmt9xH85rOS+A=
7
+ github.com/aperturerobotics/go-protoc-gen-prost v0.0.0-20260705010911-9f53feac967b h1:MMk+AbWPCMfqc2Lm2bJl8lCCsuvlM2+C0CP10fpE3bc=
8
+ github.com/aperturerobotics/go-protoc-gen-prost v0.0.0-20260705010911-9f53feac967b/go.mod h1:OBb/beWmr/pDIZAUfi86j/4tBh2v5ctTxKMqSnh9c/4=
9
+ github.com/aperturerobotics/go-protoc-wasi v0.0.0-20260712054757-d8078c296c17 h1:WT1YmZjJf8fUF1zKbeNNKXFA+t8Wtbr8AVMAmdKcrUU=
10
+ github.com/aperturerobotics/go-protoc-wasi v0.0.0-20260712054757-d8078c296c17/go.mod h1:vEq8i7EKb32+KXGtIEZjjhNns+BdsL2dUMw4uhy3578=
11
+ github.com/aperturerobotics/go-websocket v1.8.15-0.20260619192713-a096778f08c1 h1:q2qkdNOrnhAFf6B7TBeUoAYstYWxPvozN+3vJi2jgp0=
12
+ github.com/aperturerobotics/go-websocket v1.8.15-0.20260619192713-a096778f08c1/go.mod h1:9KnSGuqxSXbdB/Oi0I6vvfPLkclfJwMGAQaDDGVgGow=
13
+ github.com/aperturerobotics/json-iterator-lite v1.1.0 h1:ZLLqHhHTKYlmCAP873ras2e/yVU/THtwC+ji3tXLMMg=
14
+ github.com/aperturerobotics/json-iterator-lite v1.1.0/go.mod h1:SvGGBv3OVxUyqO0ZxA/nvs6z3cg7NIbZ64TnbV2OISo=
15
15
  github.com/aperturerobotics/protobuf v0.0.0-20260203024654-8201686529c4 h1:4Dy3BAHh2kgVdHAqtlwcFsgY0kAwUe2m3rfFcaGwGQg=
16
16
  github.com/aperturerobotics/protobuf v0.0.0-20260203024654-8201686529c4/go.mod h1:tMgO7y6SJo/d9ZcvrpNqIQtdYT9de+QmYaHOZ4KnhOg=
17
- github.com/aperturerobotics/protobuf-go-lite v0.13.0 h1:jEvCJhHaJEikDY/va2AUnS0DOb/0n82aISLAqxSh4Sk=
18
- github.com/aperturerobotics/protobuf-go-lite v0.13.0/go.mod h1:lGH3s5ArCTXKI4wJdlNpaybUtwSjfAG0vdWjxOfMcF8=
19
- github.com/aperturerobotics/util v1.34.5 h1:007MaOJrrsiGm5o1c8Tt7p8nVwUAxkM6pmGflrBww/U=
20
- github.com/aperturerobotics/util v1.34.5/go.mod h1:mDe7WnncVuV7yjeeVSsagyfrw4xfncu7d+f0+d70niY=
17
+ github.com/aperturerobotics/protobuf-go-lite v0.16.0 h1:McGR0jrc15ZkH8HUpAARDOtazjwqr+uYXVHrrR59K28=
18
+ github.com/aperturerobotics/protobuf-go-lite v0.16.0/go.mod h1:3Ay/E7iaw2KWLirK3+dDdNJZHK0hu8Y1/kKeYeUa+8s=
19
+ github.com/aperturerobotics/util v1.34.9 h1:Eyhu1Citt+od7jKIb+Q92h/CEujWCFsvdvJavQeoRjM=
20
+ github.com/aperturerobotics/util v1.34.9/go.mod h1:GxjGkYQNEj8xvLFz+T8ifqANtK5cMesOlCxh50htvBI=
21
21
  github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
22
22
  github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
23
23
  github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
24
24
  github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
25
25
  github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
26
26
  github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
27
- github.com/libp2p/go-yamux/v4 v4.0.2 h1:nrLh89LN/LEiqcFiqdKDRHjGstN300C1269K/EX0CPU=
28
- github.com/libp2p/go-yamux/v4 v4.0.2/go.mod h1:C808cCRgOs1iBwY4S71T5oxgMxgLmqUw56qh4AeBW2o=
27
+ github.com/libp2p/go-yamux/v5 v5.1.0 h1:8Qlxj4E9JGJAQVW6+uj2o7mqkqsIVlSUGmTWhlXzoHE=
28
+ github.com/libp2p/go-yamux/v5 v5.1.0/go.mod h1:tgIQ07ObtRR/I0IWsFOyQIL9/dR5UXgc2s8xKmNZv1o=
29
29
  github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
30
30
  github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
31
31
  github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
32
32
  github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
33
- github.com/sirupsen/logrus v1.9.5-0.20260508084601-d4a50659cfd6 h1:D6qewLO/pJ+JvUwuri1dmCbc32d/eO+xyqg+p3N+9kA=
34
- github.com/sirupsen/logrus v1.9.5-0.20260508084601-d4a50659cfd6/go.mod h1:FXZFonkDAnFozmO+5hGAFvB0Yg9/j2SIhA/QuIkP180=
33
+ github.com/sirupsen/logrus v1.9.5-0.20260629095817-a23d315dfebb h1:+C8W2sTMIRbihe5hQH6JuT2mi3m/QgdGf0YdFyx2azA=
34
+ github.com/sirupsen/logrus v1.9.5-0.20260629095817-a23d315dfebb/go.mod h1:FXZFonkDAnFozmO+5hGAFvB0Yg9/j2SIhA/QuIkP180=
35
35
  github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
36
36
  github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
37
- github.com/tetratelabs/wazero v1.11.0 h1:+gKemEuKCTevU4d7ZTzlsvgd1uaToIDtlQlmNbwqYhA=
38
- github.com/tetratelabs/wazero v1.11.0/go.mod h1:eV28rsN8Q+xwjogd7f4/Pp4xFxO7uOGbLcD/LzB1wiU=
37
+ github.com/tetratelabs/wazero v1.12.0 h1:DuWcpNu/FzgEXgGBDp8J1Spc+CWOvvtvVyjKlaZopYU=
38
+ github.com/tetratelabs/wazero v1.12.0/go.mod h1:LvKtzl2RqO4gyF27BiXU+nKAjcV8f38U+kP/q2vgxh0=
39
39
  github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 h1:FnBeRrxr7OU4VvAzt5X7s6266i6cSVkkFPS0TuXWbIg=
40
40
  github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
41
- golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
42
- golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
43
- golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
44
- golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
41
+ golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
42
+ golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
43
+ golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
44
+ golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
45
45
  google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
46
46
  google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
47
47
  gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=