@gethashd/bytecave-browser 1.0.10 → 1.0.12

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.
@@ -5777,16 +5777,47 @@ var P2PProtocolClient = class {
5777
5777
  return null;
5778
5778
  }
5779
5779
  }
5780
+ /**
5781
+ * Wait for a direct (non-relay) connection to a peer
5782
+ * Returns true if direct connection is available, false if timeout
5783
+ */
5784
+ async waitForDirectConnection(peerId, timeoutMs = 3e3) {
5785
+ if (!this.node) return false;
5786
+ const peerIdObj = peerIdFromString(peerId);
5787
+ const startTime = Date.now();
5788
+ while (Date.now() - startTime < timeoutMs) {
5789
+ const connections = this.node.getConnections(peerIdObj);
5790
+ const hasDirectConnection = connections.some((conn) => {
5791
+ const isRelay = conn.remoteAddr.toString().includes("/p2p-circuit");
5792
+ return !isRelay;
5793
+ });
5794
+ if (hasDirectConnection) {
5795
+ console.log("[ByteCave P2P] Direct connection established to", peerId.slice(0, 12));
5796
+ return true;
5797
+ }
5798
+ await new Promise((resolve) => setTimeout(resolve, 100));
5799
+ }
5800
+ console.warn("[ByteCave P2P] Timeout waiting for direct connection to", peerId.slice(0, 12));
5801
+ return false;
5802
+ }
5780
5803
  /**
5781
5804
  * Get health info from a peer via P2P stream
5805
+ * Waits for direct connection upgrade before querying
5782
5806
  */
