@dxos/rpc 2.33.9-dev.d9963f00 → 2.33.9-dev.eb69ac10
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/src/proto/gen/dxos/rpc/test.d.ts +32 -4
- package/dist/src/proto/gen/dxos/rpc/test.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/rpc.d.ts +58 -8
- package/dist/src/proto/gen/dxos/rpc.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/rpc.js +4 -0
- package/dist/src/proto/gen/dxos/rpc.js.map +1 -1
- package/dist/src/proto/gen/google/protobuf.d.ts +2 -2
- package/dist/src/proto/gen/google/protobuf.d.ts.map +1 -1
- package/dist/src/proto/gen/index.d.ts.map +1 -1
- package/dist/src/proto/gen/index.js +1 -1
- package/dist/src/proto/gen/index.js.map +1 -1
- package/dist/src/rpc.d.ts.map +1 -1
- package/dist/src/rpc.js +37 -8
- package/dist/src/rpc.js.map +1 -1
- package/dist/src/rpc.test.js +102 -45
- package/dist/src/rpc.test.js.map +1 -1
- package/dist/src/service.test.js +1 -0
- package/dist/src/service.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/src/proto/gen/dxos/rpc/test.ts +32 -4
- package/src/proto/gen/dxos/rpc.ts +58 -8
- package/src/proto/gen/google/protobuf.ts +2 -2
- package/src/proto/gen/index.ts +1 -1
- package/src/rpc.test.ts +113 -45
- package/src/rpc.ts +42 -10
- package/src/service.test.ts +1 -0
package/src/rpc.test.ts
CHANGED
@@ -13,17 +13,22 @@ import { Any } from './proto/gen/google/protobuf';
|
|
13
13
|
import { RpcPeer } from './rpc';
|
14
14
|
import { createLinkedPorts } from './testutil';
|
15
15
|
|
16
|
+
const createPayload = (value = ''): Any => ({
|
17
|
+
type_url: '',
|
18
|
+
value: Buffer.from(value)
|
19
|
+
});
|
20
|
+
|
16
21
|
describe('RpcPeer', () => {
|
17
22
|
describe('handshake', () => {
|
18
23
|
test('can open', async () => {
|
19
24
|
const [alicePort, bobPort] = createLinkedPorts();
|
20
25
|
|
21
26
|
const alice = new RpcPeer({
|
22
|
-
messageHandler: async msg => (
|
27
|
+
messageHandler: async msg => createPayload(),
|
23
28
|
port: alicePort
|
24
29
|
});
|
25
30
|
const bob = new RpcPeer({
|
26
|
-
messageHandler: async msg => (
|
31
|
+
messageHandler: async msg => createPayload(),
|
27
32
|
port: bobPort
|
28
33
|
});
|
29
34
|
|
@@ -36,11 +41,11 @@ describe('RpcPeer', () => {
|
|
36
41
|
test('open waits for the other peer to call open', async () => {
|
37
42
|
const [alicePort, bobPort] = createLinkedPorts();
|
38
43
|
const alice: RpcPeer = new RpcPeer({
|
39
|
-
messageHandler: async msg => (
|
44
|
+
messageHandler: async msg => createPayload(),
|
40
45
|
port: alicePort
|
41
46
|
});
|
42
47
|
const bob = new RpcPeer({
|
43
|
-
messageHandler: async msg => (
|
48
|
+
messageHandler: async msg => createPayload(),
|
44
49
|
port: bobPort
|
45
50
|
});
|
46
51
|
|
@@ -64,7 +69,7 @@ describe('RpcPeer', () => {
|
|
64
69
|
const [alicePort, bobPort] = createLinkedPorts();
|
65
70
|
|
66
71
|
const alice: RpcPeer = new RpcPeer({
|
67
|
-
messageHandler: async msg => (
|
72
|
+
messageHandler: async msg => createPayload(),
|
68
73
|
port: alicePort
|
69
74
|
});
|
70
75
|
const aliceOpen = alice.open();
|
@@ -72,7 +77,7 @@ describe('RpcPeer', () => {
|
|
72
77
|
await sleep(5);
|
73
78
|
|
74
79
|
const bob = new RpcPeer({
|
75
|
-
messageHandler: async msg => (
|
80
|
+
messageHandler: async msg => createPayload(),
|
76
81
|
port: bobPort
|
77
82
|
});
|
78
83
|
|
@@ -88,7 +93,7 @@ describe('RpcPeer', () => {
|
|
88
93
|
let portOpen = false;
|
89
94
|
|
90
95
|
const alice: RpcPeer = new RpcPeer({
|
91
|
-
messageHandler: async msg => (
|
96
|
+
messageHandler: async msg => createPayload(),
|
92
97
|
port: {
|
93
98
|
send: msg => {
|
94
99
|
portOpen && alicePort.send(msg);
|
@@ -98,7 +103,7 @@ describe('RpcPeer', () => {
|
|
98
103
|
});
|
99
104
|
|
100
105
|
const bob = new RpcPeer({
|
101
|
-
messageHandler: async msg => (
|
106
|
+
messageHandler: async msg => createPayload(),
|
102
107
|
port: {
|
103
108
|
send: msg => {
|
104
109
|
portOpen && bobPort.send(msg);
|
@@ -123,7 +128,7 @@ describe('RpcPeer', () => {
|
|
123
128
|
const [alicePort, bobPort] = createLinkedPorts();
|
124
129
|
|
125
130
|
const alice: RpcPeer = new RpcPeer({
|
126
|
-
messageHandler: async msg => (
|
131
|
+
messageHandler: async msg => createPayload(),
|
127
132
|
port: {
|
128
133
|
send: msg => { },
|
129
134
|
subscribe: alicePort.subscribe
|
@@ -131,7 +136,7 @@ describe('RpcPeer', () => {
|
|
131
136
|
});
|
132
137
|
|
133
138
|
const bob = new RpcPeer({
|
134
|
-
messageHandler: async msg => (
|
139
|
+
messageHandler: async msg => createPayload(),
|
135
140
|
port: bobPort
|
136
141
|
});
|
137
142
|
|
@@ -160,12 +165,12 @@ describe('RpcPeer', () => {
|
|
160
165
|
messageHandler: async (method, msg) => {
|
161
166
|
expect(method).toEqual('method');
|
162
167
|
expect(msg.value).toEqual(Buffer.from('request'));
|
163
|
-
return
|
168
|
+
return createPayload('response');
|
164
169
|
},
|
165
170
|
port: alicePort
|
166
171
|
});
|
167
172
|
const bob = new RpcPeer({
|
168
|
-
messageHandler: async (method, msg) => (
|
173
|
+
messageHandler: async (method, msg) => createPayload(),
|
169
174
|
port: bobPort
|
170
175
|
});
|
171
176
|
|
@@ -174,8 +179,8 @@ describe('RpcPeer', () => {
|
|
174
179
|
bob.open()
|
175
180
|
]);
|
176
181
|
|
177
|
-
const response = await bob.call('method',
|
178
|
-
expect(response).toEqual(
|
182
|
+
const response = await bob.call('method', createPayload('request'));
|
183
|
+
expect(response).toEqual(createPayload('response'));
|
179
184
|
});
|
180
185
|
|
181
186
|
test('can send multiple requests', async () => {
|
@@ -197,7 +202,7 @@ describe('RpcPeer', () => {
|
|
197
202
|
port: alicePort
|
198
203
|
});
|
199
204
|
const bob = new RpcPeer({
|
200
|
-
messageHandler: async msg => (
|
205
|
+
messageHandler: async msg => createPayload(),
|
201
206
|
port: bobPort
|
202
207
|
});
|
203
208
|
|
@@ -206,14 +211,14 @@ describe('RpcPeer', () => {
|
|
206
211
|
bob.open()
|
207
212
|
]);
|
208
213
|
|
209
|
-
expect((await bob.call('method',
|
214
|
+
expect((await bob.call('method', createPayload('request'))).value).toEqual(Buffer.from('request'));
|
210
215
|
|
211
|
-
const parallel1 = bob.call('method',
|
212
|
-
const parallel2 = bob.call('method',
|
213
|
-
const error = bob.call('method',
|
216
|
+
const parallel1 = bob.call('method', createPayload('p1'));
|
217
|
+
const parallel2 = bob.call('method', createPayload('p2'));
|
218
|
+
const error = bob.call('method', createPayload('error'));
|
214
219
|
|
215
|
-
await expect(await parallel1).toEqual(
|
216
|
-
await expect(await parallel2).toEqual(
|
220
|
+
await expect(await parallel1).toEqual(createPayload('p1'));
|
221
|
+
await expect(await parallel2).toEqual(createPayload('p2'));
|
217
222
|
await expect(error).toBeRejected();
|
218
223
|
});
|
219
224
|
|
@@ -232,7 +237,7 @@ describe('RpcPeer', () => {
|
|
232
237
|
port: alicePort
|
233
238
|
});
|
234
239
|
const bob = new RpcPeer({
|
235
|
-
messageHandler: async msg => (
|
240
|
+
messageHandler: async msg => createPayload(),
|
236
241
|
port: bobPort
|
237
242
|
});
|
238
243
|
|
@@ -243,7 +248,7 @@ describe('RpcPeer', () => {
|
|
243
248
|
|
244
249
|
let error!: Error;
|
245
250
|
try {
|
246
|
-
await bob.call('RpcMethodName',
|
251
|
+
await bob.call('RpcMethodName', createPayload('request'));
|
247
252
|
} catch (err: any) {
|
248
253
|
error = err;
|
249
254
|
}
|
@@ -266,7 +271,7 @@ describe('RpcPeer', () => {
|
|
266
271
|
port: alicePort
|
267
272
|
});
|
268
273
|
const bob = new RpcPeer({
|
269
|
-
messageHandler: async msg => (
|
274
|
+
messageHandler: async msg => createPayload(),
|
270
275
|
port: bobPort
|
271
276
|
});
|
272
277
|
|
@@ -275,7 +280,7 @@ describe('RpcPeer', () => {
|
|
275
280
|
bob.open()
|
276
281
|
]);
|
277
282
|
|
278
|
-
const req = bob.call('method',
|
283
|
+
const req = bob.call('method', createPayload('request'));
|
279
284
|
bob.close();
|
280
285
|
|
281
286
|
await expect(req).toBeRejected();
|
@@ -293,7 +298,7 @@ describe('RpcPeer', () => {
|
|
293
298
|
port: alicePort
|
294
299
|
});
|
295
300
|
const bob = new RpcPeer({
|
296
|
-
messageHandler: async msg => (
|
301
|
+
messageHandler: async msg => createPayload(),
|
297
302
|
port: bobPort,
|
298
303
|
timeout: 50
|
299
304
|
});
|
@@ -304,8 +309,34 @@ describe('RpcPeer', () => {
|
|
304
309
|
]);
|
305
310
|
|
306
311
|
alice.close();
|
307
|
-
const req = bob.call('method',
|
312
|
+
const req = bob.call('method', createPayload('request'));
|
313
|
+
|
314
|
+
await expect(req).toBeRejected();
|
315
|
+
});
|
316
|
+
|
317
|
+
test('requests failing on timeout', async () => {
|
318
|
+
const [alicePort, bobPort] = createLinkedPorts();
|
319
|
+
|
320
|
+
const alice: RpcPeer = new RpcPeer({
|
321
|
+
messageHandler: async (method, msg) => {
|
322
|
+
expect(method).toEqual('method');
|
323
|
+
await sleep(50);
|
324
|
+
return msg;
|
325
|
+
},
|
326
|
+
port: alicePort
|
327
|
+
});
|
328
|
+
const bob = new RpcPeer({
|
329
|
+
messageHandler: async msg => createPayload(),
|
330
|
+
port: bobPort,
|
331
|
+
timeout: 10
|
332
|
+
});
|
308
333
|
|
334
|
+
await Promise.all([
|
335
|
+
alice.open(),
|
336
|
+
bob.open()
|
337
|
+
]);
|
338
|
+
|
339
|
+
const req = bob.call('method', createPayload('request'));
|
309
340
|
await expect(req).toBeRejected();
|
310
341
|
});
|
311
342
|
|
@@ -316,20 +347,20 @@ describe('RpcPeer', () => {
|
|
316
347
|
const [alicePort, bobPort] = createLinkedPorts();
|
317
348
|
|
318
349
|
const alice = new RpcPeer({
|
319
|
-
messageHandler: async msg => (
|
350
|
+
messageHandler: async msg => createPayload(),
|
320
351
|
streamHandler: (method, msg) => {
|
321
352
|
expect(method).toEqual('method');
|
322
353
|
expect(msg.value!).toEqual(Buffer.from('request'));
|
323
354
|
return new Stream<Any>(({ next, close }) => {
|
324
|
-
next(
|
325
|
-
next(
|
355
|
+
next(createPayload('res1'));
|
356
|
+
next(createPayload('res2'));
|
326
357
|
close();
|
327
358
|
});
|
328
359
|
},
|
329
360
|
port: alicePort
|
330
361
|
});
|
331
362
|
const bob = new RpcPeer({
|
332
|
-
messageHandler: async msg => (
|
363
|
+
messageHandler: async msg => createPayload(),
|
333
364
|
port: bobPort
|
334
365
|
});
|
335
366
|
|
@@ -338,12 +369,13 @@ describe('RpcPeer', () => {
|
|
338
369
|
bob.open()
|
339
370
|
]);
|
340
371
|
|
341
|
-
const stream = await bob.callStream('method',
|
372
|
+
const stream = await bob.callStream('method', createPayload('request'));
|
342
373
|
expect(stream).toBeA(Stream);
|
343
374
|
|
344
375
|
expect(await Stream.consume(stream)).toEqual([
|
345
|
-
{
|
346
|
-
{ data:
|
376
|
+
{ ready: true },
|
377
|
+
{ data: createPayload('res1') },
|
378
|
+
{ data: createPayload('res2') },
|
347
379
|
{ closed: true }
|
348
380
|
]);
|
349
381
|
});
|
@@ -352,7 +384,7 @@ describe('RpcPeer', () => {
|
|
352
384
|
const [alicePort, bobPort] = createLinkedPorts();
|
353
385
|
|
354
386
|
const alice = new RpcPeer({
|
355
|
-
messageHandler: async msg => (
|
387
|
+
messageHandler: async msg => createPayload(),
|
356
388
|
streamHandler: (method, msg) => {
|
357
389
|
expect(method).toEqual('method');
|
358
390
|
expect(msg.value).toEqual(Buffer.from('request'));
|
@@ -363,7 +395,7 @@ describe('RpcPeer', () => {
|
|
363
395
|
port: alicePort
|
364
396
|
});
|
365
397
|
const bob = new RpcPeer({
|
366
|
-
messageHandler: async msg => (
|
398
|
+
messageHandler: async msg => createPayload(),
|
367
399
|
port: bobPort
|
368
400
|
});
|
369
401
|
|
@@ -372,7 +404,7 @@ describe('RpcPeer', () => {
|
|
372
404
|
bob.open()
|
373
405
|
]);
|
374
406
|
|
375
|
-
const stream = await bob.callStream('method',
|
407
|
+
const stream = await bob.callStream('method', createPayload('request'));
|
376
408
|
expect(stream).toBeA(Stream);
|
377
409
|
|
378
410
|
const msgs = await Stream.consume(stream);
|
@@ -388,7 +420,7 @@ describe('RpcPeer', () => {
|
|
388
420
|
|
389
421
|
let closeCalled = false;
|
390
422
|
const alice = new RpcPeer({
|
391
|
-
messageHandler: async msg => (
|
423
|
+
messageHandler: async msg => createPayload(),
|
392
424
|
streamHandler: (method, msg) => new Stream<Any>(({ next, close }) => () => {
|
393
425
|
closeCalled = true;
|
394
426
|
}),
|
@@ -396,7 +428,7 @@ describe('RpcPeer', () => {
|
|
396
428
|
});
|
397
429
|
|
398
430
|
const bob = new RpcPeer({
|
399
|
-
messageHandler: async msg => (
|
431
|
+
messageHandler: async msg => createPayload(),
|
400
432
|
port: bobPort
|
401
433
|
});
|
402
434
|
|
@@ -405,13 +437,49 @@ describe('RpcPeer', () => {
|
|
405
437
|
bob.open()
|
406
438
|
]);
|
407
439
|
|
408
|
-
const stream = bob.callStream('method',
|
440
|
+
const stream = bob.callStream('method', createPayload('request'));
|
409
441
|
stream.close();
|
410
442
|
|
411
443
|
await sleep(1);
|
412
444
|
|
413
445
|
expect(closeCalled).toEqual(true);
|
414
446
|
});
|
447
|
+
|
448
|
+
test('reports stream being ready', async () => {
|
449
|
+
const [alicePort, bobPort] = createLinkedPorts();
|
450
|
+
|
451
|
+
const alice = new RpcPeer({
|
452
|
+
messageHandler: async msg => createPayload(),
|
453
|
+
streamHandler: (method, msg) => {
|
454
|
+
expect(method).toEqual('method');
|
455
|
+
expect(msg.value!).toEqual(Buffer.from('request'));
|
456
|
+
return new Stream<Any>(({ ready, close }) => {
|
457
|
+
ready();
|
458
|
+
close();
|
459
|
+
});
|
460
|
+
},
|
461
|
+
port: alicePort
|
462
|
+
});
|
463
|
+
const bob = new RpcPeer({
|
464
|
+
messageHandler: async msg => createPayload(),
|
465
|
+
port: bobPort
|
466
|
+
});
|
467
|
+
|
468
|
+
await Promise.all([
|
469
|
+
alice.open(),
|
470
|
+
bob.open()
|
471
|
+
]);
|
472
|
+
|
473
|
+
const stream = await bob.callStream('method', createPayload('request'));
|
474
|
+
expect(stream).toBeA(Stream);
|
475
|
+
|
476
|
+
await stream.waitUntilReady();
|
477
|
+
|
478
|
+
expect(await Stream.consume(stream)).toEqual([
|
479
|
+
{ ready: true },
|
480
|
+
{ closed: true }
|
481
|
+
]);
|
482
|
+
});
|
415
483
|
});
|
416
484
|
|
417
485
|
describe('with disabled handshake', () => {
|
@@ -419,7 +487,7 @@ describe('RpcPeer', () => {
|
|
419
487
|
const [alicePort] = createLinkedPorts();
|
420
488
|
|
421
489
|
const alice = new RpcPeer({
|
422
|
-
messageHandler: async msg => (
|
490
|
+
messageHandler: async msg => createPayload(),
|
423
491
|
port: alicePort,
|
424
492
|
noHandshake: true
|
425
493
|
});
|
@@ -434,13 +502,13 @@ describe('RpcPeer', () => {
|
|
434
502
|
messageHandler: async (method, msg) => {
|
435
503
|
expect(method).toEqual('method');
|
436
504
|
expect(msg.value).toEqual(Buffer.from('request'));
|
437
|
-
return
|
505
|
+
return createPayload('response');
|
438
506
|
},
|
439
507
|
port: alicePort,
|
440
508
|
noHandshake: true
|
441
509
|
});
|
442
510
|
const bob = new RpcPeer({
|
443
|
-
messageHandler: async (method, msg) => (
|
511
|
+
messageHandler: async (method, msg) => createPayload(),
|
444
512
|
port: bobPort,
|
445
513
|
noHandshake: true
|
446
514
|
});
|
@@ -448,8 +516,8 @@ describe('RpcPeer', () => {
|
|
448
516
|
await alice.open();
|
449
517
|
await bob.open();
|
450
518
|
|
451
|
-
const response = await bob.call('method',
|
452
|
-
expect(response).toEqual(
|
519
|
+
const response = await bob.call('method', createPayload('request'));
|
520
|
+
expect(response).toEqual(createPayload('response'));
|
453
521
|
});
|
454
522
|
});
|
455
523
|
});
|
package/src/rpc.ts
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
import debug from 'debug';
|
6
6
|
import assert from 'node:assert';
|
7
7
|
|
8
|
-
import {
|
8
|
+
import { synchronized, Trigger } from '@dxos/async';
|
9
9
|
import { Stream } from '@dxos/codec-protobuf';
|
10
10
|
import { StackTrace } from '@dxos/debug';
|
11
11
|
import { exponentialBackoffInterval } from '@dxos/util';
|
@@ -143,7 +143,12 @@ export class RpcPeer {
|
|
143
143
|
if (decoded.request) {
|
144
144
|
if (!this._open) {
|
145
145
|
log('Received request while not open.');
|
146
|
-
await this._sendMessage({
|
146
|
+
await this._sendMessage({
|
147
|
+
response: {
|
148
|
+
id: decoded.request.id,
|
149
|
+
error: encodeError(new RpcClosedError())
|
150
|
+
}
|
151
|
+
});
|
147
152
|
return;
|
148
153
|
}
|
149
154
|
|
@@ -240,20 +245,18 @@ export class RpcPeer {
|
|
240
245
|
// Here we're attaching a dummy handler that will not interfere with error handling to avoid that warning.
|
241
246
|
promise.catch(() => {});
|
242
247
|
|
243
|
-
|
248
|
+
void this._sendMessage({
|
244
249
|
request: {
|
245
250
|
id,
|
246
251
|
method,
|
247
|
-
payload: request
|
252
|
+
payload: request,
|
253
|
+
stream: false
|
248
254
|
}
|
249
255
|
});
|
250
256
|
|
251
|
-
const timeoutPromise = sleep(this._options.timeout ?? DEFAULT_TIMEOUT).then(() => Promise.reject(new Error('Timeout')));
|
252
|
-
timeoutPromise.catch(() => {}); // Mute the promise.
|
253
|
-
|
254
257
|
let response: Response;
|
255
258
|
try {
|
256
|
-
response = await Promise.race([promise,
|
259
|
+
response = await Promise.race([promise, createTimeoutPromise(this._options.timeout ?? DEFAULT_TIMEOUT, new Error(`RPC call timed out: ${method}`))]);
|
257
260
|
} catch (err) {
|
258
261
|
if (err instanceof RpcClosedError) {
|
259
262
|
// Rethrow the error here to have the correct stack-trace.
|
@@ -286,9 +289,11 @@ export class RpcPeer {
|
|
286
289
|
|
287
290
|
const id = this._nextId++;
|
288
291
|
|
289
|
-
return new Stream(({ next, close }) => {
|
292
|
+
return new Stream(({ ready, next, close }) => {
|
290
293
|
const onResponse = (response: Response) => {
|
291
|
-
if (response.
|
294
|
+
if (response.streamReady) {
|
295
|
+
ready();
|
296
|
+
} else if (response.close) {
|
292
297
|
close();
|
293
298
|
} else if (response.error) {
|
294
299
|
assert(response.error.name);
|
@@ -362,6 +367,12 @@ export class RpcPeer {
|
|
362
367
|
assert(req.payload);
|
363
368
|
assert(req.method);
|
364
369
|
const responseStream = this._options.streamHandler(req.method, req.payload);
|
370
|
+
responseStream.onReady(() => {
|
371
|
+
callback({
|
372
|
+
id: req.id,
|
373
|
+
streamReady: true
|
374
|
+
});
|
375
|
+
});
|
365
376
|
responseStream.subscribe(
|
366
377
|
msg => {
|
367
378
|
callback({
|
@@ -410,3 +421,24 @@ const encodeError = (err: any): ErrorResponse => {
|
|
410
421
|
};
|
411
422
|
}
|
412
423
|
};
|
424
|
+
|
425
|
+
/**
|
426
|
+
* Creates a promise that will be rejected after a certain timeout.
|
427
|
+
* The promise will never cause unhandledPromiseRejection.
|
428
|
+
* The timeout will not block the Node.JS process from exiting.
|
429
|
+
*/
|
430
|
+
const createTimeoutPromise = (timeout: number, error: Error) => {
|
431
|
+
const timeoutPromise = new Promise<any>((resolve, reject) => {
|
432
|
+
const timeoutId = setTimeout(
|
433
|
+
() => reject(error),
|
434
|
+
timeout
|
435
|
+
);
|
436
|
+
|
437
|
+
// `unref` prevents the timeout from blocking Node.JS process from exiting. Not available in browsers.
|
438
|
+
if ('unref' in timeoutId) {
|
439
|
+
timeoutId.unref();
|
440
|
+
}
|
441
|
+
});
|
442
|
+
timeoutPromise.catch(() => {}); // Mute the promise.
|
443
|
+
return timeoutPromise;
|
444
|
+
};
|
package/src/service.test.ts
CHANGED
@@ -161,6 +161,7 @@ describe('Protobuf service', () => {
|
|
161
161
|
const stream = client.rpc.testCall({ data: 'requestData' });
|
162
162
|
|
163
163
|
expect(await Stream.consume(stream)).toEqual([
|
164
|
+
{ ready: true },
|
164
165
|
{ data: { data: 'foo' } },
|
165
166
|
{ data: { data: 'bar' } },
|
166
167
|
{ data: { data: 'baz' } },
|