@gethashd/bytecave-browser 1.0.13 → 1.0.16

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/AGENTS.md CHANGED
@@ -31,45 +31,47 @@ yarn build
31
31
  - `dist/react/index.js` - React-specific exports
32
32
  - `dist/*.d.ts` - TypeScript type definitions
33
33
 
34
- ## **CRITICAL: Git Workflow**
34
+ ## **CRITICAL: npm Publishing Workflow**
35
35
 
36
36
  ### After Making Changes
37
37
  **YOU MUST FOLLOW THIS WORKFLOW:**
38
38
 
39
- 1. **Build the package**
39
+ 1. **Build and publish to npm**
40
40
  ```bash
41
+ cd bytecave-browser
41
42
  yarn build
43
+ npm publish --access public
42
44
  ```
45
+ - This automatically builds, commits to git, and publishes to npm registry
46
+ - Version is controlled in `package.json`
43
47
 
44
- 2. **Commit changes to git**
45
- ```bash
46
- git add .
47
- git commit -m "Description of changes"
48
- ```
49
-
50
- 3. **Push to git**
51
- ```bash
52
- git push
53
- ```
54
-
55
- 4. **Update dependent packages**
48
+ 2. **Update dependent packages**
56
49
  In `web/` or `dashboard/`:
57
50
  ```bash
58
- yarn upgrade @hashd/bytecave-browser
51
+ yarn upgrade @gethashd/bytecave-browser@<version>
59
52
  ```
53
+ - Use specific version number from `package.json`
54
+ - Example: `yarn upgrade @gethashd/bytecave-browser@1.0.13`
60
55
 
61
56
  ### Why This Is Critical
62
- - `web` and `dashboard` install bytecave-browser from **git**, not from local files
63
- - If you don't push to git, dependent packages will use stale code
64
- - Even after rebuilding, changes won't appear until pushed and upgraded
57
+ - `web` and `dashboard` install bytecave-browser from **npm registry**, not from git
58
+ - If you don't publish to npm, dependent packages will use stale code
59
+ - Even after rebuilding locally, changes won't appear until published and upgraded
65
60
 
66
61
  ### Common Mistake
67
62
  ❌ **WRONG**: Build bytecave-browser → Rebuild web/dashboard → Test
68
- - This will use OLD code because web/dashboard pull from git
63
+ - This will use OLD code because web/dashboard pull from npm
69
64
 
70
- ✅ **CORRECT**: Build bytecave-browser Git commit & push → Upgrade in web/dashboard → Test
65
+ ✅ **CORRECT**: Build & publish to npm → Upgrade in web/dashboard → Test
71
66
  - This ensures latest code is used
72
67
 
68
+ ### Version Management
69
+ - Bump version in `package.json` before publishing
70
+ - Follow semantic versioning: MAJOR.MINOR.PATCH
71
+ - Patch (1.0.x): Bug fixes
72
+ - Minor (1.x.0): New features, backward compatible
73
+ - Major (x.0.0): Breaking changes
74
+
73
75
  ## Key Architecture Concepts
74
76
 
75
77
  ### ByteCaveClient
@@ -98,20 +100,20 @@ Main client class for P2P storage operations:
98
100
 
99
101
  ### Web App (`/web`)
100
102
  - Uses bytecave-browser for vault storage
101
- - Installs from git: `@hashd/bytecave-browser`
102
- - After bytecave-browser changes: `yarn upgrade @hashd/bytecave-browser`
103
+ - Installs from npm: `@gethashd/bytecave-browser`
104
+ - After bytecave-browser changes: `yarn upgrade @gethashd/bytecave-browser@<version>`
103
105
 
104
106
  ### Dashboard (`/dashboard`)
105
107
  - Uses bytecave-browser for test storage
106
- - Installs from git: `@hashd/bytecave-browser`
107
- - After bytecave-browser changes: `yarn upgrade @hashd/bytecave-browser`
108
+ - Installs from npm: `@gethashd/bytecave-browser`
109
+ - After bytecave-browser changes: `yarn upgrade @gethashd/bytecave-browser@<version>`
108
110
 
