@vrtmrz/livesync-commonlib 0.1.0-rc.0 → 0.1.0-rc.10
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 +101 -17
- package/dist/API/DirectFileManipulatorV2.d.ts +3 -0
- package/dist/common/configForDoc.d.ts +1 -0
- package/dist/common/configForDoc.js +24 -7
- package/dist/common/models/setting.const.defaults.d.ts +19 -0
- package/dist/common/models/setting.const.defaults.js +21 -2
- package/dist/common/models/setting.const.preferred.js +1 -2
- package/dist/common/models/setting.lifecycle.d.ts +33 -0
- package/dist/common/models/setting.lifecycle.js +121 -0
- package/dist/common/models/setting.type.d.ts +10 -4
- package/dist/common/models/shared.definition.configNames.js +3 -3
- package/dist/common/models/tweak.definition.d.ts +1 -1
- package/dist/common/models/tweak.definition.js +1 -6
- package/dist/common/settingConstants.d.ts +3 -2
- package/dist/common/settingConstants.js +6 -6
- package/dist/common/types.d.ts +4 -2
- package/dist/common/types.js +16 -1
- package/dist/context.d.ts +3 -1
- package/dist/context.js +4 -0
- package/dist/interfaces/Confirm.d.ts +10 -2
- package/dist/interfaces/DatabaseFileAccess.d.ts +8 -0
- package/dist/interfaces/DatabaseRebuilder.d.ts +12 -2
- package/dist/interfaces/FileReflectionProvenance.d.ts +32 -0
- package/dist/interfaces/FileReflectionProvenance.js +25 -0
- package/dist/managers/ConflictManager.js +16 -7
- package/dist/managers/EntryManager/EntryManager.d.ts +1 -0
- package/dist/managers/EntryManager/EntryManager.js +5 -1
- package/dist/managers/EntryManager/EntryManagerImpls.d.ts +1 -0
- package/dist/managers/EntryManager/EntryManagerImpls.js +29 -1
- package/dist/platform/node/index.d.ts +1 -0
- package/dist/platform/node/index.js +4 -0
- package/dist/platform/node/standardIo.d.ts +24 -0
- package/dist/platform/node/standardIo.js +39 -0
- package/dist/platform/node/storage.d.ts +10 -1
- package/dist/platform/node/storage.js +86 -25
- package/dist/platform/standardIo.d.ts +19 -0
- package/dist/platform/standardIo.js +0 -0
- package/dist/pouchdb/LiveSyncLocalDB.d.ts +1 -0
- package/dist/pouchdb/LiveSyncLocalDB.js +3 -0
- package/dist/remoteConfigurations.d.ts +9 -0
- package/dist/remoteConfigurations.js +14 -0
- package/dist/replication/LiveSyncAbstractReplicator.d.ts +3 -3
- package/dist/replication/couchdb/LiveSyncReplicator.d.ts +0 -1
- package/dist/replication/couchdb/LiveSyncReplicator.js +0 -3
- package/dist/replication/journal/LiveSyncJournalReplicator.d.ts +0 -1
- package/dist/replication/journal/LiveSyncJournalReplicator.js +0 -3
- package/dist/replication/trystero/LiveSyncTrysteroReplicator.d.ts +5 -3
- package/dist/replication/trystero/LiveSyncTrysteroReplicator.js +42 -30
- package/dist/replication/trystero/P2PReplicatorCore.d.ts +2 -6
- package/dist/replication/trystero/P2PReplicatorCore.js +16 -86
- package/dist/replication/trystero/TrysteroReplicator.d.ts +2 -1
- package/dist/replication/trystero/TrysteroReplicator.js +10 -4
- package/dist/replication/trystero/TrysteroReplicatorP2PServer.d.ts +4 -5
- package/dist/replication/trystero/TrysteroReplicatorP2PServer.js +22 -30
- package/dist/replication/trystero/UseP2PReplicatorResult.d.ts +10 -2
- package/dist/replication/trystero/addP2PEventHandlers.d.ts +4 -2
- package/dist/replication/trystero/addP2PEventHandlers.js +9 -10
- package/dist/replication/trystero/types.d.ts +2 -0
- package/dist/replication/trystero/useP2PReplicatorCommands.d.ts +1 -1
- package/dist/replication/trystero/useP2PReplicatorCommands.js +3 -1
- package/dist/replication/trystero/useP2PReplicatorFeature.js +25 -15
- package/dist/rpc/RpcRoom.d.ts +1 -1
- package/dist/rpc/RpcRoom.js +22 -16
- package/dist/rpc/transports/TrysteroTransport.d.ts +2 -0
- package/dist/rpc/transports/TrysteroTransport.js +24 -17
- package/dist/rpc/transports/trysteroRoomEvents.d.ts +14 -0
- package/dist/rpc/transports/trysteroRoomEvents.js +34 -0
- package/dist/serviceFeatures/checkRemoteSize.d.ts +5 -3
- package/dist/serviceFeatures/checkRemoteSize.js +51 -11
- package/dist/serviceFeatures/remoteConfig.d.ts +37 -1
- package/dist/serviceFeatures/remoteConfig.js +90 -0
- package/dist/serviceModules/Rebuilder.d.ts +3 -6
- package/dist/serviceModules/Rebuilder.js +31 -22
- package/dist/serviceModules/ServiceDatabaseFileAccessBase.d.ts +5 -0
- package/dist/serviceModules/ServiceDatabaseFileAccessBase.js +69 -13
- package/dist/serviceModules/ServiceFileHandlerBase.d.ts +20 -0
- package/dist/serviceModules/ServiceFileHandlerBase.js +224 -40
- package/dist/services/BrowserServices.d.ts +2 -0
- package/dist/services/BrowserServices.js +4 -1
- package/dist/services/HeadlessServices.d.ts +2 -0
- package/dist/services/HeadlessServices.js +2 -1
- package/dist/services/base/CommonlibMessages.d.ts +318 -0
- package/dist/services/base/CommonlibMessages.js +313 -0
- package/dist/services/base/IService.d.ts +13 -6
- package/dist/services/base/KeyValueDBService.d.ts +1 -1
- package/dist/services/base/KeyValueDBService.js +3 -1
- package/dist/services/base/MessageTranslator.d.ts +5 -2
- package/dist/services/base/MessageTranslator.js +21 -0
- package/dist/services/base/ReplicationService.d.ts +4 -2
- package/dist/services/base/ReplicationService.js +11 -16
- package/dist/services/base/ServiceBase.d.ts +1 -1
- package/dist/services/base/ServiceBase.js +2 -4
- package/dist/services/base/SettingService.d.ts +17 -9
- package/dist/services/base/SettingService.js +38 -19
- package/dist/services/implements/headless/HeadlessAPIService.d.ts +3 -3
- package/dist/services/implements/headless/HeadlessAPIService.js +2 -2
- package/dist/services/implements/injectable/InjectableTweakValueService.d.ts +3 -3
- package/dist/settings.d.ts +10 -0
- package/dist/settings.js +32 -0
- package/dist/worker/bgWorker.js +1 -1
- package/docs/conflict-resolution.md +153 -0
- package/docs/development.md +108 -8
- package/docs/p2p-transport-lifecycle.md +62 -0
- package/docs/platform-standard-io.md +44 -0
- package/docs/platform-storage.md +4 -0
- package/docs/proven-in-use.md +65 -0
- package/docs/releasing.md +26 -6
- package/docs/remote-configurations.md +63 -0
- package/docs/settings-lifecycle.md +85 -0
- package/package.json +17 -27
- package/dist/common/i18n.d.ts +0 -18
- package/dist/common/i18n.js +0 -7193
- package/dist/common/messages/combinedMessages.dev.d.ts +0 -7
- package/dist/common/messages/combinedMessages.dev.js +0 -44
- package/dist/common/messages/combinedMessages.prod.d.ts +0 -9264
- package/dist/common/messages/combinedMessages.prod.js +0 -9271
- package/dist/common/messages/de.d.ts +0 -297
- package/dist/common/messages/de.js +0 -7
- package/dist/common/messages/def.d.ts +0 -1119
- package/dist/common/messages/def.js +0 -7
- package/dist/common/messages/es.d.ts +0 -689
- package/dist/common/messages/es.js +0 -7
- package/dist/common/messages/fr.d.ts +0 -582
- package/dist/common/messages/fr.js +0 -7
- package/dist/common/messages/he.d.ts +0 -583
- package/dist/common/messages/he.js +0 -7
- package/dist/common/messages/ja.d.ts +0 -838
- package/dist/common/messages/ja.js +0 -7
- package/dist/common/messages/ko.d.ts +0 -800
- package/dist/common/messages/ko.js +0 -7
- package/dist/common/messages/ru.d.ts +0 -858
- package/dist/common/messages/ru.js +0 -7
- package/dist/common/messages/zh-tw.d.ts +0 -384
- package/dist/common/messages/zh-tw.js +0 -7
- package/dist/common/messages/zh.d.ts +0 -1093
- package/dist/common/messages/zh.js +0 -7
- package/dist/common/messagesJson/de.json +0 -295
- package/dist/common/messagesJson/en.json +0 -1117
- package/dist/common/messagesJson/es.json +0 -687
- package/dist/common/messagesJson/fr.json +0 -580
- package/dist/common/messagesJson/he.json +0 -581
- package/dist/common/messagesJson/ja.json +0 -836
- package/dist/common/messagesJson/ko.json +0 -798
- package/dist/common/messagesJson/ru.json +0 -856
- package/dist/common/messagesJson/zh-tw.json +0 -382
- package/dist/common/messagesJson/zh.json +0 -1091
- package/dist/common/rosetta.d.ts +0 -42
- package/dist/common/rosetta.js +0 -57
|
@@ -1,16 +1,40 @@
|
|
|
1
|
+
import { constants as nodeFsConstants } from "node:fs";
|
|
1
2
|
import * as nodeFsPromises from "node:fs/promises";
|
|
2
3
|
import * as nodePath from "node:path";
|
|
3
4
|
import { validateStoragePath } from "../storagePath.js";
|
|
5
|
+
const NO_FOLLOW = nodeFsConstants.O_NOFOLLOW ?? 0;
|
|
6
|
+
class SymbolicLinkStoragePathError extends Error {
|
|
7
|
+
constructor(path) {
|
|
8
|
+
super(`Storage paths must not contain symbolic links: ${path}`);
|
|
9
|
+
this.name = "SymbolicLinkStoragePathError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
4
12
|
class NodeStorageAdapter {
|
|
13
|
+
rootPath;
|
|
5
14
|
constructor(rootPath) {
|
|
6
|
-
this.rootPath = rootPath;
|
|
15
|
+
this.rootPath = nodePath.resolve(rootPath);
|
|
7
16
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
17
|
+
async resolvePath(path, allowRoot = true) {
|
|
18
|
+
const fullPath = nodePath.join(this.rootPath, validateStoragePath(path, allowRoot));
|
|
19
|
+
await this.assertNoSymbolicLinks(fullPath);
|
|
20
|
+
return fullPath;
|
|
21
|
+
}
|
|
22
|
+
async assertNoSymbolicLinks(fullPath) {
|
|
23
|
+
const relativePath = nodePath.relative(this.rootPath, fullPath);
|
|
24
|
+
let currentPath = this.rootPath;
|
|
25
|
+
for (const segment of relativePath.split(nodePath.sep).filter(Boolean)) {
|
|
26
|
+
currentPath = nodePath.join(currentPath, segment);
|
|
27
|
+
try {
|
|
28
|
+
const stat = await nodeFsPromises.lstat(currentPath);
|
|
29
|
+
if (stat.isSymbolicLink()) throw new SymbolicLinkStoragePathError(currentPath);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (error.code === "ENOENT") return;
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
11
35
|
}
|
|
12
36
|
async exists(path) {
|
|
13
|
-
const fullPath = this.resolvePath(path);
|
|
37
|
+
const fullPath = await this.resolvePath(path);
|
|
14
38
|
try {
|
|
15
39
|
await nodeFsPromises.access(fullPath);
|
|
16
40
|
return true;
|
|
@@ -20,14 +44,15 @@ class NodeStorageAdapter {
|
|
|
20
44
|
}
|
|
21
45
|
async trystat(path) {
|
|
22
46
|
try {
|
|
23
|
-
const stat = await nodeFsPromises.stat(this.resolvePath(path));
|
|
47
|
+
const stat = await nodeFsPromises.stat(await this.resolvePath(path));
|
|
24
48
|
return {
|
|
25
49
|
size: stat.size,
|
|
26
50
|
mtime: Math.floor(stat.mtimeMs),
|
|
27
51
|
ctime: Math.floor(stat.ctimeMs),
|
|
28
52
|
type: stat.isDirectory() ? "folder" : "file"
|
|
29
53
|
};
|
|
30
|
-
} catch {
|
|
54
|
+
} catch (error) {
|
|
55
|
+
if (error instanceof SymbolicLinkStoragePathError) throw error;
|
|
31
56
|
return null;
|
|
32
57
|
}
|
|
33
58
|
}
|
|
@@ -35,10 +60,12 @@ class NodeStorageAdapter {
|
|
|
35
60
|
return await this.trystat(path);
|
|
36
61
|
}
|
|
37
62
|
async mkdir(path) {
|
|
38
|
-
await
|
|
63
|
+
const fullPath = await this.resolvePath(path);
|
|
64
|
+
await nodeFsPromises.mkdir(fullPath, { recursive: true });
|
|
65
|
+
await this.assertNoSymbolicLinks(fullPath);
|
|
39
66
|
}
|
|
40
67
|
async remove(path) {
|
|
41
|
-
const fullPath = this.resolvePath(path, false);
|
|
68
|
+
const fullPath = await this.resolvePath(path, false);
|
|
42
69
|
const stat = await nodeFsPromises.stat(fullPath);
|
|
43
70
|
if (stat.isDirectory()) {
|
|
44
71
|
await nodeFsPromises.rm(fullPath, { recursive: true, force: true });
|
|
@@ -47,33 +74,55 @@ class NodeStorageAdapter {
|
|
|
47
74
|
}
|
|
48
75
|
}
|
|
49
76
|
async read(path) {
|
|
50
|
-
|
|
77
|
+
const handle = await nodeFsPromises.open(
|
|
78
|
+
await this.resolvePath(path, false),
|
|
79
|
+
nodeFsConstants.O_RDONLY | NO_FOLLOW
|
|
80
|
+
);
|
|
81
|
+
try {
|
|
82
|
+
return await handle.readFile("utf-8");
|
|
83
|
+
} finally {
|
|
84
|
+
await handle.close();
|
|
85
|
+
}
|
|
51
86
|
}
|
|
52
87
|
async readBinary(path) {
|
|
53
|
-
const
|
|
54
|
-
|
|
88
|
+
const handle = await nodeFsPromises.open(
|
|
89
|
+
await this.resolvePath(path, false),
|
|
90
|
+
nodeFsConstants.O_RDONLY | NO_FOLLOW
|
|
91
|
+
);
|
|
92
|
+
try {
|
|
93
|
+
const buffer = await handle.readFile();
|
|
94
|
+
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
95
|
+
} finally {
|
|
96
|
+
await handle.close();
|
|
97
|
+
}
|
|
55
98
|
}
|
|
56
99
|
async write(path, data, options) {
|
|
57
|
-
const fullPath = this.resolvePath(path, false);
|
|
100
|
+
const fullPath = await this.resolvePath(path, false);
|
|
58
101
|
await nodeFsPromises.mkdir(nodePath.dirname(fullPath), { recursive: true });
|
|
59
|
-
await
|
|
60
|
-
await this.applyTimes(fullPath, options);
|
|
102
|
+
await this.writeFile(fullPath, data, options, false);
|
|
61
103
|
}
|
|
62
104
|
async writeBinary(path, data, options) {
|
|
63
|
-
const fullPath = this.resolvePath(path, false);
|
|
105
|
+
const fullPath = await this.resolvePath(path, false);
|
|
64
106
|
await nodeFsPromises.mkdir(nodePath.dirname(fullPath), { recursive: true });
|
|
65
|
-
await
|
|
66
|
-
await this.applyTimes(fullPath, options);
|
|
107
|
+
await this.writeFile(fullPath, new Uint8Array(data), options, false);
|
|
67
108
|
}
|
|
68
109
|
async append(path, data, options) {
|
|
69
|
-
const fullPath = this.resolvePath(path, false);
|
|
110
|
+
const fullPath = await this.resolvePath(path, false);
|
|
70
111
|
await nodeFsPromises.mkdir(nodePath.dirname(fullPath), { recursive: true });
|
|
71
|
-
await
|
|
72
|
-
|
|
112
|
+
await this.writeFile(fullPath, data, options, true);
|
|
113
|
+
}
|
|
114
|
+
/** Atomically rename or move an entry without leaving the injected root. */
|
|
115
|
+
async rename(sourcePath, targetPath) {
|
|
116
|
+
const fullSourcePath = await this.resolvePath(sourcePath, false);
|
|
117
|
+
const fullTargetPath = await this.resolvePath(targetPath, false);
|
|
118
|
+
await nodeFsPromises.mkdir(nodePath.dirname(fullTargetPath), { recursive: true });
|
|
119
|
+
await this.assertNoSymbolicLinks(fullSourcePath);
|
|
120
|
+
await this.assertNoSymbolicLinks(fullTargetPath);
|
|
121
|
+
await nodeFsPromises.rename(fullSourcePath, fullTargetPath);
|
|
73
122
|
}
|
|
74
123
|
async list(basePath) {
|
|
75
124
|
try {
|
|
76
|
-
const entries = await nodeFsPromises.readdir(this.resolvePath(basePath), { withFileTypes: true });
|
|
125
|
+
const entries = await nodeFsPromises.readdir(await this.resolvePath(basePath), { withFileTypes: true });
|
|
77
126
|
const files = [];
|
|
78
127
|
const folders = [];
|
|
79
128
|
for (const entry of entries) {
|
|
@@ -82,15 +131,27 @@ class NodeStorageAdapter {
|
|
|
82
131
|
else if (entry.isFile()) files.push(entryPath);
|
|
83
132
|
}
|
|
84
133
|
return { files, folders };
|
|
85
|
-
} catch {
|
|
134
|
+
} catch (error) {
|
|
135
|
+
if (error instanceof SymbolicLinkStoragePathError) throw error;
|
|
86
136
|
return { files: [], folders: [] };
|
|
87
137
|
}
|
|
88
138
|
}
|
|
89
|
-
async
|
|
139
|
+
async writeFile(fullPath, data, options, append) {
|
|
140
|
+
await this.assertNoSymbolicLinks(fullPath);
|
|
141
|
+
const flags = nodeFsConstants.O_WRONLY | nodeFsConstants.O_CREAT | NO_FOLLOW | (append ? nodeFsConstants.O_APPEND : nodeFsConstants.O_TRUNC);
|
|
142
|
+
const handle = await nodeFsPromises.open(fullPath, flags, 438);
|
|
143
|
+
try {
|
|
144
|
+
await handle.writeFile(data, typeof data === "string" ? "utf-8" : void 0);
|
|
145
|
+
await this.applyTimes(handle, options);
|
|
146
|
+
} finally {
|
|
147
|
+
await handle.close();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async applyTimes(handle, options) {
|
|
90
151
|
if (!options?.mtime && !options?.ctime) return;
|
|
91
152
|
const accessTime = options.mtime ? new Date(options.mtime) : /* @__PURE__ */ new Date();
|
|
92
153
|
const modificationTime = options.mtime ? new Date(options.mtime) : /* @__PURE__ */ new Date();
|
|
93
|
-
await
|
|
154
|
+
await handle.utimes(accessTime, modificationTime);
|
|
94
155
|
}
|
|
95
156
|
}
|
|
96
157
|
function createNodeStorage({ rootPath }) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** A chunk written to standard output or standard error. */
|
|
2
|
+
export type StandardIoChunk = string | Uint8Array;
|
|
3
|
+
/**
|
|
4
|
+
* Host-provided standard input and output for a command-line composition.
|
|
5
|
+
*
|
|
6
|
+
* The contract deliberately excludes process lifecycle, logging policy, and
|
|
7
|
+
* terminal capability detection. Hosts own those concerns separately. None of
|
|
8
|
+
* the write operations add a newline implicitly.
|
|
9
|
+
*/
|
|
10
|
+
export interface StandardIo {
|
|
11
|
+
/** Read standard input to completion and decode it as UTF-8 text. */
|
|
12
|
+
readStdin(): Promise<string>;
|
|
13
|
+
/** Ask one line-oriented question and return the entered text. */
|
|
14
|
+
prompt(question: string): Promise<string>;
|
|
15
|
+
/** Write a text or binary chunk to standard output. */
|
|
16
|
+
writeStdout(chunk: StandardIoChunk): void;
|
|
17
|
+
/** Write a text or binary chunk to standard error. */
|
|
18
|
+
writeStderr(chunk: StandardIoChunk): void;
|
|
19
|
+
}
|
|
File without changes
|
|
@@ -190,6 +190,7 @@ export declare class LiveSyncLocalDB {
|
|
|
190
190
|
getDBEntry(path: FilePathWithPrefix | FilePath, opt?: PouchDB.Core.GetOptions, dump?: boolean, waitForReady?: boolean, includeDeleted?: boolean): Promise<false | LoadedEntry>;
|
|
191
191
|
getDBEntryFromMeta(meta: LoadedEntry | MetaEntry, dump?: boolean, waitForReady?: boolean): Promise<false | LoadedEntry>;
|
|
192
192
|
deleteDBEntry(path: FilePathWithPrefix | FilePath, opt?: PouchDB.Core.GetOptions): Promise<boolean>;
|
|
193
|
+
storeDeletionAtRevision(path: FilePathWithPrefix | FilePath, baseRevision: string): Promise<false | PouchDB.Core.Response>;
|
|
193
194
|
putDBEntry(note: SavingEntry, onlyChunks?: boolean, conflictBaseRev?: string): Promise<false | PouchDB.Core.Response>;
|
|
194
195
|
getConflictedDoc(path: FilePathWithPrefix, rev: string): Promise<false | diff_result_leaf>;
|
|
195
196
|
tryAutoMerge(path: FilePathWithPrefix, enableMarkdownAutoMerge: boolean): AutoMergeResult;
|
|
@@ -364,6 +364,9 @@ class LiveSyncLocalDB {
|
|
|
364
364
|
async deleteDBEntry(path, opt) {
|
|
365
365
|
return await this.managers.entryManager.deleteDBEntry(path, opt);
|
|
366
366
|
}
|
|
367
|
+
async storeDeletionAtRevision(path, baseRevision) {
|
|
368
|
+
return await this.managers.entryManager.storeDeletionAtRevision(path, baseRevision);
|
|
369
|
+
}
|
|
367
370
|
async putDBEntry(note, onlyChunks, conflictBaseRev) {
|
|
368
371
|
return await this.managers.entryManager.putDBEntry(note, onlyChunks, conflictBaseRev);
|
|
369
372
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Focused public primitives for storing and selecting multiple remote connection profiles.
|
|
3
|
+
*
|
|
4
|
+
* The compatibility fields remain available to existing hosts, but new profile-management code
|
|
5
|
+
* should use this entry point instead of importing the wider service feature module.
|
|
6
|
+
*/
|
|
7
|
+
export { activateP2PRemoteConfiguration, activateRemoteConfiguration, createRemoteConfigurationId, suggestRemoteConfigurationName, upsertRemoteConfigurationInPlace, } from "./serviceFeatures/remoteConfig.js";
|
|
8
|
+
export type { SerializableRemoteConfigurationType, UpsertRemoteConfigurationOptions, } from "./serviceFeatures/remoteConfig.js";
|
|
9
|
+
export type { RemoteConfiguration } from "./common/models/setting.type.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
activateP2PRemoteConfiguration,
|
|
3
|
+
activateRemoteConfiguration,
|
|
4
|
+
createRemoteConfigurationId,
|
|
5
|
+
suggestRemoteConfigurationName,
|
|
6
|
+
upsertRemoteConfigurationInPlace
|
|
7
|
+
} from "./serviceFeatures/remoteConfig.js";
|
|
8
|
+
export {
|
|
9
|
+
activateP2PRemoteConfiguration,
|
|
10
|
+
activateRemoteConfiguration,
|
|
11
|
+
createRemoteConfigurationId,
|
|
12
|
+
suggestRemoteConfigurationName,
|
|
13
|
+
upsertRemoteConfigurationInPlace
|
|
14
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type EntryDoc, type DatabaseConnectingStatus, type RemoteDBSettings, type EntryLeaf, type TweakValues, type NodeData } from "../common/types.js";
|
|
2
2
|
import type { RequiredServices } from "../interfaces/ServiceModule.js";
|
|
3
3
|
import type { TranslationParameters } from "../services/base/MessageTranslator.js";
|
|
4
|
+
import type { CommonlibMessageKey } from "../services/base/CommonlibMessages.js";
|
|
4
5
|
export type ReplicationCallback = (e: PouchDB.Core.ExistingDocument<EntryDoc>[]) => Promise<boolean> | boolean;
|
|
5
6
|
export type ReplicationStat = {
|
|
6
7
|
sent: number;
|
|
@@ -34,11 +35,10 @@ export declare abstract class LiveSyncAbstractReplicator {
|
|
|
34
35
|
remoteLockedAndDeviceNotAccepted: boolean;
|
|
35
36
|
tweakSettingsMismatched: boolean;
|
|
36
37
|
preferredTweakValue?: TweakValues;
|
|
37
|
-
abstract get isChunkSendingSupported(): boolean;
|
|
38
38
|
get database(): import("../pouchdb/LiveSyncLocalDB.js").LiveSyncLocalDB;
|
|
39
39
|
get rawDatabase(): PouchDB.Database<EntryDoc>;
|
|
40
40
|
get currentSettings(): import("../common/types.js").ObsidianLiveSyncSettings;
|
|
41
|
-
protected translate
|
|
41
|
+
protected translate(key: CommonlibMessageKey, params?: TranslationParameters): string;
|
|
42
42
|
sendChunks(setting: RemoteDBSettings, remoteDB: PouchDB.Database<EntryDoc> | undefined, showResult: boolean, fromSeq?: number | string): Promise<boolean>;
|
|
43
43
|
abstract getReplicationPBKDF2Salt(setting: RemoteDBSettings, refresh?: boolean): Promise<Uint8Array<ArrayBuffer>>;
|
|
44
44
|
ensurePBKDF2Salt(setting: RemoteDBSettings, showMessage?: boolean, useCache?: boolean): Promise<boolean>;
|
|
@@ -49,7 +49,7 @@ export declare abstract class LiveSyncAbstractReplicator {
|
|
|
49
49
|
abstract openReplication(setting: RemoteDBSettings, keepAlive: boolean, showResult: boolean, ignoreCleanLock: boolean): Promise<void | boolean>;
|
|
50
50
|
updateInfo: () => void;
|
|
51
51
|
abstract tryConnectRemote(setting: RemoteDBSettings, showResult?: boolean): Promise<boolean>;
|
|
52
|
-
abstract replicateAllToServer(setting: RemoteDBSettings, showingNotice?: boolean
|
|
52
|
+
abstract replicateAllToServer(setting: RemoteDBSettings, showingNotice?: boolean): Promise<boolean>;
|
|
53
53
|
abstract replicateAllFromServer(setting: RemoteDBSettings, showingNotice?: boolean): Promise<boolean>;
|
|
54
54
|
abstract closeReplication(): void;
|
|
55
55
|
abstract tryResetRemoteDatabase(setting: RemoteDBSettings): Promise<void>;
|
|
@@ -5,7 +5,6 @@ export interface LiveSyncCouchDBReplicatorEnv extends LiveSyncReplicatorEnv {
|
|
|
5
5
|
services: ServiceHub;
|
|
6
6
|
}
|
|
7
7
|
export declare class LiveSyncCouchDBReplicator extends LiveSyncAbstractReplicator {
|
|
8
|
-
get isChunkSendingSupported(): boolean;
|
|
9
8
|
isMobile(): boolean;
|
|
10
9
|
constructor(env: LiveSyncCouchDBReplicatorEnv);
|
|
11
10
|
getInitialSyncParameters(setting: RemoteDBSettings): Promise<SyncParameters>;
|
|
@@ -7,7 +7,6 @@ import { type SimpleStore } from "../../common/utils.js";
|
|
|
7
7
|
import type { LiveSyncJournalReplicatorEnv } from "./LiveSyncJournalReplicatorEnv.js";
|
|
8
8
|
export declare class LiveSyncJournalReplicator extends LiveSyncAbstractReplicator {
|
|
9
9
|
env: LiveSyncJournalReplicatorEnv;
|
|
10
|
-
get isChunkSendingSupported(): boolean;
|
|
11
10
|
get client(): JournalSyncCore;
|
|
12
11
|
get simpleStore(): SimpleStore<CheckPointInfo>;
|
|
13
12
|
_client: JournalSyncCore;
|
|
@@ -18,13 +18,15 @@ export interface LiveSyncTrysteroReplicatorEnv extends LiveSyncReplicatorEnv {
|
|
|
18
18
|
export declare class LiveSyncTrysteroReplicator extends LiveSyncAbstractReplicator {
|
|
19
19
|
private _p2pHost?;
|
|
20
20
|
private _replicator?;
|
|
21
|
+
private _lifecycleOperation;
|
|
22
|
+
private _shouldBeOpen;
|
|
21
23
|
get openReplicationUI(): (showResult: boolean) => Promise<boolean | void>;
|
|
22
24
|
get rawReplicator(): TrysteroReplicator;
|
|
23
25
|
get rawHost(): P2PHost;
|
|
24
|
-
get isChunkSendingSupported(): boolean;
|
|
25
26
|
getReplicationPBKDF2Salt(_setting: RemoteDBSettings, _refresh?: boolean): Promise<Uint8Array<ArrayBuffer>>;
|
|
26
27
|
terminateSync(): void;
|
|
27
28
|
private _buildEnv;
|
|
29
|
+
private _enqueueLifecycleOperation;
|
|
28
30
|
open(): Promise<void>;
|
|
29
31
|
close(): Promise<void>;
|
|
30
32
|
closeReplication(): void;
|
|
@@ -36,7 +38,7 @@ export declare class LiveSyncTrysteroReplicator extends LiveSyncAbstractReplicat
|
|
|
36
38
|
onNewPeer(peer: Advertisement): Promise<void>;
|
|
37
39
|
onPeerLeaved(peerId: string): void;
|
|
38
40
|
replicateFromCommand(showResult?: boolean): Promise<void>;
|
|
39
|
-
replicateFrom(peerId: string, showNotice?: boolean): Promise<{
|
|
41
|
+
replicateFrom(peerId: string, showNotice?: boolean, skipOrdinaryReplicationPolicy?: boolean): Promise<{
|
|
40
42
|
error: any;
|
|
41
43
|
ok?: undefined;
|
|
42
44
|
} | {
|
|
@@ -67,7 +69,7 @@ export declare class LiveSyncTrysteroReplicator extends LiveSyncAbstractReplicat
|
|
|
67
69
|
makeSureOpened(): Promise<void>;
|
|
68
70
|
openReplication(_setting: RemoteDBSettings, _keepAlive: boolean, showResult: boolean, _ignoreCleanLock: boolean): Promise<void | boolean>;
|
|
69
71
|
tryConnectRemote(_setting: RemoteDBSettings, _showResult?: boolean): Promise<boolean>;
|
|
70
|
-
replicateAllToServer(_setting: RemoteDBSettings, _showingNotice?: boolean
|
|
72
|
+
replicateAllToServer(_setting: RemoteDBSettings, _showingNotice?: boolean): Promise<boolean>;
|
|
71
73
|
selectPeer(settingPeerName: string, r: TrysteroReplicator, logLevel: LOG_LEVEL): Promise<string | false>;
|
|
72
74
|
tryUntilSuccess<T>(func: () => Promise<T | false>, repeat: number, logLevel: LOG_LEVEL): Promise<T | false>;
|
|
73
75
|
replicateAllFromServer(setting: RemoteDBSettings, showingNotice?: boolean): Promise<boolean>;
|
|
@@ -18,6 +18,8 @@ import { delay } from "octagonal-wheels/promises";
|
|
|
18
18
|
class LiveSyncTrysteroReplicator extends LiveSyncAbstractReplicator {
|
|
19
19
|
_p2pHost;
|
|
20
20
|
_replicator;
|
|
21
|
+
_lifecycleOperation = Promise.resolve();
|
|
22
|
+
_shouldBeOpen = false;
|
|
21
23
|
get openReplicationUI() {
|
|
22
24
|
return this.env.openReplicationUI;
|
|
23
25
|
}
|
|
@@ -27,9 +29,6 @@ class LiveSyncTrysteroReplicator extends LiveSyncAbstractReplicator {
|
|
|
27
29
|
get rawHost() {
|
|
28
30
|
return this._p2pHost;
|
|
29
31
|
}
|
|
30
|
-
get isChunkSendingSupported() {
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
32
|
getReplicationPBKDF2Salt(_setting, _refresh) {
|
|
34
33
|
return Promise.resolve(new Uint8Array(32));
|
|
35
34
|
}
|
|
@@ -59,6 +58,7 @@ class LiveSyncTrysteroReplicator extends LiveSyncAbstractReplicator {
|
|
|
59
58
|
return services.API.confirm;
|
|
60
59
|
},
|
|
61
60
|
runFiniteReplicationActivity: (task, options) => services.replicator.runFiniteReplicationActivity(task, options),
|
|
61
|
+
canStartOrdinaryReplication: (showMessage = false) => services.replication.onCheckReplicationReady(showMessage),
|
|
62
62
|
processReplicatedDocs: async (docs) => {
|
|
63
63
|
const settings = services.setting.currentSettings();
|
|
64
64
|
if (settings.suspendParseReplicationResult) {
|
|
@@ -75,36 +75,48 @@ class LiveSyncTrysteroReplicator extends LiveSyncAbstractReplicator {
|
|
|
75
75
|
}
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
|
+
_enqueueLifecycleOperation(operation) {
|
|
79
|
+
const queued = this._lifecycleOperation.catch(() => void 0).then(operation);
|
|
80
|
+
this._lifecycleOperation = queued.catch(() => void 0);
|
|
81
|
+
return queued;
|
|
82
|
+
}
|
|
78
83
|
async open() {
|
|
79
84
|
if (!this.env.services.setting.currentSettings().P2P_Enabled) {
|
|
80
85
|
Logger(this.translate("P2P.NotEnabled"), LOG_LEVEL_NOTICE);
|
|
81
86
|
return;
|
|
82
87
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
88
|
+
this._shouldBeOpen = true;
|
|
89
|
+
await this._enqueueLifecycleOperation(async () => {
|
|
90
|
+
if (!this._shouldBeOpen) return;
|
|
91
|
+
if (this._replicator && this._p2pHost?.isServing) {
|
|
92
|
+
Logger("P2P replicator is already open.");
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
const env = this._buildEnv();
|
|
97
|
+
const host = new P2PHost(env);
|
|
98
|
+
const replicator = new TrysteroReplicator(env, host);
|
|
99
|
+
this._p2pHost = host;
|
|
100
|
+
this._replicator = replicator;
|
|
101
|
+
await replicator.open();
|
|
102
|
+
} catch (e) {
|
|
103
|
+
Logger(e instanceof Error ? e.message : "Error while opening P2P connection", LOG_LEVEL_NOTICE);
|
|
104
|
+
Logger(e, LOG_LEVEL_VERBOSE);
|
|
105
|
+
this._p2pHost = void 0;
|
|
106
|
+
this._replicator = void 0;
|
|
107
|
+
}
|
|
108
|
+
});
|
|
100
109
|
}
|
|
101
110
|
async close() {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
111
|
+
this._shouldBeOpen = false;
|
|
112
|
+
await this._enqueueLifecycleOperation(async () => {
|
|
113
|
+
if (this._replicator) {
|
|
114
|
+
this._replicator.disableBroadcastChanges();
|
|
115
|
+
await this._replicator.close();
|
|
116
|
+
this._replicator = void 0;
|
|
117
|
+
}
|
|
118
|
+
this._p2pHost = void 0;
|
|
119
|
+
});
|
|
108
120
|
}
|
|
109
121
|
closeReplication() {
|
|
110
122
|
this._replicator?.disconnectFromServer();
|
|
@@ -138,11 +150,11 @@ class LiveSyncTrysteroReplicator extends LiveSyncAbstractReplicator {
|
|
|
138
150
|
{ label: "replication" }
|
|
139
151
|
);
|
|
140
152
|
}
|
|
141
|
-
async replicateFrom(peerId, showNotice = false) {
|
|
153
|
+
async replicateFrom(peerId, showNotice = false, skipOrdinaryReplicationPolicy = false) {
|
|
142
154
|
const replicator = this._replicator;
|
|
143
155
|
if (!replicator) throw new Error("P2P replicator is not open");
|
|
144
156
|
return await this.env.services.replicator.runFiniteReplicationActivity(
|
|
145
|
-
() => replicator.replicateFrom(peerId, showNotice),
|
|
157
|
+
() => skipOrdinaryReplicationPolicy ? replicator.replicateFrom(peerId, showNotice, false, true) : replicator.replicateFrom(peerId, showNotice),
|
|
146
158
|
{ label: "replication" }
|
|
147
159
|
);
|
|
148
160
|
}
|
|
@@ -200,7 +212,7 @@ class LiveSyncTrysteroReplicator extends LiveSyncAbstractReplicator {
|
|
|
200
212
|
tryConnectRemote(_setting, _showResult) {
|
|
201
213
|
return Promise.resolve(false);
|
|
202
214
|
}
|
|
203
|
-
replicateAllToServer(_setting, _showingNotice
|
|
215
|
+
replicateAllToServer(_setting, _showingNotice) {
|
|
204
216
|
return Promise.resolve(false);
|
|
205
217
|
}
|
|
206
218
|
async selectPeer(settingPeerName, r, logLevel) {
|
|
@@ -303,7 +315,7 @@ class LiveSyncTrysteroReplicator extends LiveSyncAbstractReplicator {
|
|
|
303
315
|
}
|
|
304
316
|
this.env.services.setting.currentSettings().P2P_RebuildFrom = "";
|
|
305
317
|
Logger("Fetching from peer " + peerId + ".", logLevel);
|
|
306
|
-
const rep = await r.replicateFrom(peerId, showingNotice);
|
|
318
|
+
const rep = await r.replicateFrom(peerId, showingNotice, false, true);
|
|
307
319
|
if (rep.ok) {
|
|
308
320
|
Logger("P2P Fetching has been succeed from " + peerId + ".", logLevel);
|
|
309
321
|
return true;
|
|
@@ -2,11 +2,7 @@ import type { NecessaryServices } from "../../interfaces/ServiceModule.js";
|
|
|
2
2
|
import type { P2PPaneParams } from "./UseP2PReplicatorResult.js";
|
|
3
3
|
export type P2PViewFactory = (leaf: unknown) => unknown;
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* following the same middleware style as useOfflineScanner.
|
|
8
|
-
*
|
|
9
|
-
* @param viewTypeAndFactory Optional [viewType, factory] pair for registering the P2P pane view.
|
|
10
|
-
* When provided, also registers commands and ribbon icon via services.API.
|
|
5
|
+
* @deprecated Compose `useP2PReplicatorFeature` with host-specific commands
|
|
6
|
+
* and UI instead. This wrapper remains for source compatibility.
|
|
11
7
|
*/
|
|
12
8
|
export declare function useP2PReplicator(host: NecessaryServices<"API" | "appLifecycle" | "setting" | "vault" | "database" | "databaseEvents" | "keyValueDB" | "replication" | "config" | "UI" | "replicator" | "remote", never>, viewTypeAndFactory?: [viewType: string, factory: P2PViewFactory]): P2PPaneParams;
|
|
@@ -1,110 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { reactiveSource } from "octagonal-wheels/dataobject/
|
|
1
|
+
import { REMOTE_P2P } from "../../common/types.js";
|
|
2
|
+
import { reactiveSource } from "octagonal-wheels/dataobject/reactive_v2";
|
|
3
3
|
import { EVENT_REQUEST_OPEN_P2P } from "../../events/coreEvents.js";
|
|
4
|
-
import { LiveSyncTrysteroReplicator } from "./LiveSyncTrysteroReplicator.js";
|
|
5
|
-
import { Logger, LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE } from "../../common/logger.js";
|
|
6
4
|
import { P2PLogCollector } from "./P2PLogCollector.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
5
|
+
import { useP2PReplicatorCommands } from "./useP2PReplicatorCommands.js";
|
|
6
|
+
import { useP2PReplicatorFeature } from "./useP2PReplicatorFeature.js";
|
|
9
7
|
function useP2PReplicator(host, viewTypeAndFactory) {
|
|
10
|
-
const
|
|
11
|
-
let replicator = new LiveSyncTrysteroReplicator(env);
|
|
12
|
-
const activeReplicator = {
|
|
13
|
-
get instance() {
|
|
14
|
-
return replicator;
|
|
15
|
-
}
|
|
16
|
-
};
|
|
8
|
+
const activeReplicator = useP2PReplicatorFeature(host);
|
|
17
9
|
const events = host.services.context.events;
|
|
18
|
-
addP2PEventHandlers(activeReplicator.instance, events);
|
|
19
10
|
const p2pLogCollector = new P2PLogCollector(events);
|
|
20
11
|
const storeP2PStatusLine = reactiveSource("");
|
|
21
12
|
p2pLogCollector.p2pReplicationLine.onChanged((line) => {
|
|
22
13
|
storeP2PStatusLine.value = line.value;
|
|
23
14
|
});
|
|
24
|
-
host.services.appLifecycle.onResumed.addHandler(() => {
|
|
25
|
-
const settings = host.services.setting.currentSettings();
|
|
26
|
-
if (settings.P2P_Enabled && settings.P2P_AutoStart) {
|
|
27
|
-
compatGlobal.setTimeout(() => void replicator.open(), 100);
|
|
28
|
-
}
|
|
29
|
-
return Promise.resolve(true);
|
|
30
|
-
});
|
|
31
|
-
host.services.appLifecycle.onUnload.addHandler(async () => {
|
|
32
|
-
await replicator.close();
|
|
33
|
-
return true;
|
|
34
|
-
});
|
|
35
|
-
host.services.appLifecycle.onSuspending.addHandler(async () => {
|
|
36
|
-
await replicator.close();
|
|
37
|
-
return true;
|
|
38
|
-
});
|
|
39
|
-
host.services.databaseEvents.onDatabaseInitialisation.addHandler(async () => {
|
|
40
|
-
await replicator.close();
|
|
41
|
-
return true;
|
|
42
|
-
});
|
|
43
|
-
host.services.setting.suspendExtraSync.addHandler(() => {
|
|
44
|
-
const s = host.services.setting.currentSettings();
|
|
45
|
-
if (s.remoteType !== REMOTE_P2P) {
|
|
46
|
-
s.P2P_Enabled = false;
|
|
47
|
-
}
|
|
48
|
-
s.P2P_AutoAccepting = AutoAccepting.NONE;
|
|
49
|
-
s.P2P_AutoBroadcast = false;
|
|
50
|
-
s.P2P_AutoStart = false;
|
|
51
|
-
s.P2P_AutoSyncPeers = "";
|
|
52
|
-
s.P2P_AutoWatchPeers = "";
|
|
53
|
-
return Promise.resolve(true);
|
|
54
|
-
});
|
|
55
|
-
host.services.replicator.getNewReplicator.addHandler(
|
|
56
|
-
async (settingOverride = {}) => {
|
|
57
|
-
const settings = { ...host.services.setting.currentSettings(), ...settingOverride };
|
|
58
|
-
if (settings.remoteType == REMOTE_P2P) {
|
|
59
|
-
try {
|
|
60
|
-
await replicator.close();
|
|
61
|
-
} catch (e) {
|
|
62
|
-
Logger(`Error closing existing p2p replicator`);
|
|
63
|
-
Logger(e, LOG_LEVEL_VERBOSE);
|
|
64
|
-
}
|
|
65
|
-
const newReplicator = new LiveSyncTrysteroReplicator({ services: host.services });
|
|
66
|
-
replicator = newReplicator;
|
|
67
|
-
return Promise.resolve(replicator);
|
|
68
|
-
}
|
|
69
|
-
return void 0;
|
|
70
|
-
}
|
|
71
|
-
);
|
|
72
15
|
if (viewTypeAndFactory) {
|
|
73
16
|
const [viewType, factory] = viewTypeAndFactory;
|
|
74
17
|
const openPane = () => host.services.API.showWindow(viewType);
|
|
18
|
+
useP2PReplicatorCommands(host, activeReplicator);
|
|
75
19
|
host.services.appLifecycle.onInitialise.addHandler(() => {
|
|
76
20
|
host.services.API.registerWindow(viewType, factory);
|
|
77
|
-
events.onEvent(EVENT_REQUEST_OPEN_P2P, () =>
|
|
78
|
-
void openPane();
|
|
79
|
-
});
|
|
21
|
+
events.onEvent(EVENT_REQUEST_OPEN_P2P, () => void openPane());
|
|
80
22
|
host.services.API.addCommand({
|
|
81
23
|
id: "open-p2p-replicator",
|
|
82
24
|
name: "P2P Sync : Open P2P Replicator",
|
|
83
|
-
callback: () =>
|
|
84
|
-
void openPane();
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
host.services.API.addCommand({
|
|
88
|
-
id: "p2p-establish-connection",
|
|
89
|
-
name: "P2P Sync : Connect to the Signalling Server",
|
|
90
|
-
checkCallback: (isChecking) => {
|
|
91
|
-
if (isChecking) return !(replicator.server?.isServing ?? false);
|
|
92
|
-
void replicator.open();
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
host.services.API.addCommand({
|
|
96
|
-
id: "p2p-close-connection",
|
|
97
|
-
name: "P2P Sync : Disconnect from the Signalling Server",
|
|
98
|
-
checkCallback: (isChecking) => {
|
|
99
|
-
if (isChecking) return replicator.server?.isServing ?? false;
|
|
100
|
-
Logger("Closing P2P Connection", LOG_LEVEL_NOTICE);
|
|
101
|
-
void replicator.close();
|
|
102
|
-
}
|
|
25
|
+
callback: () => void openPane()
|
|
103
26
|
});
|
|
104
27
|
host.services.API.addCommand({
|
|
105
28
|
id: "replicate-now-by-p2p",
|
|
106
29
|
name: "Replicate now by P2P",
|
|
107
30
|
checkCallback: (isChecking) => {
|
|
31
|
+
const replicator = activeReplicator.replicator;
|
|
108
32
|
const settings = host.services.setting.currentSettings();
|
|
109
33
|
if (isChecking) {
|
|
110
34
|
if (settings.remoteType == REMOTE_P2P) return false;
|
|
@@ -119,7 +43,13 @@ function useP2PReplicator(host, viewTypeAndFactory) {
|
|
|
119
43
|
return Promise.resolve(true);
|
|
120
44
|
});
|
|
121
45
|
}
|
|
122
|
-
return {
|
|
46
|
+
return {
|
|
47
|
+
get replicator() {
|
|
48
|
+
return activeReplicator.replicator;
|
|
49
|
+
},
|
|
50
|
+
p2pLogCollector,
|
|
51
|
+
storeP2PStatusLine
|
|
52
|
+
};
|
|
123
53
|
}
|
|
124
54
|
export {
|
|
125
55
|
useP2PReplicator
|
|
@@ -64,6 +64,7 @@ export declare class TrysteroReplicator {
|
|
|
64
64
|
get confirm(): Confirm;
|
|
65
65
|
get translate(): import("../../context.js").MessageTranslator;
|
|
66
66
|
private runFiniteReplicationActivity;
|
|
67
|
+
private canStartOrdinaryReplication;
|
|
67
68
|
constructor(env: ReplicatorHostEnv, server?: P2PHost);
|
|
68
69
|
close(): Promise<void>;
|
|
69
70
|
open(): Promise<void>;
|
|
@@ -123,7 +124,7 @@ export declare class TrysteroReplicator {
|
|
|
123
124
|
onReplicationProgress(peerId: string, info?: ProgressInfo): boolean;
|
|
124
125
|
onProgressAcknowledged(peerId: string, info?: ProgressInfo): boolean;
|
|
125
126
|
acknowledgeProgress(remotePeerId: string, info?: ProgressInfo): void;
|
|
126
|
-
replicateFrom(remotePeer: string, showNotice?: boolean, fromStart?: boolean): Promise<{
|
|
127
|
+
replicateFrom(remotePeer: string, showNotice?: boolean, fromStart?: boolean, skipOrdinaryReplicationPolicy?: boolean): Promise<{
|
|
127
128
|
error: any;
|
|
128
129
|
ok?: undefined;
|
|
129
130
|
} | {
|