starpc 0.4.7 → 0.5.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 (68) 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 +165 -12
  6. package/dist/echo/echo.pb.js +61 -17
  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 +46 -1
  12. package/dist/rpcstream/rpcstream.pb.js +157 -9
  13. package/dist/srpc/broadcast-channel.d.ts +2 -2
  14. package/dist/srpc/broadcast-channel.js +6 -6
  15. package/dist/srpc/client.d.ts +3 -4
  16. package/dist/srpc/client.js +12 -46
  17. package/dist/srpc/common-rpc.d.ts +3 -2
  18. package/dist/srpc/common-rpc.js +12 -0
  19. package/dist/srpc/definition.d.ts +3 -3
  20. package/dist/srpc/handler.d.ts +2 -3
  21. package/dist/srpc/handler.js +5 -22
  22. package/dist/srpc/index.d.ts +2 -2
  23. package/dist/srpc/index.js +2 -2
  24. package/dist/srpc/packet.js +0 -32
  25. package/dist/srpc/pushable.d.ts +2 -0
  26. package/dist/srpc/pushable.js +13 -0
  27. package/dist/srpc/rpcproto.pb.d.ts +13 -6
  28. package/dist/srpc/rpcproto.pb.js +95 -10
  29. package/dist/srpc/server.d.ts +1 -0
  30. package/dist/srpc/server.js +7 -0
  31. package/dist/srpc/ts-proto-rpc.d.ts +3 -4
  32. package/e2e/e2e.ts +4 -3
  33. package/e2e/e2e_test.go +35 -7
  34. package/echo/client-test.ts +23 -18
  35. package/echo/echo.pb.go +33 -20
  36. package/echo/echo.pb.ts +90 -34
  37. package/echo/echo.proto +4 -0
  38. package/echo/echo_srpc.pb.go +77 -0
  39. package/echo/server.go +18 -0
  40. package/echo/server.ts +47 -41
  41. package/integration/integration.go +1 -2
  42. package/integration/integration.ts +5 -1
  43. package/integration/integration_srpc.pb.go +139 -0
  44. package/package.json +13 -11
  45. package/patches/{ts-poet+4.13.0.patch → ts-poet+4.14.0.patch} +1 -1
  46. package/patches/ts-proto+1.115.5.patch +1339 -0
  47. package/srpc/broadcast-channel.ts +8 -8
  48. package/srpc/client.ts +16 -50
  49. package/srpc/common-rpc.ts +14 -2
  50. package/srpc/definition.ts +3 -3
  51. package/srpc/handler.ts +17 -34
  52. package/srpc/index.ts +3 -3
  53. package/srpc/muxed-conn.go +2 -2
  54. package/srpc/packet-rw.go +4 -6
  55. package/srpc/packet.ts +0 -33
  56. package/srpc/pushable.ts +17 -0
  57. package/srpc/rpcproto.pb.ts +122 -12
  58. package/srpc/server-pipe.go +2 -2
  59. package/srpc/server.go +2 -2
  60. package/srpc/server.ts +8 -0
  61. package/srpc/ts-proto-rpc.ts +4 -6
  62. package/srpc/websocket.go +2 -2
  63. package/dist/echo/sever.d.ts +0 -0
  64. package/dist/echo/sever.js +0 -1
  65. package/dist/srpc/observable-source.d.ts +0 -9
  66. package/dist/srpc/observable-source.js +0 -25
  67. package/echo/sever.ts +0 -0
  68. 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,7 @@
1
1
  import Long from 'long';
2
+ import { EchoMsg as EchoMsg1 } from './echo.pb.js';
3
+ import { RpcStreamPacket } from '../rpcstream/rpcstream.pb.js';
2
4
  import * as _m0 from 'protobufjs/minimal';
3
- import { Observable } from 'rxjs';
4
5
  export declare const protobufPackage = "echo";
5
6
  /** EchoMsg is the message body for Echo. */