109
111
  ## Testing Workflow
110
112
 
111
113
  ### After Code Changes
112
- 1. Build: `yarn build`
113
- 2. Commit and push to git
114
- 3. In web/dashboard: `yarn upgrade @hashd/bytecave-browser`
114
+ 1. Bump version in `package.json`
115
+ 2. Build and publish: `yarn build && npm publish --access public`
116
+ 3. In web/dashboard: `yarn upgrade @gethashd/bytecave-browser@<version>`
115
117
  4. Rebuild web/dashboard: `yarn build`
116
118
  5. Hard refresh browser (Cmd+Shift+R) to clear cache
117
119
  6. Test storage functionality
@@ -121,9 +123,9 @@ Main client class for P2P storage operations:
121
123
  #### Stale Code in Web/Dashboard
122
124
  **Symptom**: Changes to bytecave-browser don't appear in web/dashboard
123
125
  **Solution**:
124
- 1. Verify bytecave-browser was pushed to git
125
- 2. Run `yarn upgrade @hashd/bytecave-browser` in web/dashboard
126
- 3. Check `node_modules/@hashd/bytecave-browser/package.json` version/commit
126
+ 1. Verify bytecave-browser was published to npm (check version on npmjs.com)
127
+ 2. Run `yarn upgrade @gethashd/bytecave-browser@<version>` in web/dashboard
128
+ 3. Check `node_modules/@gethashd/bytecave-browser/package.json` version matches
127
129
  4. Hard refresh browser
128
130
 
129
131
  #### Type Errors After Changes
@@ -6120,6 +6120,23 @@ var ByteCaveClient = class {
6120
6120
  }
6121
6121
  });
6122
6122
  await Promise.allSettled(peerPromises);
6123
+ } else {
6124
+ console.log("[ByteCave] Relay returned 0 peers, trying direct addresses from localStorage...");
6125
+ if (this.config.directNodeAddrs && this.config.directNodeAddrs.length > 0) {
6126
+ console.log("[ByteCave] Attempting direct connections to", this.config.directNodeAddrs.length, "cached peers...");
6127
+ for (const addr of this.config.directNodeAddrs) {
6128
+ try {
6129
+ console.log("[ByteCave] Dialing direct address:", addr.slice(0, 60) + "...");
6130
+ const ma = multiaddr(addr);
6131
+ await this.node.dial(ma);
6132
+ console.log("[ByteCave] \u2713 Connected directly to peer");
6133
+ } catch (dialErr) {
6134
+ console.warn("[ByteCave] Direct dial failed:", dialErr.message);
6135
+ }
6136
+ }
6137
+ } else {
6138
+ console.log("[ByteCave] No direct addresses in localStorage");
6139
+ }
6123
6140
  }
6124
6141
  } catch (err) {
6125
6142
  console.warn("[ByteCave] HTTP relay discovery failed:", err.message);
@@ -6139,6 +6156,7 @@ var ByteCaveClient = class {
6139
6156
  }
6140
6157
  }
6141
6158
  console.log("[ByteCave] Querying relay for peer directory via P2P...");
