@hashtree/nostr 0.1.10 → 0.1.11
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/webrtc/peerSelector.d.ts +1 -31
- package/dist/webrtc/peerSelector.d.ts.map +1 -1
- package/dist/webrtc/peerSelector.js +1 -341
- package/dist/webrtc/peerSelector.js.map +1 -1
- package/dist/webrtc/protocol.d.ts +2 -86
- package/dist/webrtc/protocol.d.ts.map +1 -1
- package/dist/webrtc/protocol.js +1 -180
- package/dist/webrtc/protocol.js.map +1 -1
- package/dist/webrtc/types.d.ts +18 -178
- package/dist/webrtc/types.d.ts.map +1 -1
- package/dist/webrtc/types.js +2 -105
- package/dist/webrtc/types.js.map +1 -1
- package/package.json +4 -3
|
@@ -1,32 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export declare function peerPrincipal(peerId: string): string;
|
|
3
|
-
export declare class PeerSelector {
|
|
4
|
-
private stats;
|
|
5
|
-
private persistedMetadata;
|
|
6
|
-
private strategy;
|
|
7
|
-
private fairnessEnabled;
|
|
8
|
-
private roundRobinIdx;
|
|
9
|
-
constructor(strategy?: SelectionStrategy);
|
|
10
|
-
static withStrategy(strategy: SelectionStrategy): PeerSelector;
|
|
11
|
-
setFairness(enabled: boolean): void;
|
|
12
|
-
setStrategy(strategy: SelectionStrategy): void;
|
|
13
|
-
getPeerIds(): string[];
|
|
14
|
-
addPeer(peerId: string): void;
|
|
15
|
-
removePeer(peerId: string): void;
|
|
16
|
-
isPeerBackedOff(peerId: string): boolean;
|
|
17
|
-
recordRequest(peerId: string, bytes: number): void;
|
|
18
|
-
recordSuccess(peerId: string, rttMs: number, bytes: number): void;
|
|
19
|
-
recordTimeout(peerId: string): void;
|
|
20
|
-
recordFailure(peerId: string): void;
|
|
21
|
-
selectPeers(): string[];
|
|
22
|
-
exportPeerMetadataSnapshot(): PeerMetadataSnapshot;
|
|
23
|
-
importPeerMetadataSnapshot(snapshot: PeerMetadataSnapshot): void;
|
|
24
|
-
private order;
|
|
25
|
-
private scoreFor;
|
|
26
|
-
private applyFairness;
|
|
27
|
-
}
|
|
28
|
-
export declare function normalizeDispatchConfig(dispatch: RequestDispatchConfig, availablePeers: number): RequestDispatchConfig;
|
|
29
|
-
export declare function buildHedgedWavePlan(peerCount: number, dispatch: RequestDispatchConfig): number[];
|
|
30
|
-
export declare function syncSelectorPeers(selector: PeerSelector, currentPeerIds: string[]): void;
|
|
31
|
-
export declare function blendWeightedScore(baseScore: number, boostWeight: number, boostValue: number): number;
|
|
1
|
+
export { PeerSelector, peerPrincipal, normalizeDispatchConfig, buildHedgedWavePlan, syncSelectorPeers, blendWeightedScore, } from '@hashtree/mesh';
|
|
32
2
|
//# sourceMappingURL=peerSelector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"peerSelector.d.ts","sourceRoot":"","sources":["../../src/webrtc/peerSelector.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"peerSelector.d.ts","sourceRoot":"","sources":["../../src/webrtc/peerSelector.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC"}
|
|
@@ -1,342 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
const FAIRNESS_SELECTION_SHARE_WARNING = 0.30;
|
|
3
|
-
const FAIRNESS_MIN_PEERS = 5;
|
|
4
|
-
const INITIAL_BACKOFF_MS = 1000;
|
|
5
|
-
const BACKOFF_MULTIPLIER = 2;
|
|
6
|
-
const MAX_BACKOFF_MS = 480_000;
|
|
7
|
-
const MIN_RTO_MS = 50;
|
|
8
|
-
const MAX_RTO_MS = 60_000;
|
|
9
|
-
const INITIAL_RTO_MS = 1000;
|
|
10
|
-
function clamp01(n) {
|
|
11
|
-
return Math.max(0, Math.min(1, n));
|
|
12
|
-
}
|
|
13
|
-
function clampRtoMs(rtoMs) {
|
|
14
|
-
if (!Number.isFinite(rtoMs) || rtoMs <= 0)
|
|
15
|
-
return INITIAL_RTO_MS;
|
|
16
|
-
return Math.max(MIN_RTO_MS, Math.min(MAX_RTO_MS, Math.floor(rtoMs)));
|
|
17
|
-
}
|
|
18
|
-
function sanitizeLatency(value) {
|
|
19
|
-
if (!Number.isFinite(value) || value < 0)
|
|
20
|
-
return 0;
|
|
21
|
-
return value;
|
|
22
|
-
}
|
|
23
|
-
function defaultStats(peerId) {
|
|
24
|
-
return {
|
|
25
|
-
peerId,
|
|
26
|
-
connectedAtMs: Date.now(),
|
|
27
|
-
requestsSent: 0,
|
|
28
|
-
successes: 0,
|
|
29
|
-
timeouts: 0,
|
|
30
|
-
failures: 0,
|
|
31
|
-
srttMs: 0,
|
|
32
|
-
rttvarMs: 0,
|
|
33
|
-
rtoMs: INITIAL_RTO_MS,
|
|
34
|
-
consecutiveRtoBackoffs: 0,
|
|
35
|
-
backoffLevel: 0,
|
|
36
|
-
bytesReceived: 0,
|
|
37
|
-
bytesSent: 0,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
function successRate(stats) {
|
|
41
|
-
if (stats.requestsSent === 0)
|
|
42
|
-
return 0.5;
|
|
43
|
-
return stats.successes / stats.requestsSent;
|
|
44
|
-
}
|
|
45
|
-
function isBackedOff(stats) {
|
|
46
|
-
return Boolean(stats.backedOffUntilMs && Date.now() < stats.backedOffUntilMs);
|
|
47
|
-
}
|
|
48
|
-
function scoreWeighted(stats) {
|
|
49
|
-
const reliability = successRate(stats);
|
|
50
|
-
const latencyScore = stats.srttMs > 0 ? Math.min(1, 500 / (stats.srttMs + 50)) : 0.5;
|
|
51
|
-
const recencyBonus = stats.lastSuccessMs && Date.now() - stats.lastSuccessMs < 60_000 ? 0.1 : 0;
|
|
52
|
-
return 0.6 * reliability + 0.3 * latencyScore + 0.1 * (1 + recencyBonus);
|
|
53
|
-
}
|
|
54
|
-
function scoreUtilityUcb(stats, totalRequests) {
|
|
55
|
-
const good = stats.successes + 1;
|
|
56
|
-
const bad = stats.failures + stats.timeouts + 1;
|
|
57
|
-
const ratio = good / bad;
|
|
58
|
-
const ratioScore = ratio / (1 + ratio);
|
|
59
|
-
const latencyScore = stats.srttMs > 0 ? Math.min(1, 300 / (stats.srttMs + 50)) : 0.5;
|
|
60
|
-
const efficiencyScore = stats.bytesSent > 0 ? Math.min(1, stats.bytesReceived / stats.bytesSent) : 0.5;
|
|
61
|
-
const exploitation = 0.55 * ratioScore + 0.25 * latencyScore + 0.2 * efficiencyScore;
|
|
62
|
-
const uncertainty = Math.sqrt(Math.log(totalRequests + 1) / (stats.requestsSent + 1));
|
|
63
|
-
return exploitation + 0.2 * uncertainty;
|
|
64
|
-
}
|
|
65
|
-
function peerMetadataFromStats(principal, stats) {
|
|
66
|
-
return {
|
|
67
|
-
principal,
|
|
68
|
-
requestsSent: stats.requestsSent,
|
|
69
|
-
successes: stats.successes,
|
|
70
|
-
timeouts: stats.timeouts,
|
|
71
|
-
failures: stats.failures,
|
|
72
|
-
srttMs: sanitizeLatency(stats.srttMs),
|
|
73
|
-
rttvarMs: sanitizeLatency(stats.rttvarMs),
|
|
74
|
-
rtoMs: clampRtoMs(stats.rtoMs),
|
|
75
|
-
bytesReceived: stats.bytesReceived,
|
|
76
|
-
bytesSent: stats.bytesSent,
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
function applyMetadata(stats, metadata) {
|
|
80
|
-
stats.requestsSent = Math.max(0, Math.floor(metadata.requestsSent));
|
|
81
|
-
stats.successes = Math.max(0, Math.floor(metadata.successes));
|
|
82
|
-
stats.timeouts = Math.max(0, Math.floor(metadata.timeouts));
|
|
83
|
-
stats.failures = Math.max(0, Math.floor(metadata.failures));
|
|
84
|
-
stats.srttMs = sanitizeLatency(metadata.srttMs);
|
|
85
|
-
stats.rttvarMs = sanitizeLatency(metadata.rttvarMs);
|
|
86
|
-
stats.rtoMs = clampRtoMs(metadata.rtoMs);
|
|
87
|
-
stats.bytesReceived = Math.max(0, Math.floor(metadata.bytesReceived));
|
|
88
|
-
stats.bytesSent = Math.max(0, Math.floor(metadata.bytesSent));
|
|
89
|
-
stats.backoffLevel = 0;
|
|
90
|
-
stats.backedOffUntilMs = undefined;
|
|
91
|
-
stats.lastSuccessMs = undefined;
|
|
92
|
-
stats.lastFailureMs = undefined;
|
|
93
|
-
stats.consecutiveRtoBackoffs = 0;
|
|
94
|
-
}
|
|
95
|
-
function totalRequests(stats) {
|
|
96
|
-
let total = 0;
|
|
97
|
-
for (const s of stats)
|
|
98
|
-
total += s.requestsSent;
|
|
99
|
-
return total;
|
|
100
|
-
}
|
|
101
|
-
export function peerPrincipal(peerId) {
|
|
102
|
-
return peerId;
|
|
103
|
-
}
|
|
104
|
-
export class PeerSelector {
|
|
105
|
-
stats = new Map();
|
|
106
|
-
persistedMetadata = new Map();
|
|
107
|
-
strategy;
|
|
108
|
-
fairnessEnabled = true;
|
|
109
|
-
roundRobinIdx = 0;
|
|
110
|
-
constructor(strategy = 'weighted') {
|
|
111
|
-
this.strategy = strategy;
|
|
112
|
-
}
|
|
113
|
-
static withStrategy(strategy) {
|
|
114
|
-
return new PeerSelector(strategy);
|
|
115
|
-
}
|
|
116
|
-
setFairness(enabled) {
|
|
117
|
-
this.fairnessEnabled = enabled;
|
|
118
|
-
}
|
|
119
|
-
setStrategy(strategy) {
|
|
120
|
-
this.strategy = strategy;
|
|
121
|
-
}
|
|
122
|
-
getPeerIds() {
|
|
123
|
-
return Array.from(this.stats.keys());
|
|
124
|
-
}
|
|
125
|
-
addPeer(peerId) {
|
|
126
|
-
if (this.stats.has(peerId))
|
|
127
|
-
return;
|
|
128
|
-
const stats = defaultStats(peerId);
|
|
129
|
-
const persisted = this.persistedMetadata.get(peerPrincipal(peerId));
|
|
130
|
-
if (persisted)
|
|
131
|
-
applyMetadata(stats, persisted);
|
|
132
|
-
this.stats.set(peerId, stats);
|
|
133
|
-
}
|
|
134
|
-
removePeer(peerId) {
|
|
135
|
-
const stats = this.stats.get(peerId);
|
|
136
|
-
if (!stats)
|
|
137
|
-
return;
|
|
138
|
-
const principal = peerPrincipal(peerId);
|
|
139
|
-
this.persistedMetadata.set(principal, peerMetadataFromStats(principal, stats));
|
|
140
|
-
this.stats.delete(peerId);
|
|
141
|
-
}
|
|
142
|
-
isPeerBackedOff(peerId) {
|
|
143
|
-
const stats = this.stats.get(peerId);
|
|
144
|
-
return stats ? isBackedOff(stats) : false;
|
|
145
|
-
}
|
|
146
|
-
recordRequest(peerId, bytes) {
|
|
147
|
-
const stats = this.stats.get(peerId);
|
|
148
|
-
if (!stats)
|
|
149
|
-
return;
|
|
150
|
-
stats.requestsSent += 1;
|
|
151
|
-
stats.bytesSent += Math.max(0, Math.floor(bytes));
|
|
152
|
-
}
|
|
153
|
-
recordSuccess(peerId, rttMs, bytes) {
|
|
154
|
-
const stats = this.stats.get(peerId);
|
|
155
|
-
if (!stats)
|
|
156
|
-
return;
|
|
157
|
-
const now = Date.now();
|
|
158
|
-
stats.successes += 1;
|
|
159
|
-
stats.bytesReceived += Math.max(0, Math.floor(bytes));
|
|
160
|
-
stats.lastSuccessMs = now;
|
|
161
|
-
stats.consecutiveRtoBackoffs = 0;
|
|
162
|
-
stats.backoffLevel = 0;
|
|
163
|
-
stats.backedOffUntilMs = undefined;
|
|
164
|
-
const rtt = Math.max(0, rttMs);
|
|
165
|
-
if (stats.srttMs === 0) {
|
|
166
|
-
stats.srttMs = rtt;
|
|
167
|
-
stats.rttvarMs = rtt / 2;
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
stats.rttvarMs = 0.75 * stats.rttvarMs + 0.25 * Math.abs(stats.srttMs - rtt);
|
|
171
|
-
stats.srttMs = 0.875 * stats.srttMs + 0.125 * rtt;
|
|
172
|
-
}
|
|
173
|
-
const rto = stats.srttMs + Math.max(20, 4 * stats.rttvarMs);
|
|
174
|
-
stats.rtoMs = clampRtoMs(rto);
|
|
175
|
-
}
|
|
176
|
-
recordTimeout(peerId) {
|
|
177
|
-
const stats = this.stats.get(peerId);
|
|
178
|
-
if (!stats)
|
|
179
|
-
return;
|
|
180
|
-
const now = Date.now();
|
|
181
|
-
stats.timeouts += 1;
|
|
182
|
-
stats.lastFailureMs = now;
|
|
183
|
-
stats.backoffLevel += 1;
|
|
184
|
-
const backoffMs = Math.min(MAX_BACKOFF_MS, INITIAL_BACKOFF_MS * BACKOFF_MULTIPLIER ** (stats.backoffLevel - 1));
|
|
185
|
-
stats.backedOffUntilMs = now + backoffMs;
|
|
186
|
-
if (stats.consecutiveRtoBackoffs < 5) {
|
|
187
|
-
stats.rtoMs = Math.min(MAX_RTO_MS, stats.rtoMs * 2);
|
|
188
|
-
stats.consecutiveRtoBackoffs += 1;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
recordFailure(peerId) {
|
|
192
|
-
const stats = this.stats.get(peerId);
|
|
193
|
-
if (!stats)
|
|
194
|
-
return;
|
|
195
|
-
const now = Date.now();
|
|
196
|
-
stats.failures += 1;
|
|
197
|
-
stats.lastFailureMs = now;
|
|
198
|
-
stats.backoffLevel += 1;
|
|
199
|
-
const backoffMs = Math.min(MAX_BACKOFF_MS, INITIAL_BACKOFF_MS * BACKOFF_MULTIPLIER ** (stats.backoffLevel - 1));
|
|
200
|
-
stats.backedOffUntilMs = now + backoffMs;
|
|
201
|
-
}
|
|
202
|
-
selectPeers() {
|
|
203
|
-
const allStats = Array.from(this.stats.values());
|
|
204
|
-
if (allStats.length === 0)
|
|
205
|
-
return [];
|
|
206
|
-
const ready = allStats.filter((s) => !isBackedOff(s));
|
|
207
|
-
const backedOff = allStats.filter((s) => isBackedOff(s));
|
|
208
|
-
const total = totalRequests(allStats);
|
|
209
|
-
let orderedReady = this.order(ready, total);
|
|
210
|
-
if (this.fairnessEnabled && orderedReady.length >= FAIRNESS_MIN_PEERS) {
|
|
211
|
-
orderedReady = this.applyFairness(orderedReady);
|
|
212
|
-
}
|
|
213
|
-
const orderedBackedOff = this.order(backedOff, total);
|
|
214
|
-
return orderedReady.concat(orderedBackedOff).map((s) => s.peerId);
|
|
215
|
-
}
|
|
216
|
-
exportPeerMetadataSnapshot() {
|
|
217
|
-
const snapshot = new Map(this.persistedMetadata);
|
|
218
|
-
for (const [peerId, stats] of this.stats.entries()) {
|
|
219
|
-
const principal = peerPrincipal(peerId);
|
|
220
|
-
snapshot.set(principal, peerMetadataFromStats(principal, stats));
|
|
221
|
-
}
|
|
222
|
-
const peers = Array.from(snapshot.values()).sort((a, b) => a.principal.localeCompare(b.principal));
|
|
223
|
-
return {
|
|
224
|
-
version: PEER_METADATA_SNAPSHOT_VERSION,
|
|
225
|
-
peers,
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
importPeerMetadataSnapshot(snapshot) {
|
|
229
|
-
if (!snapshot || snapshot.version !== PEER_METADATA_SNAPSHOT_VERSION)
|
|
230
|
-
return;
|
|
231
|
-
this.persistedMetadata.clear();
|
|
232
|
-
for (const peer of snapshot.peers ?? []) {
|
|
233
|
-
if (!peer?.principal)
|
|
234
|
-
continue;
|
|
235
|
-
this.persistedMetadata.set(peer.principal, {
|
|
236
|
-
principal: peer.principal,
|
|
237
|
-
requestsSent: Math.max(0, Math.floor(peer.requestsSent)),
|
|
238
|
-
successes: Math.max(0, Math.floor(peer.successes)),
|
|
239
|
-
timeouts: Math.max(0, Math.floor(peer.timeouts)),
|
|
240
|
-
failures: Math.max(0, Math.floor(peer.failures)),
|
|
241
|
-
srttMs: sanitizeLatency(peer.srttMs),
|
|
242
|
-
rttvarMs: sanitizeLatency(peer.rttvarMs),
|
|
243
|
-
rtoMs: clampRtoMs(peer.rtoMs),
|
|
244
|
-
bytesReceived: Math.max(0, Math.floor(peer.bytesReceived)),
|
|
245
|
-
bytesSent: Math.max(0, Math.floor(peer.bytesSent)),
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
for (const [peerId, stats] of this.stats.entries()) {
|
|
249
|
-
const persisted = this.persistedMetadata.get(peerPrincipal(peerId));
|
|
250
|
-
if (persisted)
|
|
251
|
-
applyMetadata(stats, persisted);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
order(peers, allTotalRequests) {
|
|
255
|
-
if (peers.length <= 1)
|
|
256
|
-
return peers.slice();
|
|
257
|
-
if (this.strategy === 'roundRobin') {
|
|
258
|
-
const sorted = peers.slice().sort((a, b) => a.peerId.localeCompare(b.peerId));
|
|
259
|
-
const offset = this.roundRobinIdx % sorted.length;
|
|
260
|
-
this.roundRobinIdx = (this.roundRobinIdx + 1) % sorted.length;
|
|
261
|
-
return sorted.slice(offset).concat(sorted.slice(0, offset));
|
|
262
|
-
}
|
|
263
|
-
if (this.strategy === 'random') {
|
|
264
|
-
return peers.slice().sort(() => Math.random() - 0.5);
|
|
265
|
-
}
|
|
266
|
-
return peers.slice().sort((a, b) => this.scoreFor(b, allTotalRequests) - this.scoreFor(a, allTotalRequests));
|
|
267
|
-
}
|
|
268
|
-
scoreFor(stats, allTotalRequests) {
|
|
269
|
-
switch (this.strategy) {
|
|
270
|
-
case 'lowestLatency':
|
|
271
|
-
return stats.srttMs > 0 ? -stats.srttMs : -1_000_000;
|
|
272
|
-
case 'highestSuccessRate':
|
|
273
|
-
return successRate(stats);
|
|
274
|
-
case 'utilityUcb':
|
|
275
|
-
return scoreUtilityUcb(stats, allTotalRequests);
|
|
276
|
-
case 'weighted':
|
|
277
|
-
default:
|
|
278
|
-
return scoreWeighted(stats);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
applyFairness(peers) {
|
|
282
|
-
const ordered = peers.slice();
|
|
283
|
-
const total = totalRequests(ordered);
|
|
284
|
-
if (total <= 0)
|
|
285
|
-
return ordered;
|
|
286
|
-
for (let i = 0; i < ordered.length; i++) {
|
|
287
|
-
const top = ordered[0];
|
|
288
|
-
const share = top.requestsSent / total;
|
|
289
|
-
if (share <= FAIRNESS_SELECTION_SHARE_WARNING)
|
|
290
|
-
break;
|
|
291
|
-
ordered.push(ordered.shift());
|
|
292
|
-
}
|
|
293
|
-
return ordered;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
export function normalizeDispatchConfig(dispatch, availablePeers) {
|
|
297
|
-
let cap = dispatch.maxFanout === 0 ? availablePeers : Math.min(dispatch.maxFanout, availablePeers);
|
|
298
|
-
if (cap < 0)
|
|
299
|
-
cap = 0;
|
|
300
|
-
const initialFanout = (dispatch.initialFanout === 0 ? 1 : dispatch.initialFanout);
|
|
301
|
-
const hedgeFanout = (dispatch.hedgeFanout === 0 ? 1 : dispatch.hedgeFanout);
|
|
302
|
-
const floor = Math.max(1, cap);
|
|
303
|
-
return {
|
|
304
|
-
initialFanout: Math.min(initialFanout, floor),
|
|
305
|
-
hedgeFanout: Math.min(hedgeFanout, floor),
|
|
306
|
-
maxFanout: cap,
|
|
307
|
-
hedgeIntervalMs: Math.max(0, Math.floor(dispatch.hedgeIntervalMs)),
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
export function buildHedgedWavePlan(peerCount, dispatch) {
|
|
311
|
-
if (peerCount <= 0)
|
|
312
|
-
return [];
|
|
313
|
-
const cap = Math.min(dispatch.maxFanout, peerCount);
|
|
314
|
-
if (cap <= 0)
|
|
315
|
-
return [];
|
|
316
|
-
const plan = [];
|
|
317
|
-
let sent = 0;
|
|
318
|
-
const first = Math.max(1, Math.min(dispatch.initialFanout, cap));
|
|
319
|
-
plan.push(first);
|
|
320
|
-
sent += first;
|
|
321
|
-
while (sent < cap) {
|
|
322
|
-
const next = Math.max(1, Math.min(dispatch.hedgeFanout, cap - sent));
|
|
323
|
-
plan.push(next);
|
|
324
|
-
sent += next;
|
|
325
|
-
}
|
|
326
|
-
return plan;
|
|
327
|
-
}
|
|
328
|
-
export function syncSelectorPeers(selector, currentPeerIds) {
|
|
329
|
-
const current = new Set(currentPeerIds);
|
|
330
|
-
for (const peerId of selector.getPeerIds()) {
|
|
331
|
-
if (!current.has(peerId))
|
|
332
|
-
selector.removePeer(peerId);
|
|
333
|
-
}
|
|
334
|
-
for (const peerId of currentPeerIds)
|
|
335
|
-
selector.addPeer(peerId);
|
|
336
|
-
}
|
|
337
|
-
export function blendWeightedScore(baseScore, boostWeight, boostValue) {
|
|
338
|
-
const weight = clamp01(boostWeight);
|
|
339
|
-
const boost = clamp01(boostValue);
|
|
340
|
-
return (1 - weight) * baseScore + weight * (baseScore + boost);
|
|
341
|
-
}
|
|
1
|
+
export { PeerSelector, peerPrincipal, normalizeDispatchConfig, buildHedgedWavePlan, syncSelectorPeers, blendWeightedScore, } from '@hashtree/mesh';
|
|
342
2
|
//# sourceMappingURL=peerSelector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"peerSelector.js","sourceRoot":"","sources":["../../src/webrtc/peerSelector.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"peerSelector.js","sourceRoot":"","sources":["../../src/webrtc/peerSelector.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC"}
|
|
@@ -1,87 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Encode a request message to wire format
|
|
5
|
-
*/
|
|
6
|
-
export declare function encodeRequest(req: DataRequest): ArrayBuffer;
|
|
7
|
-
/**
|
|
8
|
-
* Encode a response message to wire format
|
|
9
|
-
*/
|
|
10
|
-
export declare function encodeResponse(res: DataResponse): ArrayBuffer;
|
|
11
|
-
/**
|
|
12
|
-
* Parse a wire format message
|
|
13
|
-
*/
|
|
14
|
-
export declare function parseMessage(data: ArrayBuffer | Uint8Array): DataMessage | null;
|
|
15
|
-
/**
|
|
16
|
-
* Verify that data matches its expected hash
|
|
17
|
-
*/
|
|
18
|
-
export declare function verifyHash(data: Uint8Array, expectedHash: Uint8Array): Promise<boolean>;
|
|
19
|
-
/**
|
|
20
|
-
* Pending request tracking
|
|
21
|
-
*/
|
|
22
|
-
export interface PendingRequest {
|
|
23
|
-
hash: Uint8Array;
|
|
24
|
-
resolve: (data: Uint8Array | null) => void;
|
|
25
|
-
timeout: ReturnType<typeof setTimeout>;
|
|
26
|
-
startedAt?: number;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Per-peer HTL config (Freenet-style probabilistic decrement)
|
|
30
|
-
* Generated once per peer connection, stays fixed for connection lifetime
|
|
31
|
-
*/
|
|
32
|
-
export interface PeerHTLConfig {
|
|
33
|
-
atMaxSample: number;
|
|
34
|
-
atMinSample: number;
|
|
35
|
-
decrementAtMax?: boolean;
|
|
36
|
-
decrementAtMin?: boolean;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Generate random HTL config for a new peer connection
|
|
40
|
-
*/
|
|
41
|
-
export declare function generatePeerHTLConfig(): PeerHTLConfig;
|
|
42
|
-
/**
|
|
43
|
-
* Decrement HTL using peer's config and selected policy.
|
|
44
|
-
*/
|
|
45
|
-
export declare function decrementHTLWithPolicy(htl: number, policy: HtlPolicy, config: PeerHTLConfig): number;
|
|
46
|
-
/**
|
|
47
|
-
* Backward-compatible helper using blob-request policy.
|
|
48
|
-
*/
|
|
49
|
-
export declare function decrementHTL(htl: number, config: PeerHTLConfig): number;
|
|
50
|
-
/**
|
|
51
|
-
* Check if a request should be forwarded based on HTL
|
|
52
|
-
*/
|
|
53
|
-
export declare function shouldForwardHTL(htl: number): boolean;
|
|
54
|
-
/**
|
|
55
|
-
* Backward-compatible helper.
|
|
56
|
-
*/
|
|
57
|
-
export declare function shouldForward(htl: number): boolean;
|
|
58
|
-
/**
|
|
59
|
-
* Create a request body
|
|
60
|
-
*/
|
|
61
|
-
export declare function createRequest(hash: Uint8Array, htl?: number): DataRequest;
|
|
62
|
-
/**
|
|
63
|
-
* Create a response body
|
|
64
|
-
*/
|
|
65
|
-
export declare function createResponse(hash: Uint8Array, data: Uint8Array): DataResponse;
|
|
66
|
-
/**
|
|
67
|
-
* Create a fragmented response body
|
|
68
|
-
*/
|
|
69
|
-
export declare function createFragmentResponse(hash: Uint8Array, data: Uint8Array, index: number, total: number): DataResponse;
|
|
70
|
-
/**
|
|
71
|
-
* Check if a response is fragmented
|
|
72
|
-
*/
|
|
73
|
-
export declare function isFragmented(res: DataResponse): boolean;
|
|
74
|
-
/**
|
|
75
|
-
* Convert hash to hex string for use as map key
|
|
76
|
-
*/
|
|
77
|
-
export declare function hashToKey(hash: Uint8Array): string;
|
|
78
|
-
/**
|
|
79
|
-
* Handle a response message - verify hash and resolve pending request
|
|
80
|
-
* Returns true if hash verified, false if hash mismatch, undefined if no pending request
|
|
81
|
-
*/
|
|
82
|
-
export declare function handleResponse(res: DataResponse, pendingRequests: Map<string, PendingRequest>): Promise<boolean | undefined>;
|
|
83
|
-
/**
|
|
84
|
-
* Clear all pending requests (on disconnect/close)
|
|
85
|
-
*/
|
|
86
|
-
export declare function clearPendingRequests(pendingRequests: Map<string, PendingRequest>): void;
|
|
1
|
+
export { encodeRequest, encodeResponse, parseMessage, verifyHash, generatePeerHTLConfig, decrementHTLWithPolicy, decrementHTL, shouldForwardHTL, shouldForward, createRequest, createResponse, createFragmentResponse, isFragmented, hashToKey, handleResponse, clearPendingRequests, } from '@hashtree/mesh';
|
|
2
|
+
export type { PendingRequest, PeerHTLConfig, } from '@hashtree/mesh';
|
|
87
3
|
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/webrtc/protocol.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/webrtc/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EACd,YAAY,EACZ,UAAU,EACV,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,EACd,sBAAsB,EACtB,YAAY,EACZ,SAAS,EACT,cAAc,EACd,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,cAAc,EACd,aAAa,GACd,MAAM,gBAAgB,CAAC"}
|
package/dist/webrtc/protocol.js
CHANGED
|
@@ -1,181 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* Shared protocol utilities for hashtree data exchange
|
|
3
|
-
*
|
|
4
|
-
* Used by WebRTC peer.ts implementation.
|
|
5
|
-
*
|
|
6
|
-
* Wire format: [type byte][msgpack body]
|
|
7
|
-
* Request: [0x00][msgpack: {id: u32, h: bytes32, htl?: u8}]
|
|
8
|
-
* Response: [0x01][msgpack: {id: u32, h: bytes32, d: bytes}]
|
|
9
|
-
*/
|
|
10
|
-
import { encode, decode } from '@msgpack/msgpack';
|
|
11
|
-
import { sha256 } from '@hashtree/core';
|
|
12
|
-
import { BLOB_REQUEST_POLICY, HtlMode, MSG_TYPE_REQUEST, MSG_TYPE_RESPONSE, } from './types.js';
|
|
13
|
-
/**
|
|
14
|
-
* Encode a request message to wire format
|
|
15
|
-
*/
|
|
16
|
-
export function encodeRequest(req) {
|
|
17
|
-
const body = encode(req);
|
|
18
|
-
const result = new Uint8Array(1 + body.length);
|
|
19
|
-
result[0] = MSG_TYPE_REQUEST;
|
|
20
|
-
result.set(body, 1);
|
|
21
|
-
return result.buffer;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Encode a response message to wire format
|
|
25
|
-
*/
|
|
26
|
-
export function encodeResponse(res) {
|
|
27
|
-
const body = encode(res);
|
|
28
|
-
const result = new Uint8Array(1 + body.length);
|
|
29
|
-
result[0] = MSG_TYPE_RESPONSE;
|
|
30
|
-
result.set(body, 1);
|
|
31
|
-
return result.buffer;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Parse a wire format message
|
|
35
|
-
*/
|
|
36
|
-
export function parseMessage(data) {
|
|
37
|
-
try {
|
|
38
|
-
const bytes = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
|
|
39
|
-
if (bytes.length < 2)
|
|
40
|
-
return null;
|
|
41
|
-
const type = bytes[0];
|
|
42
|
-
const body = bytes.slice(1);
|
|
43
|
-
if (type === MSG_TYPE_REQUEST) {
|
|
44
|
-
return { type: MSG_TYPE_REQUEST, body: decode(body) };
|
|
45
|
-
}
|
|
46
|
-
else if (type === MSG_TYPE_RESPONSE) {
|
|
47
|
-
return { type: MSG_TYPE_RESPONSE, body: decode(body) };
|
|
48
|
-
}
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Verify that data matches its expected hash
|
|
57
|
-
*/
|
|
58
|
-
export async function verifyHash(data, expectedHash) {
|
|
59
|
-
const computedHash = await sha256(data);
|
|
60
|
-
if (computedHash.length !== expectedHash.length)
|
|
61
|
-
return false;
|
|
62
|
-
for (let i = 0; i < computedHash.length; i++) {
|
|
63
|
-
if (computedHash[i] !== expectedHash[i])
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Generate random HTL config for a new peer connection
|
|
70
|
-
*/
|
|
71
|
-
export function generatePeerHTLConfig() {
|
|
72
|
-
return {
|
|
73
|
-
atMaxSample: Math.random(),
|
|
74
|
-
atMinSample: Math.random(),
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Decrement HTL using peer's config and selected policy.
|
|
79
|
-
*/
|
|
80
|
-
export function decrementHTLWithPolicy(htl, policy, config) {
|
|
81
|
-
if (htl <= 0)
|
|
82
|
-
return 0;
|
|
83
|
-
const bounded = Math.min(htl, policy.maxHtl);
|
|
84
|
-
const maxSample = config.atMaxSample ?? (config.decrementAtMax ? 0 : 1);
|
|
85
|
-
const minSample = config.atMinSample ?? (config.decrementAtMin ? 0 : 1);
|
|
86
|
-
if (policy.mode !== HtlMode.Probabilistic) {
|
|
87
|
-
return Math.max(0, bounded - 1);
|
|
88
|
-
}
|
|
89
|
-
const pAtMax = Math.max(0, Math.min(1, policy.pAtMax));
|
|
90
|
-
const pAtMin = Math.max(0, Math.min(1, policy.pAtMin));
|
|
91
|
-
if (bounded === policy.maxHtl) {
|
|
92
|
-
return maxSample < pAtMax ? bounded - 1 : bounded;
|
|
93
|
-
}
|
|
94
|
-
if (bounded === 1) {
|
|
95
|
-
return minSample < pAtMin ? 0 : 1;
|
|
96
|
-
}
|
|
97
|
-
return bounded - 1;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Backward-compatible helper using blob-request policy.
|
|
101
|
-
*/
|
|
102
|
-
export function decrementHTL(htl, config) {
|
|
103
|
-
return decrementHTLWithPolicy(htl, BLOB_REQUEST_POLICY, config);
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Check if a request should be forwarded based on HTL
|
|
107
|
-
*/
|
|
108
|
-
export function shouldForwardHTL(htl) {
|
|
109
|
-
return htl > 0;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Backward-compatible helper.
|
|
113
|
-
*/
|
|
114
|
-
export function shouldForward(htl) {
|
|
115
|
-
return shouldForwardHTL(htl);
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Create a request body
|
|
119
|
-
*/
|
|
120
|
-
export function createRequest(hash, htl = BLOB_REQUEST_POLICY.maxHtl) {
|
|
121
|
-
return { h: hash, htl };
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Create a response body
|
|
125
|
-
*/
|
|
126
|
-
export function createResponse(hash, data) {
|
|
127
|
-
return { h: hash, d: data };
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Create a fragmented response body
|
|
131
|
-
*/
|
|
132
|
-
export function createFragmentResponse(hash, data, index, total) {
|
|
133
|
-
return { h: hash, d: data, i: index, n: total };
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Check if a response is fragmented
|
|
137
|
-
*/
|
|
138
|
-
export function isFragmented(res) {
|
|
139
|
-
return res.i !== undefined && res.n !== undefined;
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Convert hash to hex string for use as map key
|
|
143
|
-
*/
|
|
144
|
-
export function hashToKey(hash) {
|
|
145
|
-
let key = '';
|
|
146
|
-
for (let i = 0; i < hash.length; i++) {
|
|
147
|
-
key += hash[i].toString(16).padStart(2, '0');
|
|
148
|
-
}
|
|
149
|
-
return key;
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Handle a response message - verify hash and resolve pending request
|
|
153
|
-
* Returns true if hash verified, false if hash mismatch, undefined if no pending request
|
|
154
|
-
*/
|
|
155
|
-
export async function handleResponse(res, pendingRequests) {
|
|
156
|
-
const key = hashToKey(res.h);
|
|
157
|
-
const pending = pendingRequests.get(key);
|
|
158
|
-
if (!pending)
|
|
159
|
-
return undefined;
|
|
160
|
-
clearTimeout(pending.timeout);
|
|
161
|
-
pendingRequests.delete(key);
|
|
162
|
-
const isValid = await verifyHash(res.d, res.h);
|
|
163
|
-
if (isValid) {
|
|
164
|
-
pending.resolve(res.d);
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
pending.resolve(null);
|
|
168
|
-
}
|
|
169
|
-
return isValid;
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Clear all pending requests (on disconnect/close)
|
|
173
|
-
*/
|
|
174
|
-
export function clearPendingRequests(pendingRequests) {
|
|
175
|
-
for (const pending of pendingRequests.values()) {
|
|
176
|
-
clearTimeout(pending.timeout);
|
|
177
|
-
pending.resolve(null);
|
|
178
|
-
}
|
|
179
|
-
pendingRequests.clear();
|
|
180
|
-
}
|
|
1
|
+
export { encodeRequest, encodeResponse, parseMessage, verifyHash, generatePeerHTLConfig, decrementHTLWithPolicy, decrementHTL, shouldForwardHTL, shouldForward, createRequest, createResponse, createFragmentResponse, isFragmented, hashToKey, handleResponse, clearPendingRequests, } from '@hashtree/mesh';
|
|
181
2
|
//# sourceMappingURL=protocol.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/webrtc/protocol.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/webrtc/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EACd,YAAY,EACZ,UAAU,EACV,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,EACd,sBAAsB,EACtB,YAAY,EACZ,SAAS,EACT,cAAc,EACd,oBAAoB,GACrB,MAAM,gBAAgB,CAAC"}
|
package/dist/webrtc/types.d.ts
CHANGED
|
@@ -1,91 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* WebRTC
|
|
3
|
-
*
|
|
4
|
-
* These types match the Rust hashtree-network mesh transport types.
|
|
2
|
+
* @hashtree/nostr-specific WebRTC store types layered on the shared mesh core.
|
|
5
3
|
*/
|
|
6
4
|
import type { Store } from '@hashtree/core';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
sdpMid?: string;
|
|
11
|
-
}
|
|
12
|
-
export interface HelloMessage {
|
|
13
|
-
type: 'hello';
|
|
14
|
-
peerId: string;
|
|
15
|
-
roots?: string[];
|
|
16
|
-
hashGet?: boolean;
|
|
17
|
-
}
|
|
18
|
-
export interface OfferMessage {
|
|
19
|
-
type: 'offer';
|
|
20
|
-
peerId: string;
|
|
21
|
-
targetPeerId: string;
|
|
22
|
-
sdp: string;
|
|
23
|
-
}
|
|
24
|
-
export interface AnswerMessage {
|
|
25
|
-
type: 'answer';
|
|
26
|
-
peerId: string;
|
|
27
|
-
targetPeerId: string;
|
|
28
|
-
sdp: string;
|
|
29
|
-
}
|
|
30
|
-
export interface CandidateMessage {
|
|
31
|
-
type: 'candidate';
|
|
32
|
-
peerId: string;
|
|
33
|
-
targetPeerId: string;
|
|
34
|
-
candidate: string;
|
|
35
|
-
sdpMLineIndex?: number;
|
|
36
|
-
sdpMid?: string;
|
|
37
|
-
}
|
|
38
|
-
export interface CandidatesMessage {
|
|
39
|
-
type: 'candidates';
|
|
40
|
-
peerId: string;
|
|
41
|
-
targetPeerId: string;
|
|
42
|
-
candidates: IceCandidate[];
|
|
43
|
-
}
|
|
44
|
-
export type SignalingMessage = HelloMessage | OfferMessage | AnswerMessage | CandidateMessage | CandidatesMessage;
|
|
45
|
-
export type DirectedMessage = OfferMessage | AnswerMessage | CandidateMessage | CandidatesMessage;
|
|
46
|
-
export declare const MAX_HTL = 10;
|
|
47
|
-
export declare const DECREMENT_AT_MAX_PROB = 0.5;
|
|
48
|
-
export declare const DECREMENT_AT_MIN_PROB = 0.25;
|
|
49
|
-
export declare const WEBRTC_KIND = 25050;
|
|
50
|
-
export declare enum HtlMode {
|
|
51
|
-
Probabilistic = "probabilistic"
|
|
52
|
-
}
|
|
53
|
-
export interface HtlPolicy {
|
|
54
|
-
mode: HtlMode;
|
|
55
|
-
maxHtl: number;
|
|
56
|
-
pAtMax: number;
|
|
57
|
-
pAtMin: number;
|
|
58
|
-
}
|
|
59
|
-
export declare const BLOB_REQUEST_POLICY: HtlPolicy;
|
|
60
|
-
export declare const MESH_EVENT_POLICY: HtlPolicy;
|
|
61
|
-
export declare const MESH_PROTOCOL = "htree.nostr.mesh.v1";
|
|
62
|
-
export declare const MESH_PROTOCOL_VERSION = 1;
|
|
63
|
-
export declare const MESH_DEFAULT_HTL: number;
|
|
64
|
-
export declare const MESH_MAX_HTL = 6;
|
|
65
|
-
export declare const FRAGMENT_SIZE: number;
|
|
66
|
-
export declare const FRAGMENT_STALL_TIMEOUT = 5000;
|
|
67
|
-
export declare const FRAGMENT_TOTAL_TIMEOUT = 120000;
|
|
68
|
-
export declare const MAX_PENDING_REASSEMBLIES = 20;
|
|
69
|
-
export declare const MAX_PENDING_BYTES: number;
|
|
70
|
-
export declare const MSG_TYPE_REQUEST = 0;
|
|
71
|
-
export declare const MSG_TYPE_RESPONSE = 1;
|
|
72
|
-
export interface DataRequest {
|
|
73
|
-
h: Uint8Array;
|
|
74
|
-
htl?: number;
|
|
75
|
-
}
|
|
76
|
-
export interface DataResponse {
|
|
77
|
-
h: Uint8Array;
|
|
78
|
-
d: Uint8Array;
|
|
79
|
-
i?: number;
|
|
80
|
-
n?: number;
|
|
81
|
-
}
|
|
82
|
-
export type DataMessage = {
|
|
83
|
-
type: typeof MSG_TYPE_REQUEST;
|
|
84
|
-
body: DataRequest;
|
|
85
|
-
} | {
|
|
86
|
-
type: typeof MSG_TYPE_RESPONSE;
|
|
87
|
-
body: DataResponse;
|
|
88
|
-
};
|
|
5
|
+
import type { PeerPool, PoolConfig, SelectionStrategy, RequestDispatchConfig } from '@hashtree/mesh';
|
|
6
|
+
export { PeerId, WEBRTC_KIND, MAX_HTL, HtlMode, BLOB_REQUEST_POLICY, MESH_EVENT_POLICY, MESH_PROTOCOL, MESH_PROTOCOL_VERSION, MESH_DEFAULT_HTL, MESH_MAX_HTL, PEER_METADATA_SNAPSHOT_VERSION, DECREMENT_AT_MAX_PROB, DECREMENT_AT_MIN_PROB, MSG_TYPE_REQUEST, MSG_TYPE_RESPONSE, FRAGMENT_SIZE, FRAGMENT_STALL_TIMEOUT, FRAGMENT_TOTAL_TIMEOUT, MAX_PENDING_REASSEMBLIES, MAX_PENDING_BYTES, createMeshNostrEventFrame, validateMeshNostrFrame, parseMeshNostrFrameText, generateUuid, } from '@hashtree/mesh';
|
|
7
|
+
export type { IceCandidate, HelloMessage, OfferMessage, AnswerMessage, CandidateMessage, CandidatesMessage, SignalingMessage, DirectedMessage, HtlPolicy, DataRequest, DataResponse, DataMessage, SignedEvent, MeshNostrPayload, MeshNostrEventPayload, MeshNostrFrame, PeerPool, PoolConfig, SelectionStrategy, RequestDispatchConfig, PersistedPeerMetadata, PeerMetadataSnapshot, MeshStats, WebRTCStats, BandwidthSample, PendingReassembly, } from '@hashtree/mesh';
|
|
89
8
|
export type EventSigner = (event: {
|
|
90
9
|
kind: number;
|
|
91
10
|
created_at: number;
|
|
@@ -102,7 +21,11 @@ export type EventSigner = (event: {
|
|
|
102
21
|
}>;
|
|
103
22
|
export type EventEncrypter = (pubkey: string, plaintext: string) => Promise<string>;
|
|
104
23
|
export type EventDecrypter = (pubkey: string, ciphertext: string) => Promise<string>;
|
|
105
|
-
export
|
|
24
|
+
export type GiftWrapper = (innerEvent: {
|
|
25
|
+
kind: number;
|
|
26
|
+
content: string;
|
|
27
|
+
tags: string[][];
|
|
28
|
+
}, recipientPubkey: string) => Promise<{
|
|
106
29
|
id: string;
|
|
107
30
|
pubkey: string;
|
|
108
31
|
sig: string;
|
|
@@ -110,64 +33,22 @@ export interface SignedEvent {
|
|
|
110
33
|
created_at: number;
|
|
111
34
|
tags: string[][];
|
|
112
35
|
content: string;
|
|
113
|
-
}
|
|
114
|
-
export
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
export type MeshNostrPayload = MeshNostrEventPayload;
|
|
119
|
-
export interface MeshNostrFrame {
|
|
120
|
-
protocol: string;
|
|
121
|
-
version: number;
|
|
122
|
-
frame_id: string;
|
|
123
|
-
htl: number;
|
|
124
|
-
sender_peer_id: string;
|
|
125
|
-
payload: MeshNostrPayload;
|
|
126
|
-
}
|
|
127
|
-
export declare function createMeshNostrEventFrame(event: SignedEvent, senderPeerId: string, htl?: number): MeshNostrFrame;
|
|
128
|
-
export declare function validateMeshNostrFrame(frame: MeshNostrFrame): string | null;
|
|
129
|
-
export declare function parseMeshNostrFrameText(text: string): MeshNostrFrame | null;
|
|
130
|
-
export type GiftWrapper = (innerEvent: {
|
|
36
|
+
}>;
|
|
37
|
+
export type GiftUnwrapper = (event: {
|
|
38
|
+
id: string;
|
|
39
|
+
pubkey: string;
|
|
40
|
+
sig: string;
|
|
131
41
|
kind: number;
|
|
132
|
-
|
|
42
|
+
created_at: number;
|
|
133
43
|
tags: string[][];
|
|
134
|
-
|
|
135
|
-
|
|
44
|
+
content: string;
|
|
45
|
+
}) => Promise<{
|
|
136
46
|
pubkey: string;
|
|
137
47
|
kind: number;
|
|
138
48
|
content: string;
|
|
139
49
|
tags: string[][];
|
|
140
50
|
} | null>;
|
|
141
|
-
export type PeerPool = 'follows' | 'other';
|
|
142
51
|
export type PeerClassifier = (pubkey: string) => PeerPool;
|
|
143
|
-
export interface PoolConfig {
|
|
144
|
-
maxConnections: number;
|
|
145
|
-
satisfiedConnections: number;
|
|
146
|
-
}
|
|
147
|
-
export type SelectionStrategy = 'weighted' | 'roundRobin' | 'random' | 'lowestLatency' | 'highestSuccessRate' | 'utilityUcb';
|
|
148
|
-
export interface RequestDispatchConfig {
|
|
149
|
-
initialFanout: number;
|
|
150
|
-
hedgeFanout: number;
|
|
151
|
-
maxFanout: number;
|
|
152
|
-
hedgeIntervalMs: number;
|
|
153
|
-
}
|
|
154
|
-
export declare const PEER_METADATA_SNAPSHOT_VERSION = 1;
|
|
155
|
-
export interface PersistedPeerMetadata {
|
|
156
|
-
principal: string;
|
|
157
|
-
requestsSent: number;
|
|
158
|
-
successes: number;
|
|
159
|
-
timeouts: number;
|
|
160
|
-
failures: number;
|
|
161
|
-
srttMs: number;
|
|
162
|
-
rttvarMs: number;
|
|
163
|
-
rtoMs: number;
|
|
164
|
-
bytesReceived: number;
|
|
165
|
-
bytesSent: number;
|
|
166
|
-
}
|
|
167
|
-
export interface PeerMetadataSnapshot {
|
|
168
|
-
version: number;
|
|
169
|
-
peers: PersistedPeerMetadata[];
|
|
170
|
-
}
|
|
171
52
|
export interface WebRTCStoreConfig {
|
|
172
53
|
signer: EventSigner;
|
|
173
54
|
pubkey: string;
|
|
@@ -184,7 +65,7 @@ export interface WebRTCStoreConfig {
|
|
|
184
65
|
relays?: string[];
|
|
185
66
|
localStore?: Store;
|
|
186
67
|
debug?: boolean;
|
|
187
|
-
peerClassifier?:
|
|
68
|
+
peerClassifier?: (pubkey: string) => PeerPool;
|
|
188
69
|
pools?: {
|
|
189
70
|
follows: PoolConfig;
|
|
190
71
|
other: PoolConfig;
|
|
@@ -217,45 +98,4 @@ export type WebRTCStoreEvent = {
|
|
|
217
98
|
type: 'update';
|
|
218
99
|
};
|
|
219
100
|
export type WebRTCStoreEventHandler = (event: WebRTCStoreEvent) => void;
|
|
220
|
-
export interface MeshStats {
|
|
221
|
-
requestsSent: number;
|
|
222
|
-
requestsReceived: number;
|
|
223
|
-
responsesSent: number;
|
|
224
|
-
responsesReceived: number;
|
|
225
|
-
receiveErrors: number;
|
|
226
|
-
blossomFetches: number;
|
|
227
|
-
fragmentsSent: number;
|
|
228
|
-
fragmentsReceived: number;
|
|
229
|
-
fragmentTimeouts: number;
|
|
230
|
-
reassembliesCompleted: number;
|
|
231
|
-
bytesSent: number;
|
|
232
|
-
bytesReceived: number;
|
|
233
|
-
bytesForwarded: number;
|
|
234
|
-
meshReceived: number;
|
|
235
|
-
meshForwarded: number;
|
|
236
|
-
meshDroppedDuplicate: number;
|
|
237
|
-
}
|
|
238
|
-
export type WebRTCStats = MeshStats;
|
|
239
|
-
export interface BandwidthSample {
|
|
240
|
-
timestamp: number;
|
|
241
|
-
bytesSent: number;
|
|
242
|
-
bytesReceived: number;
|
|
243
|
-
}
|
|
244
|
-
export interface PendingReassembly {
|
|
245
|
-
hash: Uint8Array;
|
|
246
|
-
fragments: Map<number, Uint8Array>;
|
|
247
|
-
totalExpected: number;
|
|
248
|
-
receivedBytes: number;
|
|
249
|
-
firstFragmentAt: number;
|
|
250
|
-
lastFragmentAt: number;
|
|
251
|
-
}
|
|
252
|
-
export declare function generateUuid(): string;
|
|
253
|
-
export declare class PeerId {
|
|
254
|
-
readonly pubkey: string;
|
|
255
|
-
private readonly str;
|
|
256
|
-
constructor(pubkey: string);
|
|
257
|
-
toString(): string;
|
|
258
|
-
short(): string;
|
|
259
|
-
static fromString(str: string): PeerId;
|
|
260
|
-
}
|
|
261
101
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/webrtc/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/webrtc/types.ts"],"names":[],"mappings":"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"}
|
package/dist/webrtc/types.js
CHANGED
|
@@ -1,108 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* WebRTC
|
|
3
|
-
*
|
|
4
|
-
* These types match the Rust hashtree-network mesh transport types.
|
|
2
|
+
* @hashtree/nostr-specific WebRTC store types layered on the shared mesh core.
|
|
5
3
|
*/
|
|
6
|
-
|
|
7
|
-
export const MAX_HTL = 10;
|
|
8
|
-
export const DECREMENT_AT_MAX_PROB = 0.5; // 50% chance to decrement at max
|
|
9
|
-
export const DECREMENT_AT_MIN_PROB = 0.25; // 25% chance to decrement at 1
|
|
10
|
-
// Signaling kind for WebRTC events
|
|
11
|
-
export const WEBRTC_KIND = 25050;
|
|
12
|
-
export var HtlMode;
|
|
13
|
-
(function (HtlMode) {
|
|
14
|
-
HtlMode["Probabilistic"] = "probabilistic";
|
|
15
|
-
})(HtlMode || (HtlMode = {}));
|
|
16
|
-
export const BLOB_REQUEST_POLICY = {
|
|
17
|
-
mode: HtlMode.Probabilistic,
|
|
18
|
-
maxHtl: MAX_HTL,
|
|
19
|
-
pAtMax: DECREMENT_AT_MAX_PROB,
|
|
20
|
-
pAtMin: DECREMENT_AT_MIN_PROB,
|
|
21
|
-
};
|
|
22
|
-
export const MESH_EVENT_POLICY = {
|
|
23
|
-
mode: HtlMode.Probabilistic,
|
|
24
|
-
maxHtl: 4,
|
|
25
|
-
pAtMax: 0.75,
|
|
26
|
-
pAtMin: 0.5,
|
|
27
|
-
};
|
|
28
|
-
export const MESH_PROTOCOL = 'htree.nostr.mesh.v1';
|
|
29
|
-
export const MESH_PROTOCOL_VERSION = 1;
|
|
30
|
-
export const MESH_DEFAULT_HTL = MESH_EVENT_POLICY.maxHtl;
|
|
31
|
-
export const MESH_MAX_HTL = 6;
|
|
32
|
-
// Fragment constants for WebRTC transport
|
|
33
|
-
export const FRAGMENT_SIZE = 32 * 1024; // 32KB per WebRTC message (safe limit)
|
|
34
|
-
export const FRAGMENT_STALL_TIMEOUT = 5_000; // 5s without fragment = stall
|
|
35
|
-
export const FRAGMENT_TOTAL_TIMEOUT = 120_000; // 2min max for full chunk reassembly
|
|
36
|
-
export const MAX_PENDING_REASSEMBLIES = 20; // Memory cap: max concurrent reassemblies
|
|
37
|
-
export const MAX_PENDING_BYTES = 64 * 1024 * 1024; // 64MB memory cap for reassembly buffers
|
|
38
|
-
// Message type bytes (prefix before MessagePack body)
|
|
39
|
-
export const MSG_TYPE_REQUEST = 0x00;
|
|
40
|
-
export const MSG_TYPE_RESPONSE = 0x01;
|
|
41
|
-
export function createMeshNostrEventFrame(event, senderPeerId, htl = MESH_DEFAULT_HTL) {
|
|
42
|
-
return {
|
|
43
|
-
protocol: MESH_PROTOCOL,
|
|
44
|
-
version: MESH_PROTOCOL_VERSION,
|
|
45
|
-
frame_id: generateUuid(),
|
|
46
|
-
htl,
|
|
47
|
-
sender_peer_id: senderPeerId,
|
|
48
|
-
payload: {
|
|
49
|
-
type: 'EVENT',
|
|
50
|
-
event,
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
export function validateMeshNostrFrame(frame) {
|
|
55
|
-
if (frame.protocol !== MESH_PROTOCOL)
|
|
56
|
-
return 'invalid protocol';
|
|
57
|
-
if (frame.version !== MESH_PROTOCOL_VERSION)
|
|
58
|
-
return 'invalid version';
|
|
59
|
-
if (!frame.frame_id)
|
|
60
|
-
return 'missing frame id';
|
|
61
|
-
if (!frame.sender_peer_id)
|
|
62
|
-
return 'missing sender peer id';
|
|
63
|
-
if (frame.sender_peer_id.includes(':'))
|
|
64
|
-
return 'invalid sender peer id';
|
|
65
|
-
if (frame.htl <= 0 || frame.htl > MESH_MAX_HTL)
|
|
66
|
-
return 'invalid htl';
|
|
67
|
-
if (frame.payload?.type !== 'EVENT')
|
|
68
|
-
return 'invalid payload type';
|
|
69
|
-
if (frame.payload.event.kind !== WEBRTC_KIND)
|
|
70
|
-
return 'unsupported event kind';
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
export function parseMeshNostrFrameText(text) {
|
|
74
|
-
try {
|
|
75
|
-
const value = JSON.parse(text);
|
|
76
|
-
return validateMeshNostrFrame(value) === null ? value : null;
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
export const PEER_METADATA_SNAPSHOT_VERSION = 1;
|
|
83
|
-
export function generateUuid() {
|
|
84
|
-
return Math.random().toString(36).substring(2, 15) +
|
|
85
|
-
Math.random().toString(36).substring(2, 15);
|
|
86
|
-
}
|
|
87
|
-
export class PeerId {
|
|
88
|
-
pubkey;
|
|
89
|
-
str;
|
|
90
|
-
constructor(pubkey) {
|
|
91
|
-
this.pubkey = pubkey;
|
|
92
|
-
this.str = pubkey;
|
|
93
|
-
}
|
|
94
|
-
toString() {
|
|
95
|
-
return this.str;
|
|
96
|
-
}
|
|
97
|
-
short() {
|
|
98
|
-
return this.pubkey.slice(0, 8);
|
|
99
|
-
}
|
|
100
|
-
static fromString(str) {
|
|
101
|
-
const pubkey = str.trim();
|
|
102
|
-
if (!pubkey || pubkey.includes(':')) {
|
|
103
|
-
throw new Error(`Invalid peer string: ${str}`);
|
|
104
|
-
}
|
|
105
|
-
return new PeerId(pubkey);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
4
|
+
export { PeerId, WEBRTC_KIND, MAX_HTL, HtlMode, BLOB_REQUEST_POLICY, MESH_EVENT_POLICY, MESH_PROTOCOL, MESH_PROTOCOL_VERSION, MESH_DEFAULT_HTL, MESH_MAX_HTL, PEER_METADATA_SNAPSHOT_VERSION, DECREMENT_AT_MAX_PROB, DECREMENT_AT_MIN_PROB, MSG_TYPE_REQUEST, MSG_TYPE_RESPONSE, FRAGMENT_SIZE, FRAGMENT_STALL_TIMEOUT, FRAGMENT_TOTAL_TIMEOUT, MAX_PENDING_REASSEMBLIES, MAX_PENDING_BYTES, createMeshNostrEventFrame, validateMeshNostrFrame, parseMeshNostrFrameText, generateUuid, } from '@hashtree/mesh';
|
|
108
5
|
//# sourceMappingURL=types.js.map
|
package/dist/webrtc/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/webrtc/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/webrtc/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,OAAO,EACL,MAAM,EACN,WAAW,EACX,OAAO,EACP,OAAO,EACP,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,8BAA8B,EAC9B,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,YAAY,GACb,MAAM,gBAAgB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hashtree/nostr",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "Nostr integration for hashtree - WebRTC P2P store and ref resolver",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -34,9 +34,10 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@msgpack/msgpack": "^3.1.2",
|
|
36
36
|
"nostr-tools": "^2.18.2",
|
|
37
|
-
"@hashtree/
|
|
37
|
+
"@hashtree/collection": "0.1.3",
|
|
38
38
|
"@hashtree/index": "0.1.7",
|
|
39
|
-
"@hashtree/
|
|
39
|
+
"@hashtree/mesh": "0.1.1",
|
|
40
|
+
"@hashtree/core": "0.1.5"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"@nostr-dev-kit/ndk": "^2.18.1",
|