5783
- async getHealthFromPeer(peerId) {
5807
+ async getHealthFromPeer(peerId, waitForDirect = true) {
5784
5808
  if (!this.node) {
5785
5809
  console.warn("[ByteCave P2P] No node available for health request");
5786
5810
  return null;
5787
5811
  }
5788
5812
  try {
5789
5813
  const peerIdObj = peerIdFromString(peerId);
5814
+ if (waitForDirect) {
5815
+ const hasDirect = await this.waitForDirectConnection(peerId, 3e3);
5816
+ if (!hasDirect) {
5817
+ console.warn("[ByteCave P2P] No direct connection available for health query to", peerId.slice(0, 12));
5818
+ return null;
5819
+ }
5820
+ }
5790
5821
  const stream = await this.node.dialProtocol(peerIdObj, PROTOCOL_HEALTH);
5791
5822
  await this.writeMessage(stream, {});
5792
5823
  const response = await this.readMessage(stream);
@@ -6731,8 +6762,7 @@ function ByteCaveProvider({
6731
6762
  }
6732
6763
  };
6733
6764
  client.on("connectionStateChange", handleStateChange);
6734
- client.on("peerConnect", handlePeerUpdate);
6735
- client.on("peerDisconnect", handlePeerUpdate);
6765
+ client.on("peerAnnounce", handlePeerUpdate);
6736
6766
  const hasPeers = directNodeAddrs.length > 0 || relayPeers.length > 0;
6737
6767
  console.log("[ByteCaveProvider] Auto-connect check:", {
6738
6768
  hasPeers,
package/dist/index.cjs CHANGED
@@ -5845,16 +5845,47 @@ var P2PProtocolClient = class {
5845
5845
  return null;
5846
5846
  }
5847
5847
  }
5848
+ /**
5849
+ * Wait for a direct (non-relay) connection to a peer
5850
+ * Returns true if direct connection is available, false if timeout
5851
+ */
5852
+ async waitForDirectConnection(peerId, timeoutMs = 3e3) {
5853
+ if (!this.node) return false;
5854
+ const peerIdObj = peerIdFromString(peerId);
5855
+ const startTime = Date.now();
5856
+ while (Date.now() - startTime < timeoutMs) {
5857
+ const connections = this.node.getConnections(peerIdObj);
5858
+ const hasDirectConnection = connections.some((conn) => {
5859
+ const isRelay = conn.remoteAddr.toString().includes("/p2p-circuit");
5860
+ return !isRelay;
5861
+ });
5862
+ if (hasDirectConnection) {
5863
+ console.log("[ByteCave P2P] Direct connection established to", peerId.slice(0, 12));
5864
+ return true;
5865
+ }
5866
+ await new Promise((resolve) => setTimeout(resolve, 100));
5867
+ }
5868
+ console.warn("[ByteCave P2P] Timeout waiting for direct connection to", peerId.slice(0, 12));
5869
+ return false;
5870
+ }
5848
5871
  /**
5849
5872
  * Get health info from a peer via P2P stream
5873
+ * Waits for direct connection upgrade before querying
5850
5874
  */
5851
- async getHealthFromPeer(peerId) {
5875
+ async getHealthFromPeer(peerId, waitForDirect = true) {
5852
5876
  if (!this.node) {
5853
5877
  console.warn("[ByteCave P2P] No node available for health request");
5854
5878
  return null;
5855
5879
  }
5856
5880
  try {
5857
5881
  const peerIdObj = peerIdFromString(peerId);
5882
+ if (waitForDirect) {
5883
+ const hasDirect = await this.waitForDirectConnection(peerId, 3e3);
5884
+ if (!hasDirect) {
5885
+ console.warn("[ByteCave P2P] No direct connection available for health query to", peerId.slice(0, 12));
5886
+ return null;
5887
+ }
5888
+ }
5858
5889
  const stream = await this.node.dialProtocol(peerIdObj, PROTOCOL_HEALTH);
5859
5890
  await this.writeMessage(stream, {});
5860
5891
  const response = await this.readMessage(stream);
@@ -6784,8 +6815,7 @@ function ByteCaveProvider({
6784
6815
  }
6785
6816
  };
6786
6817
  client.on("connectionStateChange", handleStateChange);
6787
- client.on("peerConnect", handlePeerUpdate);
6788
- client.on("peerDisconnect", handlePeerUpdate);
6818
+ client.on("peerAnnounce", handlePeerUpdate);
6789
6819
  const hasPeers = directNodeAddrs.length > 0 || relayPeers.length > 0;
6790
6820
  console.log("[ByteCaveProvider] Auto-connect check:", {
6791
6821
  hasPeers,
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  useHashdImage,
14
14
  useHashdMedia,
15
15
  useHashdUrl
16
- } from "./chunk-DJDKXTUN.js";
16
+ } from "./chunk-XC5Z2TQH.js";
17
17
  import {
18
18
  clearHashdCache,
19
19
  createHashdUrl,
@@ -90,10 +90,16 @@ export declare class P2PProtocolClient {
90
90
  data: Uint8Array;
91
91
  mimeType: string;
92
92
  } | null>;
93
+ /**
94
+ * Wait for a direct (non-relay) connection to a peer
95
+ * Returns true if direct connection is available, false if timeout
96
+ */
97
+ private waitForDirectConnection;
93
98
  /**
94
99
  * Get health info from a peer via P2P stream
100
+ * Waits for direct connection upgrade before querying
95
101
  */
96
- getHealthFromPeer(peerId: string): Promise<P2PHealthResponse | null>;
102
+ getHealthFromPeer(peerId: string, waitForDirect?: boolean): Promise<P2PHealthResponse | null>;
97
103
  /**
98
104
  * Query relay for peer directory
99
105
  */
@@ -6100,16 +6100,47 @@ var P2PProtocolClient = class {
6100
6100
  return null;
6101
6101
  }
6102
6102
  }
6103
+ /**
6104
+ * Wait for a direct (non-relay) connection to a peer
6105
+ * Returns true if direct connection is available, false if timeout
6106
+ */
6107
+ async waitForDirectConnection(peerId, timeoutMs = 3e3) {
6108
+ if (!this.node) return false;
6109
+ const peerIdObj = peerIdFromString(peerId);
6110
+ const startTime = Date.now();
6111
+ while (Date.now() - startTime < timeoutMs) {
6112
+ const connections = this.node.getConnections(peerIdObj);
6113
+ const hasDirectConnection = connections.some((conn) => {
6114
+ const isRelay = conn.remoteAddr.toString().includes("/p2p-circuit");
6115
+ return !isRelay;
6116
+ });
6117
+ if (hasDirectConnection) {
6118
+ console.log("[ByteCave P2P] Direct connection established to", peerId.slice(0, 12));
6119
+ return true;
6120
+ }
6121
+ await new Promise((resolve) => setTimeout(resolve, 100));
6122
+ }
6123
+ console.warn("[ByteCave P2P] Timeout waiting for direct connection to", peerId.slice(0, 12));
6124
+ return false;
6125
+ }
6103
6126
  /**
6104
6127
  * Get health info from a peer via P2P stream
6128
+ * Waits for direct connection upgrade before querying
6105
6129
  */
6106
- async getHealthFromPeer(peerId) {
6130
+ async getHealthFromPeer(peerId, waitForDirect = true) {
6107
6131
  if (!this.node) {
6108
6132
  console.warn("[ByteCave P2P] No node available for health request");
6109
6133
  return null;
6110
6134
  }
6111
6135
  try {
6112
6136
  const peerIdObj = peerIdFromString(peerId);
6137
+ if (waitForDirect) {
6138
+ const hasDirect = await this.waitForDirectConnection(peerId, 3e3);
6139
+ if (!hasDirect) {
6140
+ console.warn("[ByteCave P2P] No direct connection available for health query to", peerId.slice(0, 12));
6141
+ return null;
6142
+ }
6143
+ }
6113
6144
  const stream = await this.node.dialProtocol(peerIdObj, PROTOCOL_HEALTH);
6114
6145
  await this.writeMessage(stream, {});
6115
6146
  const response = await this.readMessage(stream);
@@ -8,7 +8,7 @@ import {
8
8
  useHashdImage,
9
9
  useHashdMedia,
10
10
  useHashdUrl
11
- } from "../chunk-DJDKXTUN.js";
11
+ } from "../chunk-XC5Z2TQH.js";
12
12
  import "../chunk-EEZWRIUI.js";
13
13
  export {
14
14
  HashdAudio,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gethashd/bytecave-browser",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "ByteCave browser client for WebRTC P2P connections to storage nodes",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -219,20 +219,59 @@ export class P2PProtocolClient {
219
219
  }
220
220
  }
221
221
 
222
+ /**
223
+ * Wait for a direct (non-relay) connection to a peer
224
+ * Returns true if direct connection is available, false if timeout
225
+ */
226
+ private async waitForDirectConnection(peerId: string, timeoutMs: number = 3000): Promise<boolean> {
227
+ if (!this.node) return false;
228
+
229
+ const peerIdObj = peerIdFromString(peerId);
230
+ const startTime = Date.now();
231
+
232
+ while (Date.now() - startTime < timeoutMs) {
233
+ const connections = this.node.getConnections(peerIdObj);
234
+ const hasDirectConnection = connections.some(conn => {
235
+ // Check if connection is NOT a relay circuit (direct WebRTC or WebSocket)
236
+ const isRelay = conn.remoteAddr.toString().includes('/p2p-circuit');
237
+ return !isRelay;
238
+ });
239
+
240
+ if (hasDirectConnection) {
241
+ console.log('[ByteCave P2P] Direct connection established to', peerId.slice(0, 12));
242
+ return true;
243
+ }
244
+
245
+ // Wait 100ms before checking again
246
+ await new Promise(resolve => setTimeout(resolve, 100));
247
+ }
248
+
249
+ console.warn('[ByteCave P2P] Timeout waiting for direct connection to', peerId.slice(0, 12));
250
+ return false;
251
+ }
252
+
222
253
  /**
223
254
  * Get health info from a peer via P2P stream
255
+ * Waits for direct connection upgrade before querying
224
256
  */
225
- async getHealthFromPeer(peerId: string): Promise<P2PHealthResponse | null> {
257
+ async getHealthFromPeer(peerId: string, waitForDirect: boolean = true): Promise<P2PHealthResponse | null> {
226
258
  if (!this.node) {
227
259
  console.warn('[ByteCave P2P] No node available for health request');
228
260
  return null;
229
261
  }
230
262
 
231
263
  try {
232
-
233
264
  // Convert string peerId to PeerId object
234
265
  const peerIdObj = peerIdFromString(peerId);
235
266
 
267
+ // Wait for DCUtR to upgrade connection to direct WebRTC
268
+ if (waitForDirect) {
269
+ const hasDirect = await this.waitForDirectConnection(peerId, 3000);
270
+ if (!hasDirect) {
271
+ console.warn('[ByteCave P2P] No direct connection available for health query to', peerId.slice(0, 12));
272
+ return null;
273
+ }
274
+ }
236
275
 
237
276
  const stream = await this.node.dialProtocol(peerIdObj, PROTOCOL_HEALTH);
238
277
 
package/src/provider.tsx CHANGED
@@ -141,8 +141,9 @@ export function ByteCaveProvider({
141
141
  };
142
142
 
143
143
  client.on('connectionStateChange', handleStateChange);
144
- client.on('peerConnect', handlePeerUpdate);
145
- client.on('peerDisconnect', handlePeerUpdate);
144
+ // Only listen to peerAnnounce - floodsub announcements are the single source of truth
145
+ // They include all health data (nodeId, storage, blobs, etc.)
146
+ client.on('peerAnnounce', handlePeerUpdate);
146
147
 
147
148
  const hasPeers = directNodeAddrs.length > 0 || relayPeers.length > 0;
148
149