6159
+ let gotPeersFromDirectory = false;
6142
6160
  for (const relayAddr of bootstrapPeers) {
6143
6161
  try {
6144
6162
  const parts = relayAddr.split("/p2p/");
@@ -6147,6 +6165,7 @@ var ByteCaveClient = class {
6147
6165
  const directory = await p2pProtocolClient.getPeerDirectoryFromRelay(relayPeerId);
6148
6166
  if (directory && directory.peers.length > 0) {
6149
6167
  console.log("[ByteCave] Got", directory.peers.length, "peers from relay directory");
6168
+ gotPeersFromDirectory = true;
6150
6169
  for (const peer of directory.peers) {
6151
6170
  try {
6152
6171
  console.log("[ByteCave] Dialing peer from directory:", peer.peerId.slice(0, 12) + "...");
@@ -6188,6 +6207,23 @@ var ByteCaveClient = class {
6188
6207
  console.warn("[ByteCave] Failed to get directory from relay:", err.message);
6189
6208
  }
6190
6209
  }
6210
+ if (!gotPeersFromDirectory && this.knownPeers.size === 0) {
6211
+ if (this.config.directNodeAddrs && this.config.directNodeAddrs.length > 0) {
6212
+ console.log("[ByteCave] No peers from relay, attempting direct connections to", this.config.directNodeAddrs.length, "cached peers...");
6213
+ for (const addr of this.config.directNodeAddrs) {
6214
+ try {
6215
+ console.log("[ByteCave] Dialing direct address:", addr.slice(0, 60) + "...");
6216
+ const ma = multiaddr(addr);
6217
+ await this.node.dial(ma);
6218
+ console.log("[ByteCave] \u2713 Connected directly to peer");
6219
+ } catch (dialErr) {
6220
+ console.warn("[ByteCave] Direct dial failed:", dialErr.message);
6221
+ }
6222
+ }
6223
+ } else {
6224
+ console.log("[ByteCave] No direct addresses in localStorage and no relay available");
6225
+ }
6226
+ }
6191
6227
  this.setConnectionState("connected");
6192
6228
  console.log("[ByteCave] Client started", {
6193
6229
  peerId: this.node.peerId.toString(),
@@ -6641,7 +6677,10 @@ Nonce: ${nonce}`;
6641
6677
  blobCount: announcement.blobCount,
6642
6678
  timestamp: announcement.timestamp,
6643
6679
  multiaddrs: announcement.multiaddrs,
6644
- relayAddrs: announcement.relayAddrs || existing?.relayAddrs
6680
+ relayAddrs: announcement.relayAddrs || existing?.relayAddrs,
6681
+ // Store on-chain registration status
6682
+ registeredOnChain: announcement.registeredOnChain || false,
6683
+ onChainNodeId: announcement.onChainNodeId || existing?.onChainNodeId
6645
6684
  };
6646
6685
  this.knownPeers.set(announcement.peerId, peerInfo);
6647
6686
  this.emit("peerAnnounce", peerInfo);
package/dist/index.cjs CHANGED
@@ -6173,6 +6173,23 @@ var ByteCaveClient = class {
6173
6173
  }
6174
6174
  });
6175
6175
  await Promise.allSettled(peerPromises);
6176
+ } else {
6177
+ console.log("[ByteCave] Relay returned 0 peers, trying direct addresses from localStorage...");
6178
+ if (this.config.directNodeAddrs && this.config.directNodeAddrs.length > 0) {
6179
+ console.log("[ByteCave] Attempting direct connections to", this.config.directNodeAddrs.length, "cached peers...");
6180
+ for (const addr of this.config.directNodeAddrs) {
6181
+ try {
6182
+ console.log("[ByteCave] Dialing direct address:", addr.slice(0, 60) + "...");
6183
+ const ma = (0, import_multiaddr.multiaddr)(addr);
6184
+ await this.node.dial(ma);
6185
+ console.log("[ByteCave] \u2713 Connected directly to peer");
6186
+ } catch (dialErr) {
6187
+ console.warn("[ByteCave] Direct dial failed:", dialErr.message);
6188
+ }
6189
+ }
6190
+ } else {
6191
+ console.log("[ByteCave] No direct addresses in localStorage");
6192
+ }
6176
6193
  }
6177
6194
  } catch (err) {
6178
6195
  console.warn("[ByteCave] HTTP relay discovery failed:", err.message);
@@ -6192,6 +6209,7 @@ var ByteCaveClient = class {
6192
6209
  }
6193
6210
  }
6194
6211
  console.log("[ByteCave] Querying relay for peer directory via P2P...");
6212
+ let gotPeersFromDirectory = false;
6195
6213
  for (const relayAddr of bootstrapPeers) {
6196
6214
  try {
6197
6215
  const parts = relayAddr.split("/p2p/");
@@ -6200,6 +6218,7 @@ var ByteCaveClient = class {
6200
6218
  const directory = await p2pProtocolClient.getPeerDirectoryFromRelay(relayPeerId);
6201
6219
  if (directory && directory.peers.length > 0) {
6202
6220
  console.log("[ByteCave] Got", directory.peers.length, "peers from relay directory");
6221
+ gotPeersFromDirectory = true;
6203
6222
  for (const peer of directory.peers) {
6204
6223
  try {
6205
6224
  console.log("[ByteCave] Dialing peer from directory:", peer.peerId.slice(0, 12) + "...");
@@ -6241,6 +6260,23 @@ var ByteCaveClient = class {
6241
6260
  console.warn("[ByteCave] Failed to get directory from relay:", err.message);
6242
6261
  }
6243
6262
  }
6263
+ if (!gotPeersFromDirectory && this.knownPeers.size === 0) {
6264
+ if (this.config.directNodeAddrs && this.config.directNodeAddrs.length > 0) {
6265
+ console.log("[ByteCave] No peers from relay, attempting direct connections to", this.config.directNodeAddrs.length, "cached peers...");
6266
+ for (const addr of this.config.directNodeAddrs) {
6267
+ try {
6268
+ console.log("[ByteCave] Dialing direct address:", addr.slice(0, 60) + "...");
6269
+ const ma = (0, import_multiaddr.multiaddr)(addr);
6270
+ await this.node.dial(ma);
6271
+ console.log("[ByteCave] \u2713 Connected directly to peer");
6272
+ } catch (dialErr) {
6273
+ console.warn("[ByteCave] Direct dial failed:", dialErr.message);
6274
+ }
6275
+ }
6276
+ } else {
6277
+ console.log("[ByteCave] No direct addresses in localStorage and no relay available");
6278
+ }
6279
+ }
6244
6280
  this.setConnectionState("connected");
6245
6281
  console.log("[ByteCave] Client started", {
6246
6282
  peerId: this.node.peerId.toString(),
@@ -6694,7 +6730,10 @@ Nonce: ${nonce}`;
6694
6730
  blobCount: announcement.blobCount,
6695
6731
  timestamp: announcement.timestamp,
6696
6732
  multiaddrs: announcement.multiaddrs,
6697
- relayAddrs: announcement.relayAddrs || existing?.relayAddrs
6733
+ relayAddrs: announcement.relayAddrs || existing?.relayAddrs,
6734
+ // Store on-chain registration status
6735
+ registeredOnChain: announcement.registeredOnChain || false,
6736
+ onChainNodeId: announcement.onChainNodeId || existing?.onChainNodeId
6698
6737
  };
6699
6738
  this.knownPeers.set(announcement.peerId, peerInfo);
6700
6739
  this.emit("peerAnnounce", peerInfo);
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  useHashdImage,
14
14
  useHashdMedia,
15
15
  useHashdUrl
16
- } from "./chunk-W2MGINUZ.js";
16
+ } from "./chunk-OS5QOU7R.js";
17
17
  import {
18
18
  clearHashdCache,
19
19
  createHashdUrl,
@@ -8,7 +8,7 @@ import {
8
8
  useHashdImage,
9
9
  useHashdMedia,
10
10
  useHashdUrl
11
- } from "../chunk-W2MGINUZ.js";
11
+ } from "../chunk-OS5QOU7R.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.13",
3
+ "version": "1.0.16",
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",
package/src/client.ts CHANGED
@@ -192,6 +192,24 @@ export class ByteCaveClient {
192
192
 
193
193
  // Wait for all peer connections and health queries to complete
194
194
  await Promise.allSettled(peerPromises);
195
+ } else {
196
+ // Relay returned 0 peers - try direct addresses from localStorage
197
+ console.log('[ByteCave] Relay returned 0 peers, trying direct addresses from localStorage...');
198
+ if (this.config.directNodeAddrs && this.config.directNodeAddrs.length > 0) {
199
+ console.log('[ByteCave] Attempting direct connections to', this.config.directNodeAddrs.length, 'cached peers...');
200
+ for (const addr of this.config.directNodeAddrs) {
201
+ try {
202
+ console.log('[ByteCave] Dialing direct address:', addr.slice(0, 60) + '...');
203
+ const ma = multiaddr(addr);
204
+ await this.node!.dial(ma as any);
205
+ console.log('[ByteCave] ✓ Connected directly to peer');
206
+ } catch (dialErr: any) {
207
+ console.warn('[ByteCave] Direct dial failed:', dialErr.message);
208
+ }
209
+ }
210
+ } else {
211
+ console.log('[ByteCave] No direct addresses in localStorage');
212
+ }
195
213
  }
196
214
  } catch (err: any) {
197
215
  console.warn('[ByteCave] HTTP relay discovery failed:', err.message);
@@ -215,6 +233,7 @@ export class ByteCaveClient {
215
233
 
216
234
  // Fallback: Query relay for peer directory via P2P protocol
217
235
  console.log('[ByteCave] Querying relay for peer directory via P2P...');
236
+ let gotPeersFromDirectory = false;
218
237
  for (const relayAddr of bootstrapPeers) {
219
238
  try {
220
239
  // Extract relay peer ID from multiaddr
@@ -225,6 +244,7 @@ export class ByteCaveClient {
225
244
  const directory = await p2pProtocolClient.getPeerDirectoryFromRelay(relayPeerId);
226
245
  if (directory && directory.peers.length > 0) {
227
246
  console.log('[ByteCave] Got', directory.peers.length, 'peers from relay directory');
247
+ gotPeersFromDirectory = true;
228
248
 
229
249
  // Dial each peer and fetch health data
230
250
  for (const peer of directory.peers) {
@@ -275,6 +295,25 @@ export class ByteCaveClient {
275
295
  }
276
296
  }
277
297
 
298
+ // Final fallback: If no peers from relay (HTTP or P2P), try direct addresses
299
+ if (!gotPeersFromDirectory && this.knownPeers.size === 0) {
300
+ if (this.config.directNodeAddrs && this.config.directNodeAddrs.length > 0) {
301
+ console.log('[ByteCave] No peers from relay, attempting direct connections to', this.config.directNodeAddrs.length, 'cached peers...');
302
+ for (const addr of this.config.directNodeAddrs) {
303
+ try {
304
+ console.log('[ByteCave] Dialing direct address:', addr.slice(0, 60) + '...');
305
+ const ma = multiaddr(addr);
306
+ await this.node!.dial(ma as any);
307
+ console.log('[ByteCave] ✓ Connected directly to peer');
308
+ } catch (dialErr: any) {
309
+ console.warn('[ByteCave] Direct dial failed:', dialErr.message);
310
+ }
311
+ }
312
+ } else {
313
+ console.log('[ByteCave] No direct addresses in localStorage and no relay available');
314
+ }
315
+ }
316
+
278
317
  this.setConnectionState('connected');
279
318
  console.log('[ByteCave] Client started', {
280
319
  peerId: this.node.peerId.toString(),
@@ -842,7 +881,10 @@ Nonce: ${nonce}`;
842
881
  blobCount: announcement.blobCount,
843
882
  timestamp: announcement.timestamp,
844
883
  multiaddrs: announcement.multiaddrs,
845
- relayAddrs: announcement.relayAddrs || (existing as any)?.relayAddrs
884
+ relayAddrs: announcement.relayAddrs || (existing as any)?.relayAddrs,
885
+ // Store on-chain registration status
886
+ registeredOnChain: announcement.registeredOnChain || false,
887
+ onChainNodeId: announcement.onChainNodeId || (existing as any)?.onChainNodeId
846
888
  };
847
889
 
848
890
  this.knownPeers.set(announcement.peerId, peerInfo);