@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 +32 -30
- package/dist/{chunk-W2MGINUZ.js → chunk-OS5QOU7R.js} +40 -1
- package/dist/index.cjs +40 -1
- package/dist/index.js +1 -1
- package/dist/react/index.js +1 -1
- package/package.json +1 -1
- package/src/client.ts +43 -1
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:
|
|
34
|
+
## **CRITICAL: npm Publishing Workflow**
|
|
35
35
|
|
|
36
36
|
### After Making Changes
|
|
37
37
|
**YOU MUST FOLLOW THIS WORKFLOW:**
|
|
38
38
|
|
|
39
|
-
1. **Build
|
|
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. **
|
|
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 @
|
|
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 **
|
|
63
|
-
- If you don't
|
|
64
|
-
- Even after rebuilding, changes won't appear until
|
|
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
|
|
63
|
+
- This will use OLD code because web/dashboard pull from npm
|
|
69
64
|
|
|
70
|
-
✅ **CORRECT**: Build
|
|
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
|
|
102
|
-
- After bytecave-browser changes: `yarn upgrade @
|
|
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
|
|
107
|
-
- After bytecave-browser changes: `yarn upgrade @
|
|
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.
|
|
113
|
-
2.
|
|
114
|
-
3. In web/dashboard: `yarn upgrade @
|
|
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
|
|
125
|
-
2. Run `yarn upgrade @
|
|
126
|
-
3. Check `node_modules/@
|
|
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
package/dist/react/index.js
CHANGED
package/package.json
CHANGED
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);
|