ts-proto 2.18.2 → 2.18.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.
@@ -300,6 +300,9 @@ function createObservableUnaryMethod(ctx) {
300
300
  function createInvokeMethod(ctx) {
301
301
  const { options } = ctx;
302
302
  const { useAbortSignal } = options;
303
+ if (options.useAsyncIterable) {
304
+ return createAsyncIterableInvokeMethod(ctx);
305
+ }
303
306
  return (0, ts_poet_1.code) `
304
307
  invoke<T extends UnaryMethodDefinitionish>(
305
308
  methodDesc: T,
@@ -363,3 +366,121 @@ function createInvokeMethod(ctx) {
363
366
  }
364
367
  `;
365
368
  }
369
+ /** Creates the streaming `invoke` method for `useAsyncIterable=true`, which returns an async generator. */
370
+ function createAsyncIterableInvokeMethod(ctx) {
371
+ const { useAbortSignal } = ctx.options;
372
+ return (0, ts_poet_1.code) `
373
+ invoke<T extends UnaryMethodDefinitionish>(
374
+ methodDesc: T,
375
+ _request: any,
376
+ metadata: grpc.Metadata | undefined,
377
+ ${useAbortSignal ? "abortSignal?: AbortSignal," : ""}
378
+ ): AsyncIterable<any> {
379
+ const upStreamCodes = this.options.upStreamRetryCodes ?? [];
380
+ const DEFAULT_TIMEOUT_TIME: number = 3_000;
381
+ const request = { ..._request, ...methodDesc.requestType };
382
+ const transport = this.options.streamingTransport ?? this.options.transport;
383
+ const maybeCombinedMetadata = metadata && this.options.metadata
384
+ ? new ${BrowserHeaders}({ ...this.options?.metadata.headersMap, ...metadata?.headersMap })
385
+ : metadata ?? this.options.metadata;
386
+ const host = this.host;
387
+ const debug = this.options.debug ?? false;
388
+ return (async function* () {
389
+ ${useAbortSignal
390
+ ? `
391
+ // A listener added after the abort would never run.
392
+ if (abortSignal?.aborted) {
393
+ throw abortSignal.reason;
394
+ }
395
+ `
396
+ : ""}
397
+ const queue: any[] = [];
398
+ let done = false;
399
+ let error: unknown = undefined;
400
+ ${useAbortSignal ? "let aborted = false;" : ""}
401
+ let wake: (() => void) | undefined;
402
+ const notify = () => {
403
+ const resolve = wake;
404
+ wake = undefined;
405
+ resolve?.();
406
+ };
407
+ let client: { close(): void } | undefined;
408
+ let retryTimer: ReturnType<typeof setTimeout> | undefined;
409
+ let closed = false;
410
+ // Stops the retry timer and closes the active call, at most once.
411
+ const close = () => {
412
+ closed = true;
413
+ clearTimeout(retryTimer);
414
+ retryTimer = undefined;
415
+ const active = client;
416
+ client = undefined;
417
+ active?.close();
418
+ };
419
+ const upStream = () => {
420
+ retryTimer = undefined;
421
+ if (closed) {
422
+ return;
423
+ }
424
+ client = ${grpc}.invoke(methodDesc, {
425
+ host,
426
+ request,
427
+ ...(transport !== undefined ? {transport} : {}),
428
+ metadata: maybeCombinedMetadata ?? {},
429
+ debug,
430
+ onMessage: (next) => {
431
+ queue.push(next);
432
+ notify();
433
+ },
434
+ onEnd: (code: ${grpc}.Code, message: string, trailers: ${grpc}.Metadata) => {
435
+ if (code === 0) {
436
+ done = true;
437
+ } else if (upStreamCodes.includes(code)) {
438
+ retryTimer = setTimeout(upStream, DEFAULT_TIMEOUT_TIME);
439
+ return;
440
+ } else {
441
+ const err = new Error(message) as any;
442
+ err.code = code;
443
+ err.metadata = trailers;
444
+ error = err;
445
+ done = true;
446
+ }
447
+ notify();
448
+ },
449
+ });
450
+ };
451
+ ${useAbortSignal
452
+ ? `
453
+ const abort = () => {
454
+ aborted = true;
455
+ error = abortSignal!.reason;
456
+ done = true;
457
+ close();
458
+ notify();
459
+ };
460
+ abortSignal?.addEventListener("abort", abort);
461
+ `
462
+ : ""}
463
+ upStream();
464
+ try {
465
+ while (true) {
466
+ if (${useAbortSignal ? "!aborted && " : ""}queue.length > 0) {
467
+ yield queue.shift();
468
+ } else if (done) {
469
+ break;
470
+ } else {
471
+ await new Promise<void>((resolve) => {
472
+ wake = resolve;
473
+ });
474
+ }
475
+ }
476
+ if (error !== undefined) {
477
+ throw error;
478
+ }
479
+ } finally {
480
+ ${useAbortSignal ? `abortSignal?.removeEventListener("abort", abort);` : ""}
481
+ close();
482
+ }
483
+ })();
484
+ }
485
+ `;
486
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "2.18.2",
3
+ "version": "2.18.3",
4
4
  "description": "",
5
5
  "main": "build/src/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",