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