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.
- package/build/src/generate-grpc-web.js +121 -0
- package/package.json +1 -1
|
@@ -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
|
+
}
|