starpc 0.4.9 → 0.5.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 (65) hide show
  1. package/Makefile +1 -0
  2. package/README.md +20 -10
  3. package/dist/echo/client-test.d.ts +1 -0
  4. package/dist/echo/client-test.js +20 -18
  5. package/dist/echo/echo.pb.d.ts +162 -10
  6. package/dist/echo/echo.pb.js +48 -5
  7. package/dist/echo/server.d.ts +8 -4
  8. package/dist/echo/server.js +29 -37
  9. package/dist/rpcstream/rpcstream.d.ts +6 -6
  10. package/dist/rpcstream/rpcstream.js +92 -51
  11. package/dist/rpcstream/rpcstream.pb.d.ts +44 -0
  12. package/dist/rpcstream/rpcstream.pb.js +151 -4
  13. package/dist/srpc/client.d.ts +3 -4
  14. package/dist/srpc/client.js +12 -46
  15. package/dist/srpc/common-rpc.d.ts +3 -2
  16. package/dist/srpc/common-rpc.js +12 -0
  17. package/dist/srpc/definition.d.ts +3 -3
  18. package/dist/srpc/handler.d.ts +2 -3
  19. package/dist/srpc/handler.js +5 -22
  20. package/dist/srpc/index.d.ts +2 -2
  21. package/dist/srpc/index.js +2 -2
  22. package/dist/srpc/packet.js +0 -32
  23. package/dist/srpc/pushable.d.ts +2 -0
  24. package/dist/srpc/pushable.js +13 -0
  25. package/dist/srpc/rpcproto.pb.d.ts +6 -0
  26. package/dist/srpc/rpcproto.pb.js +84 -0
  27. package/dist/srpc/server.d.ts +1 -0
  28. package/dist/srpc/server.js +7 -0
  29. package/dist/srpc/ts-proto-rpc.d.ts +3 -4
  30. package/e2e/e2e.ts +4 -3
  31. package/e2e/e2e_test.go +24 -1
  32. package/echo/client-test.ts +23 -18
  33. package/echo/echo.pb.go +33 -20
  34. package/echo/echo.pb.ts +75 -20
  35. package/echo/echo.proto +4 -0
  36. package/echo/echo_srpc.pb.go +77 -0
  37. package/echo/server.go +18 -0
  38. package/echo/server.ts +47 -41
  39. package/integration/integration.go +1 -2
  40. package/integration/integration.ts +5 -1
  41. package/integration/integration_srpc.pb.go +139 -0
  42. package/package.json +13 -9
  43. package/patches/{ts-poet+4.14.0.patch → ts-poet+4.15.0.patch} +1 -1
  44. package/patches/ts-proto+1.116.0.patch +14 -0
  45. package/srpc/client.ts +16 -50
  46. package/srpc/common-rpc.ts +14 -2
  47. package/srpc/definition.ts +3 -3
  48. package/srpc/handler.ts +17 -34
  49. package/srpc/index.ts +2 -2
  50. package/srpc/muxed-conn.go +2 -2
  51. package/srpc/packet-rw.go +4 -6
  52. package/srpc/packet.ts +0 -33
  53. package/srpc/pushable.ts +17 -0
  54. package/srpc/rpcproto.pb.ts +106 -0
  55. package/srpc/server-pipe.go +2 -2
  56. package/srpc/server.go +2 -2
  57. package/srpc/server.ts +8 -0
  58. package/srpc/ts-proto-rpc.ts +4 -6
  59. package/srpc/websocket.go +2 -2
  60. package/dist/echo/sever.d.ts +0 -0
  61. package/dist/echo/sever.js +0 -1
  62. package/dist/srpc/observable-source.d.ts +0 -9
  63. package/dist/srpc/observable-source.js +0 -25
  64. package/echo/sever.ts +0 -0
  65. package/srpc/observable-source.ts +0 -40
package/Makefile CHANGED
@@ -109,6 +109,7 @@ gents: $(PROTOWRAP) node_modules
109
109
  --ts_proto_opt=forceLong=long \
110
110
  --ts_proto_opt=oneof=unions \
111
111
  --ts_proto_opt=outputServices=default,outputServices=generic-definitions \
