@gethashd/bytecave-browser 1.0.12 → 1.0.15
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-XC5Z2TQH.js → chunk-ZFKOXO6W.js} +50 -1
- package/dist/index.cjs +50 -1
- package/dist/index.js +1 -1
- package/dist/react/index.js +1 -1
- package/package.json +1 -1
- package/src/client.ts +55 -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,12 +6120,43 @@ 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
|
-
console.warn("[ByteCave] HTTP relay discovery failed
|
|
6142
|
+
console.warn("[ByteCave] HTTP relay discovery failed:", err.message);
|
|
6143
|
+
if (this.config.directNodeAddrs && this.config.directNodeAddrs.length > 0) {
|
|
6144
|
+
console.log("[ByteCave] Attempting direct connections to cached peers...");
|
|
6145
|
+
for (const addr of this.config.directNodeAddrs) {
|
|
6146
|
+
try {
|
|
6147
|
+
console.log("[ByteCave] Dialing direct address:", addr.slice(0, 60) + "...");
|
|
6148
|
+
const ma = multiaddr(addr);
|
|
6149
|
+
await this.node.dial(ma);
|
|
6150
|
+
console.log("[ByteCave] \u2713 Connected directly to peer");
|
|
6151
|
+
} catch (dialErr) {
|
|
6152
|
+
console.warn("[ByteCave] Direct dial failed:", dialErr.message);
|
|
6153
|
+
}
|
|
6154
|
+
}
|
|
6155
|
+
}
|
|
6126
6156
|
}
|
|
6127
6157
|
}
|
|
6128
6158
|
console.log("[ByteCave] Querying relay for peer directory via P2P...");
|
|
6159
|
+
let gotPeersFromDirectory = false;
|
|
6129
6160
|
for (const relayAddr of bootstrapPeers) {
|
|
6130
6161
|
try {
|
|
6131
6162
|
const parts = relayAddr.split("/p2p/");
|
|
@@ -6134,6 +6165,7 @@ var ByteCaveClient = class {
|
|
|
6134
6165
|
const directory = await p2pProtocolClient.getPeerDirectoryFromRelay(relayPeerId);
|
|
6135
6166
|
if (directory && directory.peers.length > 0) {
|
|
6136
6167
|
console.log("[ByteCave] Got", directory.peers.length, "peers from relay directory");
|
|
6168
|
+
gotPeersFromDirectory = true;
|
|
6137
6169
|
for (const peer of directory.peers) {
|
|
6138
6170
|
try {
|
|
6139
6171
|
console.log("[ByteCave] Dialing peer from directory:", peer.peerId.slice(0, 12) + "...");
|
|
@@ -6175,6 +6207,23 @@ var ByteCaveClient = class {
|
|
|
6175
6207
|
console.warn("[ByteCave] Failed to get directory from relay:", err.message);
|
|
6176
6208
|
}
|
|
6177
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
|
+
}
|
|
6178
6227
|
this.setConnectionState("connected");
|
|
6179
6228
|
console.log("[ByteCave] Client started", {
|
|
6180
6229
|
peerId: this.node.peerId.toString(),
|
package/dist/index.cjs
CHANGED
|
@@ -6173,12 +6173,43 @@ 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
|
-
console.warn("[ByteCave] HTTP relay discovery failed
|
|
6195
|
+
console.warn("[ByteCave] HTTP relay discovery failed:", err.message);
|
|
6196
|
+
if (this.config.directNodeAddrs && this.config.directNodeAddrs.length > 0) {
|
|
6197
|
+
console.log("[ByteCave] Attempting direct connections to cached peers...");
|
|
6198
|
+
for (const addr of this.config.directNodeAddrs) {
|
|
6199
|
+
try {
|
|
6200
|
+
console.log("[ByteCave] Dialing direct address:", addr.slice(0, 60) + "...");
|
|
6201
|
+
const ma = (0, import_multiaddr.multiaddr)(addr);
|
|
6202
|
+
await this.node.dial(ma);
|
|
6203
|
+
console.log("[ByteCave] \u2713 Connected directly to peer");
|
|
6204
|
+
} catch (dialErr) {
|
|
6205
|
+
console.warn("[ByteCave] Direct dial failed:", dialErr.message);
|
|
6206
|
+
}
|
|
6207
|
+
}
|
|
6208
|
+
}
|
|
6179
6209
|
}
|
|
6180
6210
|
}
|
|
6181
6211
|
console.log("[ByteCave] Querying relay for peer directory via P2P...");
|
|
6212
|
+
let gotPeersFromDirectory = false;
|
|
6182
6213
|
for (const relayAddr of bootstrapPeers) {
|
|
6183
6214
|
try {
|
|
6184
6215
|
const parts = relayAddr.split("/p2p/");
|
|
@@ -6187,6 +6218,7 @@ var ByteCaveClient = class {
|
|
|
6187
6218
|
const directory = await p2pProtocolClient.getPeerDirectoryFromRelay(relayPeerId);
|
|
6188
6219
|
if (directory && directory.peers.length > 0) {
|
|
6189
6220
|
console.log("[ByteCave] Got", directory.peers.length, "peers from relay directory");
|
|
6221
|
+
gotPeersFromDirectory = true;
|
|
6190
6222
|
for (const peer of directory.peers) {
|
|
6191
6223
|
try {
|
|
6192
6224
|
console.log("[ByteCave] Dialing peer from directory:", peer.peerId.slice(0, 12) + "...");
|
|
@@ -6228,6 +6260,23 @@ var ByteCaveClient = class {
|
|
|
6228
6260
|
console.warn("[ByteCave] Failed to get directory from relay:", err.message);
|
|
6229
6261
|
}
|
|
6230
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
|
+
}
|
|
6231
6280
|
this.setConnectionState("connected");
|
|
6232
6281
|
console.log("[ByteCave] Client started", {
|
|
6233
6282
|
peerId: this.node.peerId.toString(),
|
package/dist/index.js
CHANGED
package/dist/react/index.js
CHANGED
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -192,14 +192,48 @@ 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
|
-
console.warn('[ByteCave] HTTP relay discovery failed
|
|
215
|
+
console.warn('[ByteCave] HTTP relay discovery failed:', err.message);
|
|
216
|
+
|
|
217
|
+
// Fallback: Try direct node addresses from localStorage
|
|
218
|
+
if (this.config.directNodeAddrs && this.config.directNodeAddrs.length > 0) {
|
|
219
|
+
console.log('[ByteCave] Attempting direct connections to cached peers...');
|
|
220
|
+
for (const addr of this.config.directNodeAddrs) {
|
|
221
|
+
try {
|
|
222
|
+
console.log('[ByteCave] Dialing direct address:', addr.slice(0, 60) + '...');
|
|
223
|
+
const ma = multiaddr(addr);
|
|
224
|
+
await this.node!.dial(ma as any);
|
|
225
|
+
console.log('[ByteCave] ✓ Connected directly to peer');
|
|
226
|
+
} catch (dialErr: any) {
|
|
227
|
+
console.warn('[ByteCave] Direct dial failed:', dialErr.message);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
198
231
|
}
|
|
199
232
|
}
|
|
200
233
|
|
|
201
234
|
// Fallback: Query relay for peer directory via P2P protocol
|
|
202
235
|
console.log('[ByteCave] Querying relay for peer directory via P2P...');
|
|
236
|
+
let gotPeersFromDirectory = false;
|
|
203
237
|
for (const relayAddr of bootstrapPeers) {
|
|
204
238
|
try {
|
|
205
239
|
// Extract relay peer ID from multiaddr
|
|
@@ -210,6 +244,7 @@ export class ByteCaveClient {
|
|
|
210
244
|
const directory = await p2pProtocolClient.getPeerDirectoryFromRelay(relayPeerId);
|
|
211
245
|
if (directory && directory.peers.length > 0) {
|
|
212
246
|
console.log('[ByteCave] Got', directory.peers.length, 'peers from relay directory');
|
|
247
|
+
gotPeersFromDirectory = true;
|
|
213
248
|
|
|
214
249
|
// Dial each peer and fetch health data
|
|
215
250
|
for (const peer of directory.peers) {
|
|
@@ -260,6 +295,25 @@ export class ByteCaveClient {
|
|
|
260
295
|
}
|
|
261
296
|
}
|
|
262
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
|
+
|
|
263
317
|
this.setConnectionState('connected');
|
|
264
318
|
console.log('[ByteCave] Client started', {
|
|
265
319
|
peerId: this.node.peerId.toString(),
|