starpc 0.25.2 → 0.25.3

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.
@@ -5,7 +5,7 @@ import { OpenStreamFunc, PacketStream } from '../srpc/stream.js';
5
5
  export type RpcStreamCaller = (request: AsyncIterable<RpcStreamPacket>) => AsyncIterable<RpcStreamPacket>;
6
6
  export declare function openRpcStream(componentId: string, caller: RpcStreamCaller, waitAck?: boolean): Promise<PacketStream>;
7
7
  export declare function buildRpcStreamOpenStream(componentId: string, caller: RpcStreamCaller): OpenStreamFunc;
8
- export type RpcStreamHandler = (stream: PacketStream) => void;
8
+ export type RpcStreamHandler = (stream: PacketStream) => Promise<void>;
9
9
  export type RpcStreamGetter = (componentId: string) => Promise<RpcStreamHandler | null>;
10
10
  export declare function handleRpcStream(packetRx: AsyncIterator<RpcStreamPacket>, getter: RpcStreamGetter): AsyncIterable<RpcStreamPacket>;
11
11
  export declare class RpcStream implements PacketStream {
@@ -86,7 +86,9 @@ export async function* handleRpcStream(packetRx, getter) {
86
86
  const packetTx = pushable({ objectMode: true });
87
87
  // start the handler
88
88
  const rpcStream = new RpcStream(packetTx, packetRx);
89
- handler(rpcStream);
89
+ handler(rpcStream)
90
+ .catch((err) => packetTx.end(err))
91
+ .then(() => packetTx.end());
90
92
  // process packets
91
93
  for await (const packet of packetTx) {
92
94
  yield* [packet];
@@ -6,6 +6,7 @@ import { ERR_STREAM_IDLE } from './errors.js';
6
6
  // NOTE: there is no way to tell if a BroadcastChannel or MessagePort is closed.
7
7
  // This implementation sends a "closed" message when close() is called.
8
8
  // However: if the remote is removed w/o closing cleanly, the stream will be left open!
9
+ // Enable keepAliveMs and idleTimeoutMs to mitigate this issue with keep-alive messages.
9
10
  export class ChannelStream {
10
11
  // isAcked checks if the stream is acknowledged by the remote.
11
12
  get isAcked() {
@@ -85,8 +85,8 @@ export class Client {
85
85
  call.close(new Error(ERR_RPC_ABORT));
86
86
  });
87
87
  pipe(stream, decodePacketSource, call, encodePacketSource, stream)
88
- .then(() => call.close())
89
- .catch((err) => call.close(err));
88
+ .catch((err) => call.close(err))
89
+ .then(() => call.close());
90
90
  await call.writeCallStart(data || undefined);
91
91
  return call;
92
92
  }
@@ -9,7 +9,12 @@ export class Server {
9
9
  // rpcStreamHandler implements the RpcStreamHandler interface.
10
10
  // uses handlePacketDuplex (expects 1 buf = 1 Packet)
11
11
  get rpcStreamHandler() {
12
- return this.handlePacketStream.bind(this);
12
+ return async (stream) => {
13
+ const rpc = this.startRpc();
14
+ return pipe(stream, decodePacketSource, rpc, encodePacketSource, stream)
15
+ .catch((err) => rpc.close(err))
16
+ .then(() => rpc.close());
17
+ };
13
18
  }
14
19
  // startRpc starts a new server-side RPC.
15
20
  // the returned RPC handles incoming Packets.
@@ -10,7 +10,9 @@ export class WebSocketConn extends StreamConn {
10
10
  const socketDuplex = duplex(socket);
11
11
  pipe(socketDuplex, this,
12
12
  // it-ws only supports sending Uint8Array.
13
- combineUint8ArrayListTransform(), socketDuplex);
13
+ combineUint8ArrayListTransform(), socketDuplex)
14
+ .catch((err) => this.close(err))
15
+ .then(() => this.close());
14
16
  }
15
17
  // getSocket returns the websocket.
16
18
  getSocket() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starpc",
3
- "version": "0.25.2",
3
+ "version": "0.25.3",
4
4
  "description": "Streaming protobuf RPC service protocol over any two-way channel.",
5
5
  "license": "MIT",
6
6
  "author": {
package/srpc/channel.ts CHANGED
@@ -42,6 +42,7 @@ export interface ChannelStreamOpts {
42
42
  // NOTE: there is no way to tell if a BroadcastChannel or MessagePort is closed.
43
43
  // This implementation sends a "closed" message when close() is called.
44
44
  // However: if the remote is removed w/o closing cleanly, the stream will be left open!
45
+ // Enable keepAliveMs and idleTimeoutMs to mitigate this issue with keep-alive messages.
45
46
  export class ChannelStream<T = Uint8Array>
46
47
  implements Duplex<AsyncGenerator<T>, Source<T>, Promise<void>>
47
48
  {
package/srpc/client.ts CHANGED
@@ -122,8 +122,8 @@ export class Client implements TsProtoRpc {
122
122
  call.close(new Error(ERR_RPC_ABORT))
123
123
  })
124
124
  pipe(stream, decodePacketSource, call, encodePacketSource, stream)
125
- .then(() => call.close())
126
125
  .catch((err) => call.close(err))
126
+ .then(() => call.close())
127
127
  await call.writeCallStart(data || undefined)
128
128
  return call
129
129
  }
package/srpc/server.ts CHANGED
@@ -19,7 +19,12 @@ export class Server implements StreamHandler {
19
19
  // rpcStreamHandler implements the RpcStreamHandler interface.
20
20
  // uses handlePacketDuplex (expects 1 buf = 1 Packet)
21
21
  public get rpcStreamHandler(): RpcStreamHandler {
22
- return this.handlePacketStream.bind(this)
22
+ return async (stream: PacketStream) => {
23
+ const rpc = this.startRpc()
24
+ return pipe(stream, decodePacketSource, rpc, encodePacketSource, stream)
25
+ .catch((err: Error) => rpc.close(err))
26
+ .then(() => rpc.close())
27
+ }
23
28
  }
24
29
 
25
30
  // startRpc starts a new server-side RPC.
package/srpc/websocket.ts CHANGED
@@ -24,6 +24,8 @@ export class WebSocketConn extends StreamConn {
24
24
  combineUint8ArrayListTransform(),
25
25
  socketDuplex,
26
26
  )
27
+ .catch((err) => this.close(err))
28
+ .then(() => this.close())
27
29
  }
28
30
 
29
31
  // getSocket returns the websocket.