@pqstudio/protobuf_ts_plugin
Version:
The protocol buffer compiler plugin "protobuf-ts" generates TypeScript, gRPC-web, Twirp, and more.
258 lines (257 loc) • 42.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServiceClientGeneratorRxjs = void 0;
const ts = require("typescript");
const typescript_1 = require("typescript");
const service_client_generator_base_1 = require("./service-client-generator-base");
const runtime_1 = require("@protobuf-ts/runtime");
class ServiceClientGeneratorRxjs extends service_client_generator_base_1.ServiceClientGeneratorBase {
constructor() {
super(...arguments);
this.symbolKindInterface = 'rx-client-interface';
this.symbolKindImplementation = 'rx-client';
}
createUnary(source, methodInfo) {
let RpcOptions = this.imports.name(source, 'RpcOptions', this.options.runtimeRpcImportPath);
let RpcError = this.imports.name(source, "RpcError", this.options.runtimeRpcImportPath);
let stackIntercept = this.imports.name(source, "stackIntercept", this.options.runtimeRpcImportPath);
let Observable = this.imports.name(source, 'Observable', "rxjs");
let methodIndex = methodInfo.service.methods.indexOf(methodInfo);
runtime_1.assert(methodIndex >= 0);
return ts.createMethod(undefined, undefined, undefined, ts.createIdentifier(methodInfo.localName), undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("input"), undefined, this.makeI(source, methodInfo)),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createIdentifier(RpcOptions), undefined), undefined)
], ts.createTypeReferenceNode(Observable, [
this.makeO(source, methodInfo),
]), ts.createBlock([
// const method = this.methods[0], opt = this._transport.mergeOptions(options);
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([
ts.createVariableDeclaration(ts.createIdentifier("method"), undefined, ts.createElementAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("methods")), ts.createNumericLiteral(methodIndex.toString()))),
ts.createVariableDeclaration(ts.createIdentifier("opt"), undefined, ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")), ts.createIdentifier("mergeOptions")), undefined, [ts.createIdentifier("options")])),
], ts.NodeFlags.Const)),
// const abort = new globalThis.AbortController();
ts.addSyntheticLeadingComment(ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("abort"), undefined, ts.createNew(ts.createPropertyAccess(ts.createIdentifier("globalThis"), ts.createIdentifier("AbortController")), undefined, []))], ts.NodeFlags.Const)), ts.SyntaxKind.SingleLineCommentTrivia, " setup own abort signal because we want to be able to abort on unsubscribe()"),
// opt.abort?.addEventListener("abort", () => abort.abort());
ts.createExpressionStatement(ts.createCallChain(ts.createPropertyAccessChain(ts.createPropertyAccess(ts.createIdentifier("opt"), ts.createIdentifier("abort")), ts.createToken(ts.SyntaxKind.QuestionDotToken), ts.createIdentifier("addEventListener")), undefined, undefined, [
ts.createStringLiteral("abort"),
ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("abort"), ts.createIdentifier("abort")), undefined, []))
])),
// opt.abort = abort.signal;
ts.createExpressionStatement(ts.createBinary(ts.createPropertyAccess(ts.createIdentifier("opt"), ts.createIdentifier("abort")), ts.createToken(ts.SyntaxKind.EqualsToken), ts.createPropertyAccess(ts.createIdentifier("abort"), ts.createIdentifier("signal")))),
ts.createReturn(ts.createNew(ts.createIdentifier(Observable), [this.makeO(source, methodInfo)], [ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("subscriber"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createBlock([
// subscriber.add(() => abort.abort());
ts.addSyntheticLeadingComment(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("add")), undefined, [ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("abort"), ts.createIdentifier("abort")), undefined, []))])), ts.SyntaxKind.SingleLineCommentTrivia, " cancel call on unsubscribe"),
ts.addSyntheticLeadingComment(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createCall(ts.createIdentifier(stackIntercept), [
this.makeI(source, methodInfo),
this.makeO(source, methodInfo)
], [
ts.createStringLiteral("unary"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")),
ts.createIdentifier("method"),
ts.createIdentifier("opt"),
ts.createIdentifier("input")
]), ts.createIdentifier("then")), undefined, [
ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("finished"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createBlock([
ts.addSyntheticLeadingComment(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("next")), undefined, [ts.createPropertyAccess(ts.createIdentifier("finished"), ts.createIdentifier("response"))])), ts.SyntaxKind.SingleLineCommentTrivia, " resolved: emit message and complete"),
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("complete")), undefined, []))
], true)),
ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("reason"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createBlock([
ts.addSyntheticLeadingComment(ts.createIf(ts.createBinary(ts.createBinary(ts.createIdentifier("reason"), ts.createToken(ts.SyntaxKind.InstanceOfKeyword), ts.createIdentifier(RpcError)), ts.createToken(ts.SyntaxKind.AmpersandAmpersandToken), ts.createBinary(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("reason"), ts.createIdentifier("code")), ts.createIdentifier("toUpperCase")), undefined, []), ts.createToken(ts.SyntaxKind.EqualsEqualsToken), ts.createStringLiteral("CANCELLED"))), ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("complete")), undefined, [])), ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("error")), undefined, [ts.createIdentifier("reason")]))), ts.SyntaxKind.SingleLineCommentTrivia, " rejected: complete if cancellation, otherwise emit error")
], true))
])), ts.SyntaxKind.SingleLineCommentTrivia, " wait for the call to finish")
], true))])),
], true));
}
createServerStreaming(source, methodInfo) {
let RpcOptions = this.imports.name(source, 'RpcOptions', this.options.runtimeRpcImportPath);
let RpcError = this.imports.name(source, 'RpcError', this.options.runtimeRpcImportPath);
let stackIntercept = this.imports.name(source, 'stackIntercept', this.options.runtimeRpcImportPath);
let Observable = this.imports.name(source, "Observable", "rxjs");
let methodIndex = methodInfo.service.methods.indexOf(methodInfo);
runtime_1.assert(methodIndex >= 0);
return ts.createMethod(undefined, undefined, undefined, ts.createIdentifier(methodInfo.localName), undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("input"), undefined, this.makeI(source, methodInfo)),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createIdentifier(RpcOptions), undefined), undefined)
], ts.createTypeReferenceNode(Observable, [
this.makeO(source, methodInfo),
]), ts.createBlock([
// const method = this.methods[0], opt = this._transport.mergeOptions(options);
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([
ts.createVariableDeclaration(ts.createIdentifier("method"), undefined, ts.createElementAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("methods")), ts.createNumericLiteral(methodIndex.toString()))),
ts.createVariableDeclaration(ts.createIdentifier("opt"), undefined, ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")), ts.createIdentifier("mergeOptions")), undefined, [ts.createIdentifier("options")])),
], ts.NodeFlags.Const)),
// const abort = new globalThis.AbortController();
ts.addSyntheticLeadingComment(ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("abort"), undefined, ts.createNew(ts.createPropertyAccess(ts.createIdentifier("globalThis"), ts.createIdentifier("AbortController")), undefined, []))], ts.NodeFlags.Const)), ts.SyntaxKind.SingleLineCommentTrivia, " setup own abort signal because we want to be able to abort on unsubscribe()"),
// opt.abort?.addEventListener("abort", () => abort.abort());
ts.createExpressionStatement(ts.createCallChain(ts.createPropertyAccessChain(ts.createPropertyAccess(ts.createIdentifier("opt"), ts.createIdentifier("abort")), ts.createToken(ts.SyntaxKind.QuestionDotToken), ts.createIdentifier("addEventListener")), undefined, undefined, [
ts.createStringLiteral("abort"),
ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("abort"), ts.createIdentifier("abort")), undefined, []))
])),
// opt.abort = abort.signal;
ts.createExpressionStatement(ts.createBinary(ts.createPropertyAccess(ts.createIdentifier("opt"), ts.createIdentifier("abort")), ts.createToken(ts.SyntaxKind.EqualsToken), ts.createPropertyAccess(ts.createIdentifier("abort"), ts.createIdentifier("signal")))),
ts.createReturn(ts.createNew(ts.createIdentifier(Observable), [
this.makeO(source, methodInfo)
], [ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("subscriber"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createBlock([
// subscriber.add(() => abort.abort());
ts.addSyntheticLeadingComment(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("add")), undefined, [ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("abort"), ts.createIdentifier("abort")), undefined, []))])), ts.SyntaxKind.SingleLineCommentTrivia, " cancel call on unsubscribe"),
// const onErr = (reason: Error) => {...
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("onErr"), undefined, ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("reason"), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier("globalThis"), ts.createIdentifier("Error")), undefined), undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createBlock([ts.createIf(ts.createPrefix(ts.SyntaxKind.ExclamationToken, ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("closed"))), ts.createBlock([ts.createIf(ts.createBinary(ts.createBinary(ts.createIdentifier("reason"), ts.createToken(ts.SyntaxKind.InstanceOfKeyword), ts.createIdentifier("RpcError")), ts.createToken(ts.SyntaxKind.AmpersandAmpersandToken), ts.createBinary(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("reason"), ts.createIdentifier("code")), ts.createIdentifier("toUpperCase")), undefined, []), ts.createToken(ts.SyntaxKind.EqualsEqualsToken), ts.createStringLiteral("CANCELLED"))), ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("complete")), undefined, [])), ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("error")), undefined, [ts.createIdentifier("reason")])))], true), undefined)], true)))], ts.NodeFlags.Const)),
// const call = stackIntercept<StringValue, Int32Value>("serverStreaming", this._transport, method, opt, i);
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("call"), undefined, ts.createCall(ts.createIdentifier(stackIntercept), [
this.makeI(source, methodInfo),
this.makeO(source, methodInfo),
], [
ts.createStringLiteral("serverStreaming"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")),
ts.createIdentifier("method"),
ts.createIdentifier("opt"),
ts.createIdentifier("input")
]))], ts.NodeFlags.Const)),
// call.headers.catch(onErr);
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("headers")), ts.createIdentifier("catch")), undefined, [ts.createIdentifier("onErr")])),
// call.response.onMessage(message => subscriber.next(message));
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("response")), ts.createIdentifier("onMessage")), undefined, [ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("message"), undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("next")), undefined, [ts.createIdentifier("message")]))])),
// call.response.onComplete(() => subscriber.closed || subscriber.complete());
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("response")), ts.createIdentifier("onComplete")), undefined, [ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createBinary(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("closed")), ts.createToken(ts.SyntaxKind.BarBarToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("complete")), undefined, [])))])),
// call.response.onError(onErr);
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("response")), ts.createIdentifier("onError")), undefined, [ts.createIdentifier("onErr")])),
// call.status.catch(onErr);
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("status")), ts.createIdentifier("catch")), undefined, [ts.createIdentifier("onErr")])),
// call.trailers.catch(onErr);
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("trailers")), ts.createIdentifier("catch")), undefined, [ts.createIdentifier("onErr")])),
], true))]))
], true));
}
createClientStreaming(source, methodInfo) {
let RpcOptions = this.imports.name(source, 'RpcOptions', this.options.runtimeRpcImportPath);
let RpcError = this.imports.name(source, 'RpcError', this.options.runtimeRpcImportPath);
let stackIntercept = this.imports.name(source, "stackIntercept", this.options.runtimeRpcImportPath);
let Observable = this.imports.name(source, 'Observable', "rxjs");
let from = this.imports.name(source, 'from', "rxjs");
let switchMap = this.imports.name(source, 'switchMap', "rxjs/operators");
let concatMap = this.imports.name(source, 'concatMap', "rxjs/operators");
let methodIndex = methodInfo.service.methods.indexOf(methodInfo);
runtime_1.assert(methodIndex >= 0);
return ts.createMethod(undefined, undefined, undefined, ts.createIdentifier(methodInfo.localName), undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("input"), undefined, ts.createTypeReferenceNode(ts.createIdentifier(Observable), [this.makeI(source, methodInfo),]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createIdentifier(RpcOptions), undefined), undefined)
], ts.createTypeReferenceNode(Observable, [
this.makeO(source, methodInfo),
]), ts.createBlock([
// const method = this.methods[0], opt = this._transport.mergeOptions(options)
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([
ts.createVariableDeclaration(ts.createIdentifier("method"), undefined, ts.createElementAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("methods")), ts.createNumericLiteral(methodIndex.toString()))),
ts.createVariableDeclaration(ts.createIdentifier("opt"), undefined, ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")), ts.createIdentifier("mergeOptions")), undefined, [ts.createIdentifier("options")]))
], ts.NodeFlags.Const)),
// setup own abort signal because we want to abort on unsubscribe()
ts.addSyntheticLeadingComment(ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("abort"), undefined, ts.createNew(ts.createPropertyAccess(ts.createIdentifier("globalThis"), ts.createIdentifier("AbortController")), undefined, []))], ts.NodeFlags.Const)), typescript_1.SyntaxKind.SingleLineCommentTrivia, "setup own abort signal because we want to abort on unsubscribe()", false),
ts.createExpressionStatement(ts.createCallChain(ts.createPropertyAccessChain(ts.createPropertyAccess(ts.createIdentifier("opt"), ts.createIdentifier("abort")), ts.createToken(ts.SyntaxKind.QuestionDotToken), ts.createIdentifier("addEventListener")), undefined, undefined, [
ts.createStringLiteral("abort"),
ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("abort"), ts.createIdentifier("abort")), undefined, []))
])),
ts.createExpressionStatement(ts.createBinary(ts.createPropertyAccess(ts.createIdentifier("opt"), ts.createIdentifier("abort")), ts.createToken(ts.SyntaxKind.EqualsToken), ts.createPropertyAccess(ts.createIdentifier("abort"), ts.createIdentifier("signal")))),
// return an observable that completes when the server closes the request
ts.addSyntheticLeadingComment(ts.createReturn(ts.createNew(ts.createIdentifier(Observable), [
this.makeO(source, methodInfo)
], [ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("subscriber"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createBlock([
// cancel call on unsubscribe
ts.addSyntheticLeadingComment(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("add")), undefined, [ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("abort"), ts.createIdentifier("abort")), undefined, []))])), typescript_1.SyntaxKind.SingleLineCommentTrivia, "cancel call on unsubscribe", true),
// start the call
ts.addSyntheticLeadingComment(ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("call"), undefined, ts.createCall(ts.createIdentifier(stackIntercept), [
this.makeI(source, methodInfo),
this.makeO(source, methodInfo),
], [
ts.createStringLiteral("clientStreaming"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")),
ts.createIdentifier("method"),
ts.createIdentifier("opt")
]))], ts.NodeFlags.Const)), typescript_1.SyntaxKind.SingleLineCommentTrivia, "start the call", true),
// map request and response errors to error our observable, but ignore cancellation
ts.addSyntheticLeadingComment(ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("onErr"), undefined, ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("reason"), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier("globalThis"), ts.createIdentifier("Error")), undefined), undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createBlock([ts.createIf(ts.createPrefix(ts.SyntaxKind.ExclamationToken, ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("closed"))), ts.createIf(ts.createBinary(ts.createBinary(ts.createIdentifier("reason"), ts.createToken(ts.SyntaxKind.InstanceOfKeyword), ts.createIdentifier(RpcError)), ts.createToken(ts.SyntaxKind.AmpersandAmpersandToken), ts.createBinary(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("reason"), ts.createIdentifier("code")), ts.createIdentifier("toUpperCase")), undefined, []), ts.createToken(ts.SyntaxKind.EqualsEqualsToken), ts.createStringLiteral("CANCELLED"))), ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("complete")), undefined, [])), ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("error")), undefined, [ts.createIdentifier("reason")]))), undefined)], true)))], ts.NodeFlags.Const)), typescript_1.SyntaxKind.SingleLineCommentTrivia, "map request and response errors to error our observable, but ignore cancellation", true),
// for every input value, send request message, then complete the request
ts.addSyntheticLeadingComment(ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("inputSub"), undefined, ts.createCall(ts.createPropertyAccess(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("input"), ts.createIdentifier("pipe")), undefined, [
ts.createCall(ts.createIdentifier(switchMap), undefined, [ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("message"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createIdentifier(from), undefined, [ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("request")), ts.createIdentifier("send")), undefined, [ts.createIdentifier("message")])]))]),
ts.createCall(ts.createIdentifier(concatMap), undefined, [ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createIdentifier(from), undefined, [ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("request")), ts.createIdentifier("complete")), undefined, [])]))])
]), ts.createIdentifier("subscribe")), undefined, [
ts.createIdentifier("undefined"),
ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createIdentifier("onErr"), undefined, [ts.createIdentifier("err")]))
]))], ts.NodeFlags.Const)), typescript_1.SyntaxKind.SingleLineCommentTrivia, "for every input value, send request message, then complete the request", true),
// cancel input subscription when our observable is unsubscribed
ts.addSyntheticLeadingComment(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("add")), undefined, [ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("inputSub"), ts.createIdentifier("unsubscribe")), undefined, []))])), typescript_1.SyntaxKind.SingleLineCommentTrivia, "cancel input subscription when our observable is unsubscribed", true),
// wait for the call to finish, emit message and complete
ts.addSyntheticLeadingComment(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("then")), undefined, [
ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("finished"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createBlock([
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("next")), undefined, [ts.createPropertyAccess(ts.createIdentifier("finished"), ts.createIdentifier("response"))])),
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("complete")), undefined, []))
], true)),
ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("reason"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createIdentifier("onErr"), undefined, [ts.createIdentifier("reason")]))
])), typescript_1.SyntaxKind.SingleLineCommentTrivia, "wait for the call to finish, emit message and complete", true),
], true))])), typescript_1.SyntaxKind.SingleLineCommentTrivia, "return an observable that completes when the server closes the request", true),
], true));
}
createDuplexStreaming(source, methodInfo) {
let RpcOptions = this.imports.name(source, 'RpcOptions', this.options.runtimeRpcImportPath);
let RpcError = this.imports.name(source, 'RpcError', this.options.runtimeRpcImportPath);
let stackIntercept = this.imports.name(source, "stackIntercept", this.options.runtimeRpcImportPath);
let Observable = this.imports.name(source, 'Observable', "rxjs");
let from = this.imports.name(source, 'from', "rxjs");
let switchMap = this.imports.name(source, 'switchMap', "rxjs/operators");
let concatMap = this.imports.name(source, 'concatMap', "rxjs/operators");
let methodIndex = methodInfo.service.methods.indexOf(methodInfo);
runtime_1.assert(methodIndex >= 0);
return ts.createMethod(undefined, undefined, undefined, ts.createIdentifier(methodInfo.localName), undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("input"), undefined, ts.createTypeReferenceNode(ts.createIdentifier(Observable), [this.makeI(source, methodInfo),]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createIdentifier(RpcOptions), undefined), undefined)
], ts.createTypeReferenceNode(Observable, [
this.makeO(source, methodInfo),
]), ts.createBlock([
// const method = this.methods[0], opt = this._transport.mergeOptions(options)
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([
ts.createVariableDeclaration(ts.createIdentifier("method"), undefined, ts.createElementAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("methods")), ts.createNumericLiteral(methodIndex.toString()))),
ts.createVariableDeclaration(ts.createIdentifier("opt"), undefined, ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")), ts.createIdentifier("mergeOptions")), undefined, [ts.createIdentifier("options")]))
], ts.NodeFlags.Const)),
// setup own abort signal because we want to abort on unsubscribe()
ts.addSyntheticLeadingComment(ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("abort"), undefined, ts.createNew(ts.createPropertyAccess(ts.createIdentifier("globalThis"), ts.createIdentifier("AbortController")), undefined, []))], ts.NodeFlags.Const)), typescript_1.SyntaxKind.SingleLineCommentTrivia, "setup own abort signal because we want to abort on unsubscribe()", true),
ts.createExpressionStatement(ts.createCallChain(ts.createPropertyAccessChain(ts.createPropertyAccess(ts.createIdentifier("opt"), ts.createIdentifier("abort")), ts.createToken(ts.SyntaxKind.QuestionDotToken), ts.createIdentifier("addEventListener")), undefined, undefined, [
ts.createStringLiteral("abort"),
ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("abort"), ts.createIdentifier("abort")), undefined, []))
])),
ts.createExpressionStatement(ts.createBinary(ts.createPropertyAccess(ts.createIdentifier("opt"), ts.createIdentifier("abort")), ts.createToken(ts.SyntaxKind.EqualsToken), ts.createPropertyAccess(ts.createIdentifier("abort"), ts.createIdentifier("signal")))),
// return an observable that completes when the server closes the request
ts.addSyntheticLeadingComment(ts.createReturn(ts.createNew(ts.createIdentifier(Observable), [this.makeO(source, methodInfo)], [ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("subscriber"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createBlock([
// cancel call on unsubscribe
ts.addSyntheticLeadingComment(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("add")), undefined, [ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("abort"), ts.createIdentifier("abort")), undefined, []))])), typescript_1.SyntaxKind.SingleLineCommentTrivia, "cancel call on unsubscribe", false),
// start the call
ts.addSyntheticLeadingComment(ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("call"), undefined, ts.createCall(ts.createIdentifier(stackIntercept), [
this.makeI(source, methodInfo),
this.makeO(source, methodInfo),
], [
ts.createStringLiteral("duplex"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")),
ts.createIdentifier("method"),
ts.createIdentifier("opt")
]))], ts.NodeFlags.Const)), typescript_1.SyntaxKind.SingleLineCommentTrivia, "start the call", false),
// map request and response errors to error our observable, but ignore cancellation
ts.addSyntheticLeadingComment(ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("onErr"), undefined, ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("reason"), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier("globalThis"), ts.createIdentifier("Error")), undefined), undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createBlock([ts.createIf(ts.createPrefix(ts.SyntaxKind.ExclamationToken, ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("closed"))), ts.createIf(ts.createBinary(ts.createBinary(ts.createIdentifier("reason"), ts.createToken(ts.SyntaxKind.InstanceOfKeyword), ts.createIdentifier(RpcError)), ts.createToken(ts.SyntaxKind.AmpersandAmpersandToken), ts.createBinary(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("reason"), ts.createIdentifier("code")), ts.createIdentifier("toUpperCase")), undefined, []), ts.createToken(ts.SyntaxKind.EqualsEqualsToken), ts.createStringLiteral("CANCELLED"))), ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("complete")), undefined, [])), ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("error")), undefined, [ts.createIdentifier("reason")]))), undefined)], true)))], ts.NodeFlags.Const)), typescript_1.SyntaxKind.SingleLineCommentTrivia, "map request and response errors to error our observable, but ignore cancellation", false),
// for every input value, send request message, then complete the request
ts.addSyntheticLeadingComment(ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("inputSub"), undefined, ts.createCall(ts.createPropertyAccess(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("input"), ts.createIdentifier("pipe")), undefined, [
ts.createCall(ts.createIdentifier(switchMap), undefined, [ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("message"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createIdentifier(from), undefined, [ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("request")), ts.createIdentifier("send")), undefined, [ts.createIdentifier("message")])]))]),
ts.createCall(ts.createIdentifier(concatMap), undefined, [ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createIdentifier(from), undefined, [ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("request")), ts.createIdentifier("complete")), undefined, [])]))])
]), ts.createIdentifier("subscribe")), undefined, [
ts.createIdentifier("undefined"),
ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createIdentifier("onErr"), undefined, [ts.createIdentifier("err")]))
]))], ts.NodeFlags.Const)), typescript_1.SyntaxKind.SingleLineCommentTrivia, "for every input value, send request message, then complete the request", false),
// cancel input subscription when our observable is unsubscribed
ts.addSyntheticLeadingComment(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("add")), undefined, [ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("inputSub"), ts.createIdentifier("unsubscribe")), undefined, []))])), typescript_1.SyntaxKind.SingleLineCommentTrivia, "cancel input subscription when our observable is unsubscribed", false),
// map response data to our observable
ts.addSyntheticLeadingComment(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("headers")), ts.createIdentifier("catch")), undefined, [ts.createIdentifier("onErr")])), typescript_1.SyntaxKind.SingleLineCommentTrivia, "map response data to our observable", false),
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("response")), ts.createIdentifier("onMessage")), undefined, [ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("message"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("next")), undefined, [ts.createIdentifier("message")]))])),
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("response")), ts.createIdentifier("onComplete")), undefined, [ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createBinary(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("closed")), ts.createToken(ts.SyntaxKind.BarBarToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("subscriber"), ts.createIdentifier("complete")), undefined, [])))])),
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("response")), ts.createIdentifier("onError")), undefined, [ts.createIdentifier("onErr")])),
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("status")), ts.createIdentifier("catch")), undefined, [ts.createIdentifier("onErr")])),
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("call"), ts.createIdentifier("trailers")), ts.createIdentifier("catch")), undefined, [ts.createIdentifier("onErr")]))
], true))])), ts.SyntaxKind.SingleLineCommentTrivia, "return an observable that completes when the server closes the request", false),
], true));
}
}
exports.ServiceClientGeneratorRxjs = ServiceClientGeneratorRxjs;