@highway1/cli 0.1.42 → 0.1.44
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/dist/index.js +32 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/commands/join.ts +43 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@highway1/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.44",
|
|
4
4
|
"description": "CLI tool for Clawiverse network",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"clean": "rm -rf dist"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@highway1/core": "^0.1.
|
|
16
|
+
"@highway1/core": "^0.1.44",
|
|
17
17
|
"chalk": "^5.3.0",
|
|
18
18
|
"cli-table3": "^0.6.5",
|
|
19
19
|
"commander": "^12.1.0",
|
package/src/commands/join.ts
CHANGED
|
@@ -39,6 +39,9 @@ export function registerJoinCommand(program: Command): void {
|
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
const bootstrapPeers = options.bootstrap || getBootstrapPeers();
|
|
42
|
+
const bootstrapPeerIds = bootstrapPeers
|
|
43
|
+
.map((addr: string) => addr.split('/p2p/')[1])
|
|
44
|
+
.filter((peerId: string | undefined): peerId is string => Boolean(peerId));
|
|
42
45
|
|
|
43
46
|
const node = await createNode({
|
|
44
47
|
keyPair,
|
|
@@ -195,7 +198,25 @@ export function registerJoinCommand(program: Command): void {
|
|
|
195
198
|
|
|
196
199
|
cardSpin.succeed('Agent Card published!');
|
|
197
200
|
|
|
198
|
-
// Keep
|
|
201
|
+
// Keep bootstrap connectivity stable: proactively re-dial missing bootstrap peers.
|
|
202
|
+
const ensureBootstrapConnections = async () => {
|
|
203
|
+
const connections = node.libp2p.getConnections();
|
|
204
|
+
const connectedPeerIds = new Set(connections.map((conn) => conn.remotePeer.toString()));
|
|
205
|
+
|
|
206
|
+
for (const bootstrapAddr of bootstrapPeers) {
|
|
207
|
+
const targetPeerId = bootstrapAddr.split('/p2p/')[1];
|
|
208
|
+
if (!targetPeerId || connectedPeerIds.has(targetPeerId)) continue;
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
await node.libp2p.dial(bootstrapAddr);
|
|
212
|
+
info(`Reconnected bootstrap peer: ${targetPeerId}`);
|
|
213
|
+
} catch {
|
|
214
|
+
// best effort; keep trying on next tick
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
// Keep connection alive by pinging peers periodically
|
|
199
220
|
const pingInterval = setInterval(async () => {
|
|
200
221
|
const peers = node.libp2p.getPeers();
|
|
201
222
|
if (peers.length === 0) {
|
|
@@ -210,6 +231,7 @@ export function registerJoinCommand(program: Command): void {
|
|
|
210
231
|
}
|
|
211
232
|
}
|
|
212
233
|
} else {
|
|
234
|
+
await ensureBootstrapConnections();
|
|
213
235
|
// Ping existing peers to keep connection alive
|
|
214
236
|
for (const peer of peers) {
|
|
215
237
|
try {
|
|
@@ -221,6 +243,25 @@ export function registerJoinCommand(program: Command): void {
|
|
|
221
243
|
}
|
|
222
244
|
}, 15000); // ping every 15s (reduced from 30s for better stability)
|
|
223
245
|
|
|
246
|
+
// If a bootstrap peer disconnects, attempt immediate recovery.
|
|
247
|
+
const onPeerDisconnect = async (evt: any) => {
|
|
248
|
+
const disconnectedPeerId = evt?.detail?.toString?.() ?? '';
|
|
249
|
+
if (!bootstrapPeerIds.includes(disconnectedPeerId)) return;
|
|
250
|
+
|
|
251
|
+
info(`Bootstrap peer disconnected: ${disconnectedPeerId}, attempting reconnect...`);
|
|
252
|
+
for (const bootstrapAddr of bootstrapPeers) {
|
|
253
|
+
if (!bootstrapAddr.endsWith(`/p2p/${disconnectedPeerId}`)) continue;
|
|
254
|
+
try {
|
|
255
|
+
await node.libp2p.dial(bootstrapAddr);
|
|
256
|
+
info(`Recovered bootstrap connection: ${disconnectedPeerId}`);
|
|
257
|
+
return;
|
|
258
|
+
} catch {
|
|
259
|
+
// Continue trying other bootstrap peers if available
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
node.libp2p.addEventListener('peer:disconnect', onPeerDisconnect);
|
|
264
|
+
|
|
224
265
|
const verifyFn = async (signature: Uint8Array, data: Uint8Array): Promise<boolean> => {
|
|
225
266
|
try {
|
|
226
267
|
const decoded = JSON.parse(new TextDecoder().decode(data)) as { from?: string };
|
|
@@ -303,6 +344,7 @@ export function registerJoinCommand(program: Command): void {
|
|
|
303
344
|
console.log();
|
|
304
345
|
const stopSpin = spinner('Stopping node...');
|
|
305
346
|
clearInterval(pingInterval);
|
|
347
|
+
node.libp2p.removeEventListener('peer:disconnect', onPeerDisconnect);
|
|
306
348
|
await router.stop();
|
|
307
349
|
await node.stop();
|
|
308
350
|
stopSpin.succeed('Node stopped');
|