112
+ --ts_proto_opt=useAsyncIterable=true \
112
113
  --proto_path $$(pwd)/vendor \
113
114
  --print_structure \
114
115
  --only_specified_files \
package/README.md CHANGED
@@ -19,19 +19,17 @@ Can use any Stream multiplexer: defaults to [libp2p-mplex] over a WebSocket.
19
19
 
20
20
  # Usage
21
21
 
22
- Starting with the [protobuf-project] repository on the "starpc" branch.
22
+ Start with the [protobuf-project] template repository on the "starpc" branch.
23
+
24
+ [protobuf-project]: https://github.com/aperturerobotics/protobuf-project/tree/starpc
23
25
 
24
26
  Use "git add" to add your new .proto files, then `yarn gen` to generate the
25
- TypeScript and Go code for them.
27
+ TypeScript and Go code.
26
28
 
27
29
  # Examples
28
30
 
29
- See the [protobuf-project] template on the "starpc" branch.
30
-
31
31
  The demo/boilerplate project implements the Echo example below.
32
32
 
33
- [protobuf-project]: https://github.com/aperturerobotics/protobuf-project/tree/starpc
34
-
35
33
  This repository uses protowrap, see the [Makefile](./Makefile).
36
34
 
37
35
  ## Protobuf
@@ -118,6 +116,7 @@ This example demonstrates both the server and client:
118
116
  import { pipe } from 'it-pipe'
119
117
  import { createHandler, createMux, Server, Client, Conn } from 'srpc'
120
118
  import { EchoerDefinition, EchoerServer, runClientTest } from 'srpc/echo'
119
+ import { pushable } from 'it-pushable'
121
120
 
122
121
  const mux = createMux()
123
122
  const echoer = new EchoerServer()
@@ -129,20 +128,31 @@ const serverConn = new Conn(server)
129
128
  pipe(clientConn, serverConn, clientConn)
130
129
  const client = new Client(clientConn.buildOpenStreamFunc())
131
130
 
131
+ // call the unary rpc
132
132
  console.log('Calling Echo: unary call...')
133
133
  let result = await demoServiceClient.Echo({
134
134
  body: 'Hello world!',
135
135
  })
136
136
  console.log('success: output', result.body)
137
137
 
138
- const clientRequestStream = new Observable<EchoMsg>(subscriber => {
139
- subscriber.next({body: 'Hello world from streaming request.'})
140
- subscriber.complete()
141
- })
138
+ // create a client -> server stream
139
+ const clientRequestStream = pushable<EchoMsg>({objectMode: true})
140
+ clientRequestStream.push({body: 'Hello world from streaming request.'})
141
+ clientRequestStream.end()
142
142
 
143
+ // call the client -> server streaming rpc
143
144
  console.log('Calling EchoClientStream: client -> server...')
144
145
  result = await demoServiceClient.EchoClientStream(clientRequestStream)
145
146
  console.log('success: output', result.body)
