mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-10-13 04:42:30 +00:00
Refactor: Refactor P2P Replicator
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import type { LiveSyncBaseCore } from "../../../LiveSyncBaseCore";
|
import type { LiveSyncBaseCore } from "../../../LiveSyncBaseCore";
|
||||||
import { P2P_DEFAULT_SETTINGS, SETTING_KEY_P2P_DEVICE_NAME, type EntryDoc } from "@lib/common/types";
|
import { P2P_DEFAULT_SETTINGS } from "@lib/common/types";
|
||||||
import type { ServiceContext } from "@lib/services/base/ServiceBase";
|
import type { ServiceContext } from "@lib/services/base/ServiceBase";
|
||||||
import { TrysteroReplicator } from "@lib/replication/trystero/TrysteroReplicator";
|
import { LiveSyncTrysteroReplicator } from "@lib/replication/trystero/LiveSyncTrysteroReplicator";
|
||||||
|
|
||||||
type CLIP2PPeer = {
|
type CLIP2PPeer = {
|
||||||
peerId: string;
|
peerId: string;
|
||||||
@@ -32,42 +32,12 @@ function validateP2PSettings(core: LiveSyncBaseCore<ServiceContext, any>) {
|
|||||||
settings.P2P_IsHeadless = true;
|
settings.P2P_IsHeadless = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createReplicator(core: LiveSyncBaseCore<ServiceContext, any>): Promise<TrysteroReplicator> {
|
function createReplicator(core: LiveSyncBaseCore<ServiceContext, any>): LiveSyncTrysteroReplicator {
|
||||||
validateP2PSettings(core);
|
validateP2PSettings(core);
|
||||||
const getSettings = () => core.services.setting.currentSettings();
|
return new LiveSyncTrysteroReplicator({ services: core.services });
|
||||||
const getDB = () => core.services.database.localDatabase.localDatabase;
|
|
||||||
const getSimpleStore = () => core.services.keyValueDB.openSimpleStore("p2p-sync");
|
|
||||||
const getDeviceName = () =>
|
|
||||||
core.services.config.getSmallConfig(SETTING_KEY_P2P_DEVICE_NAME) || core.services.vault.getVaultName();
|
|
||||||
|
|
||||||
const env = {
|
|
||||||
get settings() {
|
|
||||||
return getSettings();
|
|
||||||
},
|
|
||||||
get db() {
|
|
||||||
return getDB();
|
|
||||||
},
|
|
||||||
get simpleStore() {
|
|
||||||
return getSimpleStore();
|
|
||||||
},
|
|
||||||
get deviceName() {
|
|
||||||
return getDeviceName();
|
|
||||||
},
|
|
||||||
get platform() {
|
|
||||||
return core.services.API.getPlatform();
|
|
||||||
},
|
|
||||||
get confirm() {
|
|
||||||
return core.services.API.confirm;
|
|
||||||
},
|
|
||||||
processReplicatedDocs: async (docs: EntryDoc[]) => {
|
|
||||||
await core.services.replication.parseSynchroniseResult(docs as any);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return new TrysteroReplicator(env as any);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSortedPeers(replicator: TrysteroReplicator): CLIP2PPeer[] {
|
function getSortedPeers(replicator: LiveSyncTrysteroReplicator): CLIP2PPeer[] {
|
||||||
return [...replicator.knownAdvertisements]
|
return [...replicator.knownAdvertisements]
|
||||||
.map((peer) => ({ peerId: peer.peerId, name: peer.name }))
|
.map((peer) => ({ peerId: peer.peerId, name: peer.name }))
|
||||||
.sort((a, b) => a.peerId.localeCompare(b.peerId));
|
.sort((a, b) => a.peerId.localeCompare(b.peerId));
|
||||||
@@ -77,7 +47,7 @@ export async function collectPeers(
|
|||||||
core: LiveSyncBaseCore<ServiceContext, any>,
|
core: LiveSyncBaseCore<ServiceContext, any>,
|
||||||
timeoutSec: number
|
timeoutSec: number
|
||||||
): Promise<CLIP2PPeer[]> {
|
): Promise<CLIP2PPeer[]> {
|
||||||
const replicator = await createReplicator(core);
|
const replicator = createReplicator(core);
|
||||||
await replicator.open();
|
await replicator.open();
|
||||||
try {
|
try {
|
||||||
await delay(timeoutSec * 1000);
|
await delay(timeoutSec * 1000);
|
||||||
@@ -107,7 +77,7 @@ export async function syncWithPeer(
|
|||||||
peerToken: string,
|
peerToken: string,
|
||||||
timeoutSec: number
|
timeoutSec: number
|
||||||
): Promise<CLIP2PPeer> {
|
): Promise<CLIP2PPeer> {
|
||||||
const replicator = await createReplicator(core);
|
const replicator = createReplicator(core);
|
||||||
await replicator.open();
|
await replicator.open();
|
||||||
try {
|
try {
|
||||||
const timeoutMs = timeoutSec * 1000;
|
const timeoutMs = timeoutSec * 1000;
|
||||||
@@ -142,8 +112,8 @@ export async function syncWithPeer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function openP2PHost(core: LiveSyncBaseCore<ServiceContext, any>): Promise<TrysteroReplicator> {
|
export async function openP2PHost(core: LiveSyncBaseCore<ServiceContext, any>): Promise<LiveSyncTrysteroReplicator> {
|
||||||
const replicator = await createReplicator(core);
|
const replicator = createReplicator(core);
|
||||||
await replicator.open();
|
await replicator.open();
|
||||||
return replicator;
|
return replicator;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import { PouchDB } from "@lib/pouchdb/pouchdb-browser";
|
import { PouchDB } from "@lib/pouchdb/pouchdb-browser";
|
||||||
import {
|
import {
|
||||||
type EntryDoc,
|
type EntryDoc,
|
||||||
type LOG_LEVEL,
|
|
||||||
type ObsidianLiveSyncSettings,
|
type ObsidianLiveSyncSettings,
|
||||||
type P2PSyncSetting,
|
type P2PSyncSetting,
|
||||||
LOG_LEVEL_NOTICE,
|
|
||||||
LOG_LEVEL_VERBOSE,
|
LOG_LEVEL_VERBOSE,
|
||||||
P2P_DEFAULT_SETTINGS,
|
P2P_DEFAULT_SETTINGS,
|
||||||
REMOTE_P2P,
|
REMOTE_P2P,
|
||||||
@@ -12,35 +10,33 @@ import {
|
|||||||
import { eventHub } from "@lib/hub/hub";
|
import { eventHub } from "@lib/hub/hub";
|
||||||
|
|
||||||
import type { Confirm } from "@lib/interfaces/Confirm";
|
import type { Confirm } from "@lib/interfaces/Confirm";
|
||||||
import { LOG_LEVEL_INFO, Logger } from "@lib/common/logger";
|
import { LOG_LEVEL_NOTICE, Logger } from "@lib/common/logger";
|
||||||
import { storeP2PStatusLine } from "./CommandsShim";
|
import { storeP2PStatusLine } from "./CommandsShim";
|
||||||
import {
|
import {
|
||||||
EVENT_P2P_PEER_SHOW_EXTRA_MENU,
|
EVENT_P2P_PEER_SHOW_EXTRA_MENU,
|
||||||
type CommandShim,
|
|
||||||
type PeerStatus,
|
type PeerStatus,
|
||||||
type PluginShim,
|
type PluginShim,
|
||||||
} from "@lib/replication/trystero/P2PReplicatorPaneCommon";
|
} from "@lib/replication/trystero/P2PReplicatorPaneCommon";
|
||||||
import {
|
import {
|
||||||
closeP2PReplicator,
|
|
||||||
openP2PReplicator,
|
|
||||||
P2PLogCollector,
|
P2PLogCollector,
|
||||||
type P2PReplicatorBase,
|
type P2PReplicatorBase,
|
||||||
|
useP2PReplicator,
|
||||||
} from "@lib/replication/trystero/P2PReplicatorCore";
|
} from "@lib/replication/trystero/P2PReplicatorCore";
|
||||||
import type { SimpleStore } from "octagonal-wheels/databases/SimpleStoreBase";
|
import type { SimpleStore } from "octagonal-wheels/databases/SimpleStoreBase";
|
||||||
import { reactiveSource } from "octagonal-wheels/dataobject/reactive_v2";
|
import { reactiveSource } from "octagonal-wheels/dataobject/reactive_v2";
|
||||||
import { EVENT_SETTING_SAVED } from "@lib/events/coreEvents";
|
import { EVENT_SETTING_SAVED } from "@lib/events/coreEvents";
|
||||||
import { unique } from "octagonal-wheels/collection";
|
import { unique } from "octagonal-wheels/collection";
|
||||||
import { BrowserServiceHub } from "@lib/services/BrowserServices";
|
import { BrowserServiceHub } from "@lib/services/BrowserServices";
|
||||||
import { TrysteroReplicator } from "@lib/replication/trystero/TrysteroReplicator";
|
|
||||||
import { SETTING_KEY_P2P_DEVICE_NAME } from "@lib/common/types";
|
import { SETTING_KEY_P2P_DEVICE_NAME } from "@lib/common/types";
|
||||||
import { ServiceContext } from "@lib/services/base/ServiceBase";
|
import { ServiceContext } from "@lib/services/base/ServiceBase";
|
||||||
import type { InjectableServiceHub } from "@lib/services/InjectableServices";
|
import type { InjectableServiceHub } from "@lib/services/InjectableServices";
|
||||||
import { Menu } from "@lib/services/implements/browser/Menu";
|
import { Menu } from "@lib/services/implements/browser/Menu";
|
||||||
import type { InjectableVaultServiceCompat } from "@lib/services/implements/injectable/InjectableVaultService";
|
|
||||||
import { SimpleStoreIDBv2 } from "octagonal-wheels/databases/SimpleStoreIDBv2";
|
import { SimpleStoreIDBv2 } from "octagonal-wheels/databases/SimpleStoreIDBv2";
|
||||||
import type { InjectableAPIService } from "@/lib/src/services/implements/injectable/InjectableAPIService";
|
|
||||||
import type { BrowserAPIService } from "@/lib/src/services/implements/browser/BrowserAPIService";
|
import type { BrowserAPIService } from "@/lib/src/services/implements/browser/BrowserAPIService";
|
||||||
import type { InjectableSettingService } from "@/lib/src/services/implements/injectable/InjectableSettingService";
|
import type { InjectableSettingService } from "@/lib/src/services/implements/injectable/InjectableSettingService";
|
||||||
|
import {
|
||||||
|
LiveSyncTrysteroReplicator,
|
||||||
|
} from "@lib/replication/trystero/LiveSyncTrysteroReplicator";
|
||||||
|
|
||||||
function addToList(item: string, list: string) {
|
function addToList(item: string, list: string) {
|
||||||
return unique(
|
return unique(
|
||||||
@@ -60,12 +56,10 @@ function removeFromList(item: string, list: string) {
|
|||||||
.join(",");
|
.join(",");
|
||||||
}
|
}
|
||||||
|
|
||||||
export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim {
|
export class P2PReplicatorShim implements P2PReplicatorBase {
|
||||||
storeP2PStatusLine = reactiveSource("");
|
storeP2PStatusLine = reactiveSource("");
|
||||||
plugin!: PluginShim;
|
plugin!: PluginShim;
|
||||||
// environment!: IEnvironment;
|
|
||||||
confirm!: Confirm;
|
confirm!: Confirm;
|
||||||
// simpleStoreAPI!: ISimpleStoreAPI;
|
|
||||||
db?: PouchDB.Database<EntryDoc>;
|
db?: PouchDB.Database<EntryDoc>;
|
||||||
services: InjectableServiceHub<ServiceContext>;
|
services: InjectableServiceHub<ServiceContext>;
|
||||||
|
|
||||||
@@ -76,12 +70,26 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim {
|
|||||||
return this.db;
|
return this.db;
|
||||||
}
|
}
|
||||||
_simpleStore!: SimpleStore<any>;
|
_simpleStore!: SimpleStore<any>;
|
||||||
|
|
||||||
async closeDB() {
|
async closeDB() {
|
||||||
if (this.db) {
|
if (this.db) {
|
||||||
await this.db.close();
|
await this.db.close();
|
||||||
this.db = undefined;
|
this.db = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _liveSyncReplicator?: LiveSyncTrysteroReplicator;
|
||||||
|
p2pLogCollector!: P2PLogCollector;
|
||||||
|
|
||||||
|
private _initP2PReplicator() {
|
||||||
|
const { replicator, p2pLogCollector, storeP2PStatusLine: p2pStatusLine } = useP2PReplicator({ services: this.services } as any);
|
||||||
|
this._liveSyncReplicator = replicator;
|
||||||
|
this.p2pLogCollector = p2pLogCollector;
|
||||||
|
p2pLogCollector.p2pReplicationLine.onChanged((line) => {
|
||||||
|
storeP2PStatusLine.set(line.value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
const browserServiceHub = new BrowserServiceHub<ServiceContext>();
|
const browserServiceHub = new BrowserServiceHub<ServiceContext>();
|
||||||
this.services = browserServiceHub;
|
this.services = browserServiceHub;
|
||||||
@@ -89,7 +97,6 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim {
|
|||||||
(this.services.API as BrowserAPIService<ServiceContext>).getSystemVaultName.setHandler(
|
(this.services.API as BrowserAPIService<ServiceContext>).getSystemVaultName.setHandler(
|
||||||
() => "p2p-livesync-web-peer"
|
() => "p2p-livesync-web-peer"
|
||||||
);
|
);
|
||||||
// this.services.API.addLog.setHandler(Logger);
|
|
||||||
const repStore = SimpleStoreIDBv2.open<any>("p2p-livesync-web-peer");
|
const repStore = SimpleStoreIDBv2.open<any>("p2p-livesync-web-peer");
|
||||||
this._simpleStore = repStore;
|
this._simpleStore = repStore;
|
||||||
let _settings = { ...P2P_DEFAULT_SETTINGS, additionalSuffixOfDatabaseName: "" } as ObsidianLiveSyncSettings;
|
let _settings = { ...P2P_DEFAULT_SETTINGS, additionalSuffixOfDatabaseName: "" } as ObsidianLiveSyncSettings;
|
||||||
@@ -103,14 +110,13 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim {
|
|||||||
return settings;
|
return settings;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get settings() {
|
get settings() {
|
||||||
return this.services.setting.currentSettings() as P2PSyncSetting;
|
return this.services.setting.currentSettings() as P2PSyncSetting;
|
||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
// const { simpleStoreAPI } = await getWrappedSynchromesh();
|
|
||||||
// this.confirm = confirm;
|
|
||||||
this.confirm = this.services.UI.confirm;
|
this.confirm = this.services.UI.confirm;
|
||||||
// this.environment = environment;
|
|
||||||
|
|
||||||
if (this.db) {
|
if (this.db) {
|
||||||
try {
|
try {
|
||||||
@@ -123,30 +129,16 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim {
|
|||||||
|
|
||||||
await this.services.setting.loadSettings();
|
await this.services.setting.loadSettings();
|
||||||
this.plugin = {
|
this.plugin = {
|
||||||
// saveSettings: async () => {
|
|
||||||
// await repStore.set("settings", _settings);
|
|
||||||
// eventHub.emitEvent(EVENT_SETTING_SAVED, _settings);
|
|
||||||
// },
|
|
||||||
// get settings() {
|
|
||||||
// return _settings;
|
|
||||||
// },
|
|
||||||
// set settings(newSettings: P2PSyncSetting) {
|
|
||||||
// _settings = { ..._settings, ...newSettings };
|
|
||||||
// },
|
|
||||||
// rebuilder: null,
|
|
||||||
// core: {
|
|
||||||
// settings: this.services.setting.settings,
|
|
||||||
// },
|
|
||||||
services: this.services,
|
services: this.services,
|
||||||
core: {
|
core: {
|
||||||
services: this.services,
|
services: this.services,
|
||||||
},
|
},
|
||||||
// $$scheduleAppReload: () => {},
|
|
||||||
// $$getVaultName: () => "p2p-livesync-web-peer",
|
|
||||||
};
|
};
|
||||||
// const deviceName = this.getDeviceName();
|
|
||||||
const database_name = this.settings.P2P_AppID + "-" + this.settings.P2P_roomID + "p2p-livesync-web-peer";
|
const database_name = this.settings.P2P_AppID + "-" + this.settings.P2P_roomID + "p2p-livesync-web-peer";
|
||||||
this.db = new PouchDB<EntryDoc>(database_name);
|
this.db = new PouchDB<EntryDoc>(database_name);
|
||||||
|
|
||||||
|
this._initP2PReplicator();
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.settings.P2P_AutoStart && this.settings.P2P_Enabled) {
|
if (this.settings.P2P_AutoStart && this.settings.P2P_Enabled) {
|
||||||
void this.open();
|
void this.open();
|
||||||
@@ -155,7 +147,7 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
_log(msg: any, level?: LOG_LEVEL): void {
|
_log(msg: any, level?: any): void {
|
||||||
Logger(msg, level);
|
Logger(msg, level);
|
||||||
}
|
}
|
||||||
_notice(msg: string, key?: string): void {
|
_notice(msg: string, key?: string): void {
|
||||||
@@ -167,14 +159,10 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim {
|
|||||||
simpleStore(): SimpleStore<any> {
|
simpleStore(): SimpleStore<any> {
|
||||||
return this._simpleStore;
|
return this._simpleStore;
|
||||||
}
|
}
|
||||||
handleReplicatedDocuments(docs: EntryDoc[]): Promise<boolean> {
|
handleReplicatedDocuments(_docs: EntryDoc[]): Promise<boolean> {
|
||||||
// No op. This is a client and does not need to process the docs
|
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
getPluginShim() {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
getConfig(key: string) {
|
getConfig(key: string) {
|
||||||
const vaultName = this.services.vault.getVaultName();
|
const vaultName = this.services.vault.getVaultName();
|
||||||
const dbKey = `${vaultName}-${key}`;
|
const dbKey = `${vaultName}-${key}`;
|
||||||
@@ -189,9 +177,7 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim {
|
|||||||
getDeviceName(): string {
|
getDeviceName(): string {
|
||||||
return this.getConfig(SETTING_KEY_P2P_DEVICE_NAME) ?? this.plugin.services.vault.getVaultName();
|
return this.getConfig(SETTING_KEY_P2P_DEVICE_NAME) ?? this.plugin.services.vault.getVaultName();
|
||||||
}
|
}
|
||||||
getPlatform(): string {
|
|
||||||
return "pseudo-replicator";
|
|
||||||
}
|
|
||||||
m?: Menu;
|
m?: Menu;
|
||||||
afterConstructor(): void {
|
afterConstructor(): void {
|
||||||
eventHub.onEvent(EVENT_P2P_PEER_SHOW_EXTRA_MENU, ({ peer, event }) => {
|
eventHub.onEvent(EVENT_P2P_PEER_SHOW_EXTRA_MENU, ({ peer, event }) => {
|
||||||
@@ -202,12 +188,6 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim {
|
|||||||
.addItem((item) => item.setTitle("📥 Only Fetch").onClick(() => this.replicateFrom(peer)))
|
.addItem((item) => item.setTitle("📥 Only Fetch").onClick(() => this.replicateFrom(peer)))
|
||||||
.addItem((item) => item.setTitle("📤 Only Send").onClick(() => this.replicateTo(peer)))
|
.addItem((item) => item.setTitle("📤 Only Send").onClick(() => this.replicateTo(peer)))
|
||||||
.addSeparator()
|
.addSeparator()
|
||||||
// .addItem((item) => {
|
|
||||||
// item.setTitle("🔧 Get Configuration").onClick(async () => {
|
|
||||||
// await this.getRemoteConfig(peer);
|
|
||||||
// });
|
|
||||||
// })
|
|
||||||
// .addSeparator()
|
|
||||||
.addItem((item) => {
|
.addItem((item) => {
|
||||||
const mark = peer.syncOnConnect ? "checkmark" : null;
|
const mark = peer.syncOnConnect ? "checkmark" : null;
|
||||||
item.setTitle("Toggle Sync on connect")
|
item.setTitle("Toggle Sync on connect")
|
||||||
@@ -234,97 +214,43 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim {
|
|||||||
});
|
});
|
||||||
void this.m.showAtPosition({ x: event.x, y: event.y });
|
void this.m.showAtPosition({ x: event.x, y: event.y });
|
||||||
});
|
});
|
||||||
this.p2pLogCollector.p2pReplicationLine.onChanged((line) => {
|
|
||||||
storeP2PStatusLine.set(line.value);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_replicatorInstance?: TrysteroReplicator;
|
|
||||||
p2pLogCollector = new P2PLogCollector();
|
|
||||||
async open() {
|
async open() {
|
||||||
await openP2PReplicator(this);
|
await this._liveSyncReplicator?.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
async close() {
|
async close() {
|
||||||
await closeP2PReplicator(this);
|
await this._liveSyncReplicator?.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
enableBroadcastCastings() {
|
enableBroadcastCastings() {
|
||||||
return this?._replicatorInstance?.enableBroadcastChanges();
|
return this._liveSyncReplicator?.enableBroadcastChanges();
|
||||||
}
|
}
|
||||||
disableBroadcastCastings() {
|
disableBroadcastCastings() {
|
||||||
return this?._replicatorInstance?.disableBroadcastChanges();
|
return this._liveSyncReplicator?.disableBroadcastChanges();
|
||||||
}
|
|
||||||
|
|
||||||
async initialiseP2PReplicator(): Promise<TrysteroReplicator> {
|
|
||||||
await this.init();
|
|
||||||
try {
|
|
||||||
if (this._replicatorInstance) {
|
|
||||||
await this._replicatorInstance.close();
|
|
||||||
this._replicatorInstance = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.settings.P2P_AppID) {
|
|
||||||
this.settings.P2P_AppID = P2P_DEFAULT_SETTINGS.P2P_AppID;
|
|
||||||
}
|
|
||||||
const getInitialDeviceName = () =>
|
|
||||||
this.getConfig(SETTING_KEY_P2P_DEVICE_NAME) || this.services.vault.getVaultName();
|
|
||||||
|
|
||||||
const getSettings = () => this.settings;
|
|
||||||
const store = () => this.simpleStore();
|
|
||||||
const getDB = () => this.getDB();
|
|
||||||
|
|
||||||
const getConfirm = () => this.confirm;
|
|
||||||
const getPlatform = () => this.getPlatform();
|
|
||||||
const env = {
|
|
||||||
get db() {
|
|
||||||
return getDB();
|
|
||||||
},
|
|
||||||
get confirm() {
|
|
||||||
return getConfirm();
|
|
||||||
},
|
|
||||||
get deviceName() {
|
|
||||||
return getInitialDeviceName();
|
|
||||||
},
|
|
||||||
get platform() {
|
|
||||||
return getPlatform();
|
|
||||||
},
|
|
||||||
get settings() {
|
|
||||||
return getSettings();
|
|
||||||
},
|
|
||||||
processReplicatedDocs: async (docs: EntryDoc[]): Promise<void> => {
|
|
||||||
await this.handleReplicatedDocuments(docs);
|
|
||||||
// No op. This is a client and does not need to process the docs
|
|
||||||
},
|
|
||||||
get simpleStore() {
|
|
||||||
return store();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this._replicatorInstance = new TrysteroReplicator(env);
|
|
||||||
return this._replicatorInstance;
|
|
||||||
} catch (e) {
|
|
||||||
this._log(
|
|
||||||
e instanceof Error ? e.message : "Something occurred on Initialising P2P Replicator",
|
|
||||||
LOG_LEVEL_INFO
|
|
||||||
);
|
|
||||||
this._log(e, LOG_LEVEL_VERBOSE);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get replicator() {
|
get replicator() {
|
||||||
return this._replicatorInstance!;
|
return this._liveSyncReplicator;
|
||||||
}
|
}
|
||||||
|
|
||||||
async replicateFrom(peer: PeerStatus) {
|
async replicateFrom(peer: PeerStatus) {
|
||||||
await this.replicator.replicateFrom(peer.peerId);
|
const r = this._liveSyncReplicator;
|
||||||
|
if (!r) return;
|
||||||
|
await r.replicateFrom(peer.peerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async replicateTo(peer: PeerStatus) {
|
async replicateTo(peer: PeerStatus) {
|
||||||
await this.replicator.requestSynchroniseToPeer(peer.peerId);
|
await this._liveSyncReplicator?.requestSynchroniseToPeer(peer.peerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getRemoteConfig(peer: PeerStatus) {
|
async getRemoteConfig(peer: PeerStatus) {
|
||||||
Logger(
|
Logger(
|
||||||
`Requesting remote config for ${peer.name}. Please input the passphrase on the remote device`,
|
`Requesting remote config for ${peer.name}. Please input the passphrase on the remote device`,
|
||||||
LOG_LEVEL_NOTICE
|
LOG_LEVEL_NOTICE
|
||||||
);
|
);
|
||||||
const remoteConfig = await this.replicator.getRemoteConfig(peer.peerId);
|
const remoteConfig = await this._liveSyncReplicator?.getRemoteConfig(peer.peerId);
|
||||||
if (remoteConfig) {
|
if (remoteConfig) {
|
||||||
Logger(`Remote config for ${peer.name} is retrieved successfully`);
|
Logger(`Remote config for ${peer.name} is retrieved successfully`);
|
||||||
const DROP = "Yes, and drop local database";
|
const DROP = "Yes, and drop local database";
|
||||||
@@ -344,9 +270,7 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim {
|
|||||||
if (remoteConfig.remoteType !== REMOTE_P2P) {
|
if (remoteConfig.remoteType !== REMOTE_P2P) {
|
||||||
const yn2 = await this.confirm.askYesNoDialog(
|
const yn2 = await this.confirm.askYesNoDialog(
|
||||||
`Do you want to set the remote type to "P2P Sync" to rebuild by "P2P replication"?`,
|
`Do you want to set the remote type to "P2P Sync" to rebuild by "P2P replication"?`,
|
||||||
{
|
{ title: "Rebuild from remote device" }
|
||||||
title: "Rebuild from remote device",
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
if (yn2 === "yes") {
|
if (yn2 === "yes") {
|
||||||
remoteConfig.remoteType = REMOTE_P2P;
|
remoteConfig.remoteType = REMOTE_P2P;
|
||||||
@@ -355,9 +279,7 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
await this.services.setting.applyPartial(remoteConfig, true);
|
await this.services.setting.applyPartial(remoteConfig, true);
|
||||||
if (yn === DROP) {
|
if (yn !== DROP) {
|
||||||
// await this.plugin.rebuilder.scheduleFetch();
|
|
||||||
} else {
|
|
||||||
await this.plugin.core.services.appLifecycle.scheduleRestart();
|
await this.plugin.core.services.appLifecycle.scheduleRestart();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -381,8 +303,6 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim {
|
|||||||
[targetSetting]: currentSettingAll ? currentSettingAll[targetSetting] : "",
|
[targetSetting]: currentSettingAll ? currentSettingAll[targetSetting] : "",
|
||||||
};
|
};
|
||||||
if (peer[prop]) {
|
if (peer[prop]) {
|
||||||
// this.plugin.settings[targetSetting] = removeFromList(peer.name, this.plugin.settings[targetSetting]);
|
|
||||||
// await this.plugin.saveSettings();
|
|
||||||
currentSetting[targetSetting] = removeFromList(peer.name, currentSetting[targetSetting]);
|
currentSetting[targetSetting] = removeFromList(peer.name, currentSetting[targetSetting]);
|
||||||
} else {
|
} else {
|
||||||
currentSetting[targetSetting] = addToList(peer.name, currentSetting[targetSetting]);
|
currentSetting[targetSetting] = addToList(peer.name, currentSetting[targetSetting]);
|
||||||
|
|||||||
@@ -2,40 +2,36 @@ import { P2PReplicatorPaneView, VIEW_TYPE_P2P } from "./P2PReplicator/P2PReplica
|
|||||||
import {
|
import {
|
||||||
AutoAccepting,
|
AutoAccepting,
|
||||||
LOG_LEVEL_NOTICE,
|
LOG_LEVEL_NOTICE,
|
||||||
P2P_DEFAULT_SETTINGS,
|
|
||||||
REMOTE_P2P,
|
REMOTE_P2P,
|
||||||
type EntryDoc,
|
|
||||||
type P2PSyncSetting,
|
type P2PSyncSetting,
|
||||||
type RemoteDBSettings,
|
type RemoteDBSettings,
|
||||||
} from "../../lib/src/common/types.ts";
|
} from "../../lib/src/common/types.ts";
|
||||||
import { LiveSyncCommands } from "../LiveSyncCommands.ts";
|
import { LiveSyncCommands } from "../LiveSyncCommands.ts";
|
||||||
import {
|
import { LiveSyncTrysteroReplicator } from "../../lib/src/replication/trystero/LiveSyncTrysteroReplicator.ts";
|
||||||
LiveSyncTrysteroReplicator,
|
|
||||||
setReplicatorFunc,
|
|
||||||
} from "../../lib/src/replication/trystero/LiveSyncTrysteroReplicator.ts";
|
|
||||||
import { EVENT_REQUEST_OPEN_P2P, eventHub } from "../../common/events.ts";
|
import { EVENT_REQUEST_OPEN_P2P, eventHub } from "../../common/events.ts";
|
||||||
import type { LiveSyncAbstractReplicator } from "../../lib/src/replication/LiveSyncAbstractReplicator.ts";
|
import type { LiveSyncAbstractReplicator } from "../../lib/src/replication/LiveSyncAbstractReplicator.ts";
|
||||||
import { LOG_LEVEL_INFO, LOG_LEVEL_VERBOSE, Logger } from "octagonal-wheels/common/logger";
|
import { Logger } from "octagonal-wheels/common/logger";
|
||||||
import type { CommandShim } from "../../lib/src/replication/trystero/P2PReplicatorPaneCommon.ts";
|
|
||||||
import {
|
import {
|
||||||
addP2PEventHandlers,
|
|
||||||
closeP2PReplicator,
|
|
||||||
openP2PReplicator,
|
|
||||||
P2PLogCollector,
|
P2PLogCollector,
|
||||||
removeP2PReplicatorInstance,
|
|
||||||
type P2PReplicatorBase,
|
type P2PReplicatorBase,
|
||||||
|
useP2PReplicator,
|
||||||
} from "../../lib/src/replication/trystero/P2PReplicatorCore.ts";
|
} from "../../lib/src/replication/trystero/P2PReplicatorCore.ts";
|
||||||
import { reactiveSource } from "octagonal-wheels/dataobject/reactive_v2";
|
import type { ReactiveSource } from "octagonal-wheels/dataobject/reactive_v2";
|
||||||
import type { Confirm } from "../../lib/src/interfaces/Confirm.ts";
|
import type { Confirm } from "../../lib/src/interfaces/Confirm.ts";
|
||||||
import type ObsidianLiveSyncPlugin from "../../main.ts";
|
import type ObsidianLiveSyncPlugin from "../../main.ts";
|
||||||
import type { SimpleStore } from "octagonal-wheels/databases/SimpleStoreBase";
|
import type { SimpleStore } from "octagonal-wheels/databases/SimpleStoreBase";
|
||||||
// import { getPlatformName } from "../../lib/src/PlatformAPIs/obsidian/Environment.ts";
|
|
||||||
import type { LiveSyncCore } from "../../main.ts";
|
import type { LiveSyncCore } from "../../main.ts";
|
||||||
import { TrysteroReplicator } from "../../lib/src/replication/trystero/TrysteroReplicator.ts";
|
import type { EntryDoc } from "../../lib/src/common/types.ts";
|
||||||
import { SETTING_KEY_P2P_DEVICE_NAME } from "../../lib/src/common/types.ts";
|
|
||||||
|
|
||||||
export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase, CommandShim {
|
export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase {
|
||||||
storeP2PStatusLine = reactiveSource("");
|
storeP2PStatusLine!: ReactiveSource<string>;
|
||||||
|
p2pLogCollector!: P2PLogCollector;
|
||||||
|
|
||||||
|
private _liveSyncReplicator?: LiveSyncTrysteroReplicator;
|
||||||
|
|
||||||
|
get liveSyncReplicator() {
|
||||||
|
return this._liveSyncReplicator;
|
||||||
|
}
|
||||||
|
|
||||||
getSettings(): P2PSyncSetting {
|
getSettings(): P2PSyncSetting {
|
||||||
return this.core.settings;
|
return this.core.settings;
|
||||||
@@ -43,27 +39,20 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase
|
|||||||
getDB() {
|
getDB() {
|
||||||
return this.core.localDatabase.localDatabase;
|
return this.core.localDatabase.localDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
get confirm(): Confirm {
|
get confirm(): Confirm {
|
||||||
return this.core.confirm;
|
return this.core.confirm;
|
||||||
}
|
}
|
||||||
_simpleStore!: SimpleStore<any>;
|
_simpleStore!: SimpleStore<any>;
|
||||||
|
|
||||||
simpleStore(): SimpleStore<any> {
|
simpleStore(): SimpleStore<any> {
|
||||||
return this._simpleStore;
|
return this._simpleStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(plugin: ObsidianLiveSyncPlugin, core: LiveSyncCore) {
|
constructor(plugin: ObsidianLiveSyncPlugin, core: LiveSyncCore) {
|
||||||
super(plugin, core);
|
super(plugin, core);
|
||||||
setReplicatorFunc(() => this._replicatorInstance);
|
|
||||||
addP2PEventHandlers(this);
|
|
||||||
this.afterConstructor();
|
this.afterConstructor();
|
||||||
// onBindFunction is called in super class
|
|
||||||
// this.onBindFunction(plugin, plugin.services);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleReplicatedDocuments(docs: EntryDoc[]): Promise<boolean> {
|
async handleReplicatedDocuments(docs: EntryDoc[]): Promise<boolean> {
|
||||||
// console.log("Processing Replicated Docs", docs);
|
|
||||||
return await this.services.replication.parseSynchroniseResult(
|
return await this.services.replication.parseSynchroniseResult(
|
||||||
docs as PouchDB.Core.ExistingDocument<EntryDoc>[]
|
docs as PouchDB.Core.ExistingDocument<EntryDoc>[]
|
||||||
);
|
);
|
||||||
@@ -72,22 +61,21 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase
|
|||||||
_anyNewReplicator(settingOverride: Partial<RemoteDBSettings> = {}): Promise<LiveSyncAbstractReplicator> {
|
_anyNewReplicator(settingOverride: Partial<RemoteDBSettings> = {}): Promise<LiveSyncAbstractReplicator> {
|
||||||
const settings = { ...this.settings, ...settingOverride };
|
const settings = { ...this.settings, ...settingOverride };
|
||||||
if (settings.remoteType == REMOTE_P2P) {
|
if (settings.remoteType == REMOTE_P2P) {
|
||||||
return Promise.resolve(new LiveSyncTrysteroReplicator(this.plugin.core));
|
return Promise.resolve(new LiveSyncTrysteroReplicator({ services: this.services }));
|
||||||
}
|
}
|
||||||
return undefined!;
|
return undefined!;
|
||||||
}
|
}
|
||||||
_replicatorInstance?: TrysteroReplicator;
|
|
||||||
p2pLogCollector = new P2PLogCollector();
|
|
||||||
|
|
||||||
afterConstructor() {
|
afterConstructor() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
async open() {
|
async open() {
|
||||||
await openP2PReplicator(this);
|
await this._liveSyncReplicator?.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
async close() {
|
async close() {
|
||||||
await closeP2PReplicator(this);
|
await this._liveSyncReplicator?.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
getConfig(key: string) {
|
getConfig(key: string) {
|
||||||
@@ -97,10 +85,10 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase
|
|||||||
return this.services.config.setSmallConfig(key, value);
|
return this.services.config.setSmallConfig(key, value);
|
||||||
}
|
}
|
||||||
enableBroadcastCastings() {
|
enableBroadcastCastings() {
|
||||||
return this?._replicatorInstance?.enableBroadcastChanges();
|
return this._liveSyncReplicator?.enableBroadcastChanges();
|
||||||
}
|
}
|
||||||
disableBroadcastCastings() {
|
disableBroadcastCastings() {
|
||||||
return this?._replicatorInstance?.disableBroadcastChanges();
|
return this._liveSyncReplicator?.disableBroadcastChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
@@ -108,64 +96,7 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase
|
|||||||
return Promise.resolve(this);
|
return Promise.resolve(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
async initialiseP2PReplicator(): Promise<TrysteroReplicator> {
|
|
||||||
await this.init();
|
|
||||||
try {
|
|
||||||
if (this._replicatorInstance) {
|
|
||||||
await this._replicatorInstance.close();
|
|
||||||
this._replicatorInstance = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.settings.P2P_AppID) {
|
|
||||||
this.settings.P2P_AppID = P2P_DEFAULT_SETTINGS.P2P_AppID;
|
|
||||||
}
|
|
||||||
const getInitialDeviceName = () =>
|
|
||||||
this.getConfig(SETTING_KEY_P2P_DEVICE_NAME) || this.services.vault.getVaultName();
|
|
||||||
|
|
||||||
const getSettings = () => this.settings;
|
|
||||||
const store = () => this.simpleStore();
|
|
||||||
const getDB = () => this.getDB();
|
|
||||||
|
|
||||||
const getConfirm = () => this.confirm;
|
|
||||||
const getPlatform = () => this.services.API.getPlatform();
|
|
||||||
const env = {
|
|
||||||
get db() {
|
|
||||||
return getDB();
|
|
||||||
},
|
|
||||||
get confirm() {
|
|
||||||
return getConfirm();
|
|
||||||
},
|
|
||||||
get deviceName() {
|
|
||||||
return getInitialDeviceName();
|
|
||||||
},
|
|
||||||
get platform() {
|
|
||||||
return getPlatform();
|
|
||||||
},
|
|
||||||
get settings() {
|
|
||||||
return getSettings();
|
|
||||||
},
|
|
||||||
processReplicatedDocs: async (docs: EntryDoc[]): Promise<void> => {
|
|
||||||
await this.handleReplicatedDocuments(docs);
|
|
||||||
// No op. This is a client and does not need to process the docs
|
|
||||||
},
|
|
||||||
get simpleStore() {
|
|
||||||
return store();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this._replicatorInstance = new TrysteroReplicator(env);
|
|
||||||
return this._replicatorInstance;
|
|
||||||
} catch (e) {
|
|
||||||
this._log(
|
|
||||||
e instanceof Error ? e.message : "Something occurred on Initialising P2P Replicator",
|
|
||||||
LOG_LEVEL_INFO
|
|
||||||
);
|
|
||||||
this._log(e, LOG_LEVEL_VERBOSE);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onunload(): void {
|
onunload(): void {
|
||||||
removeP2PReplicatorInstance();
|
|
||||||
void this.close();
|
void this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,13 +104,6 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase
|
|||||||
eventHub.onEvent(EVENT_REQUEST_OPEN_P2P, () => {
|
eventHub.onEvent(EVENT_REQUEST_OPEN_P2P, () => {
|
||||||
void this.openPane();
|
void this.openPane();
|
||||||
});
|
});
|
||||||
this.p2pLogCollector.p2pReplicationLine.onChanged((line) => {
|
|
||||||
this.storeP2PStatusLine.value = line.value;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
async _everyOnInitializeDatabase(): Promise<boolean> {
|
|
||||||
await this.initialiseP2PReplicator();
|
|
||||||
return Promise.resolve(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _allSuspendExtraSync() {
|
private async _allSuspendExtraSync() {
|
||||||
@@ -192,10 +116,6 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase
|
|||||||
return await Promise.resolve(true);
|
return await Promise.resolve(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// async $everyOnLoadStart() {
|
|
||||||
// return await Promise.resolve();
|
|
||||||
// }
|
|
||||||
|
|
||||||
async openPane() {
|
async openPane() {
|
||||||
await this.services.API.showWindow(VIEW_TYPE_P2P);
|
await this.services.API.showWindow(VIEW_TYPE_P2P);
|
||||||
}
|
}
|
||||||
@@ -217,7 +137,7 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase
|
|||||||
name: "P2P Sync : Connect to the Signalling Server",
|
name: "P2P Sync : Connect to the Signalling Server",
|
||||||
checkCallback: (isChecking) => {
|
checkCallback: (isChecking) => {
|
||||||
if (isChecking) {
|
if (isChecking) {
|
||||||
return !(this._replicatorInstance?.server?.isServing ?? false);
|
return !(this._liveSyncReplicator?.server?.isServing ?? false);
|
||||||
}
|
}
|
||||||
void this.open();
|
void this.open();
|
||||||
},
|
},
|
||||||
@@ -227,7 +147,7 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase
|
|||||||
name: "P2P Sync : Disconnect from the Signalling Server",
|
name: "P2P Sync : Disconnect from the Signalling Server",
|
||||||
checkCallback: (isChecking) => {
|
checkCallback: (isChecking) => {
|
||||||
if (isChecking) {
|
if (isChecking) {
|
||||||
return this._replicatorInstance?.server?.isServing ?? false;
|
return this._liveSyncReplicator?.server?.isServing ?? false;
|
||||||
}
|
}
|
||||||
Logger(`Closing P2P Connection`, LOG_LEVEL_NOTICE);
|
Logger(`Closing P2P Connection`, LOG_LEVEL_NOTICE);
|
||||||
void this.close();
|
void this.close();
|
||||||
@@ -239,10 +159,10 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase
|
|||||||
checkCallback: (isChecking) => {
|
checkCallback: (isChecking) => {
|
||||||
if (isChecking) {
|
if (isChecking) {
|
||||||
if (this.settings.remoteType == REMOTE_P2P) return false;
|
if (this.settings.remoteType == REMOTE_P2P) return false;
|
||||||
if (!this._replicatorInstance?.server?.isServing) return false;
|
if (!this._liveSyncReplicator?.server?.isServing) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void this._replicatorInstance?.replicateFromCommand(false);
|
void this._liveSyncReplicator?.replicateFromCommand(false);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
this.plugin
|
this.plugin
|
||||||
@@ -253,26 +173,16 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase
|
|||||||
|
|
||||||
return await Promise.resolve(true);
|
return await Promise.resolve(true);
|
||||||
}
|
}
|
||||||
_everyAfterResumeProcess(): Promise<boolean> {
|
|
||||||
if (this.settings.P2P_Enabled && this.settings.P2P_AutoStart) {
|
|
||||||
setTimeout(() => void this.open(), 100);
|
|
||||||
}
|
|
||||||
const rep = this._replicatorInstance;
|
|
||||||
rep?.allowReconnection();
|
|
||||||
return Promise.resolve(true);
|
|
||||||
}
|
|
||||||
_everyBeforeSuspendProcess(): Promise<boolean> {
|
|
||||||
const rep = this._replicatorInstance;
|
|
||||||
rep?.disconnectFromServer();
|
|
||||||
return Promise.resolve(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
override onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
override onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||||
|
// Initialise useP2PReplicator — wires lifecycle, event handlers, and log collector
|
||||||
|
const { replicator, p2pLogCollector, storeP2PStatusLine } = useP2PReplicator({ services } as any);
|
||||||
|
this._liveSyncReplicator = replicator;
|
||||||
|
this.p2pLogCollector = p2pLogCollector;
|
||||||
|
this.storeP2PStatusLine = storeP2PStatusLine;
|
||||||
|
|
||||||
services.replicator.getNewReplicator.addHandler(this._anyNewReplicator.bind(this));
|
services.replicator.getNewReplicator.addHandler(this._anyNewReplicator.bind(this));
|
||||||
services.databaseEvents.onDatabaseInitialisation.addHandler(this._everyOnInitializeDatabase.bind(this));
|
|
||||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||||
services.appLifecycle.onSuspending.addHandler(this._everyBeforeSuspendProcess.bind(this));
|
|
||||||
services.appLifecycle.onResumed.addHandler(this._everyAfterResumeProcess.bind(this));
|
|
||||||
services.setting.suspendExtraSync.addHandler(this._allSuspendExtraSync.bind(this));
|
services.setting.suspendExtraSync.addHandler(this._allSuspendExtraSync.bind(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,9 @@
|
|||||||
import {
|
import {
|
||||||
AcceptedStatus,
|
AcceptedStatus,
|
||||||
ConnectionStatus,
|
ConnectionStatus,
|
||||||
type CommandShim,
|
|
||||||
type PeerStatus,
|
type PeerStatus,
|
||||||
type PluginShim,
|
|
||||||
} from "../../../lib/src/replication/trystero/P2PReplicatorPaneCommon";
|
} from "../../../lib/src/replication/trystero/P2PReplicatorPaneCommon";
|
||||||
|
import type { P2PReplicator } from "../CmdP2PReplicator";
|
||||||
import PeerStatusRow from "../P2PReplicator/PeerStatusRow.svelte";
|
import PeerStatusRow from "../P2PReplicator/PeerStatusRow.svelte";
|
||||||
import { EVENT_LAYOUT_READY, eventHub } from "../../../common/events";
|
import { EVENT_LAYOUT_READY, eventHub } from "../../../common/events";
|
||||||
import {
|
import {
|
||||||
@@ -23,7 +22,7 @@
|
|||||||
import type { LiveSyncBaseCore } from "@/LiveSyncBaseCore";
|
import type { LiveSyncBaseCore } from "@/LiveSyncBaseCore";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
cmdSync: CommandShim;
|
cmdSync: P2PReplicator;
|
||||||
core: LiveSyncBaseCore;
|
core: LiveSyncBaseCore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,9 +94,8 @@
|
|||||||
},
|
},
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
cmdSync.setConfig(SETTING_KEY_P2P_DEVICE_NAME, eDeviceName);
|
core.services.config.setSmallConfig(SETTING_KEY_P2P_DEVICE_NAME, eDeviceName);
|
||||||
deviceName = eDeviceName;
|
deviceName = eDeviceName;
|
||||||
// await plugin.saveSettings();
|
|
||||||
}
|
}
|
||||||
async function revert() {
|
async function revert() {
|
||||||
eP2PEnabled = settings.P2P_Enabled;
|
eP2PEnabled = settings.P2P_Enabled;
|
||||||
@@ -115,7 +113,7 @@
|
|||||||
const applyLoadSettings = (d: P2PSyncSetting, force: boolean) => {
|
const applyLoadSettings = (d: P2PSyncSetting, force: boolean) => {
|
||||||
if (force) {
|
if (force) {
|
||||||
const initDeviceName =
|
const initDeviceName =
|
||||||
cmdSync.getConfig(SETTING_KEY_P2P_DEVICE_NAME) ?? core.services.vault.getVaultName();
|
core.services.config.getSmallConfig(SETTING_KEY_P2P_DEVICE_NAME) ?? core.services.vault.getVaultName();
|
||||||
deviceName = initDeviceName;
|
deviceName = initDeviceName;
|
||||||
eDeviceName = initDeviceName;
|
eDeviceName = initDeviceName;
|
||||||
}
|
}
|
||||||
@@ -248,7 +246,7 @@
|
|||||||
const initialDialogStatusKey = `p2p-dialog-status`;
|
const initialDialogStatusKey = `p2p-dialog-status`;
|
||||||
const getDialogStatus = () => {
|
const getDialogStatus = () => {
|
||||||
try {
|
try {
|
||||||
const initialDialogStatus = JSON.parse(cmdSync.getConfig(initialDialogStatusKey) ?? "{}") as {
|
const initialDialogStatus = JSON.parse(core.services.config.getSmallConfig(initialDialogStatusKey) ?? "{}") as {
|
||||||
notice?: boolean;
|
notice?: boolean;
|
||||||
setting?: boolean;
|
setting?: boolean;
|
||||||
};
|
};
|
||||||
@@ -265,7 +263,7 @@
|
|||||||
notice: isNoticeOpened,
|
notice: isNoticeOpened,
|
||||||
setting: isSettingOpened,
|
setting: isSettingOpened,
|
||||||
};
|
};
|
||||||
cmdSync.setConfig(initialDialogStatusKey, JSON.stringify(dialogStatus));
|
core.services.config.setSmallConfig(initialDialogStatusKey, JSON.stringify(dialogStatus));
|
||||||
});
|
});
|
||||||
let isObsidian = $derived.by(() => {
|
let isObsidian = $derived.by(() => {
|
||||||
return core.services.API.getPlatform() === "obsidian";
|
return core.services.API.getPlatform() === "obsidian";
|
||||||
|
|||||||
@@ -46,10 +46,10 @@ export class P2PReplicatorPaneView extends SvelteItemView {
|
|||||||
}
|
}
|
||||||
get replicator() {
|
get replicator() {
|
||||||
const r = this.core.getAddOn<P2PReplicator>(P2PReplicator.name);
|
const r = this.core.getAddOn<P2PReplicator>(P2PReplicator.name);
|
||||||
if (!r || !r._replicatorInstance) {
|
if (!r || !r.liveSyncReplicator) {
|
||||||
throw new Error("Replicator not found");
|
throw new Error("Replicator not found");
|
||||||
}
|
}
|
||||||
return r._replicatorInstance;
|
return r.liveSyncReplicator;
|
||||||
}
|
}
|
||||||
async replicateFrom(peer: PeerStatus) {
|
async replicateFrom(peer: PeerStatus) {
|
||||||
await this.replicator.replicateFrom(peer.peerId);
|
await this.replicator.replicateFrom(peer.peerId);
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
let isNew = $derived.by(() => peer.accepted === AcceptedStatus.UNKNOWN);
|
let isNew = $derived.by(() => peer.accepted === AcceptedStatus.UNKNOWN);
|
||||||
|
|
||||||
function makeDecision(isAccepted: boolean, isTemporary: boolean) {
|
function makeDecision(isAccepted: boolean, isTemporary: boolean) {
|
||||||
cmdReplicator._replicatorInstance?.server?.makeDecision({
|
cmdReplicator.liveSyncReplicator?.makeDecision({
|
||||||
peerId: peer.peerId,
|
peerId: peer.peerId,
|
||||||
name: peer.name,
|
name: peer.name,
|
||||||
decision: isAccepted,
|
decision: isAccepted,
|
||||||
@@ -65,13 +65,13 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
function revokeDecision() {
|
function revokeDecision() {
|
||||||
cmdReplicator._replicatorInstance?.server?.revokeDecision({
|
cmdReplicator.liveSyncReplicator?.revokeDecision({
|
||||||
peerId: peer.peerId,
|
peerId: peer.peerId,
|
||||||
name: peer.name,
|
name: peer.name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const cmdReplicator = getContext<() => P2PReplicator>("getReplicator")();
|
const cmdReplicator = getContext<() => P2PReplicator>("getReplicator")();
|
||||||
const replicator = cmdReplicator._replicatorInstance!;
|
const replicator = cmdReplicator.liveSyncReplicator;
|
||||||
|
|
||||||
const peerAttrLabels = $derived.by(() => {
|
const peerAttrLabels = $derived.by(() => {
|
||||||
const attrs = [];
|
const attrs = [];
|
||||||
@@ -87,14 +87,14 @@
|
|||||||
return attrs;
|
return attrs;
|
||||||
});
|
});
|
||||||
function startWatching() {
|
function startWatching() {
|
||||||
replicator.watchPeer(peer.peerId);
|
replicator?.watchPeer(peer.peerId);
|
||||||
}
|
}
|
||||||
function stopWatching() {
|
function stopWatching() {
|
||||||
replicator.unwatchPeer(peer.peerId);
|
replicator?.unwatchPeer(peer.peerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function sync() {
|
function sync() {
|
||||||
replicator.sync(peer.peerId, false);
|
void replicator?.sync(peer.peerId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function moreMenu(evt: MouseEvent) {
|
function moreMenu(evt: MouseEvent) {
|
||||||
|
|||||||
+1
-1
Submodule src/lib updated: 10aa32108b...b5f22eb8f3
@@ -1,6 +1,6 @@
|
|||||||
import { expect } from "vitest";
|
import { expect } from "vitest";
|
||||||
import { waitForIdle, type LiveSyncHarness } from "../harness/harness";
|
import { waitForIdle, type LiveSyncHarness } from "../harness/harness";
|
||||||
import { LOG_LEVEL_INFO, RemoteTypes, type ObsidianLiveSyncSettings } from "@/lib/src/common/types";
|
import { RemoteTypes, type ObsidianLiveSyncSettings } from "@/lib/src/common/types";
|
||||||
|
|
||||||
import { delay, fireAndForget } from "@/lib/src/common/utils";
|
import { delay, fireAndForget } from "@/lib/src/common/utils";
|
||||||
import { commands } from "vitest/browser";
|
import { commands } from "vitest/browser";
|
||||||
@@ -15,14 +15,10 @@ async function waitForP2PPeers(harness: LiveSyncHarness) {
|
|||||||
if (!(replicator instanceof LiveSyncTrysteroReplicator)) {
|
if (!(replicator instanceof LiveSyncTrysteroReplicator)) {
|
||||||
throw new Error("Replicator is not an instance of LiveSyncTrysteroReplicator");
|
throw new Error("Replicator is not an instance of LiveSyncTrysteroReplicator");
|
||||||
}
|
}
|
||||||
const p2pReplicator = await replicator.getP2PConnection(LOG_LEVEL_INFO);
|
|
||||||
if (!p2pReplicator) {
|
|
||||||
throw new Error("P2P Replicator is not initialized");
|
|
||||||
}
|
|
||||||
while (retries-- > 0) {
|
while (retries-- > 0) {
|
||||||
fireAndForget(() => commands.acceptWebPeer());
|
fireAndForget(() => commands.acceptWebPeer());
|
||||||
await delay(1000);
|
await delay(1000);
|
||||||
const peers = p2pReplicator.knownAdvertisements;
|
const peers = replicator.knownAdvertisements;
|
||||||
|
|
||||||
if (peers && peers.length > 0) {
|
if (peers && peers.length > 0) {
|
||||||
console.log("P2P peers connected:", peers);
|
console.log("P2P peers connected:", peers);
|
||||||
|
|||||||
Reference in New Issue
Block a user