grpc-libp2p-client 0.0.37 → 0.0.39

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/src/index.ts CHANGED
@@ -154,6 +154,7 @@ export class Libp2pGrpcClient {
154
154
 
155
155
  await new Promise<void>((resolve, reject) => {
156
156
  let settled = false;
157
+ // eslint-disable-next-line prefer-const
157
158
  let timeoutId: ReturnType<typeof setTimeout> | undefined;
158
159
  const cleanup = () => {
159
160
  const idx = state.waiters.indexOf(waiter);
@@ -239,7 +240,7 @@ export class Libp2pGrpcClient {
239
240
  if (signal?.aborted) {
240
241
  throw new Error("Operation aborted");
241
242
  }
242
- await writer.write(frame as any);
243
+ await writer.write(frame);
243
244
  if (payloadLength > 0) {
244
245
  parser.consumeSendWindow(streamId, payloadLength);
245
246
  }
@@ -252,7 +253,7 @@ export class Libp2pGrpcClient {
252
253
  if (pooled) {
253
254
  const conn = pooled.connection;
254
255
  if (conn) {
255
- const status = (conn as any)?.stat?.status?.toLowerCase?.();
256
+ const status = conn.status;
256
257
  if (!status || status === "open") {
257
258
  return conn;
258
259
  }
@@ -279,15 +280,8 @@ export class Libp2pGrpcClient {
279
280
  }
280
281
  };
281
282
  try {
282
- const anyConn = conn as any;
283
- if (typeof anyConn.addEventListener === "function") {
284
- anyConn.addEventListener("close", removeFromPool, {
285
- once: true,
286
- });
287
- } else if (typeof anyConn.once === "function") {
288
- anyConn.once("close", removeFromPool);
289
- }
290
- } catch {}
283
+ conn.addEventListener("close", removeFromPool, { once: true });
284
+ } catch { /* ignore event listener registration errors */ }
291
285
  }
292
286
  }
293
287
  return conn;
@@ -364,17 +358,17 @@ export class Libp2pGrpcClient {
364
358
  bufferSize: 16 * 1024 * 1024,
365
359
  });
366
360
  try {
367
- writer.addEventListener("backpressure", (e: any) => {
368
- const d = e?.detail || {};
361
+ writer.addEventListener("backpressure", (e: CustomEvent) => {
362
+ const d = e.detail || {};
369
363
  console.warn(
370
364
  `[unary stream ${streamId}] backpressure current=${d.currentSize} avg=${d.averageSize} threshold=${d.threshold}`
371
365
  );
372
366
  });
373
- writer.addEventListener("drain", (e: any) => {
374
- const d = e?.detail || {};
367
+ writer.addEventListener("drain", () => {
368
+ // drain event - no action needed
375
369
  });
376
- writer.addEventListener("stalled", (e: any) => {
377
- const d = e?.detail || {};
370
+ writer.addEventListener("stalled", (e: CustomEvent) => {
371
+ const d = e.detail || {};
378
372
  console.warn(
379
373
  `[unary stream ${streamId}] stalled queue=${d.queueSize} drained=${d.drained} since=${d.sinceMs}ms — sending PING`
380
374
  );
@@ -382,10 +376,10 @@ export class Libp2pGrpcClient {
382
376
  const payload = new Uint8Array(8);
383
377
  crypto.getRandomValues?.(payload);
384
378
  const ping = Http2Frame.createFrame(0x6, 0x0, 0, payload);
385
- writer.write(ping as any);
386
- } catch {}
379
+ writer.write(ping);
380
+ } catch { /* ignore ping write errors */ }
387
381
  });
388
- } catch {}
382
+ } catch { /* ignore addEventListener errors */ }
389
383
  const parser = new HTTP2Parser(writer);
390
384
  parser.onGoaway = (info) => {
391
385
  console.warn("[unaryCall] GOAWAY received from server", info);
@@ -399,7 +393,7 @@ export class Libp2pGrpcClient {
399
393
  exitFlag = true;
400
394
  errMsg = `GOAWAY received: code=${info.errorCode}`;
401
395
  try {
402
- (connection as any)?.close?.();
396
+ connection?.close();
403
397
  } catch (err) {
404
398
  console.warn("Error closing connection after GOAWAY:", err);
405
399
  }
@@ -425,7 +419,6 @@ export class Libp2pGrpcClient {
425
419
  if (payload.length < 5) {
426
420
  return;
427
421
  }
428
- const compressionFlag = payload[0]; // 压缩标志
429
422
  const lengthBytes = payload.slice(1, 5); // 消息长度的4字节
430
423
  responseDataExpectedLength = new DataView(
431
424
  lengthBytes.buffer,
@@ -508,19 +501,16 @@ export class Libp2pGrpcClient {
508
501
  parser.onSettings = () => {
509
502
  //接收settings,反馈ack
510
503
  const ackSettingFrame = Http2Frame.createSettingsAckFrame();
511
- writer.write(ackSettingFrame as any);
504
+ writer.write(ackSettingFrame);
512
505
  };
513
- parser.onHeaders = (headers, header) => {
514
-
506
+ parser.onHeaders = (headers) => {
515
507
  const plainHeaders = hpack.decodeHeaderFields(headers);
516
508
  if (plainHeaders.get("grpc-status") === "0") {
517
509
  // 成功状态
518
-
519
510
  } else if (plainHeaders.get("grpc-status") !== undefined) {
520
511
  exitFlag = true;
521
512
  errMsg = plainHeaders.get("grpc-message") || "gRPC call failed";
522
513
  }
523
-
524
514
  };
525
515
  // 启动后台流处理,捕获任何异步错误
526
516
  parser.processStream(stream).catch((error: unknown) => {
@@ -533,26 +523,17 @@ export class Libp2pGrpcClient {
533
523
 
534
524
  // 握手
535
525
  const preface = Http2Frame.createPreface();
536
- await writer.write(preface as any);
526
+ await writer.write(preface);
537
527
  // 发送Settings请求
538
528
  const settingFrme = Http2Frame.createSettingsFrame();
539
- await writer.write(settingFrme as any);
529
+ await writer.write(settingFrme);
540
530
  // 等待对端 SETTINGS 或 ACK,择一即可,避免偶发握手竞态
541
- {
542
- let progressed = false;
543
- await Promise.race([
544
- (async () => {
545
- await parser.waitForPeerSettings(1000);
546
- progressed = true;
547
- })(),
548
- (async () => {
549
- await parser.waitForSettingsAck();
550
- progressed = true;
551
- })(),
552
- new Promise<void>((res) => setTimeout(res, 300)),
553
- ]);
554
- // 即使未等到,也继续;多数实现会随后发送
555
- }
531
+ await Promise.race([
532
+ parser.waitForPeerSettings(1000),
533
+ parser.waitForSettingsAck(),
534
+ new Promise<void>((res) => setTimeout(res, 300)),
535
+ ]);
536
+ // 即使未等到,也继续;多数实现会随后发送
556
537
  // 创建头部帧
557
538
  const headerFrame = Http2Frame.createHeadersFrame(
558
539
  streamId,
@@ -560,7 +541,7 @@ export class Libp2pGrpcClient {
560
541
  true,
561
542
  this.token
562
543
  );
563
- await writer.write(headerFrame as any);
544
+ await writer.write(headerFrame);
564
545
  // 直接按帧大小分片发送(保持与之前一致的稳定路径)
565
546
  const dataFrames = Http2Frame.createDataFrames(
566
547
  streamId,
@@ -596,8 +577,8 @@ export class Libp2pGrpcClient {
596
577
  checkResponse();
597
578
  });
598
579
  try {
599
- await (writer as any).flush?.(timeout);
600
- } catch {}
580
+ await writer.flush(timeout);
581
+ } catch { /* ignore flush errors */ }
601
582
  await writer.end();
602
583
  } catch (err) {
603
584
  console.error("unaryCall error:", err);
@@ -649,7 +630,7 @@ export class Libp2pGrpcClient {
649
630
  ) {
650
631
  // 创建内部AbortController用于控制操作
651
632
  const internalController = new AbortController();
652
- let timeoutHandle: any;
633
+ let timeoutHandle: ReturnType<typeof setTimeout> | undefined;
653
634
  let stream: Stream | null = null;
654
635
 
655
636
  const profile: TransportProfile =
@@ -715,7 +696,7 @@ export class Libp2pGrpcClient {
715
696
  if (options?.freshConnection) {
716
697
  try {
717
698
  this.connectionPool.delete(this.peerAddr.toString());
718
- await (this as any).node?.hangUp?.(this.peerAddr as any);
699
+ await this.node.hangUp(this.peerAddr);
719
700
  console.warn(
720
701
  "[Call] hangUp existing connection before dialing due to freshConnection=true"
721
702
  );
@@ -757,17 +738,17 @@ export class Libp2pGrpcClient {
757
738
  bufferSize: 16 * 1024 * 1024,
758
739
  });
759
740
  try {
760
- writer.addEventListener("backpressure", (e: any) => {
761
- const d = e?.detail || {};
741
+ writer.addEventListener("backpressure", (e: CustomEvent) => {
742
+ const d = e.detail || {};
762
743
  console.warn(
763
744
  `[stream ${streamId}] backpressure current=${d.currentSize} avg=${d.averageSize} threshold=${d.threshold}`
764
745
  );
765
746
  });
766
- writer.addEventListener("drain", (e: any) => {
767
- const d = e?.detail || {};
747
+ writer.addEventListener("drain", () => {
748
+ // drain event - no action needed
768
749
  });
769
- writer.addEventListener("stalled", (e: any) => {
770
- const d = e?.detail || {};
750
+ writer.addEventListener("stalled", (e: CustomEvent) => {
751
+ const d = e.detail || {};
771
752
  console.warn(
772
753
  `[stream ${streamId}] stalled queue=${d.queueSize} drained=${d.drained} since=${d.sinceMs}ms — sending PING`
773
754
  );
@@ -775,10 +756,10 @@ export class Libp2pGrpcClient {
775
756
  const payload = new Uint8Array(8);
776
757
  crypto.getRandomValues?.(payload);
777
758
  const ping = Http2Frame.createFrame(0x6, 0x0, 0, payload);
778
- writer.write(ping as any);
779
- } catch { /* empty */ }
759
+ writer.write(ping);
760
+ } catch { /* ignore ping write errors */ }
780
761
  });
781
- } catch { /* empty */ }
762
+ } catch { /* ignore addEventListener errors */ }
782
763
  const parser = new HTTP2Parser(writer, {
783
764
  compatibilityMode: !useFlowControl,
784
765
  });
@@ -798,7 +779,7 @@ export class Libp2pGrpcClient {
798
779
  }
799
780
  internalController.abort();
800
781
  try {
801
- (connection as any)?.close?.();
782
+ connection?.close();
802
783
  } catch (err) {
803
784
  console.warn("Error closing connection after GOAWAY:", err);
804
785
  }
@@ -832,7 +813,7 @@ export class Libp2pGrpcClient {
832
813
  if (internalController.signal.aborted) {
833
814
  throw new Error("Operation aborted");
834
815
  }
835
- await writer.write(frame as any);
816
+ await writer.write(frame);
836
817
  }
837
818
  };
838
819
  const writeDataFrames = async (frames: Uint8Array[]) => {
@@ -842,7 +823,7 @@ export class Libp2pGrpcClient {
842
823
  };
843
824
 
844
825
  // 在各个回调中检查是否已中止
845
- parser.onData = async (payload, frameHeader): Promise<void> => {
826
+ parser.onData = async (payload): Promise<void> => {
846
827
  // 检查是否已中止
847
828
  if (internalController.signal.aborted) {
848
829
  return;
@@ -867,7 +848,6 @@ export class Libp2pGrpcClient {
867
848
  // 如果还没有读取消息长度,且缓冲区有足够数据
868
849
  if (expectedMessageLength === -1 && messageBuffer.length >= 5) {
869
850
  // 读取 gRPC 消息头:1字节压缩标志 + 4字节长度
870
- const compressionFlag = messageBuffer[0];
871
851
  const lengthBytes = messageBuffer.slice(1, 5);
872
852
  expectedMessageLength = new DataView(
873
853
  lengthBytes.buffer,
@@ -911,10 +891,10 @@ export class Libp2pGrpcClient {
911
891
  if (internalController.signal.aborted) return;
912
892
 
913
893
  const ackSettingFrame = Http2Frame.createSettingsAckFrame();
914
- writer.write(ackSettingFrame as any);
894
+ writer.write(ackSettingFrame);
915
895
  };
916
896
 
917
- parser.onHeaders = (headers, header) => {
897
+ parser.onHeaders = (headers) => {
918
898
  // 检查是否已中止
919
899
  if (internalController.signal.aborted) return;
920
900
 
@@ -947,7 +927,7 @@ export class Libp2pGrpcClient {
947
927
 
948
928
  // Handshake - send HTTP/2 preface
949
929
  const preface = Http2Frame.createPreface();
950
- await writer.write(preface as any);
930
+ await writer.write(preface);
951
931
 
952
932
  // 检查是否已中止
953
933
  if (internalController.signal.aborted) {
@@ -956,7 +936,7 @@ export class Libp2pGrpcClient {
956
936
 
957
937
  // Send Settings request
958
938
  const settingFrame = Http2Frame.createSettingsFrame();
959
- await writer.write(settingFrame as any);
939
+ await writer.write(settingFrame);
960
940
 
961
941
  // 检查是否已中止
962
942
  if (internalController.signal.aborted) {
@@ -965,16 +945,9 @@ export class Libp2pGrpcClient {
965
945
 
966
946
  // 等待对端 SETTINGS 或 ACK,择一即可,避免偶发握手竞态
967
947
  {
968
- let progressed = false;
969
948
  await Promise.race([
970
- (async () => {
971
- await parser.waitForPeerSettings(1000);
972
- progressed = true;
973
- })(),
974
- (async () => {
975
- await parser.waitForSettingsAck();
976
- progressed = true;
977
- })(),
949
+ parser.waitForPeerSettings(1000),
950
+ parser.waitForSettingsAck(),
978
951
  new Promise<void>((res) => setTimeout(res, 300)),
979
952
  ]);
980
953
  // 即使未等到,也继续;多数实现会随后发送
@@ -998,7 +971,7 @@ export class Libp2pGrpcClient {
998
971
  this.token
999
972
  );
1000
973
  if (mode === "unary" || mode === "server-streaming") {
1001
- await writer.write(headerFrame as any);
974
+ await writer.write(headerFrame);
1002
975
  const dfs = Http2Frame.createDataFrames(streamId, requestData, true);
1003
976
  await writeDataFrames(dfs);
1004
977
 
@@ -1010,7 +983,7 @@ export class Libp2pGrpcClient {
1010
983
  (mode === "client-streaming" || mode === "bidirectional") &&
1011
984
  dataSourceCallback
1012
985
  ) {
1013
- await writer.write(headerFrame as any);
986
+ await writer.write(headerFrame);
1014
987
 
1015
988
  // 检查是否已中止
1016
989
  if (internalController.signal.aborted) {
@@ -1028,13 +1001,12 @@ export class Libp2pGrpcClient {
1028
1001
 
1029
1002
  // 动态批量处理逻辑 - 在处理过程中动态补充新数据
1030
1003
  const batchSize = options?.batchSize || 10;
1031
- const maxBatchWaitMs = options?.maxBatchWaitMs || 50;
1032
1004
 
1033
1005
  // 动态批处理器
1034
1006
  const processingQueue: {
1035
1007
  chunk: Uint8Array;
1036
1008
  resolve: (value: void | PromiseLike<void>) => void;
1037
- reject: (reason?: any) => void;
1009
+ reject: (reason?: unknown) => void;
1038
1010
  }[] = [];
1039
1011
 
1040
1012
  let isProcessing = false;
@@ -1195,8 +1167,8 @@ export class Libp2pGrpcClient {
1195
1167
  await writeFrame(finalFrame);
1196
1168
  // 在结束前尽量冲刷内部队列,避免服务器看到部分数据 + context canceled
1197
1169
  try {
1198
- await (writer as any).flush?.(timeout);
1199
- } catch {}
1170
+ await writer.flush(timeout);
1171
+ } catch { /* ignore flush errors */ }
1200
1172
  await writer.end();
1201
1173
  }
1202
1174
 
@@ -1242,14 +1214,14 @@ export class Libp2pGrpcClient {
1242
1214
  if (options?.freshConnection) {
1243
1215
  try {
1244
1216
  // 通过 libp2p 连接管理器关闭到该 peer 的连接
1245
- const conns =
1246
- (this as any).node?.getConnections?.(this.peerAddr as any) || [];
1217
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1218
+ const conns = (this.node as any).getConnections?.(this.peerAddr as any) || [];
1247
1219
  for (const c of conns) {
1248
1220
  try {
1249
1221
  await c.close?.();
1250
- } catch {}
1222
+ } catch { /* ignore close errors */ }
1251
1223
  }
1252
- } catch {}
1224
+ } catch { /* ignore connection cleanup errors */ }
1253
1225
  }
1254
1226
  if (streamSlotAcquired && state) {
1255
1227
  state.activeStreams = Math.max(0, state.activeStreams - 1);