6
7
  export interface EchoMsg {
@@ -9,6 +10,8 @@ export interface EchoMsg {
9
10
  export declare const EchoMsg: {
10
11
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
11
12
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
13
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
14
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
12
15
  fromJSON(object: any): EchoMsg;
13
16
  toJSON(message: EchoMsg): unknown;
14
17
  fromPartial<I extends {
@@ -20,21 +23,24 @@ export declare const EchoMsg: {
20
23
  /** Echoer service returns the given message. */
21
24
  export interface Echoer {
22
25
  /** Echo returns the given message. */
23
- Echo(request: EchoMsg): Promise<EchoMsg>;
26
+ Echo(request: EchoMsg1): Promise<EchoMsg1>;
24
27
  /** EchoServerStream is an example of a server -> client one-way stream. */
25
- EchoServerStream(request: EchoMsg): Observable<EchoMsg>;
28
+ EchoServerStream(request: EchoMsg1): AsyncIterable<EchoMsg1>;
26
29
  /** EchoClientStream is an example of client->server one-way stream. */
27
- EchoClientStream(request: Observable<EchoMsg>): Promise<EchoMsg>;
30
+ EchoClientStream(request: AsyncIterable<EchoMsg1>): Promise<EchoMsg1>;
28
31
  /** EchoBidiStream is an example of a two-way stream. */
29
- EchoBidiStream(request: Observable<EchoMsg>): Observable<EchoMsg>;
32
+ EchoBidiStream(request: AsyncIterable<EchoMsg1>): AsyncIterable<EchoMsg1>;
33
+ /** RpcStream opens a nested rpc call stream. */
34
+ RpcStream(request: AsyncIterable<RpcStreamPacket>): AsyncIterable<RpcStreamPacket>;
30
35
  }
31
36
  export declare class EchoerClientImpl implements Echoer {
32
37
  private readonly rpc;
33
38
  constructor(rpc: Rpc);
34
- 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
+ Echo(request: EchoMsg1): Promise<EchoMsg1>;
40
+ EchoServerStream(request: EchoMsg1): AsyncIterable<EchoMsg1>;
41
+ EchoClientStream(request: AsyncIterable<EchoMsg1>): Promise<EchoMsg1>;
42
+ EchoBidiStream(request: AsyncIterable<EchoMsg1>): AsyncIterable<EchoMsg1>;
43
+ RpcStream(request: AsyncIterable<RpcStreamPacket>): AsyncIterable<RpcStreamPacket>;
38
44
  }
39
45
  /** Echoer service returns the given message. */
40
46
  export declare type EchoerDefinition = typeof EchoerDefinition;
@@ -48,6 +54,8 @@ export declare const EchoerDefinition: {
48
54
  readonly requestType: {
49
55
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
50
56
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
57
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
58
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
51
59
  fromJSON(object: any): EchoMsg;
52
60
  toJSON(message: EchoMsg): unknown;
53
61
  fromPartial<I extends {
@@ -60,6 +68,8 @@ export declare const EchoerDefinition: {
60
68
  readonly responseType: {
61
69
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
62
70
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
71
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
72
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
63
73
  fromJSON(object: any): EchoMsg;
64
74
  toJSON(message: EchoMsg): unknown;
65
75
  fromPartial<I extends {
@@ -77,6 +87,8 @@ export declare const EchoerDefinition: {
77
87
  readonly requestType: {
78
88
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
79
89
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
90
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
91
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
80
92
  fromJSON(object: any): EchoMsg;
81
93
  toJSON(message: EchoMsg): unknown;
82
94
  fromPartial<I extends {
@@ -89,6 +101,8 @@ export declare const EchoerDefinition: {
89
101
  readonly responseType: {
90
102
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
91
103
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
104
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
105
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
92
106
  fromJSON(object: any): EchoMsg;
93
107
  toJSON(message: EchoMsg): unknown;
94
108
  fromPartial<I extends {
@@ -106,6 +120,8 @@ export declare const EchoerDefinition: {
106
120
  readonly requestType: {
107
121
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
108
122
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
123
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
124
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
109
125
  fromJSON(object: any): EchoMsg;
110
126
  toJSON(message: EchoMsg): unknown;
111
127
  fromPartial<I extends {
@@ -118,6 +134,8 @@ export declare const EchoerDefinition: {
118
134
  readonly responseType: {
119
135
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
120
136
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
137
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
138
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
121
139
  fromJSON(object: any): EchoMsg;
122
140
  toJSON(message: EchoMsg): unknown;
123
141
  fromPartial<I extends {
@@ -135,6 +153,8 @@ export declare const EchoerDefinition: {
135
153
  readonly requestType: {
136
154
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
137
155
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
156
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
157
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
138
158
  fromJSON(object: any): EchoMsg;
139
159
  toJSON(message: EchoMsg): unknown;
140
160
  fromPartial<I extends {
@@ -147,6 +167,8 @@ export declare const EchoerDefinition: {
147
167
  readonly responseType: {
148
168
  encode(message: EchoMsg, writer?: _m0.Writer): _m0.Writer;
149
169
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg;
170
+ encodeTransform(source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>): AsyncIterable<Uint8Array>;
171
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<EchoMsg>;
150
172
  fromJSON(object: any): EchoMsg;
151
173
  toJSON(message: EchoMsg): unknown;
152
174
  fromPartial<I extends {
@@ -158,13 +180,144 @@ export declare const EchoerDefinition: {
158
180
  readonly responseStream: true;
159
181
  readonly options: {};
160
182
  };
183
+ /** RpcStream opens a nested rpc call stream. */
184
+ readonly rpcStream: {
185
+ readonly name: "RpcStream";
186
+ readonly requestType: {
187
+ encode(message: RpcStreamPacket, writer?: _m0.Writer): _m0.Writer;
188
+ decode(input: Uint8Array | _m0.Reader, length?: number | undefined): RpcStreamPacket;
189
+ encodeTransform(source: AsyncIterable<RpcStreamPacket | RpcStreamPacket[]> | Iterable<RpcStreamPacket | RpcStreamPacket[]>): AsyncIterable<Uint8Array>;
190
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<RpcStreamPacket>;
191
+ fromJSON(object: any): RpcStreamPacket;
192
+ toJSON(message: RpcStreamPacket): unknown;
193
+ fromPartial<I_1 extends {
194
+ body?: ({
195
+ init?: {
196
+ componentId?: string | undefined;
197
+ } | undefined;
198
+ } & {
199
+ $case: "init";
200
+ }) | ({
201
+ ack?: {
202
+ error?: string | undefined;
203
+ } | undefined;
204
+ } & {
205
+ $case: "ack";
206
+ }) | ({
207
+ data?: Uint8Array | undefined;
208
+ } & {
209
+ $case: "data";
210
+ }) | undefined;
211
+ } & {
212
+ body?: ({
213
+ init?: {
214
+ componentId?: string | undefined;
215
+ } | undefined;
216
+ } & {
217
+ $case: "init";
218
+ } & {
219
+ init?: ({
220
+ componentId?: string | undefined;
221
+ } & {
222
+ componentId?: string | undefined;
223
+ } & Record<Exclude<keyof I_1["body"]["init"], "componentId">, never>) | undefined;
224
+ $case: "init";
225
+ } & Record<Exclude<keyof I_1["body"], "$case" | "init">, never>) | ({
226
+ ack?: {
227
+ error?: string | undefined;
228
+ } | undefined;
229
+ } & {
230
+ $case: "ack";
231
+ } & {
232
+ ack?: ({
233
+ error?: string | undefined;
234
+ } & {
235
+ error?: string | undefined;
236
+ } & Record<Exclude<keyof I_1["body"]["ack"], "error">, never>) | undefined;
237
+ $case: "ack";
238
+ } & Record<Exclude<keyof I_1["body"], "$case" | "ack">, never>) | ({
239
+ data?: Uint8Array | undefined;
240
+ } & {
241
+ $case: "data";
242
+ } & {
243
+ data?: Uint8Array | undefined;
244
+ $case: "data";
245
+ } & Record<Exclude<keyof I_1["body"], "$case" | "data">, never>) | undefined;
246
+ } & Record<Exclude<keyof I_1, "body">, never>>(object: I_1): RpcStreamPacket;
247
+ };
248
+ readonly requestStream: true;
249
+ readonly responseType: {
250
+ encode(message: RpcStreamPacket, writer?: _m0.Writer): _m0.Writer;
251
+ decode(input: Uint8Array | _m0.Reader, length?: number | undefined): RpcStreamPacket;
252
+ encodeTransform(source: AsyncIterable<RpcStreamPacket | RpcStreamPacket[]> | Iterable<RpcStreamPacket | RpcStreamPacket[]>): AsyncIterable<Uint8Array>;
253
+ decodeTransform(source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>): AsyncIterable<RpcStreamPacket>;
254
+ fromJSON(object: any): RpcStreamPacket;
255
+ toJSON(message: RpcStreamPacket): unknown;
256
+ fromPartial<I_1 extends {
257
+ body?: ({
258
+ init?: {
259
+ componentId?: string | undefined;
260
+ } | undefined;
261
+ } & {
262
+ $case: "init";
263
+ }) | ({
264
+ ack?: {
265
+ error?: string | undefined;
266
+ } | undefined;
267
+ } & {
268
+ $case: "ack";
269
+ }) | ({
270
+ data?: Uint8Array | undefined;
271
+ } & {
272
+ $case: "data";
273
+ }) | undefined;
274
+ } & {
275
+ body?: ({
276
+ init?: {
277
+ componentId?: string | undefined;
278
+ } | undefined;
279
+ } & {
280
+ $case: "init";
281
+ } & {
282
+ init?: ({
283
+ componentId?: string | undefined;
284
+ } & {
285
+ componentId?: string | undefined;
286
+ } & Record<Exclude<keyof I_1["body"]["init"], "componentId">, never>) | undefined;
287
+ $case: "init";
288
+ } & Record<Exclude<keyof I_1["body"], "$case" | "init">, never>) | ({
289
+ ack?: {
290
+ error?: string | undefined;
291
+ } | undefined;
292
+ } & {
293
+ $case: "ack";
294
+ } & {
295
+ ack?: ({
296
+ error?: string | undefined;
297
+ } & {
298
+ error?: string | undefined;
299
+ } & Record<Exclude<keyof I_1["body"]["ack"], "error">, never>) | undefined;
300
+ $case: "ack";
301
+ } & Record<Exclude<keyof I_1["body"], "$case" | "ack">, never>) | ({
302
+ data?: Uint8Array | undefined;
303
+ } & {
304
+ $case: "data";
305
+ } & {
306
+ data?: Uint8Array | undefined;
307
+ $case: "data";
308
+ } & Record<Exclude<keyof I_1["body"], "$case" | "data">, never>) | undefined;
309
+ } & Record<Exclude<keyof I_1, "body">, never>>(object: I_1): RpcStreamPacket;
310
+ };
311
+ readonly responseStream: true;
312
+ readonly options: {};
313
+ };
161
314
  };
162
315
  };
163
316
  interface Rpc {
164
317
  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>;
318
+ clientStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array>): Promise<Uint8Array>;
319
+ serverStreamingRequest(service: string, method: string, data: Uint8Array): AsyncIterable<Uint8Array>;
320
+ bidirectionalStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array>): AsyncIterable<Uint8Array>;
168
321
  }
169
322
  declare type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
170
323
  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,8 @@
1
1
  /* eslint-disable */
2
2
  import Long from 'long';
3
+ import { EchoMsg as EchoMsg1 } from './echo.pb.js';
4
+ import { RpcStreamPacket } from '../rpcstream/rpcstream.pb.js';
3
5
  import * as _m0 from 'protobufjs/minimal';
4
- import { map } from 'rxjs/operators';
5
6
  export const protobufPackage = 'echo';
6
7
  function createBaseEchoMsg() {
7
8
  return { body: '' };
@@ -30,6 +31,34 @@ export const EchoMsg = {
30
31
  }
31
32
  return message;
32
33
  },
34
+ // encodeTransform encodes a source of message objects.
35
+ // Transform<EchoMsg, Uint8Array>
36
+ async *encodeTransform(source) {
37
+ for await (const pkt of source) {
38
+ if (Array.isArray(pkt)) {
39
+ for (const p of pkt) {
40
+ yield* [EchoMsg.encode(p).finish()];
41
+ }
42
+ }
43
+ else {
44
+ yield* [EchoMsg.encode(pkt).finish()];
45
+ }
46
+ }
47
+ },
48
+ // decodeTransform decodes a source of encoded messages.
49
+ // Transform<Uint8Array, EchoMsg>
50
+ async *decodeTransform(source) {
51
+ for await (const pkt of source) {
52
+ if (Array.isArray(pkt)) {
53
+ for (const p of pkt) {
54
+ yield* [EchoMsg.decode(p)];
55
+ }
56
+ }
57
+ else {
58
+ yield* [EchoMsg.decode(pkt)];
59
+ }
60
+ }
61
+ },
33
62
  fromJSON(object) {
34
63
  return {
35
64
  body: isSet(object.body) ? String(object.body) : '',
@@ -53,26 +82,32 @@ export class EchoerClientImpl {
53
82
  this.EchoServerStream = this.EchoServerStream.bind(this);
54
83
  this.EchoClientStream = this.EchoClientStream.bind(this);
55
84
  this.EchoBidiStream = this.EchoBidiStream.bind(this);
85
+ this.RpcStream = this.RpcStream.bind(this);
56
86
  }
57
87
  Echo(request) {
58
- const data = EchoMsg.encode(request).finish();
88
+ const data = EchoMsg1.encode(request).finish();
59
89
  const promise = this.rpc.request('echo.Echoer', 'Echo', data);
60
- return promise.then((data) => EchoMsg.decode(new _m0.Reader(data)));
90
+ return promise.then((data) => EchoMsg1.decode(new _m0.Reader(data)));
61
91
  }
62
92
  EchoServerStream(request) {
63
- const data = EchoMsg.encode(request).finish();
93
+ const data = EchoMsg1.encode(request).finish();
64
94
  const result = this.rpc.serverStreamingRequest('echo.Echoer', 'EchoServerStream', data);
65
- return result.pipe(map((data) => EchoMsg.decode(new _m0.Reader(data))));
95
+ return EchoMsg1.decodeTransform(result);
66
96
  }
67
97
  EchoClientStream(request) {
68
- const data = request.pipe(map((request) => EchoMsg.encode(request).finish()));
98
+ const data = EchoMsg1.encodeTransform(request);
69
99
  const promise = this.rpc.clientStreamingRequest('echo.Echoer', 'EchoClientStream', data);
70
- return promise.then((data) => EchoMsg.decode(new _m0.Reader(data)));
100
+ return promise.then((data) => EchoMsg1.decode(new _m0.Reader(data)));
71
101
  }
72
102
  EchoBidiStream(request) {
73
- const data = request.pipe(map((request) => EchoMsg.encode(request).finish()));
103
+ const data = EchoMsg1.encodeTransform(request);
74
104
  const result = this.rpc.bidirectionalStreamingRequest('echo.Echoer', 'EchoBidiStream', data);
75
- return result.pipe(map((data) => EchoMsg.decode(new _m0.Reader(data))));
105
+ return EchoMsg1.decodeTransform(result);
106
+ }
107
+ RpcStream(request) {
108
+ const data = RpcStreamPacket.encodeTransform(request);
109
+ const result = this.rpc.bidirectionalStreamingRequest('echo.Echoer', 'RpcStream', data);
110
+ return RpcStreamPacket.decodeTransform(result);
76
111
  }
77
112
  }
78
113
  export const EchoerDefinition = {
@@ -82,36 +117,45 @@ export const EchoerDefinition = {
82
117
  /** Echo returns the given message. */
83
118
  echo: {
84
119
  name: 'Echo',
85
- requestType: EchoMsg,
120
+ requestType: EchoMsg1,
86
121
  requestStream: false,
87
- responseType: EchoMsg,
122
+ responseType: EchoMsg1,
88
123
  responseStream: false,
89
124
  options: {},
90
125
  },
91
126
  /** EchoServerStream is an example of a server -> client one-way stream. */
92
127
  echoServerStream: {
93
128
  name: 'EchoServerStream',
94
- requestType: EchoMsg,
129
+ requestType: EchoMsg1,
95
130
  requestStream: false,
96
- responseType: EchoMsg,
131
+ responseType: EchoMsg1,
97
132
  responseStream: true,
98
133
  options: {},
99
134
  },
100
135
  /** EchoClientStream is an example of client->server one-way stream. */
101
136
  echoClientStream: {
102
137
  name: 'EchoClientStream',
103
- requestType: EchoMsg,
138
+ requestType: EchoMsg1,
104
139
  requestStream: true,
105
- responseType: EchoMsg,
140
+ responseType: EchoMsg1,
106
141
  responseStream: false,
107
142
  options: {},
108
143
  },
109
144
  /** EchoBidiStream is an example of a two-way stream. */
110
145
  echoBidiStream: {
111
146
  name: 'EchoBidiStream',
112
- requestType: EchoMsg,
147
+ requestType: EchoMsg1,
148
+ requestStream: true,
149
+ responseType: EchoMsg1,
150
+ responseStream: true,
151
+ options: {},
152
+ },
153
+ /** RpcStream opens a nested rpc call stream. */
154
+ rpcStream: {
155
+ name: 'RpcStream',
156
+ requestType: RpcStreamPacket,
113
157
  requestStream: true,
114
- responseType: EchoMsg,
158
+ responseType: RpcStreamPacket,
115
159
  responseStream: true,
116
160
  options: {},
117
161
  },
@@ -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
  }