147
+
148
+ // call the server -> client streaming rpc
149
+ console.log('Calling EchoServerStream: server -> client...')
150
+ const serverStream = demoServiceClient.EchoServerStream({
151
+ body: 'Hello world from server to client streaming request.',
152
+ })
153
+ for await (const msg of serverStream) {
154
+ console.log('server: output', msg.body)
155
+ }
146
156
  ```
147
157
 
148
158
  ## WebSocket
@@ -1,2 +1,3 @@
1
1
  import { Client } from '../srpc/index.js';
2
2
  export declare function runClientTest(client: Client): Promise<void>;
3
+ export declare function runRpcStreamTest(client: Client): Promise<void>;
@@ -1,5 +1,7 @@
1
+ import { Client } from '../srpc/index.js';
1
2
  import { EchoerClientImpl } from './echo.pb.js';
2
- import { Observable } from 'rxjs';
3
+ import { pushable } from 'it-pushable';
4
+ import { buildRpcStreamOpenStream } from '../rpcstream/rpcstream.js';
3
5
  export async function runClientTest(client) {
4
6
  const demoServiceClient = new EchoerClientImpl(client);
5
7
  console.log('Calling Echo: unary call...');
@@ -8,10 +10,9 @@ export async function runClientTest(client) {
8
10
  });
9
11
  console.log('success: output', result.body);
10
12
  // observable for client requests
11
- const clientRequestStream = new Observable((subscriber) => {
12
- subscriber.next({ body: 'Hello world from streaming request.' });
13
- subscriber.complete();
14
- });
13
+ const clientRequestStream = pushable({ objectMode: true });
14
+ clientRequestStream.push({ body: 'Hello world from streaming request.' });
15
+ clientRequestStream.end();
15
16
  console.log('Calling EchoClientStream: client -> server...');
16
17
  result = await demoServiceClient.EchoClientStream(clientRequestStream);
17
18
  console.log('success: output', result.body);
@@ -19,17 +20,18 @@ export async function runClientTest(client) {
19
20
  const serverStream = demoServiceClient.EchoServerStream({
20
21
  body: 'Hello world from server to client streaming request.',
21
22
  });
22
- await new Promise((resolve, reject) => {
23
- serverStream.subscribe({
24
- next(result) {
25
- console.log('server: output', result.body);
26
- },
27
- complete() {
28
- resolve();
29
- },
30
- error(err) {
31
- reject(err);
32
- },
33
- });
34
- });
23
+ for await (const msg of serverStream) {
24
+ console.log('server: output', msg.body);
25
+ }
26
+ }
27
+ // runRpcStreamTest tests a RPCStream.
28
+ export async function runRpcStreamTest(client) {
29
+ console.log('Calling RpcStream to open a RPC stream client...');
30
+ const service = new EchoerClientImpl(client);
31
+ const openStreamFn = buildRpcStreamOpenStream('test', service.RpcStream.bind(service));
32
+ const proxiedClient = new Client(openStreamFn);
33
+ const proxiedService = new EchoerClientImpl(proxiedClient);
34
+ console.log('Calling Echo via RPC stream...');
35
+ const resp = await proxiedService.Echo({ body: 'hello world via proxy' });
36
+ console.log('rpc stream test: succeeded: response: ' + resp.body);
35
37
  }
@@ -1,6 +1,6 @@
1
1
  import Long from 'long';
2
+ import { RpcStreamPacket } from '../rpcstream/rpcstream.pb.js';
2
3
  import * as _m0 from 'protobufjs/minimal';
3
- import { Observable } from 'rxjs';
4
4
  export declare const protobufPackage = "echo";
5
5
  /** EchoMsg is the message body for Echo. */
6
6
  export interface EchoMsg {
@@ -9,6 +9,8 @@ export interface EchoMsg {
9
9
  export declare const EchoMsg: {
10
10
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
11
11
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
12
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
13
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
12
14
  fromJSON(object: any): EchoMsg;
13
15
  toJSON(message: EchoMsg): unknown;
14
16
  fromPartial<I extends {
@@ -22,19 +24,22 @@ export interface Echoer {
22
24
  /** Echo returns the given message. */
23
25
  Echo(request: EchoMsg): Promise<EchoMsg>;
24
26
  /** EchoServerStream is an example of a server -> client one-way stream. */
25
- EchoServerStream(request: EchoMsg): Observable<EchoMsg>;
27
+ EchoServerStream(request: EchoMsg): AsyncIterable<EchoMsg>;
26
28
  /** EchoClientStream is an example of client->server one-way stream. */
27
- EchoClientStream(request: Observable<EchoMsg>): Promise<EchoMsg>;
29
+ EchoClientStream(request: AsyncIterable<EchoMsg>): Promise<EchoMsg>;
28
30
  /** EchoBidiStream is an example of a two-way stream. */
29
- EchoBidiStream(request: Observable<EchoMsg>): Observable<EchoMsg>;
31
+ EchoBidiStream(request: AsyncIterable<EchoMsg>): AsyncIterable<EchoMsg>;
32
+ /** RpcStream opens a nested rpc call stream. */
33
+ RpcStream(request: AsyncIterable<RpcStreamPacket>): AsyncIterable<RpcStreamPacket>;
30
34
  }
31
35
  export declare class EchoerClientImpl implements Echoer {
32
36
  private readonly rpc;
33
37
  constructor(rpc: Rpc);
34
38
  Echo(request: EchoMsg): Promise<EchoMsg>;
35
- EchoServerStream(request: EchoMsg): Observable<EchoMsg>;
36
- EchoClientStream(request: Observable<EchoMsg>): Promise<EchoMsg>;
37
- EchoBidiStream(request: Observable<EchoMsg>): Observable<EchoMsg>;
39
+ EchoServerStream(request: EchoMsg): AsyncIterable<EchoMsg>;
40
+ EchoClientStream(request: AsyncIterable<EchoMsg>): Promise<EchoMsg>;
41
+ EchoBidiStream(request: AsyncIterable<EchoMsg>): AsyncIterable<EchoMsg>;
42
+ RpcStream(request: AsyncIterable<RpcStreamPacket>): AsyncIterable<RpcStreamPacket>;
38
43
  }
39
44
  /** Echoer service returns the given message. */
40
45
  export declare type EchoerDefinition = typeof EchoerDefinition;
@@ -48,6 +53,8 @@ export declare const EchoerDefinition: {
48
53
  readonly requestType: {
49
54
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
50
55
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
56
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
57
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
51
58
  fromJSON(object: any): EchoMsg;
52
59
  toJSON(message: EchoMsg): unknown;
53
60
  fromPartial<I extends {
@@ -60,6 +67,8 @@ export declare const EchoerDefinition: {
60
67
  readonly responseType: {
61
68
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
62
69
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
70
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
71
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
63
72
  fromJSON(object: any): EchoMsg;
64
73
  toJSON(message: EchoMsg): unknown;
65
74
  fromPartial<I extends {
@@ -77,6 +86,8 @@ export declare const EchoerDefinition: {
77
86
  readonly requestType: {
78
87
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
79
88
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
89
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
90
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
80
91
  fromJSON(object: any): EchoMsg;
81
92
  toJSON(message: EchoMsg): unknown;
82
93
  fromPartial<I extends {
@@ -89,6 +100,8 @@ export declare const EchoerDefinition: {
89
100
  readonly responseType: {
90
101
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
91
102
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
103
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
104
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
92
105
  fromJSON(object: any): EchoMsg;
93
106
  toJSON(message: EchoMsg): unknown;
94
107
  fromPartial<I extends {
@@ -106,6 +119,8 @@ export declare const EchoerDefinition: {
106
119
  readonly requestType: {
107
120
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
108
121
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
122
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
123
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
109
124
  fromJSON(object: any): EchoMsg;
110
125
  toJSON(message: EchoMsg): unknown;
111
126
  fromPartial<I extends {
@@ -118,6 +133,8 @@ export declare const EchoerDefinition: {
118
133
  readonly responseType: {
119
134
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
120
135
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
136
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
137
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
121
138
  fromJSON(object: any): EchoMsg;
122
139
  toJSON(message: EchoMsg): unknown;
123
140
  fromPartial<I extends {
@@ -135,6 +152,8 @@ export declare const EchoerDefinition: {
135
152
  readonly requestType: {
136
153
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
137
154
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
155
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
156
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
138
157
  fromJSON(object: any): EchoMsg;
139
158
  toJSON(message: EchoMsg): unknown;
140
159
  fromPartial<I extends {
@@ -147,6 +166,8 @@ export declare const EchoerDefinition: {
147
166
  readonly responseType: {
148
167
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
149
168
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
169
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
170
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
150
171
  fromJSON(object: any): EchoMsg;
151
172
  toJSON(message: EchoMsg): unknown;
152
173
  fromPartial<I extends {
@@ -158,13 +179,144 @@ export declare const EchoerDefinition: {
158
179
  readonly responseStream: true;
159
180
  readonly options: {};
160
181
  };
182
+ /** RpcStream opens a nested rpc call stream. */
183
+ readonly rpcStream: {
184
+ readonly name: "RpcStream";
185
+ readonly requestType: {
186
+ encode(message: RpcStreamPacket, writer?: _m0.Writer): _m0.Writer;
187
+ decode(input: Uint8Array | _m0.Reader, length?: number | undefined): RpcStreamPacket;
188
+ encodeTransform(source: AsyncIterable<RpcStreamPacket | RpcStreamPacket[]> | Iterable<RpcStreamPacket | RpcStreamPacket[]>): AsyncIterable<Uint8Array>;
189
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<RpcStreamPacket>;
190
+ fromJSON(object: any): RpcStreamPacket;
191
+ toJSON(message: RpcStreamPacket): unknown;
192
+ fromPartial<I_1 extends {
193
+ body?: ({
194
+ init?: {
195
+ componentId?: string | undefined;
196
+ } | undefined;
197
+ } & {
198
+ $case: "init";
199
+ }) | ({
200
+ ack?: {
201
+ error?: string | undefined;
202
+ } | undefined;
203
+ } & {
204
+ $case: "ack";
205
+ }) | ({
206
+ data?: Uint8Array | undefined;
207
+ } & {
208
+ $case: "data";
209
+ }) | undefined;
210
+ } & {
211
+ body?: ({
212
+ init?: {
213
+ componentId?: string | undefined;
214
+ } | undefined;
215
+ } & {
216
+ $case: "init";
217
+ } & {
218
+ init?: ({
219
+ componentId?: string | undefined;
220
+ } & {
221
+ componentId?: string | undefined;
222
+ } & Record<Exclude<keyof I_1["body"]["init"], "componentId">, never>) | undefined;
223
+ $case: "init";
224
+ } & Record<Exclude<keyof I_1["body"], "$case" | "init">, never>) | ({
225
+ ack?: {
226
+ error?: string | undefined;
227
+ } | undefined;
228
+ } & {
229
+ $case: "ack";
230
+ } & {
231
+ ack?: ({
232
+ error?: string | undefined;
233
+ } & {
234
+ error?: string | undefined;
235
+ } & Record<Exclude<keyof I_1["body"]["ack"], "error">, never>) | undefined;
236
+ $case: "ack";
237
+ } & Record<Exclude<keyof I_1["body"], "$case" | "ack">, never>) | ({
238
+ data?: Uint8Array | undefined;
239
+ } & {
240
+ $case: "data";
241
+ } & {
242
+ data?: Uint8Array | undefined;
243
+ $case: "data";
244
+ } & Record<Exclude<keyof I_1["body"], "$case" | "data">, never>) | undefined;
245
+ } & Record<Exclude<keyof I_1, "body">, never>>(object: I_1): RpcStreamPacket;
246
+ };
247
+ readonly requestStream: true;
248
+ readonly responseType: {
249
+ encode(message: RpcStreamPacket, writer?: _m0.Writer): _m0.Writer;
250
+ decode(input: Uint8Array | _m0.Reader, length?: number | undefined): RpcStreamPacket;
251
+ encodeTransform(source: AsyncIterable<RpcStreamPacket | RpcStreamPacket[]> | Iterable<RpcStreamPacket | RpcStreamPacket[]>): AsyncIterable<Uint8Array>;
252
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<RpcStreamPacket>;
253
+ fromJSON(object: any): RpcStreamPacket;
254
+ toJSON(message: RpcStreamPacket): unknown;
255
+ fromPartial<I_1 extends {
256
+ body?: ({
257
+ init?: {
258
+ componentId?: string | undefined;
259
+ } | undefined;
260
+ } & {
261
+ $case: "init";
262
+ }) | ({
263
+ ack?: {
264
+ error?: string | undefined;
265
+ } | undefined;
266
+ } & {
267
+ $case: "ack";
268
+ }) | ({
269
+ data?: Uint8Array | undefined;
270
+ } & {
271
+ $case: "data";
272
+ }) | undefined;
273
+ } & {
274
+ body?: ({
275
+ init?: {
276
+ componentId?: string | undefined;
277
+ } | undefined;
278
+ } & {
279
+ $case: "init";
280
+ } & {
281
+ init?: ({
282
+ componentId?: string | undefined;
283
+ } & {
284
+ componentId?: string | undefined;
285
+ } & Record<Exclude<keyof I_1["body"]["init"], "componentId">, never>) | undefined;
286
+ $case: "init";
287
+ } & Record<Exclude<keyof I_1["body"], "$case" | "init">, never>) | ({
288
+ ack?: {
289
+ error?: string | undefined;
290
+ } | undefined;
291
+ } & {
292
+ $case: "ack";
293
+ } & {
294
+ ack?: ({
295
+ error?: string | undefined;
296
+ } & {
297
+ error?: string | undefined;
298
+ } & Record<Exclude<keyof I_1["body"]["ack"], "error">, never>) | undefined;
299
+ $case: "ack";
300
+ } & Record<Exclude<keyof I_1["body"], "$case" | "ack">, never>) | ({
301
+ data?: Uint8Array | undefined;
302
+ } & {
303
+ $case: "data";
304
+ } & {
305
+ data?: Uint8Array | undefined;
306
+ $case: "data";
307
+ } & Record<Exclude<keyof I_1["body"], "$case" | "data">, never>) | undefined;
308
+ } & Record<Exclude<keyof I_1, "body">, never>>(object: I_1): RpcStreamPacket;
309
+ };
310
+ readonly responseStream: true;
311
+ readonly options: {};
312
+ };
161
313
  };
162
314
  };
163
315
  interface Rpc {
164
316
  request(service: string, method: string, data: Uint8Array): Promise<Uint8Array>;
165
- clientStreamingRequest(service: string, method: string, data: Observable<Uint8Array>): Promise<Uint8Array>;
166
- serverStreamingRequest(service: string, method: string, data: Uint8Array): Observable<Uint8Array>;
167
- bidirectionalStreamingRequest(service: string, method: string, data: Observable<Uint8Array>): Observable<Uint8Array>;
317
+ clientStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array>): Promise<Uint8Array>;
318
+ serverStreamingRequest(service: string, method: string, data: Uint8Array): AsyncIterable<Uint8Array>;
319
+ bidirectionalStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array>): AsyncIterable<Uint8Array>;
168
320
  }
169
321
  declare type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
170
322
  export declare type DeepPartial<T> = T extends Builtin ? T : T extends Long ? string | number | Long : T extends Array<infer U> ? Array<DeepPartial<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : T extends {
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable */
2
2
  import Long from 'long';
3
+ import { RpcStreamPacket } from '../rpcstream/rpcstream.pb.js';
3
4
  import * as _m0 from 'protobufjs/minimal';
4
- import { map } from 'rxjs/operators';
5
5
  export const protobufPackage = 'echo';
6
6
  function createBaseEchoMsg() {
7
7
  return { body: '' };
@@ -30,6 +30,34 @@ export const EchoMsg = {
30
30
  }
31
31
  return message;
32
32
  },
33
+ // encodeTransform encodes a source of message objects.
34
+ // Transform<EchoMsg, Uint8Array>
35
+ async *encodeTransform(source) {
36
+ for await (const pkt of source) {
37
+ if (Array.isArray(pkt)) {
38
+ for (const p of pkt) {
39
+ yield* [EchoMsg.encode(p).finish()];
40
+ }
41
+ }
42
+ else {
43
+ yield* [EchoMsg.encode(pkt).finish()];
44
+ }
45
+ }
46
+ },
47
+ // decodeTransform decodes a source of encoded messages.
48
+ // Transform<Uint8Array, EchoMsg>
49
+ async *decodeTransform(source) {
50
+ for await (const pkt of source) {
51
+ if (Array.isArray(pkt)) {
52
+ for (const p of pkt) {
53
+ yield* [EchoMsg.decode(p)];
54
+ }
55
+ }
56
+ else {
57
+ yield* [EchoMsg.decode(pkt)];
58
+ }
59
+ }
60
+ },
33
61
  fromJSON(object) {
34
62
  return {
35
63
  body: isSet(object.body) ? String(object.body) : '',
@@ -53,6 +81,7 @@ export class EchoerClientImpl {
53
81
  this.EchoServerStream = this.EchoServerStream.bind(this);
54
82
  this.EchoClientStream = this.EchoClientStream.bind(this);
55
83
  this.EchoBidiStream = this.EchoBidiStream.bind(this);
84
+ this.RpcStream = this.RpcStream.bind(this);
56
85
  }
57
86
  Echo(request) {
58
87
  const data = EchoMsg.encode(request).finish();
@@ -62,17 +91,22 @@ export class EchoerClientImpl {
62
91
  EchoServerStream(request) {
63
92
  const data = EchoMsg.encode(request).finish();
64
93
  const result = this.rpc.serverStreamingRequest('echo.Echoer', 'EchoServerStream', data);
65
- return result.pipe(map((data) => EchoMsg.decode(new _m0.Reader(data))));
94
+ return EchoMsg.decodeTransform(result);
66
95
  }
67
96
  EchoClientStream(request) {
68
- const data = request.pipe(map((request) => EchoMsg.encode(request).finish()));
97
+ const data = EchoMsg.encodeTransform(request);
69
98
  const promise = this.rpc.clientStreamingRequest('echo.Echoer', 'EchoClientStream', data);
70
99
  return promise.then((data) => EchoMsg.decode(new _m0.Reader(data)));
71
100
  }
72
101
  EchoBidiStream(request) {
73
- const data = request.pipe(map((request) => EchoMsg.encode(request).finish()));
102
+ const data = EchoMsg.encodeTransform(request);
74
103
  const result = this.rpc.bidirectionalStreamingRequest('echo.Echoer', 'EchoBidiStream', data);
75
- return result.pipe(map((data) => EchoMsg.decode(new _m0.Reader(data))));
104
+ return EchoMsg.decodeTransform(result);
105
+ }
106
+ RpcStream(request) {
107
+ const data = RpcStreamPacket.encodeTransform(request);
108
+ const result = this.rpc.bidirectionalStreamingRequest('echo.Echoer', 'RpcStream', data);
109
+ return RpcStreamPacket.decodeTransform(result);
76
110
  }
77
111
  }
78
112
  export const EchoerDefinition = {
@@ -115,6 +149,15 @@ export const EchoerDefinition = {
115
149
  responseStream: true,
116
150
  options: {},
117
151
  },
152
+ /** RpcStream opens a nested rpc call stream. */
153
+ rpcStream: {
154
+ name: 'RpcStream',
155
+ requestType: RpcStreamPacket,
156
+ requestStream: true,
157
+ responseType: RpcStreamPacket,
158
+ responseStream: true,
159
+ options: {},
160
+ },
118
161
  },
119
162
  };
120
163
  if (_m0.util.Long !== Long) {
@@ -1,8 +1,12 @@
1
- import { Observable } from 'rxjs';
2
1
  import { Echoer, EchoMsg } from './echo.pb.js';
2
+ import { Server } from '../srpc/server.js';
3
+ import { RpcStreamPacket } from '../rpcstream/rpcstream.pb.js';
3
4
  export declare class EchoerServer implements Echoer {
5
+ private proxyServer?;
6
+ constructor(proxyServer?: Server);
4
7
  Echo(request: EchoMsg): Promise<EchoMsg>;
5
- EchoServerStream(request: EchoMsg): Observable<EchoMsg>;
6
- EchoClientStream(request: Observable<EchoMsg>): Promise<EchoMsg>;
7
- EchoBidiStream(request: Observable<EchoMsg>): Observable<EchoMsg>;
8
+ EchoServerStream(request: EchoMsg): AsyncIterable<EchoMsg>;
9
+ EchoClientStream(request: AsyncIterable<EchoMsg>): Promise<EchoMsg>;
10
+ EchoBidiStream(request: AsyncIterable<EchoMsg>): AsyncIterable<EchoMsg>;
11
+ RpcStream(request: AsyncIterable<RpcStreamPacket>): AsyncIterable<RpcStreamPacket>;
8
12
  }
@@ -1,50 +1,42 @@
1
- import { from as observableFrom } from 'rxjs';
2
1
  import { pushable } from 'it-pushable';
2
+ import first from 'it-first';
3
+ import { writeToPushable } from '../srpc/pushable.js';
4
+ import { handleRpcStream } from '../rpcstream/rpcstream.js';
3
5
  // EchoServer implements the Echoer server.
4
6
  export class EchoerServer {
7
+ constructor(proxyServer) {
8
+ this.proxyServer = proxyServer;
9
+ }
5
10
  async Echo(request) {
6
11
  return request;
7
12
  }
8
- EchoServerStream(request) {
9
- // send 5 responses, with a 200ms delay for each
10
- return observableFrom((async function* response() {
11
- for (let i = 0; i < 5; i++) {
12
- yield request;
13
- await new Promise((resolve) => setTimeout(resolve, 200));
14
- }
15
- })());
13
+ async *EchoServerStream(request) {
14
+ for (let i = 0; i < 5; i++) {
15
+ yield request;
16
+ await new Promise((resolve) => setTimeout(resolve, 200));
17
+ }
16
18
  }
17
- EchoClientStream(request) {
18
- return new Promise((resolve, reject) => {
19
- request.subscribe({
20
- next(msg) {
21
- resolve(msg);
22
- },
23
- error(err) {
24
- reject(err);
25
- },
26
- complete() {
27
- reject(new Error('none received'));
28
- },
29
- });
30
- });
19
+ async EchoClientStream(request) {
20
+ // return the first message sent by the client.
21
+ const message = await first(request);
22
+ if (!message) {
23
+ throw new Error('received no messages');
24
+ }
25
+ return message;
31
26
  }
32
27
  EchoBidiStream(request) {
33
28
  // build result observable
34
- const pushResponse = pushable({ objectMode: true });
35
- const response = observableFrom(pushResponse);
36
- pushResponse.push({ body: 'hello from server' });
37
- request.subscribe({
38
- next(msg) {
39
- pushResponse.push(msg);
40
- },
41
- error(err) {
42
- pushResponse.throw(err);
43
- },
44
- complete() {
45
- pushResponse.end();
46
- },
29
+ const result = pushable({ objectMode: true });
30
+ result.push({ body: 'hello from server' });
31
+ writeToPushable(request, result);
32
+ return result;
33
+ }
34
+ RpcStream(request) {
35
+ return handleRpcStream(request[Symbol.asyncIterator](), async (_componentId) => {
36
+ if (!this.proxyServer) {
37
+ throw new Error('rpc stream proxy server not set');
38
+ }
39
+ return this.proxyServer;
47
40
  });
48
- return response;
49
41
  }
50
42
  }
@@ -1,19 +1,19 @@
1
- import { Observable } from 'rxjs';
2
1
  import { RpcStreamPacket } from './rpcstream.pb.js';
3
2
  import { Server } from '../srpc/server.js';
4
3
  import { OpenStreamFunc, Stream } from '../srpc/stream.js';
5
4
  import { Pushable } from 'it-pushable';
6
5
  import { Source, Sink } from 'it-stream-types';
7
- export declare type RpcStreamCaller = (request: Observable<RpcStreamPacket>) => Observable<RpcStreamPacket>;
6
+ export declare type RpcStreamCaller = (request: AsyncIterable<RpcStreamPacket>) => AsyncIterable<RpcStreamPacket>;
7
+ export declare function openRpcStream(componentId: string, caller: RpcStreamCaller): Promise<Stream>;
8
8
  export declare function buildRpcStreamOpenStream(componentId: string, caller: RpcStreamCaller): OpenStreamFunc;
9
9
  export declare type RpcStreamGetter = (componentId: string) => Promise<Server>;
10
- export declare function handleRpcStream(stream: Observable<RpcStreamPacket>, getter: RpcStreamGetter): AsyncIterable<RpcStreamPacket>;
10
+ export declare function handleRpcStream(packetStream: AsyncIterator<RpcStreamPacket>, getter: RpcStreamGetter): AsyncIterable<RpcStreamPacket>;
11
11
  export declare class RpcStream implements Stream {
12
12
  readonly source: Source<Uint8Array>;
13
13
  readonly sink: Sink<Uint8Array>;
14
+ private readonly _packetStream;
14
15
  private readonly _packetSink;
15
- private readonly _source;
16
- constructor(packetSink: Pushable<RpcStreamPacket>, packetSource: Observable<RpcStreamPacket>);
16
+ constructor(packetSink: Pushable<RpcStreamPacket>, packetStream: AsyncIterator<RpcStreamPacket>);
17
17
  private _createSink;
18
- private _subscribeRpcStreamPacketSource;
18
+ private _createSource;
19
19
  }