better-grpc 0.1.0 → 0.2.1

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/dist/index.cjs CHANGED
@@ -350,7 +350,7 @@ var require_metadata = __commonJS({
350
350
  }
351
351
  }
352
352
  }
353
- var Metadata = class _Metadata {
353
+ var Metadata2 = class _Metadata {
354
354
  constructor(options = {}) {
355
355
  this.internalRepr = /* @__PURE__ */ new Map();
356
356
  this.opaqueData = /* @__PURE__ */ new Map();
@@ -542,7 +542,7 @@ var require_metadata = __commonJS({
542
542
  return result;
543
543
  }
544
544
  };
545
- exports2.Metadata = Metadata;
545
+ exports2.Metadata = Metadata2;
546
546
  var bufToString = (val) => {
547
547
  return Buffer.isBuffer(val) ? val.toString("base64") : val;
548
548
  };
@@ -7717,7 +7717,7 @@ var require_root = __commonJS({
7717
7717
  var util = require_util();
7718
7718
  var Type;
7719
7719
  var parse2;
7720
- var common2;
7720
+ var common;
7721
7721
  function Root2(options) {
7722
7722
  Namespace.call(this, "", options);
7723
7723
  this.deferred = [];
@@ -7764,7 +7764,7 @@ var require_root = __commonJS({
7764
7764
  var idx = filename2.lastIndexOf("google/protobuf/");
7765
7765
  if (idx > -1) {
7766
7766
  var altname = filename2.substring(idx);
7767
- if (altname in common2) return altname;
7767
+ if (altname in common) return altname;
7768
7768
  }
7769
7769
  return null;
7770
7770
  }
@@ -7801,14 +7801,14 @@ var require_root = __commonJS({
7801
7801
  return;
7802
7802
  }
7803
7803
  self2.files.push(filename2);
7804
- if (filename2 in common2) {
7804
+ if (filename2 in common) {
7805
7805
  if (sync) {
7806
- process2(filename2, common2[filename2]);
7806
+ process2(filename2, common[filename2]);
7807
7807
  } else {
7808
7808
  ++queued;
7809
7809
  setTimeout(function() {
7810
7810
  --queued;
7811
- process2(filename2, common2[filename2]);
7811
+ process2(filename2, common[filename2]);
7812
7812
  });
7813
7813
  }
7814
7814
  return;
@@ -7948,7 +7948,7 @@ var require_root = __commonJS({
7948
7948
  Root2._configure = function(Type_, parse_, common_) {
7949
7949
  Type = Type_;
7950
7950
  parse2 = parse_;
7951
- common2 = common_;
7951
+ common = common_;
7952
7952
  };
7953
7953
  }
7954
7954
  });
@@ -9912,16 +9912,16 @@ var require_parse = __commonJS({
9912
9912
  // node_modules/protobufjs/src/common.js
9913
9913
  var require_common = __commonJS({
9914
9914
  "node_modules/protobufjs/src/common.js"(exports2, module2) {
9915
- module2.exports = common2;
9915
+ module2.exports = common;
9916
9916
  var commonRe = /\/|\./;
9917
- function common2(name, json) {
9917
+ function common(name, json) {
9918
9918
  if (!commonRe.test(name)) {
9919
9919
  name = "google/protobuf/" + name + ".proto";
9920
9920
  json = { nested: { google: { nested: { protobuf: { nested: json } } } } };
9921
9921
  }
9922
- common2[name] = json;
9922
+ common[name] = json;
9923
9923
  }
9924
- common2("any", {
9924
+ common("any", {
9925
9925
  /**
9926
9926
  * Properties of a google.protobuf.Any message.
9927
9927
  * @interface IAny
@@ -9944,7 +9944,7 @@ var require_common = __commonJS({
9944
9944
  }
9945
9945
  });
9946
9946
  var timeType;
9947
- common2("duration", {
9947
+ common("duration", {
9948
9948
  /**
9949
9949
  * Properties of a google.protobuf.Duration message.
9950
9950
  * @interface IDuration
@@ -9966,7 +9966,7 @@ var require_common = __commonJS({
9966
9966
  }
9967
9967
  }
9968
9968
  });
9969
- common2("timestamp", {
9969
+ common("timestamp", {
9970
9970
  /**
9971
9971
  * Properties of a google.protobuf.Timestamp message.
9972
9972
  * @interface ITimestamp
@@ -9977,7 +9977,7 @@ var require_common = __commonJS({
9977
9977
  */
9978
9978
  Timestamp: timeType
9979
9979
  });
9980
- common2("empty", {
9980
+ common("empty", {
9981
9981
  /**
9982
9982
  * Properties of a google.protobuf.Empty message.
9983
9983
  * @interface IEmpty
@@ -9987,7 +9987,7 @@ var require_common = __commonJS({
9987
9987
  fields: {}
9988
9988
  }
9989
9989
  });
9990
- common2("struct", {
9990
+ common("struct", {
9991
9991
  /**
9992
9992
  * Properties of a google.protobuf.Struct message.
9993
9993
  * @interface IStruct
@@ -10079,7 +10079,7 @@ var require_common = __commonJS({
10079
10079
  }
10080
10080
  }
10081
10081
  });
10082
- common2("wrappers", {
10082
+ common("wrappers", {
10083
10083
  /**
10084
10084
  * Properties of a google.protobuf.DoubleValue message.
10085
10085
  * @interface IDoubleValue
@@ -10216,7 +10216,7 @@ var require_common = __commonJS({
10216
10216
  }
10217
10217
  }
10218
10218
  });
10219
- common2("field_mask", {
10219
+ common("field_mask", {
10220
10220
  /**
10221
10221
  * Properties of a google.protobuf.FieldMask message.
10222
10222
  * @interface IDoubleValue
@@ -10234,8 +10234,8 @@ var require_common = __commonJS({
10234
10234
  }
10235
10235
  }
10236
10236
  });
10237
- common2.get = function get(file) {
10238
- return common2[file] || null;
10237
+ common.get = function get(file) {
10238
+ return common[file] || null;
10239
10239
  };
10240
10240
  }
10241
10241
  });
@@ -24043,10 +24043,19 @@ var require_src3 = __commonJS({
24043
24043
 
24044
24044
  // src/core/rpc-signatures.ts
24045
24045
  function server() {
24046
- return {
24046
+ const descriptor = {
24047
24047
  serviceType: "server",
24048
24048
  methodType: "unary"
24049
24049
  };
24050
+ const contextFn = (context) => {
24051
+ descriptor.config = {
24052
+ metadata: context.metadata !== void 0,
24053
+ ack: false
24054
+ };
24055
+ return descriptor;
24056
+ };
24057
+ Object.assign(contextFn, descriptor);
24058
+ return contextFn;
24050
24059
  }
24051
24060
  function client() {
24052
24061
  return {
@@ -24054,6 +24063,21 @@ function client() {
24054
24063
  methodType: "unary"
24055
24064
  };
24056
24065
  }
24066
+ function bidi(..._) {
24067
+ const descriptor = {
24068
+ serviceType: "bidi",
24069
+ methodType: "bidi"
24070
+ };
24071
+ const configFn = (config) => {
24072
+ descriptor.config = {
24073
+ metadata: config.metadata !== void 0,
24074
+ ack: config.ack ?? false
24075
+ };
24076
+ return descriptor;
24077
+ };
24078
+ Object.assign(configFn, descriptor);
24079
+ return configFn;
24080
+ }
24057
24081
 
24058
24082
  // src/core/service.ts
24059
24083
  var ServiceImpl = class {
@@ -24114,18 +24138,18 @@ function loadProtoFromString(source) {
24114
24138
  function encodeRequestMessage(id, value) {
24115
24139
  return {
24116
24140
  id,
24117
- value: msgpack.encode(value)
24141
+ value: value === void 0 ? void 0 : msgpack.encode(value)
24118
24142
  };
24119
24143
  }
24120
24144
  function decodeRequestMessage(message) {
24121
24145
  const id = message.id;
24122
- const mapData = message.value === void 0 ? [] : msgpack.decode(message.value);
24146
+ const mapData = message.value === void 0 ? void 0 : msgpack.decode(message.value);
24123
24147
  return [id, mapData];
24124
24148
  }
24125
24149
  function encodeResponseMessage(id, value) {
24126
24150
  return {
24127
24151
  id,
24128
- value: msgpack.encode(value)
24152
+ value: value === void 0 ? void 0 : msgpack.encode(value)
24129
24153
  };
24130
24154
  }
24131
24155
  function decodeResponseMessage(message) {
@@ -24133,6 +24157,18 @@ function decodeResponseMessage(message) {
24133
24157
  const mapData = message.value === void 0 ? void 0 : msgpack.decode(message.value);
24134
24158
  return [id, mapData];
24135
24159
  }
24160
+ function encodeMetadata(raw) {
24161
+ const m = new niceGrpc.Metadata();
24162
+ m.set("better-grpc", JSON.stringify(raw));
24163
+ return m;
24164
+ }
24165
+ function decodeMetadata(metadata) {
24166
+ const betterGrpcMetadata = metadata.get("better-grpc");
24167
+ if (!betterGrpcMetadata) {
24168
+ throw new Error("Failed to decode metadata: 'better-grpc' key not found in gRPC metadata");
24169
+ }
24170
+ return JSON.parse(betterGrpcMetadata);
24171
+ }
24136
24172
 
24137
24173
  // src/runtime/proto-builder.ts
24138
24174
  function buildProtoString(services) {
@@ -24181,6 +24217,11 @@ var GrpcClient = class {
24181
24217
  clientFactory;
24182
24218
  proto;
24183
24219
  clients = /* @__PURE__ */ new Map();
24220
+ pushableStreams = {};
24221
+ pendingStreams = /* @__PURE__ */ new Map();
24222
+ pendingBidi = /* @__PURE__ */ new Map();
24223
+ // bidi that is waiting for context
24224
+ pendingBidiAck = /* @__PURE__ */ new Map();
24184
24225
  constructor(address, serviceImpls) {
24185
24226
  this.address = address;
24186
24227
  this.serviceImpls = serviceImpls;
@@ -24205,27 +24246,90 @@ var GrpcClient = class {
24205
24246
  this.clients.set(serviceImpl.serviceClass.serviceName, client2);
24206
24247
  }
24207
24248
  }
24249
+ setStream(serviceName, methodName, stream) {
24250
+ if (!this.pushableStreams[serviceName]) {
24251
+ this.pushableStreams[serviceName] = {};
24252
+ }
24253
+ this.pushableStreams[serviceName][methodName.toUpperCase()] = stream;
24254
+ if (this.pendingStreams.has(`${serviceName}.${methodName.toUpperCase()}`)) {
24255
+ const resolve = this.pendingStreams.get(`${serviceName}.${methodName.toUpperCase()}`);
24256
+ resolve?.(stream);
24257
+ this.pendingStreams.delete(`${serviceName}.${methodName.toUpperCase()}`);
24258
+ }
24259
+ }
24260
+ async getStream(serviceName, methodName) {
24261
+ const stream = this.pushableStreams[serviceName]?.[methodName.toUpperCase()];
24262
+ if (!stream) {
24263
+ return new Promise((resolve) => {
24264
+ this.pendingStreams.set(`${serviceName}.${methodName.toUpperCase()}`, resolve);
24265
+ });
24266
+ }
24267
+ return stream;
24268
+ }
24208
24269
  watching() {
24209
24270
  for (const serviceImpl of this.serviceImpls) {
24210
24271
  const client2 = this.clients.get(serviceImpl.serviceClass.serviceName);
24211
24272
  for (const [name, descriptor] of Object.entries(serviceImpl.methods())) {
24212
- switch (descriptor.serviceType) {
24213
- case "client":
24214
- switch (descriptor.methodType) {
24215
- case "unary": {
24216
- const incomingStream = itPushable.pushable({ objectMode: true });
24217
- const incomingMessages = client2[name.toUpperCase()](incomingStream);
24218
- (async () => {
24273
+ switch (`${descriptor.serviceType}:${descriptor.methodType}`) {
24274
+ case "client:unary": {
24275
+ const incomingStream = itPushable.pushable({ objectMode: true });
24276
+ const incomingMessages = client2[name.toUpperCase()](incomingStream);
24277
+ (async () => {
24278
+ try {
24279
+ for await (const message of incomingMessages) {
24280
+ const [id, value] = decodeRequestMessage(message);
24281
+ const responseValue = await serviceImpl.implementation[name](...value ?? []);
24282
+ incomingStream.push(encodeResponseMessage(id, responseValue));
24283
+ }
24284
+ } finally {
24285
+ incomingStream.end();
24286
+ }
24287
+ })();
24288
+ break;
24289
+ }
24290
+ case "bidi:bidi": {
24291
+ const setupBidi = (context) => {
24292
+ const outStream = itPushable.pushable({ objectMode: true });
24293
+ const inStream = itPushable.pushable({ objectMode: true });
24294
+ this.setStream(
24295
+ `${serviceImpl.serviceClass.serviceName}_OUT`,
24296
+ name.toUpperCase(),
24297
+ outStream
24298
+ );
24299
+ this.setStream(`${serviceImpl.serviceClass.serviceName}_IN`, name.toUpperCase(), inStream);
24300
+ const incomingMessages = context ? client2[name.toUpperCase()](outStream, { metadata: encodeMetadata(context.metadata) }) : client2[name.toUpperCase()](outStream);
24301
+ (async () => {
24302
+ try {
24219
24303
  for await (const message of incomingMessages) {
24220
24304
  const [id, value] = decodeRequestMessage(message);
24221
- const responseValue = await serviceImpl.implementation[name](...value);
24222
- incomingStream.push(encodeResponseMessage(id, responseValue));
24305
+ if (id && descriptor.config?.ack && value === void 0) {
24306
+ this.pendingBidiAck.get(id)?.();
24307
+ this.pendingBidiAck.delete(id);
24308
+ } else {
24309
+ inStream.push(value ?? []);
24310
+ if (id && descriptor.config?.ack) {
24311
+ outStream.push(encodeRequestMessage(id, void 0));
24312
+ }
24313
+ }
24223
24314
  }
24224
- })();
24225
- break;
24226
- }
24315
+ } finally {
24316
+ inStream.end();
24317
+ outStream.end();
24318
+ }
24319
+ })();
24320
+ };
24321
+ if (descriptor.config?.metadata) {
24322
+ (async () => {
24323
+ const context = await new Promise((resolve) => {
24324
+ this.pendingBidi.set(`${serviceImpl.serviceClass.serviceName}.${name}`, resolve);
24325
+ });
24326
+ setupBidi(context);
24327
+ })();
24328
+ } else {
24329
+ setupBidi(void 0);
24227
24330
  }
24228
24331
  break;
24332
+ }
24229
24333
  }
24230
24334
  }
24231
24335
  }
@@ -24235,13 +24339,72 @@ var GrpcClient = class {
24235
24339
  const serviceCallableInstance = {};
24236
24340
  for (const [name, descriptor] of Object.entries(serviceImpl.methods())) {
24237
24341
  switch (`${descriptor.serviceType}:${descriptor.methodType}`) {
24238
- case "server:unary":
24239
- serviceCallableInstance[name] = async (...args) => {
24240
- const response = await this.clients.get(serviceImpl.serviceClass.serviceName)[name.toUpperCase()](encodeRequestMessage(void 0, args));
24241
- const [_, value] = decodeResponseMessage(response);
24242
- return value;
24342
+ case "server:unary": {
24343
+ if (descriptor.config?.metadata) {
24344
+ serviceCallableInstance[name] = (...args) => {
24345
+ return {
24346
+ withMeta: async (metadata) => {
24347
+ const response = await this.clients.get(serviceImpl.serviceClass.serviceName)[name.toUpperCase()](encodeRequestMessage(void 0, args), {
24348
+ metadata: encodeMetadata(metadata)
24349
+ });
24350
+ const [_, value] = decodeResponseMessage(response);
24351
+ return value;
24352
+ }
24353
+ };
24354
+ };
24355
+ } else {
24356
+ serviceCallableInstance[name] = async (...args) => {
24357
+ const response = await this.clients.get(serviceImpl.serviceClass.serviceName)[name.toUpperCase()](encodeRequestMessage(void 0, args));
24358
+ const [_, value] = decodeResponseMessage(response);
24359
+ return value;
24360
+ };
24361
+ }
24362
+ break;
24363
+ }
24364
+ case "bidi:bidi": {
24365
+ async function* generator(client2) {
24366
+ const inStream = await client2.getStream(
24367
+ `${serviceImpl.serviceClass.serviceName}_IN`,
24368
+ name.toUpperCase()
24369
+ );
24370
+ yield* inStream;
24371
+ }
24372
+ const emitFn = async (...args) => {
24373
+ const outStream = await this.getStream(
24374
+ `${serviceImpl.serviceClass.serviceName}_OUT`,
24375
+ name.toUpperCase()
24376
+ );
24377
+ const ackId = descriptor.config?.ack ? crypto.randomUUID() : void 0;
24378
+ outStream.push(encodeRequestMessage(ackId, args));
24379
+ if (ackId) {
24380
+ return new Promise((resolve) => {
24381
+ this.pendingBidiAck.set(ackId, resolve);
24382
+ });
24383
+ }
24243
24384
  };
24385
+ const context = {
24386
+ context: async (ctx) => {
24387
+ const resolve = this.pendingBidi.get(`${serviceImpl.serviceClass.serviceName}.${name}`);
24388
+ if (resolve) {
24389
+ resolve(ctx);
24390
+ this.pendingBidi.delete(`${serviceImpl.serviceClass.serviceName}.${name}`);
24391
+ }
24392
+ }
24393
+ };
24394
+ const hybrid = Object.assign(emitFn, {
24395
+ [Symbol.asyncIterator]: () => {
24396
+ const iterator = generator(this);
24397
+ return {
24398
+ next: iterator.next.bind(iterator),
24399
+ return: iterator.return.bind(iterator),
24400
+ throw: iterator.throw.bind(iterator)
24401
+ };
24402
+ }
24403
+ });
24404
+ Object.assign(hybrid, context);
24405
+ serviceCallableInstance[name] = hybrid;
24244
24406
  break;
24407
+ }
24245
24408
  }
24246
24409
  }
24247
24410
  Object.defineProperty(this, serviceImpl.serviceClass.serviceName, {
@@ -24293,9 +24456,10 @@ function createServiceImpl(serviceImpl, grpcServer) {
24293
24456
  for (const [name, descriptor] of Object.entries(serviceImpl.methods())) {
24294
24457
  switch (`${descriptor.serviceType}:${descriptor.methodType}`) {
24295
24458
  case "server:unary":
24296
- grpcImpl[name.toUpperCase()] = async (req) => {
24459
+ grpcImpl[name.toUpperCase()] = async (req, ctx) => {
24297
24460
  const [_, value] = decodeRequestMessage(req);
24298
- const result = await serviceImpl.implementation[name](...value);
24461
+ const args = descriptor.config?.metadata ? [{ metadata: decodeMetadata(ctx.metadata) }, ...value ?? []] : value ?? [];
24462
+ const result = await serviceImpl.implementation[name](...args);
24299
24463
  return encodeResponseMessage(void 0, result);
24300
24464
  };
24301
24465
  break;
@@ -24304,19 +24468,55 @@ function createServiceImpl(serviceImpl, grpcServer) {
24304
24468
  const stream = itPushable.pushable({ objectMode: true });
24305
24469
  grpcServer.setStream(serviceImpl.serviceClass.serviceName, name, stream);
24306
24470
  (async () => {
24307
- for await (const message of incomingStream) {
24308
- const [id, value] = decodeResponseMessage(message);
24309
- if (id) {
24310
- grpcServer.resolveResponse(id, value);
24311
- } else {
24312
- throw new Error(`Invalid response message: ${message}`);
24471
+ try {
24472
+ for await (const message of incomingStream) {
24473
+ const [id, value] = decodeResponseMessage(message);
24474
+ if (id) {
24475
+ grpcServer.resolveResponse(id, value);
24476
+ } else {
24477
+ throw new Error(`Invalid response message: ${message}`);
24478
+ }
24313
24479
  }
24480
+ } finally {
24481
+ stream.end();
24314
24482
  }
24315
- stream.end();
24316
24483
  })();
24317
24484
  yield* stream;
24318
24485
  };
24319
24486
  break;
24487
+ case "bidi:bidi":
24488
+ grpcImpl[name.toUpperCase()] = async function* (incomingStream, ctx) {
24489
+ if (descriptor.config?.metadata) {
24490
+ grpcServer.setContext(serviceImpl.serviceClass.serviceName, name, {
24491
+ metadata: decodeMetadata(ctx.metadata)
24492
+ });
24493
+ }
24494
+ const outStream = itPushable.pushable({ objectMode: true });
24495
+ const inStream = itPushable.pushable({ objectMode: true });
24496
+ grpcServer.setStream(`${serviceImpl.serviceClass.serviceName}_OUT`, name, outStream);
24497
+ grpcServer.setStream(`${serviceImpl.serviceClass.serviceName}_IN`, name, inStream);
24498
+ (async () => {
24499
+ try {
24500
+ for await (const message of incomingStream) {
24501
+ const [id, value] = decodeResponseMessage(message);
24502
+ if (id && descriptor.config?.ack && value === void 0) {
24503
+ grpcServer.pendingBidiAck.get(id)?.();
24504
+ grpcServer.pendingBidiAck.delete(id);
24505
+ } else {
24506
+ inStream.push(value ?? []);
24507
+ if (id && descriptor.config?.ack) {
24508
+ outStream.push(encodeRequestMessage(id, void 0));
24509
+ }
24510
+ }
24511
+ }
24512
+ } finally {
24513
+ inStream.end();
24514
+ outStream.end();
24515
+ }
24516
+ })();
24517
+ yield* outStream;
24518
+ };
24519
+ break;
24320
24520
  default:
24321
24521
  throw new Error(`Unknown method descriptor: ${descriptor} for ${name}`);
24322
24522
  }
@@ -24333,6 +24533,9 @@ var GrpcServer = class {
24333
24533
  pushableStreams = {};
24334
24534
  pendingRequests = /* @__PURE__ */ new Map();
24335
24535
  pendingStreams = /* @__PURE__ */ new Map();
24536
+ contexts = /* @__PURE__ */ new Map();
24537
+ pendingContext = /* @__PURE__ */ new Map();
24538
+ pendingBidiAck = /* @__PURE__ */ new Map();
24336
24539
  constructor(address, serviceImpls) {
24337
24540
  this.address = address;
24338
24541
  this.serviceImpls = serviceImpls;
@@ -24349,6 +24552,9 @@ var GrpcServer = class {
24349
24552
  await this.grpcServer.listen(this.address);
24350
24553
  }
24351
24554
  setStream(serviceName, methodName, stream) {
24555
+ if (!this.pushableStreams[serviceName]) {
24556
+ this.pushableStreams[serviceName] = {};
24557
+ }
24352
24558
  this.pushableStreams[serviceName][methodName.toUpperCase()] = stream;
24353
24559
  if (this.pendingStreams.has(`${serviceName}.${methodName.toUpperCase()}`)) {
24354
24560
  const resolve = this.pendingStreams.get(`${serviceName}.${methodName.toUpperCase()}`);
@@ -24357,7 +24563,7 @@ var GrpcServer = class {
24357
24563
  }
24358
24564
  }
24359
24565
  async getStream(serviceName, methodName) {
24360
- const stream = this.pushableStreams[serviceName][methodName.toUpperCase()];
24566
+ const stream = this.pushableStreams[serviceName]?.[methodName.toUpperCase()];
24361
24567
  if (!stream) {
24362
24568
  return new Promise((resolve) => {
24363
24569
  this.pendingStreams.set(`${serviceName}.${methodName.toUpperCase()}`, resolve);
@@ -24365,6 +24571,23 @@ var GrpcServer = class {
24365
24571
  }
24366
24572
  return stream;
24367
24573
  }
24574
+ setContext(serviceName, methodName, context) {
24575
+ this.contexts.set(`${serviceName}.${methodName.toUpperCase()}`, context);
24576
+ if (this.pendingContext.has(`${serviceName}.${methodName.toUpperCase()}`)) {
24577
+ const resolve = this.pendingContext.get(`${serviceName}.${methodName.toUpperCase()}`);
24578
+ resolve?.(context);
24579
+ this.pendingContext.delete(`${serviceName}.${methodName.toUpperCase()}`);
24580
+ }
24581
+ }
24582
+ async getContext(serviceName, methodName) {
24583
+ const context = this.contexts.get(`${serviceName}.${methodName.toUpperCase()}`);
24584
+ if (!context) {
24585
+ return new Promise((resolve) => {
24586
+ this.pendingContext.set(`${serviceName}.${methodName.toUpperCase()}`, resolve);
24587
+ });
24588
+ }
24589
+ return context;
24590
+ }
24368
24591
  resolveResponse(id, value) {
24369
24592
  const resolve = this.pendingRequests.get(id);
24370
24593
  if (!resolve) {
@@ -24388,6 +24611,44 @@ var GrpcServer = class {
24388
24611
  });
24389
24612
  };
24390
24613
  break;
24614
+ case "bidi:bidi": {
24615
+ async function* generator(server2) {
24616
+ const inStream = await server2.getStream(
24617
+ `${serviceImpl.serviceClass.serviceName}_IN`,
24618
+ name.toUpperCase()
24619
+ );
24620
+ yield* inStream;
24621
+ }
24622
+ const emitFn = async (...args) => {
24623
+ const outStream = await this.getStream(
24624
+ `${serviceImpl.serviceClass.serviceName}_OUT`,
24625
+ name.toUpperCase()
24626
+ );
24627
+ const ackId = descriptor.config?.ack ? crypto.randomUUID() : void 0;
24628
+ outStream.push(encodeRequestMessage(ackId, args));
24629
+ if (ackId) {
24630
+ return new Promise((resolve) => {
24631
+ this.pendingBidiAck.set(ackId, resolve);
24632
+ });
24633
+ }
24634
+ };
24635
+ const context = {
24636
+ context: this.getContext(serviceImpl.serviceClass.serviceName, name)
24637
+ };
24638
+ const hybrid = Object.assign(emitFn, {
24639
+ [Symbol.asyncIterator]: () => {
24640
+ const iterator = generator(this);
24641
+ return {
24642
+ next: iterator.next.bind(iterator),
24643
+ return: iterator.return.bind(iterator),
24644
+ throw: iterator.throw.bind(iterator)
24645
+ };
24646
+ }
24647
+ });
24648
+ Object.assign(hybrid, context);
24649
+ serviceCallableInstance[name] = hybrid;
24650
+ break;
24651
+ }
24391
24652
  }
24392
24653
  }
24393
24654
  Object.defineProperty(this, serviceImpl.serviceClass.serviceName, {
@@ -24452,6 +24713,7 @@ long/umd/index.js:
24452
24713
  */
24453
24714
 
24454
24715
  exports.Service = Service;
24716
+ exports.bidi = bidi;
24455
24717
  exports.client = client;
24456
24718
  exports.createGrpcClient = createGrpcClient;
24457
24719
  exports.createGrpcServer = createGrpcServer;