@fairfox/polly 0.55.0 → 0.57.0
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/mesh.d.ts +2 -2
- package/dist/src/mesh.js +223 -19
- package/dist/src/mesh.js.map +6 -6
- package/dist/src/peer.js +6 -2
- package/dist/src/peer.js.map +3 -3
- package/dist/src/shared/lib/mesh-client.d.ts +70 -5
- package/dist/src/shared/lib/mesh-webrtc-adapter.d.ts +257 -2
- package/package.json +1 -1
package/dist/src/mesh.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export type { EncryptedEnvelope, SealedBytes, } from "./shared/lib/encryption";
|
|
|
21
21
|
export { decrypt, decryptOrThrow, EncryptionError, encrypt, generateDocumentKey, KEY_BYTES as ENCRYPTION_KEY_BYTES, NONCE_BYTES as ENCRYPTION_NONCE_BYTES, TAG_BYTES as ENCRYPTION_TAG_BYTES, } from "./shared/lib/encryption";
|
|
22
22
|
export type { KeyringStorage } from "./shared/lib/keyring-storage";
|
|
23
23
|
export { deserialiseKeyring, memoryKeyringStorage, serialiseKeyring, } from "./shared/lib/keyring-storage";
|
|
24
|
-
export type { CreateMeshClientOptions, MeshClient } from "./shared/lib/mesh-client";
|
|
24
|
+
export type { CreateMeshClientOptions, MeshClient, MeshClientHandleSnapshot, MeshClientPeerStateSnapshot, } from "./shared/lib/mesh-client";
|
|
25
25
|
export { createMeshClient } from "./shared/lib/mesh-client";
|
|
26
26
|
export type { MeshKeyring, MeshNetworkAdapterOptions, } from "./shared/lib/mesh-network-adapter";
|
|
27
27
|
export { DEFAULT_MESH_KEY_ID, MeshNetworkAdapter, } from "./shared/lib/mesh-network-adapter";
|
|
@@ -29,7 +29,7 @@ export type { MeshSignalingClientOptions, SignalingMessage as MeshSignalingMessa
|
|
|
29
29
|
export { MeshSignalingClient } from "./shared/lib/mesh-signaling-client";
|
|
30
30
|
export type { MeshStateOptions } from "./shared/lib/mesh-state";
|
|
31
31
|
export { $meshCounter, $meshList, $meshState, $meshText, configureMeshState, resetMeshState, } from "./shared/lib/mesh-state";
|
|
32
|
-
export type { MeshWebRTCAdapterOptions } from "./shared/lib/mesh-webrtc-adapter";
|
|
32
|
+
export type { HandleSyncSnapshot, InFlightSyncSnapshot, MeshWebRTCAdapterOptions, SlotInitiationDecision, SlotInitiationRejectionReason, SweepSnapshot, SyncHandshakeAttemptSnapshot, SyncProgressEvent, TransportSnapshot, } from "./shared/lib/mesh-webrtc-adapter";
|
|
33
33
|
export { DEFAULT_ICE_SERVERS, MeshWebRTCAdapter } from "./shared/lib/mesh-webrtc-adapter";
|
|
34
34
|
export type { CreatePairingTokenOptions, PairingToken, } from "./shared/lib/pairing";
|
|
35
35
|
export { applyPairingToken, createPairingToken, createPairingTokenWithFreshIdentity, DEFAULT_PAIRING_TTL_MS, decodePairingToken, encodePairingToken, isPairingTokenExpired, PAIRING_NONCE_BYTES, PAIRING_TOKEN_VERSION, PairingError, parsePairingToken, serialisePairingToken, } from "./shared/lib/pairing";
|
package/dist/src/mesh.js
CHANGED
|
@@ -1075,12 +1075,16 @@ class MeshNetworkAdapter extends NetworkAdapter {
|
|
|
1075
1075
|
}
|
|
1076
1076
|
const signed = signEnvelope(payloadToSign, message.senderId, keyring.identity.secretKey);
|
|
1077
1077
|
const signedBytes = encodeSignedEnvelope(signed);
|
|
1078
|
-
|
|
1078
|
+
const outer = {
|
|
1079
1079
|
type: message.type,
|
|
1080
1080
|
senderId: message.senderId,
|
|
1081
1081
|
targetId: message.targetId,
|
|
1082
1082
|
data: signedBytes
|
|
1083
1083
|
};
|
|
1084
|
+
if ("documentId" in message && message.documentId !== undefined) {
|
|
1085
|
+
outer["documentId"] = message.documentId;
|
|
1086
|
+
}
|
|
1087
|
+
return outer;
|
|
1084
1088
|
}
|
|
1085
1089
|
tryUnwrap(message) {
|
|
1086
1090
|
if (!message.data)
|
|
@@ -2033,6 +2037,10 @@ function selectActivePair(parsed) {
|
|
|
2033
2037
|
return;
|
|
2034
2038
|
}
|
|
2035
2039
|
function serialiseSlotView(slot) {
|
|
2040
|
+
const handles = {};
|
|
2041
|
+
for (const [docId, snapshot] of slot.handles) {
|
|
2042
|
+
handles[docId] = { ...snapshot };
|
|
2043
|
+
}
|
|
2036
2044
|
return {
|
|
2037
2045
|
signalingState: slot.connection.signalingState,
|
|
2038
2046
|
iceConnectionState: slot.connection.iceConnectionState,
|
|
@@ -2044,7 +2052,17 @@ function serialiseSlotView(slot) {
|
|
|
2044
2052
|
transport: slot.transport ? {
|
|
2045
2053
|
...slot.transport,
|
|
2046
2054
|
selectedCandidatePair: slot.transport.selectedCandidatePair ? { ...slot.transport.selectedCandidatePair } : undefined
|
|
2047
|
-
} : undefined
|
|
2055
|
+
} : undefined,
|
|
2056
|
+
lastSyncHandshakeAttempt: { ...slot.lastSyncHandshakeAttempt },
|
|
2057
|
+
handles
|
|
2058
|
+
};
|
|
2059
|
+
}
|
|
2060
|
+
function emptySyncHandshakeAttempt() {
|
|
2061
|
+
return {
|
|
2062
|
+
dataChannelOpenedAt: undefined,
|
|
2063
|
+
peerCandidateEmittedAt: undefined,
|
|
2064
|
+
firstOutboundSendAt: undefined,
|
|
2065
|
+
firstInboundMessageAt: undefined
|
|
2048
2066
|
};
|
|
2049
2067
|
}
|
|
2050
2068
|
function buildCandidatePairView(pair, localCands, remoteCands) {
|
|
@@ -2063,6 +2081,14 @@ var DEFAULT_ICE_SERVERS = [
|
|
|
2063
2081
|
{ urls: "stun:stun.l.google.com:19302" },
|
|
2064
2082
|
{ urls: "stun:stun1.l.google.com:19302" }
|
|
2065
2083
|
];
|
|
2084
|
+
function emptyHandleSyncSnapshot() {
|
|
2085
|
+
return {
|
|
2086
|
+
lastSyncMessageOutAt: undefined,
|
|
2087
|
+
lastSyncMessageInAt: undefined,
|
|
2088
|
+
lastSyncMessageOutSize: undefined,
|
|
2089
|
+
lastSyncMessageOutType: undefined
|
|
2090
|
+
};
|
|
2091
|
+
}
|
|
2066
2092
|
|
|
2067
2093
|
class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
2068
2094
|
signaling;
|
|
@@ -2082,6 +2108,9 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2082
2108
|
slots = new Map;
|
|
2083
2109
|
ready = false;
|
|
2084
2110
|
readyResolver;
|
|
2111
|
+
lastSlotInitiationDecisions = new Map;
|
|
2112
|
+
sweepRunCount = 0;
|
|
2113
|
+
lastSweepAt;
|
|
2085
2114
|
get knownPeerIds() {
|
|
2086
2115
|
if (this.keyringSource !== undefined) {
|
|
2087
2116
|
return [...this.keyringSource().knownPeers.keys()].filter((id) => id !== this.localPeerId);
|
|
@@ -2134,10 +2163,13 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2134
2163
|
const peers = [];
|
|
2135
2164
|
for (const peerId of allPeers) {
|
|
2136
2165
|
const slot = this.slots.get(peerId);
|
|
2166
|
+
const decision = this.snapshotInitiationDecision(peerId);
|
|
2137
2167
|
peers.push({
|
|
2138
2168
|
peerId,
|
|
2139
2169
|
knownInKeyring: knownPeerSet.has(peerId),
|
|
2140
2170
|
presentInSignalling: this.presentPeers.has(peerId),
|
|
2171
|
+
slotInitiationRejectionReason: decision.reason,
|
|
2172
|
+
slotInitiationDecision: decision,
|
|
2141
2173
|
slot: slot ? serialiseSlotView(slot) : undefined
|
|
2142
2174
|
});
|
|
2143
2175
|
}
|
|
@@ -2145,6 +2177,12 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2145
2177
|
localPeerId: this.localPeerId,
|
|
2146
2178
|
knownPeerIds,
|
|
2147
2179
|
presentPeerIds,
|
|
2180
|
+
sweep: {
|
|
2181
|
+
enabled: this.knownPeersRefreshTimer !== undefined,
|
|
2182
|
+
intervalMs: this.knownPeersRefreshIntervalMs,
|
|
2183
|
+
runCount: this.sweepRunCount,
|
|
2184
|
+
lastRunAt: this.lastSweepAt
|
|
2185
|
+
},
|
|
2148
2186
|
peers
|
|
2149
2187
|
};
|
|
2150
2188
|
}
|
|
@@ -2152,14 +2190,27 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2152
2190
|
this.presentPeers.add(remotePeerId);
|
|
2153
2191
|
if (!this.shouldInitiateTo(remotePeerId))
|
|
2154
2192
|
return;
|
|
2155
|
-
this.
|
|
2193
|
+
this.tryCreateInitiatingSlot(remotePeerId);
|
|
2156
2194
|
}
|
|
2157
2195
|
handlePeersPresent(peerIds) {
|
|
2158
2196
|
for (const remotePeerId of peerIds) {
|
|
2159
2197
|
this.presentPeers.add(remotePeerId);
|
|
2160
2198
|
if (!this.shouldInitiateTo(remotePeerId))
|
|
2161
2199
|
continue;
|
|
2200
|
+
this.tryCreateInitiatingSlot(remotePeerId);
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
tryCreateInitiatingSlot(remotePeerId) {
|
|
2204
|
+
try {
|
|
2162
2205
|
this.createInitiatingSlot(remotePeerId);
|
|
2206
|
+
} catch (err) {
|
|
2207
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2208
|
+
this.lastSlotInitiationDecisions.set(remotePeerId, {
|
|
2209
|
+
decision: "rejected",
|
|
2210
|
+
reason: "fatal-error",
|
|
2211
|
+
error: message,
|
|
2212
|
+
at: performance.now()
|
|
2213
|
+
});
|
|
2163
2214
|
}
|
|
2164
2215
|
}
|
|
2165
2216
|
handlePeerLeft(remotePeerId) {
|
|
@@ -2183,25 +2234,49 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2183
2234
|
return;
|
|
2184
2235
|
if (!this.shouldInitiateTo(remotePeerId))
|
|
2185
2236
|
return;
|
|
2186
|
-
this.
|
|
2237
|
+
this.tryCreateInitiatingSlot(remotePeerId);
|
|
2187
2238
|
}
|
|
2188
2239
|
refreshKnownPeers() {
|
|
2189
2240
|
for (const remotePeerId of this.presentPeers) {
|
|
2190
2241
|
if (!this.shouldInitiateTo(remotePeerId))
|
|
2191
2242
|
continue;
|
|
2192
|
-
this.
|
|
2243
|
+
this.tryCreateInitiatingSlot(remotePeerId);
|
|
2193
2244
|
}
|
|
2194
2245
|
}
|
|
2195
2246
|
shouldInitiateTo(remotePeerId) {
|
|
2247
|
+
const reason = this.evaluateInitiation(remotePeerId);
|
|
2248
|
+
this.lastSlotInitiationDecisions.set(remotePeerId, {
|
|
2249
|
+
decision: reason === undefined ? "accepted" : "rejected",
|
|
2250
|
+
reason,
|
|
2251
|
+
error: undefined,
|
|
2252
|
+
at: performance.now()
|
|
2253
|
+
});
|
|
2254
|
+
return reason === undefined;
|
|
2255
|
+
}
|
|
2256
|
+
evaluateInitiation(remotePeerId) {
|
|
2196
2257
|
if (remotePeerId === this.localPeerId)
|
|
2197
|
-
return
|
|
2258
|
+
return "self";
|
|
2198
2259
|
if (!this.hasKnownPeer(remotePeerId))
|
|
2199
|
-
return
|
|
2260
|
+
return "not-in-keyring";
|
|
2261
|
+
if (!this.presentPeers.has(remotePeerId))
|
|
2262
|
+
return "not-present";
|
|
2200
2263
|
if (this.slots.has(remotePeerId))
|
|
2201
|
-
return
|
|
2264
|
+
return "slot-already-exists";
|
|
2202
2265
|
if (this.localPeerId <= remotePeerId)
|
|
2203
|
-
return
|
|
2204
|
-
return
|
|
2266
|
+
return "tie-break-other-side";
|
|
2267
|
+
return;
|
|
2268
|
+
}
|
|
2269
|
+
snapshotInitiationDecision(remotePeerId) {
|
|
2270
|
+
const cached = this.lastSlotInitiationDecisions.get(remotePeerId);
|
|
2271
|
+
if (cached?.reason === "fatal-error")
|
|
2272
|
+
return cached;
|
|
2273
|
+
const reason = this.evaluateInitiation(remotePeerId);
|
|
2274
|
+
return {
|
|
2275
|
+
decision: reason === undefined ? "accepted" : "rejected",
|
|
2276
|
+
reason,
|
|
2277
|
+
error: undefined,
|
|
2278
|
+
at: performance.now()
|
|
2279
|
+
};
|
|
2205
2280
|
}
|
|
2206
2281
|
whenReady() {
|
|
2207
2282
|
if (this.ready)
|
|
@@ -2238,7 +2313,11 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2238
2313
|
if (this.knownPeersRefreshTimer !== undefined)
|
|
2239
2314
|
return;
|
|
2240
2315
|
this.knownPeersRefreshTimer = setInterval(() => {
|
|
2241
|
-
this.
|
|
2316
|
+
this.sweepRunCount += 1;
|
|
2317
|
+
this.lastSweepAt = performance.now();
|
|
2318
|
+
try {
|
|
2319
|
+
this.refreshKnownPeers();
|
|
2320
|
+
} catch {}
|
|
2242
2321
|
}, this.knownPeersRefreshIntervalMs);
|
|
2243
2322
|
}
|
|
2244
2323
|
stopKnownPeersSweep() {
|
|
@@ -2254,6 +2333,20 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2254
2333
|
if (!slot) {
|
|
2255
2334
|
slot = this.createInitiatingSlot(targetId);
|
|
2256
2335
|
}
|
|
2336
|
+
if (slot.lastSyncHandshakeAttempt.firstOutboundSendAt === undefined) {
|
|
2337
|
+
slot.lastSyncHandshakeAttempt.firstOutboundSendAt = performance.now();
|
|
2338
|
+
}
|
|
2339
|
+
const documentId = message.documentId;
|
|
2340
|
+
if (typeof documentId === "string") {
|
|
2341
|
+
let handleEntry = slot.handles.get(documentId);
|
|
2342
|
+
if (!handleEntry) {
|
|
2343
|
+
handleEntry = emptyHandleSyncSnapshot();
|
|
2344
|
+
slot.handles.set(documentId, handleEntry);
|
|
2345
|
+
}
|
|
2346
|
+
handleEntry.lastSyncMessageOutAt = performance.now();
|
|
2347
|
+
handleEntry.lastSyncMessageOutSize = bytes.length;
|
|
2348
|
+
handleEntry.lastSyncMessageOutType = typeof message.type === "string" ? message.type : undefined;
|
|
2349
|
+
}
|
|
2257
2350
|
if (slot.channel && slot.channel.readyState === "open") {
|
|
2258
2351
|
this.sendBytesMaybeFragmented(slot.channel, bytes);
|
|
2259
2352
|
} else {
|
|
@@ -2366,7 +2459,9 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2366
2459
|
pendingRemoteIce: [],
|
|
2367
2460
|
inFlightSync: undefined,
|
|
2368
2461
|
transport: undefined,
|
|
2369
|
-
lastDataChannelError: undefined
|
|
2462
|
+
lastDataChannelError: undefined,
|
|
2463
|
+
lastSyncHandshakeAttempt: emptySyncHandshakeAttempt(),
|
|
2464
|
+
handles: new Map
|
|
2370
2465
|
};
|
|
2371
2466
|
this.slots.set(targetId, slot);
|
|
2372
2467
|
this.wireConnection(targetId, connection);
|
|
@@ -2407,7 +2502,9 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2407
2502
|
pendingRemoteIce: [],
|
|
2408
2503
|
inFlightSync: undefined,
|
|
2409
2504
|
transport: undefined,
|
|
2410
|
-
lastDataChannelError: undefined
|
|
2505
|
+
lastDataChannelError: undefined,
|
|
2506
|
+
lastSyncHandshakeAttempt: emptySyncHandshakeAttempt(),
|
|
2507
|
+
handles: new Map
|
|
2411
2508
|
};
|
|
2412
2509
|
this.slots.set(fromPeerId, slot);
|
|
2413
2510
|
this.wireConnection(fromPeerId, connection);
|
|
@@ -2477,21 +2574,32 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2477
2574
|
connection.onconnectionstatechange = () => {
|
|
2478
2575
|
const state = connection.connectionState;
|
|
2479
2576
|
if (state === "connected") {
|
|
2480
|
-
this.
|
|
2481
|
-
peerId,
|
|
2482
|
-
peerMetadata: {}
|
|
2483
|
-
});
|
|
2577
|
+
this.emitPeerCandidateOnce(peerId);
|
|
2484
2578
|
} else if (state === "disconnected" || state === "failed" || state === "closed") {
|
|
2485
2579
|
this.slots.delete(peerId);
|
|
2486
2580
|
this.emit("peer-disconnected", { peerId });
|
|
2487
2581
|
}
|
|
2488
2582
|
};
|
|
2489
2583
|
}
|
|
2584
|
+
emitPeerCandidateOnce(peerId) {
|
|
2585
|
+
const slot = this.slots.get(peerId);
|
|
2586
|
+
if (!slot)
|
|
2587
|
+
return;
|
|
2588
|
+
if (slot.lastSyncHandshakeAttempt.peerCandidateEmittedAt !== undefined)
|
|
2589
|
+
return;
|
|
2590
|
+
slot.lastSyncHandshakeAttempt.peerCandidateEmittedAt = performance.now();
|
|
2591
|
+
this.emit("peer-candidate", {
|
|
2592
|
+
peerId,
|
|
2593
|
+
peerMetadata: {}
|
|
2594
|
+
});
|
|
2595
|
+
}
|
|
2490
2596
|
wireDataChannel(peerId, channel) {
|
|
2491
2597
|
channel.onopen = () => {
|
|
2492
2598
|
const slot = this.slots.get(peerId);
|
|
2493
2599
|
if (!slot)
|
|
2494
2600
|
return;
|
|
2601
|
+
slot.lastSyncHandshakeAttempt.dataChannelOpenedAt = performance.now();
|
|
2602
|
+
this.emitPeerCandidateOnce(peerId);
|
|
2495
2603
|
for (const bytes of slot.pendingSends) {
|
|
2496
2604
|
this.sendBytesMaybeFragmented(channel, bytes);
|
|
2497
2605
|
}
|
|
@@ -2559,6 +2667,8 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2559
2667
|
} catch {}
|
|
2560
2668
|
}
|
|
2561
2669
|
scheduleEmitMessage(fromPeerId, message, viaFragmentPath) {
|
|
2670
|
+
this.stampFirstInboundMessage(fromPeerId);
|
|
2671
|
+
this.stampHandleInbound(fromPeerId, message);
|
|
2562
2672
|
if (!this.syncYieldEnabled) {
|
|
2563
2673
|
this.emit("message", message);
|
|
2564
2674
|
if (viaFragmentPath) {
|
|
@@ -2582,6 +2692,28 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2582
2692
|
}
|
|
2583
2693
|
}, 0);
|
|
2584
2694
|
}
|
|
2695
|
+
stampFirstInboundMessage(fromPeerId) {
|
|
2696
|
+
const slot = this.slots.get(fromPeerId);
|
|
2697
|
+
if (!slot)
|
|
2698
|
+
return;
|
|
2699
|
+
if (slot.lastSyncHandshakeAttempt.firstInboundMessageAt !== undefined)
|
|
2700
|
+
return;
|
|
2701
|
+
slot.lastSyncHandshakeAttempt.firstInboundMessageAt = performance.now();
|
|
2702
|
+
}
|
|
2703
|
+
stampHandleInbound(fromPeerId, message) {
|
|
2704
|
+
const documentId = message.documentId;
|
|
2705
|
+
if (typeof documentId !== "string")
|
|
2706
|
+
return;
|
|
2707
|
+
const slot = this.slots.get(fromPeerId);
|
|
2708
|
+
if (!slot)
|
|
2709
|
+
return;
|
|
2710
|
+
let entry = slot.handles.get(documentId);
|
|
2711
|
+
if (!entry) {
|
|
2712
|
+
entry = emptyHandleSyncSnapshot();
|
|
2713
|
+
slot.handles.set(documentId, entry);
|
|
2714
|
+
}
|
|
2715
|
+
entry.lastSyncMessageInAt = performance.now();
|
|
2716
|
+
}
|
|
2585
2717
|
finishInFlightSyncApply(fromPeerId) {
|
|
2586
2718
|
const slot = this.slots.get(fromPeerId);
|
|
2587
2719
|
if (!slot?.inFlightSync)
|
|
@@ -2723,6 +2855,54 @@ async function resolveIceServers(rtc) {
|
|
|
2723
2855
|
}
|
|
2724
2856
|
return rtc?.iceServers;
|
|
2725
2857
|
}
|
|
2858
|
+
function buildHandleEntry(state, wire) {
|
|
2859
|
+
return {
|
|
2860
|
+
state,
|
|
2861
|
+
announcedToPeer: wire?.lastSyncMessageOutAt !== undefined,
|
|
2862
|
+
lastSyncMessageOutAt: wire?.lastSyncMessageOutAt,
|
|
2863
|
+
lastSyncMessageInAt: wire?.lastSyncMessageInAt,
|
|
2864
|
+
lastSyncMessageOutSize: wire?.lastSyncMessageOutSize,
|
|
2865
|
+
lastSyncMessageOutType: wire?.lastSyncMessageOutType
|
|
2866
|
+
};
|
|
2867
|
+
}
|
|
2868
|
+
function stringifyHandleState(handle) {
|
|
2869
|
+
if (handle === undefined)
|
|
2870
|
+
return "unknown";
|
|
2871
|
+
return typeof handle.state === "string" ? handle.state : String(handle.state ?? "unknown");
|
|
2872
|
+
}
|
|
2873
|
+
function enrichPeerSlot(peer, knownHandleIds, repoHandles) {
|
|
2874
|
+
if (!peer.slot) {
|
|
2875
|
+
return { ...peer, slot: undefined };
|
|
2876
|
+
}
|
|
2877
|
+
const enriched = {};
|
|
2878
|
+
for (const docId of knownHandleIds) {
|
|
2879
|
+
enriched[docId] = buildHandleEntry(stringifyHandleState(repoHandles[docId]), peer.slot.handles[docId]);
|
|
2880
|
+
}
|
|
2881
|
+
for (const docId of Object.keys(peer.slot.handles)) {
|
|
2882
|
+
if (enriched[docId])
|
|
2883
|
+
continue;
|
|
2884
|
+
enriched[docId] = buildHandleEntry("unknown", peer.slot.handles[docId]);
|
|
2885
|
+
}
|
|
2886
|
+
return { ...peer, slot: { ...peer.slot, handles: enriched } };
|
|
2887
|
+
}
|
|
2888
|
+
function getReevaluateDocumentShare(repo) {
|
|
2889
|
+
const sync = repo.synchronizer;
|
|
2890
|
+
const fn = sync?.reevaluateDocumentShare;
|
|
2891
|
+
if (typeof fn !== "function" || sync === undefined)
|
|
2892
|
+
return;
|
|
2893
|
+
return () => fn.call(sync);
|
|
2894
|
+
}
|
|
2895
|
+
function installPolly107SyncReevaluation(networkAdapter, repo) {
|
|
2896
|
+
const disable = typeof process !== "undefined" && process.env?.["POLLY_107_DISABLE_FIX"] === "1";
|
|
2897
|
+
if (disable)
|
|
2898
|
+
return;
|
|
2899
|
+
const reevaluate = getReevaluateDocumentShare(repo);
|
|
2900
|
+
if (!reevaluate)
|
|
2901
|
+
return;
|
|
2902
|
+
networkAdapter.on("peer-candidate", () => {
|
|
2903
|
+
reevaluate().catch(() => {});
|
|
2904
|
+
});
|
|
2905
|
+
}
|
|
2726
2906
|
async function createMeshClient(options) {
|
|
2727
2907
|
const keyringSource = await resolveKeyringSource(options.keyring);
|
|
2728
2908
|
const keyring = keyringSource();
|
|
@@ -2795,6 +2975,7 @@ async function createMeshClient(options) {
|
|
|
2795
2975
|
...options.repoStorage !== undefined && { storage: options.repoStorage }
|
|
2796
2976
|
});
|
|
2797
2977
|
configureMeshState(repo);
|
|
2978
|
+
installPolly107SyncReevaluation(networkAdapter, repo);
|
|
2798
2979
|
await signaling.connect();
|
|
2799
2980
|
return {
|
|
2800
2981
|
repo,
|
|
@@ -2813,10 +2994,33 @@ async function createMeshClient(options) {
|
|
|
2813
2994
|
localPeerId: options.signaling.peerId,
|
|
2814
2995
|
knownPeerIds: [],
|
|
2815
2996
|
presentPeerIds: [],
|
|
2997
|
+
sweep: {
|
|
2998
|
+
enabled: false,
|
|
2999
|
+
intervalMs: 0,
|
|
3000
|
+
runCount: 0,
|
|
3001
|
+
lastRunAt: undefined
|
|
3002
|
+
},
|
|
2816
3003
|
peers: []
|
|
2817
3004
|
};
|
|
2818
3005
|
}
|
|
2819
|
-
|
|
3006
|
+
const base = webrtcAdapter.getPeerStateSnapshot();
|
|
3007
|
+
const repoHandles = repo.handles;
|
|
3008
|
+
const knownHandleIds = Object.keys(repoHandles);
|
|
3009
|
+
const enrichedPeers = base.peers.map((peer) => enrichPeerSlot(peer, knownHandleIds, repoHandles));
|
|
3010
|
+
const out = {
|
|
3011
|
+
localPeerId: base.localPeerId,
|
|
3012
|
+
knownPeerIds: base.knownPeerIds,
|
|
3013
|
+
presentPeerIds: base.presentPeerIds,
|
|
3014
|
+
sweep: base.sweep,
|
|
3015
|
+
peers: enrichedPeers
|
|
3016
|
+
};
|
|
3017
|
+
return out;
|
|
3018
|
+
},
|
|
3019
|
+
reevaluateAllSync: async () => {
|
|
3020
|
+
const reevaluate = getReevaluateDocumentShare(repo);
|
|
3021
|
+
if (!reevaluate)
|
|
3022
|
+
return;
|
|
3023
|
+
await reevaluate();
|
|
2820
3024
|
},
|
|
2821
3025
|
refreshTransportStats: async () => {
|
|
2822
3026
|
if (!webrtcAdapter)
|
|
@@ -3237,4 +3441,4 @@ export {
|
|
|
3237
3441
|
$meshCounter
|
|
3238
3442
|
};
|
|
3239
3443
|
|
|
3240
|
-
//# debugId=
|
|
3444
|
+
//# debugId=DAB92455464EE0D864756E2164756E21
|