@vrtmrz/livesync-commonlib 0.3.2 → 0.4.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/README.md +17 -0
- package/dist/managers/EntryManager/EntryManagerImpls.js +1 -1
- package/dist/p2p/P2PService.d.ts +10 -1
- package/dist/p2p/P2PService.js +25 -2
- package/dist/p2p/index.d.ts +4 -1
- package/dist/p2p/index.js +2 -0
- package/dist/p2p/p2pDiagnostics.d.ts +35 -0
- package/dist/p2p/p2pDiagnostics.js +76 -0
- package/dist/pouchdb/ReplicatorShim.batch.d.ts +30 -0
- package/dist/pouchdb/ReplicatorShim.batch.js +62 -0
- package/dist/pouchdb/ReplicatorShim.d.ts +14 -1
- package/dist/pouchdb/ReplicatorShim.js +64 -80
- package/dist/replication/trystero/P2PLogCollector.d.ts +12 -0
- package/dist/replication/trystero/P2PLogCollector.js +107 -72
- package/dist/replication/trystero/P2PRoomSessionOwner.d.ts +4 -0
- package/dist/replication/trystero/P2PRoomSessionOwner.js +39 -2
- package/dist/replication/trystero/TrysteroReplicator.d.ts +21 -24
- package/dist/replication/trystero/TrysteroReplicator.js +191 -69
- package/dist/replication/trystero/TrysteroReplicatorP2PServer.js +11 -0
- package/dist/replication/trystero/p2pReplicationDiagnostics.d.ts +9 -0
- package/dist/replication/trystero/p2pReplicationDiagnostics.js +51 -0
- package/dist/replication/trystero/p2pReplicationProgress.d.ts +15 -0
- package/dist/replication/trystero/p2pReplicationProgress.js +37 -0
- package/dist/replication/trystero/types.d.ts +3 -0
- package/dist/services/base/APIService.d.ts +10 -0
- package/dist/services/base/APIService.js +13 -0
- package/dist/services/base/IService.d.ts +2 -0
- package/docs/journal-receive-recovery.md +7 -4
- package/docs/p2p-transport-lifecycle.md +117 -10
- package/docs/releasing.md +6 -0
- package/package.json +2 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EVENT_PLATFORM_UNLOADED } from "../../events/coreEvents.js";
|
|
1
2
|
import { reactiveSource } from "octagonal-wheels/dataobject/reactive_v2";
|
|
2
3
|
import {
|
|
3
4
|
EVENT_ADVERTISEMENT_RECEIVED,
|
|
@@ -6,83 +7,117 @@ import {
|
|
|
6
7
|
EVENT_DEVICE_LEAVED,
|
|
7
8
|
EVENT_P2P_REPLICATOR_PROGRESS
|
|
8
9
|
} from "./TrysteroReplicatorP2PServer.js";
|
|
10
|
+
function initialProgress(peerId, peerName) {
|
|
11
|
+
return {
|
|
12
|
+
peerId,
|
|
13
|
+
peerName,
|
|
14
|
+
fetching: { current: 0, max: 0, isActive: false },
|
|
15
|
+
sending: { current: 0, max: 0, isActive: false }
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function applyReport(previous, report) {
|
|
19
|
+
if ("fetching" in report) {
|
|
20
|
+
if (report.fetching.isActive || report.fetching.statistics) {
|
|
21
|
+
previous.fetching = report.fetching;
|
|
22
|
+
} else {
|
|
23
|
+
previous.fetching.isActive = false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if ("sending" in report) {
|
|
27
|
+
if (report.sending.isActive || report.sending.statistics) {
|
|
28
|
+
previous.sending = report.sending;
|
|
29
|
+
} else {
|
|
30
|
+
previous.sending.isActive = false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function snapshotProgress(progress) {
|
|
35
|
+
const snapshotDirection = (direction) => Object.freeze({
|
|
36
|
+
...direction,
|
|
37
|
+
...direction.statistics ? { statistics: Object.freeze({ ...direction.statistics }) } : {}
|
|
38
|
+
});
|
|
39
|
+
return Object.freeze({
|
|
40
|
+
...progress,
|
|
41
|
+
fetching: snapshotDirection(progress.fetching),
|
|
42
|
+
sending: snapshotDirection(progress.sending)
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function renderProgressLine(progresses) {
|
|
46
|
+
const sortedProgresses = [...progresses].sort((a, b) => a.peerId.localeCompare(b.peerId));
|
|
47
|
+
const renderCount = (current, max) => {
|
|
48
|
+
if (current == max) {
|
|
49
|
+
return `${current}`;
|
|
50
|
+
}
|
|
51
|
+
return `${current} (${max})`;
|
|
52
|
+
};
|
|
53
|
+
return sortedProgresses.map(
|
|
54
|
+
(peer) => `${peer.fetching.isActive || peer.sending.isActive ? "\u26A1" : "\u{1F4A4}"} ${peer.peerName} \u2191 ${renderCount(peer.sending.current, peer.sending.max)} \u2193 ${renderCount(peer.fetching.current, peer.fetching.max)} `
|
|
55
|
+
).join("\n");
|
|
56
|
+
}
|
|
9
57
|
class P2PLogCollector {
|
|
58
|
+
eventController = new AbortController();
|
|
59
|
+
statisticsSource = reactiveSource(Object.freeze([]));
|
|
60
|
+
p2pReplicationStats = this.statisticsSource;
|
|
10
61
|
constructor(events) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
prev.sending.isActive = false;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
this.p2pReplicationResult.set(data.peerId, prev);
|
|
70
|
-
this.updateP2PReplicationLine();
|
|
71
|
-
});
|
|
62
|
+
const options = { signal: this.eventController.signal };
|
|
63
|
+
events.onEvent(EVENT_ADVERTISEMENT_RECEIVED, (data) => this.handleAdvertisementReceived(data), options);
|
|
64
|
+
events.onEvent(EVENT_P2P_CONNECTED, () => this.resetPeerState(), options);
|
|
65
|
+
events.onEvent(EVENT_P2P_DISCONNECTED, () => this.resetPeerState(), options);
|
|
66
|
+
events.onEvent(EVENT_DEVICE_LEAVED, (peerId) => this.handleDeviceLeaved(peerId), options);
|
|
67
|
+
events.onEvent(EVENT_P2P_REPLICATOR_PROGRESS, (data) => this.handleReplicationProgress(data), options);
|
|
68
|
+
events.onEvent(EVENT_PLATFORM_UNLOADED, () => this.dispose(), options);
|
|
69
|
+
}
|
|
70
|
+
handleAdvertisementReceived(data) {
|
|
71
|
+
this.p2pReplicationResult.set(data.peerId, initialProgress(data.peerId, data.name));
|
|
72
|
+
this.updateP2PReplicationLine();
|
|
73
|
+
const statistics = this.statisticsFor(data.peerId, data.name);
|
|
74
|
+
statistics.peerName = data.name;
|
|
75
|
+
this.publishStatistics(statistics);
|
|
76
|
+
}
|
|
77
|
+
resetPeerState() {
|
|
78
|
+
this.p2pReplicationResult.clear();
|
|
79
|
+
this.updateP2PReplicationLine();
|
|
80
|
+
this.statisticsSource.value = Object.freeze([]);
|
|
81
|
+
}
|
|
82
|
+
handleDeviceLeaved(peerId) {
|
|
83
|
+
this.p2pReplicationResult.delete(peerId);
|
|
84
|
+
this.updateP2PReplicationLine();
|
|
85
|
+
this.statisticsSource.value = Object.freeze(
|
|
86
|
+
this.statisticsSource.value.filter((peer) => peer.peerId !== peerId)
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
handleReplicationProgress(data) {
|
|
90
|
+
const previous = this.p2pReplicationResult.get(data.peerId) ?? initialProgress(data.peerId, data.peerName);
|
|
91
|
+
applyReport(previous, data);
|
|
92
|
+
this.p2pReplicationResult.set(data.peerId, previous);
|
|
93
|
+
this.updateP2PReplicationLine();
|
|
94
|
+
const statistics = this.statisticsFor(data.peerId, data.peerName);
|
|
95
|
+
applyReport(statistics, data);
|
|
96
|
+
this.publishStatistics(statistics);
|
|
97
|
+
}
|
|
98
|
+
statisticsFor(peerId, peerName) {
|
|
99
|
+
const previous = this.statisticsSource.value.find((peer) => peer.peerId === peerId);
|
|
100
|
+
return previous ? {
|
|
101
|
+
...previous,
|
|
102
|
+
fetching: { ...previous.fetching },
|
|
103
|
+
sending: { ...previous.sending }
|
|
104
|
+
} : initialProgress(peerId, peerName);
|
|
105
|
+
}
|
|
106
|
+
publishStatistics(progress) {
|
|
107
|
+
const snapshot = snapshotProgress(progress);
|
|
108
|
+
this.statisticsSource.value = Object.freeze(
|
|
109
|
+
[...this.statisticsSource.value.filter((peer) => peer.peerId !== progress.peerId), snapshot].sort(
|
|
110
|
+
(a, b) => a.peerId.localeCompare(b.peerId)
|
|
111
|
+
)
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
/** Release this collector's event registrations without affecting another consumer. */
|
|
115
|
+
dispose() {
|
|
116
|
+
this.eventController.abort();
|
|
72
117
|
}
|
|
73
118
|
p2pReplicationResult = /* @__PURE__ */ new Map();
|
|
74
119
|
updateP2PReplicationLine() {
|
|
75
|
-
|
|
76
|
-
(a, b) => a.peerId.localeCompare(b.peerId)
|
|
77
|
-
);
|
|
78
|
-
const renderProgress = (current, max) => {
|
|
79
|
-
if (current == max) return `${current}`;
|
|
80
|
-
return `${current} (${max})`;
|
|
81
|
-
};
|
|
82
|
-
const line = p2pReplicationResultX.map(
|
|
83
|
-
(e) => `${e.fetching.isActive || e.sending.isActive ? "\u26A1" : "\u{1F4A4}"} ${e.peerName} \u2191 ${renderProgress(e.sending.current, e.sending.max)} \u2193 ${renderProgress(e.fetching.current, e.fetching.max)} `
|
|
84
|
-
).join("\n");
|
|
85
|
-
this.p2pReplicationLine.value = line;
|
|
120
|
+
this.p2pReplicationLine.value = renderProgressLine(this.p2pReplicationResult.values());
|
|
86
121
|
}
|
|
87
122
|
p2pReplicationLine = reactiveSource("");
|
|
88
123
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type P2PDiagnosticReporter } from "../../p2p/p2pDiagnostics.js";
|
|
1
2
|
import { type P2PSyncSetting } from "../../common/types.js";
|
|
2
3
|
import type { LiveSyncReplicatorEnv } from "../LiveSyncAbstractReplicator.js";
|
|
3
4
|
import { P2PRoomSession } from "./P2PRoomSession.js";
|
|
@@ -8,6 +9,7 @@ type P2PRoomSessionFactory = (env: ReplicatorHostEnv) => P2PRoomSession;
|
|
|
8
9
|
export type PrepareP2PSettings = (settings: Readonly<P2PSyncSetting>, signal: AbortSignal) => Promise<P2PSyncSetting>;
|
|
9
10
|
export interface P2PRoomSessionOwnerOptions {
|
|
10
11
|
readonly prepareP2PSettings?: PrepareP2PSettings;
|
|
12
|
+
readonly onDiagnosticEvent?: P2PDiagnosticReporter;
|
|
11
13
|
}
|
|
12
14
|
export declare const P2P_SETTINGS_PREPARATION_TIMEOUT_MS = 30000;
|
|
13
15
|
export declare const P2P_ICE_SERVER_EXPIRY_MARGIN_MS = 30000;
|
|
@@ -39,6 +41,7 @@ export declare class P2PRoomSessionOwner implements P2PRoomSessionAccess {
|
|
|
39
41
|
private activeBinding?;
|
|
40
42
|
private pendingPreparation?;
|
|
41
43
|
private runtimeGeneration;
|
|
44
|
+
private diagnosticGeneration;
|
|
42
45
|
constructor(env: LiveSyncReplicatorEnv, createSession?: P2PRoomSessionFactory, options?: P2PRoomSessionOwnerOptions);
|
|
43
46
|
get currentSession(): P2PRoomSession | undefined;
|
|
44
47
|
get isConnected(): boolean;
|
|
@@ -62,6 +65,7 @@ export declare class P2PRoomSessionOwner implements P2PRoomSessionAccess {
|
|
|
62
65
|
private hasRoomDemand;
|
|
63
66
|
private enqueueLifecycleOperation;
|
|
64
67
|
private closeTransport;
|
|
68
|
+
private reportDiagnostic;
|
|
65
69
|
private bindingsMatch;
|
|
66
70
|
private connectionSettingsRemainUsable;
|
|
67
71
|
private fencePreparationForCurrentSettings;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { reportP2PDiagnostic } from "../../p2p/p2pDiagnostics.js";
|
|
1
2
|
import { Logger } from "../../common/logger.js";
|
|
2
3
|
import {
|
|
3
4
|
LOG_LEVEL_NOTICE,
|
|
@@ -39,6 +40,7 @@ class P2PRoomSessionOwner {
|
|
|
39
40
|
activeBinding;
|
|
40
41
|
pendingPreparation;
|
|
41
42
|
runtimeGeneration = 0;
|
|
43
|
+
diagnosticGeneration = 0;
|
|
42
44
|
get currentSession() {
|
|
43
45
|
return this.current;
|
|
44
46
|
}
|
|
@@ -105,7 +107,9 @@ class P2PRoomSessionOwner {
|
|
|
105
107
|
/** Arbitrate a complete signalling probe on the room lifecycle queue. */
|
|
106
108
|
runConnectionProbe(trialSettings, runOwnedTrial) {
|
|
107
109
|
try {
|
|
108
|
-
assertSupportedPathNormalizationVersion(
|
|
110
|
+
assertSupportedPathNormalizationVersion(
|
|
111
|
+
this.env.services.setting.currentSettings().pathNormalizationVersion
|
|
112
|
+
);
|
|
109
113
|
} catch (error) {
|
|
110
114
|
return Promise.reject(error);
|
|
111
115
|
}
|
|
@@ -154,6 +158,7 @@ class P2PRoomSessionOwner {
|
|
|
154
158
|
}
|
|
155
159
|
let candidate;
|
|
156
160
|
const operationGeneration = this.runtimeGeneration;
|
|
161
|
+
this.reportDiagnostic({ category: "relay", code: "room-opening", reason: "relay-details-unobserved" });
|
|
157
162
|
try {
|
|
158
163
|
const connectionSettings = await this.prepareConnectionSettings(binding, operationGeneration);
|
|
159
164
|
await this.assertReconciliationCurrent(binding, operationGeneration, connectionSettings);
|
|
@@ -169,13 +174,21 @@ class P2PRoomSessionOwner {
|
|
|
169
174
|
}
|
|
170
175
|
const currentBinding = await this.getEffectiveBinding();
|
|
171
176
|
if (!currentBinding.enabled || !this.hasRoomDemand() || !this.bindingsMatch(binding, currentBinding) || operationGeneration !== this.runtimeGeneration || !this.connectionSettingsRemainUsable(connectionSettings)) {
|
|
177
|
+
this.diagnosticGeneration += 1;
|
|
172
178
|
await candidate.retire();
|
|
179
|
+
this.reportDiagnostic({
|
|
180
|
+
category: "relay",
|
|
181
|
+
code: "room-open-cancelled",
|
|
182
|
+
reason: "operation-cancelled"
|
|
183
|
+
});
|
|
173
184
|
return;
|
|
174
185
|
}
|
|
175
186
|
this.current = candidate;
|
|
176
187
|
this.activeBinding = connectionBinding;
|
|
177
188
|
this.reconcileCurrentSessionPolicy(candidate);
|
|
189
|
+
this.reportDiagnostic({ category: "relay", code: "room-opened", reason: "relay-details-unobserved" });
|
|
178
190
|
} catch (error) {
|
|
191
|
+
this.diagnosticGeneration += 1;
|
|
179
192
|
await candidate?.retire(error).catch((retirementError) => {
|
|
180
193
|
if (hasManagedP2PTurnConfiguration(binding.settings)) {
|
|
181
194
|
Logger("The managed P2P room could not be retired cleanly.", LOG_LEVEL_VERBOSE);
|
|
@@ -186,8 +199,14 @@ class P2PRoomSessionOwner {
|
|
|
186
199
|
this.current = void 0;
|
|
187
200
|
this.activeBinding = void 0;
|
|
188
201
|
if (error instanceof StaleRoomReconciliationError || operationGeneration !== this.runtimeGeneration) {
|
|
202
|
+
this.reportDiagnostic({
|
|
203
|
+
category: "relay",
|
|
204
|
+
code: "room-open-cancelled",
|
|
205
|
+
reason: "operation-cancelled"
|
|
206
|
+
});
|
|
189
207
|
return;
|
|
190
208
|
}
|
|
209
|
+
this.reportDiagnostic({ category: "relay", code: "room-open-failed", reason: "transport-error" });
|
|
191
210
|
if (hasManagedP2PTurnConfiguration(binding.settings)) {
|
|
192
211
|
Logger("The managed P2P room could not be prepared or opened.", LOG_LEVEL_NOTICE);
|
|
193
212
|
Logger("Managed P2P room failure details were omitted.", LOG_LEVEL_VERBOSE);
|
|
@@ -222,9 +241,19 @@ class P2PRoomSessionOwner {
|
|
|
222
241
|
this.current = void 0;
|
|
223
242
|
this.activeBinding = void 0;
|
|
224
243
|
if (session) {
|
|
225
|
-
|
|
244
|
+
this.diagnosticGeneration += 1;
|
|
245
|
+
try {
|
|
246
|
+
await session.retire();
|
|
247
|
+
this.reportDiagnostic({ category: "relay", code: "room-closed", reason: "relay-details-unobserved" });
|
|
248
|
+
} catch (error) {
|
|
249
|
+
this.reportDiagnostic({ category: "relay", code: "room-close-failed", reason: "transport-error" });
|
|
250
|
+
throw error;
|
|
251
|
+
}
|
|
226
252
|
}
|
|
227
253
|
}
|
|
254
|
+
reportDiagnostic(input) {
|
|
255
|
+
reportP2PDiagnostic(this.options.onDiagnosticEvent, input);
|
|
256
|
+
}
|
|
228
257
|
bindingsMatch(current, candidate) {
|
|
229
258
|
return current?.database === candidate.database && current.signature === candidate.signature;
|
|
230
259
|
}
|
|
@@ -413,7 +442,15 @@ class P2PRoomSessionOwner {
|
|
|
413
442
|
}
|
|
414
443
|
buildSessionEnv(binding) {
|
|
415
444
|
const services = this.env.services;
|
|
445
|
+
const diagnosticGeneration = ++this.diagnosticGeneration;
|
|
416
446
|
return {
|
|
447
|
+
reportDiagnostic: (event) => {
|
|
448
|
+
if (diagnosticGeneration !== this.diagnosticGeneration) return;
|
|
449
|
+
try {
|
|
450
|
+
this.options.onDiagnosticEvent?.(event);
|
|
451
|
+
} catch {
|
|
452
|
+
}
|
|
453
|
+
},
|
|
417
454
|
events: services.context.events,
|
|
418
455
|
translate: services.context.translate,
|
|
419
456
|
settings: binding.settings,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { type ProgressAcknowledgement } from "./p2pReplicationProgress.js";
|
|
1
2
|
import { type EntryDoc, type ObsidianLiveSyncSettings, type P2PSyncSetting } from "../../common/types.js";
|
|
2
3
|
import { type LOG_LEVEL } from "octagonal-wheels/common/logger";
|
|
3
|
-
import { type ProgressInfo } from "../../pouchdb/ReplicatorShim.js";
|
|
4
|
+
import { type ProgressInfo, type ReplicationStatistics } from "../../pouchdb/ReplicatorShim.js";
|
|
4
5
|
import type { Confirm } from "../../interfaces/Confirm.js";
|
|
5
6
|
import { type Advertisement, type ReplicatorHostEnv } from "./types.js";
|
|
6
7
|
import { EVENT_P2P_REPLICATOR_PROGRESS, EVENT_P2P_REPLICATOR_STATUS, P2PHost } from "./TrysteroReplicatorP2PServer.js";
|
|
@@ -12,35 +13,26 @@ export type P2PReplicatorStatus = {
|
|
|
12
13
|
replicatingFrom: string[];
|
|
13
14
|
watchingPeers: string[];
|
|
14
15
|
};
|
|
16
|
+
/** Sequence progress retained for compatibility, with independently observed work counts. */
|
|
17
|
+
export type P2PReplicationDirectionProgress = {
|
|
18
|
+
max: number;
|
|
19
|
+
current: number;
|
|
20
|
+
isActive: boolean;
|
|
21
|
+
statistics?: ReplicationStatistics;
|
|
22
|
+
};
|
|
15
23
|
export type P2PReplicationProgress = {
|
|
16
24
|
peerId: string;
|
|
17
25
|
peerName: string;
|
|
18
|
-
fetching:
|
|
19
|
-
|
|
20
|
-
current: number;
|
|
21
|
-
isActive: boolean;
|
|
22
|
-
};
|
|
23
|
-
sending: {
|
|
24
|
-
max: number;
|
|
25
|
-
current: number;
|
|
26
|
-
isActive: boolean;
|
|
27
|
-
};
|
|
26
|
+
fetching: P2PReplicationDirectionProgress;
|
|
27
|
+
sending: P2PReplicationDirectionProgress;
|
|
28
28
|
};
|
|
29
29
|
export type P2PReplicationReport = {
|
|
30
30
|
peerId: string;
|
|
31
31
|
peerName: string;
|
|
32
32
|
} & ({
|
|
33
|
-
fetching:
|
|
34
|
-
max: number;
|
|
35
|
-
current: number;
|
|
36
|
-
isActive: boolean;
|
|
37
|
-
};
|
|
33
|
+
fetching: P2PReplicationDirectionProgress;
|
|
38
34
|
} | {
|
|
39
|
-
sending:
|
|
40
|
-
max: number;
|
|
41
|
-
current: number;
|
|
42
|
-
isActive: boolean;
|
|
43
|
-
};
|
|
35
|
+
sending: P2PReplicationDirectionProgress;
|
|
44
36
|
});
|
|
45
37
|
/**
|
|
46
38
|
* In-process outcome of one P2P replication request.
|
|
@@ -112,9 +104,11 @@ export declare class TrysteroReplicator {
|
|
|
112
104
|
_env: ReplicatorHostEnv;
|
|
113
105
|
private readonly finiteOperationOwner?;
|
|
114
106
|
private disposed;
|
|
107
|
+
private readonly acknowledgedAttempts;
|
|
115
108
|
private readonly fallbackAutomationCoordinator;
|
|
116
109
|
server?: P2PHost;
|
|
117
110
|
replicationStatus(): {};
|
|
111
|
+
private reportDiagnostic;
|
|
118
112
|
get settings(): P2PSyncSetting;
|
|
119
113
|
/** Latest room-local policy settings supplied by the owning host. */
|
|
120
114
|
get currentSettings(): P2PSyncSetting;
|
|
@@ -136,6 +130,7 @@ export declare class TrysteroReplicator {
|
|
|
136
130
|
get autoSyncPeers(): RegExp[];
|
|
137
131
|
get autoWatchPeers(): RegExp[];
|
|
138
132
|
onNewPeer(peer: Advertisement): Promise<void>;
|
|
133
|
+
private watchBroadcastingPeer;
|
|
139
134
|
onPeerLeaved(peerId: string): void;
|
|
140
135
|
_onSetup: boolean;
|
|
141
136
|
setOnSetup(): void;
|
|
@@ -524,7 +519,7 @@ export declare class TrysteroReplicator {
|
|
|
524
519
|
getAllConfig: (fromPeerId: string) => Promise<string | {
|
|
525
520
|
error: import("../../rpc/types.js").RpcErrorShape;
|
|
526
521
|
}>;
|
|
527
|
-
onProgressAcknowledged: (fromPeerId: string, info
|
|
522
|
+
onProgressAcknowledged: (fromPeerId: string, info?: ProgressInfo | null, acknowledgement?: ProgressAcknowledgement) => Promise<void>;
|
|
528
523
|
getIsBroadcasting: () => Promise<boolean>;
|
|
529
524
|
requestBroadcasting: (peerId: string) => Promise<true | {
|
|
530
525
|
error: import("../../rpc/types.js").RpcErrorShape;
|
|
@@ -551,13 +546,15 @@ export declare class TrysteroReplicator {
|
|
|
551
546
|
_replicateFromPeers: Set<string>;
|
|
552
547
|
dispatchReplicationProgress(peerId: string, info?: ProgressInfo): void;
|
|
553
548
|
onReplicationProgress(peerId: string, info?: ProgressInfo): boolean;
|
|
554
|
-
onProgressAcknowledged(peerId: string, info?: ProgressInfo): boolean;
|
|
555
|
-
acknowledgeProgress(remotePeerId: string, info?: ProgressInfo): void;
|
|
549
|
+
onProgressAcknowledged(peerId: string, info?: ProgressInfo | null, acknowledgement?: ProgressAcknowledgement): boolean;
|
|
550
|
+
acknowledgeProgress(remotePeerId: string, info?: ProgressInfo, acknowledgement?: ProgressAcknowledgement): void;
|
|
556
551
|
replicateFrom(remotePeer: string, showNotice?: boolean, fromStart?: boolean, skipOrdinaryReplicationPolicy?: boolean, callerSignal?: AbortSignal): Promise<P2PReplicationResult>;
|
|
557
552
|
private replicateFromWithinSession;
|
|
553
|
+
private pullFromWithinSession;
|
|
558
554
|
private checkPeerForReplication;
|
|
559
555
|
private transferFromPeer;
|
|
560
556
|
notifyProgress(excludePeerId?: string): Promise<void>;
|
|
557
|
+
private notifyPeerProgress;
|
|
561
558
|
requestBroadcastChanges(peerId: string): Promise<unknown>;
|
|
562
559
|
getRemoteIsBroadcasting(peerId: string): Promise<unknown>;
|
|
563
560
|
_watchingPeers: Set<string>;
|