@peerbit/shared-log 13.0.5-5d63b4f → 13.0.5
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/src/index.d.ts +0 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +91 -79
- package/dist/src/index.js.map +1 -1
- package/package.json +20 -20
- package/src/index.ts +92 -87
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peerbit/shared-log",
|
|
3
|
-
"version": "13.0.5
|
|
3
|
+
"version": "13.0.5",
|
|
4
4
|
"description": "Shared log",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
@@ -54,35 +54,35 @@
|
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@dao-xyz/borsh": "^6.0.0",
|
|
56
56
|
"@libp2p/crypto": "^5.1.10",
|
|
57
|
-
"@peerbit/log": "6.0.4-5d63b4f",
|
|
58
|
-
"@peerbit/logger": "2.0.0-5d63b4f",
|
|
59
|
-
"@peerbit/program": "6.0.2-5d63b4f",
|
|
60
|
-
"@peerbit/riblt": "1.2.0-5d63b4f",
|
|
61
|
-
"@peerbit/rpc": "6.0.4-5d63b4f",
|
|
62
|
-
"@peerbit/any-store": "2.2.5-5d63b4f",
|
|
63
|
-
"@peerbit/blocks": "4.0.1-5d63b4f",
|
|
64
|
-
"@peerbit/blocks-interface": "2.0.1-5d63b4f",
|
|
65
|
-
"@peerbit/cache": "3.0.0-5d63b4f",
|
|
66
|
-
"@peerbit/crypto": "3.0.0-5d63b4f",
|
|
67
|
-
"@peerbit/indexer-interface": "3.0.0-5d63b4f",
|
|
68
|
-
"@peerbit/indexer-sqlite3": "3.0.0-5d63b4f",
|
|
69
|
-
"@peerbit/pubsub": "5.0.2-5d63b4f",
|
|
70
|
-
"@peerbit/pubsub-interface": "5.0.1-5d63b4f",
|
|
71
|
-
"@peerbit/stream-interface": "6.0.1-5d63b4f",
|
|
72
|
-
"@peerbit/time": "3.0.0-5d63b4f",
|
|
73
57
|
"json-stringify-deterministic": "^1.0.7",
|
|
74
58
|
"p-each-series": "^3.0.0",
|
|
75
59
|
"p-defer": "^4.0.0",
|
|
76
60
|
"p-queue": "^8.0.1",
|
|
77
61
|
"pidusage": "^4.0.1",
|
|
78
62
|
"pino": "^9.4.0",
|
|
79
|
-
"uint8arrays": "^5.1.0"
|
|
63
|
+
"uint8arrays": "^5.1.0",
|
|
64
|
+
"@peerbit/log": "6.0.4",
|
|
65
|
+
"@peerbit/logger": "2.0.0",
|
|
66
|
+
"@peerbit/program": "6.0.2",
|
|
67
|
+
"@peerbit/riblt": "1.2.0",
|
|
68
|
+
"@peerbit/rpc": "6.0.4",
|
|
69
|
+
"@peerbit/any-store": "2.2.5",
|
|
70
|
+
"@peerbit/blocks": "4.0.1",
|
|
71
|
+
"@peerbit/blocks-interface": "2.0.1",
|
|
72
|
+
"@peerbit/cache": "3.0.0",
|
|
73
|
+
"@peerbit/crypto": "3.0.0",
|
|
74
|
+
"@peerbit/indexer-interface": "3.0.0",
|
|
75
|
+
"@peerbit/indexer-sqlite3": "3.0.0",
|
|
76
|
+
"@peerbit/pubsub": "5.0.2",
|
|
77
|
+
"@peerbit/pubsub-interface": "5.0.1",
|
|
78
|
+
"@peerbit/stream-interface": "6.0.1",
|
|
79
|
+
"@peerbit/time": "3.0.0"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
|
-
"@peerbit/test-utils": "3.0.4-5d63b4f",
|
|
83
82
|
"@types/libsodium-wrappers": "^0.7.14",
|
|
84
83
|
"@types/pidusage": "^2.0.5",
|
|
85
|
-
"uuid": "^10.0.0"
|
|
84
|
+
"uuid": "^10.0.0",
|
|
85
|
+
"@peerbit/test-utils": "3.0.4"
|
|
86
86
|
},
|
|
87
87
|
"scripts": {
|
|
88
88
|
"clean": "aegir clean",
|
package/src/index.ts
CHANGED
|
@@ -2887,14 +2887,17 @@ export class SharedLog<
|
|
|
2887
2887
|
// ignore discovery failures
|
|
2888
2888
|
}
|
|
2889
2889
|
|
|
2890
|
-
// 2)
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2890
|
+
// 2) fallback to currently connected RPC peers
|
|
2891
|
+
const self = this.node.identity.publicKey.hashcode();
|
|
2892
|
+
const out: string[] = [];
|
|
2893
|
+
const peers = (this.rpc as any)?.peers;
|
|
2894
|
+
for (const h of peers?.keys?.() ?? []) {
|
|
2895
|
+
if (h === self) continue;
|
|
2896
|
+
if (out.includes(h)) continue;
|
|
2897
|
+
out.push(h);
|
|
2898
|
+
if (out.length >= 32) break;
|
|
2899
|
+
}
|
|
2900
|
+
return out;
|
|
2898
2901
|
},
|
|
2899
2902
|
onPut: async (cid) => {
|
|
2900
2903
|
// Best-effort directory announce for "get without remote.from" workflows.
|
|
@@ -3021,11 +3024,87 @@ export class SharedLog<
|
|
|
3021
3024
|
|
|
3022
3025
|
await this.log.open(this.remoteBlocks, this.node.identity, {
|
|
3023
3026
|
keychain: this.node.services.keychain,
|
|
3024
|
-
resolveRemotePeers: (hash, options) =>
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3027
|
+
resolveRemotePeers: async (hash, options) => {
|
|
3028
|
+
if (options?.signal?.aborted) return undefined;
|
|
3029
|
+
|
|
3030
|
+
const maxPeers = 8;
|
|
3031
|
+
const self = this.node.identity.publicKey.hashcode();
|
|
3032
|
+
const seed = hashToSeed32(hash);
|
|
3033
|
+
|
|
3034
|
+
// Best hint: peers that have recently confirmed having this entry hash.
|
|
3035
|
+
const hinted = this._requestIPruneResponseReplicatorSet.get(hash);
|
|
3036
|
+
if (hinted && hinted.size > 0) {
|
|
3037
|
+
const peers = [...hinted].filter((p) => p !== self);
|
|
3038
|
+
return peers.length > 0
|
|
3039
|
+
? pickDeterministicSubset(peers, seed, maxPeers)
|
|
3040
|
+
: undefined;
|
|
3041
|
+
}
|
|
3042
|
+
|
|
3043
|
+
// Next: peers we already contacted about this hash (may still have it).
|
|
3044
|
+
const contacted = this._requestIPruneSent.get(hash);
|
|
3045
|
+
if (contacted && contacted.size > 0) {
|
|
3046
|
+
const peers = [...contacted].filter((p) => p !== self);
|
|
3047
|
+
return peers.length > 0
|
|
3048
|
+
? pickDeterministicSubset(peers, seed, maxPeers)
|
|
3049
|
+
: undefined;
|
|
3050
|
+
}
|
|
3051
|
+
|
|
3052
|
+
let candidates: string[] | undefined;
|
|
3053
|
+
|
|
3054
|
+
// Prefer the replicator cache; fall back to subscribers if we have no other signal.
|
|
3055
|
+
const replicatorCandidates = [...this.uniqueReplicators].filter(
|
|
3056
|
+
(p) => p !== self,
|
|
3057
|
+
);
|
|
3058
|
+
if (replicatorCandidates.length > 0) {
|
|
3059
|
+
candidates = replicatorCandidates;
|
|
3060
|
+
} else {
|
|
3061
|
+
try {
|
|
3062
|
+
const subscribers = await this._getTopicSubscribers(this.topic);
|
|
3063
|
+
const subscriberCandidates =
|
|
3064
|
+
subscribers?.map((k) => k.hashcode()).filter((p) => p !== self) ??
|
|
3065
|
+
[];
|
|
3066
|
+
candidates =
|
|
3067
|
+
subscriberCandidates.length > 0 ? subscriberCandidates : undefined;
|
|
3068
|
+
} catch {
|
|
3069
|
+
// Best-effort only.
|
|
3070
|
+
}
|
|
3071
|
+
|
|
3072
|
+
if (!candidates || candidates.length === 0) {
|
|
3073
|
+
// Last resort: peers we are already directly connected to. This avoids
|
|
3074
|
+
// depending on global membership knowledge in early-join scenarios.
|
|
3075
|
+
const peerMap = (this.node.services.pubsub as any)?.peers;
|
|
3076
|
+
if (peerMap?.keys) {
|
|
3077
|
+
candidates = [...peerMap.keys()];
|
|
3078
|
+
}
|
|
3079
|
+
}
|
|
3080
|
+
|
|
3081
|
+
if (!candidates || candidates.length === 0) {
|
|
3082
|
+
// Even if the pubsub stream has no established peer streams yet, we may
|
|
3083
|
+
// still have a libp2p connection to one or more peers (e.g. bootstrap).
|
|
3084
|
+
const connectionManager = (this.node.services.pubsub as any)?.components
|
|
3085
|
+
?.connectionManager;
|
|
3086
|
+
const connections = connectionManager?.getConnections?.() ?? [];
|
|
3087
|
+
const connectionHashes: string[] = [];
|
|
3088
|
+
for (const conn of connections) {
|
|
3089
|
+
const peerId = conn?.remotePeer;
|
|
3090
|
+
if (!peerId) continue;
|
|
3091
|
+
try {
|
|
3092
|
+
connectionHashes.push(getPublicKeyFromPeerId(peerId).hashcode());
|
|
3093
|
+
} catch {
|
|
3094
|
+
// Best-effort only.
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
3097
|
+
if (connectionHashes.length > 0) {
|
|
3098
|
+
candidates = connectionHashes;
|
|
3099
|
+
}
|
|
3100
|
+
}
|
|
3101
|
+
}
|
|
3102
|
+
|
|
3103
|
+
if (!candidates || candidates.length === 0) return undefined;
|
|
3104
|
+
const peers = candidates.filter((p) => p !== self);
|
|
3105
|
+
if (peers.length === 0) return undefined;
|
|
3106
|
+
return pickDeterministicSubset(peers, seed, maxPeers);
|
|
3107
|
+
},
|
|
3029
3108
|
...this._logProperties,
|
|
3030
3109
|
onChange: async (change) => {
|
|
3031
3110
|
await this.onChange(change);
|
|
@@ -3413,80 +3492,6 @@ export class SharedLog<
|
|
|
3413
3492
|
this._replicatorLivenessTargetsSize = -1;
|
|
3414
3493
|
}
|
|
3415
3494
|
|
|
3416
|
-
private async resolveCandidatePeersForHash(
|
|
3417
|
-
hash: string,
|
|
3418
|
-
options?: { signal?: AbortSignal; maxPeers?: number },
|
|
3419
|
-
): Promise<string[] | undefined> {
|
|
3420
|
-
if (options?.signal?.aborted) return undefined;
|
|
3421
|
-
|
|
3422
|
-
const maxPeers = options?.maxPeers ?? 8;
|
|
3423
|
-
const self = this.node.identity.publicKey.hashcode();
|
|
3424
|
-
const seed = hashToSeed32(hash);
|
|
3425
|
-
|
|
3426
|
-
const hinted = this._requestIPruneResponseReplicatorSet.get(hash);
|
|
3427
|
-
if (hinted && hinted.size > 0) {
|
|
3428
|
-
const peers = [...hinted].filter((p) => p !== self);
|
|
3429
|
-
return peers.length > 0
|
|
3430
|
-
? pickDeterministicSubset(peers, seed, maxPeers)
|
|
3431
|
-
: undefined;
|
|
3432
|
-
}
|
|
3433
|
-
|
|
3434
|
-
const contacted = this._requestIPruneSent.get(hash);
|
|
3435
|
-
if (contacted && contacted.size > 0) {
|
|
3436
|
-
const peers = [...contacted].filter((p) => p !== self);
|
|
3437
|
-
return peers.length > 0
|
|
3438
|
-
? pickDeterministicSubset(peers, seed, maxPeers)
|
|
3439
|
-
: undefined;
|
|
3440
|
-
}
|
|
3441
|
-
|
|
3442
|
-
let candidates: string[] | undefined;
|
|
3443
|
-
const replicatorCandidates = [...this.uniqueReplicators].filter((p) => p !== self);
|
|
3444
|
-
if (replicatorCandidates.length > 0) {
|
|
3445
|
-
candidates = replicatorCandidates;
|
|
3446
|
-
} else {
|
|
3447
|
-
try {
|
|
3448
|
-
const subscribers = await this._getTopicSubscribers(this.topic);
|
|
3449
|
-
const subscriberCandidates =
|
|
3450
|
-
subscribers?.map((k) => k.hashcode()).filter((p) => p !== self) ?? [];
|
|
3451
|
-
candidates =
|
|
3452
|
-
subscriberCandidates.length > 0 ? subscriberCandidates : undefined;
|
|
3453
|
-
} catch {
|
|
3454
|
-
// Best-effort only.
|
|
3455
|
-
}
|
|
3456
|
-
|
|
3457
|
-
if (!candidates || candidates.length === 0) {
|
|
3458
|
-
const peerMap = (this.node.services.pubsub as any)?.peers;
|
|
3459
|
-
if (peerMap?.keys) {
|
|
3460
|
-
candidates = [...peerMap.keys()];
|
|
3461
|
-
}
|
|
3462
|
-
}
|
|
3463
|
-
|
|
3464
|
-
if (!candidates || candidates.length === 0) {
|
|
3465
|
-
const connectionManager = (this.node.services.pubsub as any)?.components
|
|
3466
|
-
?.connectionManager;
|
|
3467
|
-
const connections = connectionManager?.getConnections?.() ?? [];
|
|
3468
|
-
const connectionHashes: string[] = [];
|
|
3469
|
-
for (const conn of connections) {
|
|
3470
|
-
const peerId = conn?.remotePeer;
|
|
3471
|
-
if (!peerId) continue;
|
|
3472
|
-
try {
|
|
3473
|
-
connectionHashes.push(getPublicKeyFromPeerId(peerId).hashcode());
|
|
3474
|
-
} catch {
|
|
3475
|
-
// Best-effort only.
|
|
3476
|
-
}
|
|
3477
|
-
}
|
|
3478
|
-
if (connectionHashes.length > 0) {
|
|
3479
|
-
candidates = connectionHashes;
|
|
3480
|
-
}
|
|
3481
|
-
}
|
|
3482
|
-
}
|
|
3483
|
-
|
|
3484
|
-
if (!candidates || candidates.length === 0) return undefined;
|
|
3485
|
-
const peers = candidates.filter((p) => p !== self);
|
|
3486
|
-
if (peers.length === 0) return undefined;
|
|
3487
|
-
return pickDeterministicSubset(peers, seed, maxPeers);
|
|
3488
|
-
}
|
|
3489
|
-
|
|
3490
3495
|
private async runReplicatorLivenessSweep() {
|
|
3491
3496
|
if (this.closed || this._closeController.signal.aborted) {
|
|
3492
3497
|
return;
|