diff --git a/src/apps/cli/commands/p2p.ts b/src/apps/cli/commands/p2p.ts index 41013e0..dab475e 100644 --- a/src/apps/cli/commands/p2p.ts +++ b/src/apps/cli/commands/p2p.ts @@ -1,7 +1,7 @@ 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 { TrysteroReplicator } from "@lib/replication/trystero/TrysteroReplicator"; +import { LiveSyncTrysteroReplicator } from "@lib/replication/trystero/LiveSyncTrysteroReplicator"; type CLIP2PPeer = { peerId: string; @@ -32,42 +32,12 @@ function validateP2PSettings(core: LiveSyncBaseCore) { settings.P2P_IsHeadless = true; } -async function createReplicator(core: LiveSyncBaseCore): Promise { +function createReplicator(core: LiveSyncBaseCore): LiveSyncTrysteroReplicator { validateP2PSettings(core); - const getSettings = () => core.services.setting.currentSettings(); - 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); + return new LiveSyncTrysteroReplicator({ services: core.services }); } -function getSortedPeers(replicator: TrysteroReplicator): CLIP2PPeer[] { +function getSortedPeers(replicator: LiveSyncTrysteroReplicator): CLIP2PPeer[] { return [...replicator.knownAdvertisements] .map((peer) => ({ peerId: peer.peerId, name: peer.name })) .sort((a, b) => a.peerId.localeCompare(b.peerId)); @@ -77,7 +47,7 @@ export async function collectPeers( core: LiveSyncBaseCore, timeoutSec: number ): Promise { - const replicator = await createReplicator(core); + const replicator = createReplicator(core); await replicator.open(); try { await delay(timeoutSec * 1000); @@ -107,7 +77,7 @@ export async function syncWithPeer( peerToken: string, timeoutSec: number ): Promise { - const replicator = await createReplicator(core); + const replicator = createReplicator(core); await replicator.open(); try { const timeoutMs = timeoutSec * 1000; @@ -142,8 +112,8 @@ export async function syncWithPeer( } } -export async function openP2PHost(core: LiveSyncBaseCore): Promise { - const replicator = await createReplicator(core); +export async function openP2PHost(core: LiveSyncBaseCore): Promise { + const replicator = createReplicator(core); await replicator.open(); return replicator; } diff --git a/src/apps/webpeer/src/P2PReplicatorShim.ts b/src/apps/webpeer/src/P2PReplicatorShim.ts index 282c60d..63f2b7e 100644 --- a/src/apps/webpeer/src/P2PReplicatorShim.ts +++ b/src/apps/webpeer/src/P2PReplicatorShim.ts @@ -1,10 +1,8 @@ import { PouchDB } from "@lib/pouchdb/pouchdb-browser"; import { type EntryDoc, - type LOG_LEVEL, type ObsidianLiveSyncSettings, type P2PSyncSetting, - LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE, P2P_DEFAULT_SETTINGS, REMOTE_P2P, @@ -12,35 +10,33 @@ import { import { eventHub } from "@lib/hub/hub"; 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 { EVENT_P2P_PEER_SHOW_EXTRA_MENU, - type CommandShim, type PeerStatus, type PluginShim, } from "@lib/replication/trystero/P2PReplicatorPaneCommon"; import { - closeP2PReplicator, - openP2PReplicator, P2PLogCollector, type P2PReplicatorBase, + useP2PReplicator, } from "@lib/replication/trystero/P2PReplicatorCore"; import type { SimpleStore } from "octagonal-wheels/databases/SimpleStoreBase"; import { reactiveSource } from "octagonal-wheels/dataobject/reactive_v2"; import { EVENT_SETTING_SAVED } from "@lib/events/coreEvents"; import { unique } from "octagonal-wheels/collection"; import { BrowserServiceHub } from "@lib/services/BrowserServices"; -import { TrysteroReplicator } from "@lib/replication/trystero/TrysteroReplicator"; import { SETTING_KEY_P2P_DEVICE_NAME } from "@lib/common/types"; import { ServiceContext } from "@lib/services/base/ServiceBase"; import type { InjectableServiceHub } from "@lib/services/InjectableServices"; 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 type { InjectableAPIService } from "@/lib/src/services/implements/injectable/InjectableAPIService"; import type { BrowserAPIService } from "@/lib/src/services/implements/browser/BrowserAPIService"; import type { InjectableSettingService } from "@/lib/src/services/implements/injectable/InjectableSettingService"; +import { + LiveSyncTrysteroReplicator, +} from "@lib/replication/trystero/LiveSyncTrysteroReplicator"; function addToList(item: string, list: string) { return unique( @@ -60,12 +56,10 @@ function removeFromList(item: string, list: string) { .join(","); } -export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim { +export class P2PReplicatorShim implements P2PReplicatorBase { storeP2PStatusLine = reactiveSource(""); plugin!: PluginShim; - // environment!: IEnvironment; confirm!: Confirm; - // simpleStoreAPI!: ISimpleStoreAPI; db?: PouchDB.Database; services: InjectableServiceHub; @@ -76,12 +70,26 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim { return this.db; } _simpleStore!: SimpleStore; + async closeDB() { if (this.db) { await this.db.close(); 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() { const browserServiceHub = new BrowserServiceHub(); this.services = browserServiceHub; @@ -89,7 +97,6 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim { (this.services.API as BrowserAPIService).getSystemVaultName.setHandler( () => "p2p-livesync-web-peer" ); - // this.services.API.addLog.setHandler(Logger); const repStore = SimpleStoreIDBv2.open("p2p-livesync-web-peer"); this._simpleStore = repStore; let _settings = { ...P2P_DEFAULT_SETTINGS, additionalSuffixOfDatabaseName: "" } as ObsidianLiveSyncSettings; @@ -103,14 +110,13 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim { return settings; }); } + get settings() { return this.services.setting.currentSettings() as P2PSyncSetting; } + async init() { - // const { simpleStoreAPI } = await getWrappedSynchromesh(); - // this.confirm = confirm; this.confirm = this.services.UI.confirm; - // this.environment = environment; if (this.db) { try { @@ -123,30 +129,16 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim { await this.services.setting.loadSettings(); 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, core: { 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"; this.db = new PouchDB(database_name); + + this._initP2PReplicator(); + setTimeout(() => { if (this.settings.P2P_AutoStart && this.settings.P2P_Enabled) { void this.open(); @@ -155,7 +147,7 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim { return this; } - _log(msg: any, level?: LOG_LEVEL): void { + _log(msg: any, level?: any): void { Logger(msg, level); } _notice(msg: string, key?: string): void { @@ -167,14 +159,10 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim { simpleStore(): SimpleStore { return this._simpleStore; } - handleReplicatedDocuments(docs: EntryDoc[]): Promise { - // No op. This is a client and does not need to process the docs + handleReplicatedDocuments(_docs: EntryDoc[]): Promise { return Promise.resolve(true); } - getPluginShim() { - return {}; - } getConfig(key: string) { const vaultName = this.services.vault.getVaultName(); const dbKey = `${vaultName}-${key}`; @@ -189,9 +177,7 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim { getDeviceName(): string { return this.getConfig(SETTING_KEY_P2P_DEVICE_NAME) ?? this.plugin.services.vault.getVaultName(); } - getPlatform(): string { - return "pseudo-replicator"; - } + m?: Menu; afterConstructor(): void { 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 Send").onClick(() => this.replicateTo(peer))) .addSeparator() - // .addItem((item) => { - // item.setTitle("🔧 Get Configuration").onClick(async () => { - // await this.getRemoteConfig(peer); - // }); - // }) - // .addSeparator() .addItem((item) => { const mark = peer.syncOnConnect ? "checkmark" : null; 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 }); }); - this.p2pLogCollector.p2pReplicationLine.onChanged((line) => { - storeP2PStatusLine.set(line.value); - }); } - _replicatorInstance?: TrysteroReplicator; - p2pLogCollector = new P2PLogCollector(); async open() { - await openP2PReplicator(this); + await this._liveSyncReplicator?.open(); } + async close() { - await closeP2PReplicator(this); + await this._liveSyncReplicator?.close(); } + enableBroadcastCastings() { - return this?._replicatorInstance?.enableBroadcastChanges(); + return this._liveSyncReplicator?.enableBroadcastChanges(); } disableBroadcastCastings() { - return this?._replicatorInstance?.disableBroadcastChanges(); - } - - async initialiseP2PReplicator(): Promise { - 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 => { - 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; - } + return this._liveSyncReplicator?.disableBroadcastChanges(); } get replicator() { - return this._replicatorInstance!; + return this._liveSyncReplicator; } + 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) { - await this.replicator.requestSynchroniseToPeer(peer.peerId); + await this._liveSyncReplicator?.requestSynchroniseToPeer(peer.peerId); } + async getRemoteConfig(peer: PeerStatus) { Logger( `Requesting remote config for ${peer.name}. Please input the passphrase on the remote device`, LOG_LEVEL_NOTICE ); - const remoteConfig = await this.replicator.getRemoteConfig(peer.peerId); + const remoteConfig = await this._liveSyncReplicator?.getRemoteConfig(peer.peerId); if (remoteConfig) { Logger(`Remote config for ${peer.name} is retrieved successfully`); const DROP = "Yes, and drop local database"; @@ -344,9 +270,7 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim { if (remoteConfig.remoteType !== REMOTE_P2P) { const yn2 = await this.confirm.askYesNoDialog( `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") { remoteConfig.remoteType = REMOTE_P2P; @@ -355,9 +279,7 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim { } } await this.services.setting.applyPartial(remoteConfig, true); - if (yn === DROP) { - // await this.plugin.rebuilder.scheduleFetch(); - } else { + if (yn !== DROP) { await this.plugin.core.services.appLifecycle.scheduleRestart(); } } else { @@ -381,8 +303,6 @@ export class P2PReplicatorShim implements P2PReplicatorBase, CommandShim { [targetSetting]: currentSettingAll ? currentSettingAll[targetSetting] : "", }; 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]); } else { currentSetting[targetSetting] = addToList(peer.name, currentSetting[targetSetting]); diff --git a/src/features/P2PSync/CmdP2PReplicator.ts b/src/features/P2PSync/CmdP2PReplicator.ts index fbbd37b..0325176 100644 --- a/src/features/P2PSync/CmdP2PReplicator.ts +++ b/src/features/P2PSync/CmdP2PReplicator.ts @@ -2,40 +2,36 @@ import { P2PReplicatorPaneView, VIEW_TYPE_P2P } from "./P2PReplicator/P2PReplica import { AutoAccepting, LOG_LEVEL_NOTICE, - P2P_DEFAULT_SETTINGS, REMOTE_P2P, - type EntryDoc, type P2PSyncSetting, type RemoteDBSettings, } from "../../lib/src/common/types.ts"; import { LiveSyncCommands } from "../LiveSyncCommands.ts"; -import { - LiveSyncTrysteroReplicator, - setReplicatorFunc, -} from "../../lib/src/replication/trystero/LiveSyncTrysteroReplicator.ts"; +import { LiveSyncTrysteroReplicator } from "../../lib/src/replication/trystero/LiveSyncTrysteroReplicator.ts"; import { EVENT_REQUEST_OPEN_P2P, eventHub } from "../../common/events.ts"; import type { LiveSyncAbstractReplicator } from "../../lib/src/replication/LiveSyncAbstractReplicator.ts"; -import { LOG_LEVEL_INFO, LOG_LEVEL_VERBOSE, Logger } from "octagonal-wheels/common/logger"; -import type { CommandShim } from "../../lib/src/replication/trystero/P2PReplicatorPaneCommon.ts"; +import { Logger } from "octagonal-wheels/common/logger"; import { - addP2PEventHandlers, - closeP2PReplicator, - openP2PReplicator, P2PLogCollector, - removeP2PReplicatorInstance, type P2PReplicatorBase, + useP2PReplicator, } 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 ObsidianLiveSyncPlugin from "../../main.ts"; import type { SimpleStore } from "octagonal-wheels/databases/SimpleStoreBase"; -// import { getPlatformName } from "../../lib/src/PlatformAPIs/obsidian/Environment.ts"; import type { LiveSyncCore } from "../../main.ts"; -import { TrysteroReplicator } from "../../lib/src/replication/trystero/TrysteroReplicator.ts"; -import { SETTING_KEY_P2P_DEVICE_NAME } from "../../lib/src/common/types.ts"; +import type { EntryDoc } from "../../lib/src/common/types.ts"; -export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase, CommandShim { - storeP2PStatusLine = reactiveSource(""); +export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase { + storeP2PStatusLine!: ReactiveSource; + p2pLogCollector!: P2PLogCollector; + + private _liveSyncReplicator?: LiveSyncTrysteroReplicator; + + get liveSyncReplicator() { + return this._liveSyncReplicator; + } getSettings(): P2PSyncSetting { return this.core.settings; @@ -43,27 +39,20 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase getDB() { return this.core.localDatabase.localDatabase; } - get confirm(): Confirm { return this.core.confirm; } _simpleStore!: SimpleStore; - simpleStore(): SimpleStore { return this._simpleStore; } constructor(plugin: ObsidianLiveSyncPlugin, core: LiveSyncCore) { super(plugin, core); - setReplicatorFunc(() => this._replicatorInstance); - addP2PEventHandlers(this); this.afterConstructor(); - // onBindFunction is called in super class - // this.onBindFunction(plugin, plugin.services); } async handleReplicatedDocuments(docs: EntryDoc[]): Promise { - // console.log("Processing Replicated Docs", docs); return await this.services.replication.parseSynchroniseResult( docs as PouchDB.Core.ExistingDocument[] ); @@ -72,22 +61,21 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase _anyNewReplicator(settingOverride: Partial = {}): Promise { const settings = { ...this.settings, ...settingOverride }; if (settings.remoteType == REMOTE_P2P) { - return Promise.resolve(new LiveSyncTrysteroReplicator(this.plugin.core)); + return Promise.resolve(new LiveSyncTrysteroReplicator({ services: this.services })); } return undefined!; } - _replicatorInstance?: TrysteroReplicator; - p2pLogCollector = new P2PLogCollector(); afterConstructor() { return; } async open() { - await openP2PReplicator(this); + await this._liveSyncReplicator?.open(); } + async close() { - await closeP2PReplicator(this); + await this._liveSyncReplicator?.close(); } getConfig(key: string) { @@ -97,10 +85,10 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase return this.services.config.setSmallConfig(key, value); } enableBroadcastCastings() { - return this?._replicatorInstance?.enableBroadcastChanges(); + return this._liveSyncReplicator?.enableBroadcastChanges(); } disableBroadcastCastings() { - return this?._replicatorInstance?.disableBroadcastChanges(); + return this._liveSyncReplicator?.disableBroadcastChanges(); } init() { @@ -108,64 +96,7 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase return Promise.resolve(this); } - async initialiseP2PReplicator(): Promise { - 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 => { - 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 { - removeP2PReplicatorInstance(); void this.close(); } @@ -173,13 +104,6 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase eventHub.onEvent(EVENT_REQUEST_OPEN_P2P, () => { void this.openPane(); }); - this.p2pLogCollector.p2pReplicationLine.onChanged((line) => { - this.storeP2PStatusLine.value = line.value; - }); - } - async _everyOnInitializeDatabase(): Promise { - await this.initialiseP2PReplicator(); - return Promise.resolve(true); } private async _allSuspendExtraSync() { @@ -192,10 +116,6 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase return await Promise.resolve(true); } - // async $everyOnLoadStart() { - // return await Promise.resolve(); - // } - async openPane() { 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", checkCallback: (isChecking) => { if (isChecking) { - return !(this._replicatorInstance?.server?.isServing ?? false); + return !(this._liveSyncReplicator?.server?.isServing ?? false); } void this.open(); }, @@ -227,7 +147,7 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase name: "P2P Sync : Disconnect from the Signalling Server", checkCallback: (isChecking) => { if (isChecking) { - return this._replicatorInstance?.server?.isServing ?? false; + return this._liveSyncReplicator?.server?.isServing ?? false; } Logger(`Closing P2P Connection`, LOG_LEVEL_NOTICE); void this.close(); @@ -239,10 +159,10 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase checkCallback: (isChecking) => { if (isChecking) { if (this.settings.remoteType == REMOTE_P2P) return false; - if (!this._replicatorInstance?.server?.isServing) return false; + if (!this._liveSyncReplicator?.server?.isServing) return false; return true; } - void this._replicatorInstance?.replicateFromCommand(false); + void this._liveSyncReplicator?.replicateFromCommand(false); }, }); this.plugin @@ -253,26 +173,16 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase return await Promise.resolve(true); } - _everyAfterResumeProcess(): Promise { - 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 { - const rep = this._replicatorInstance; - rep?.disconnectFromServer(); - return Promise.resolve(true); - } 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.databaseEvents.onDatabaseInitialisation.addHandler(this._everyOnInitializeDatabase.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)); } } diff --git a/src/features/P2PSync/P2PReplicator/P2PReplicatorPane.svelte b/src/features/P2PSync/P2PReplicator/P2PReplicatorPane.svelte index 7ac67eb..4c34d64 100644 --- a/src/features/P2PSync/P2PReplicator/P2PReplicatorPane.svelte +++ b/src/features/P2PSync/P2PReplicator/P2PReplicatorPane.svelte @@ -4,10 +4,9 @@ import { AcceptedStatus, ConnectionStatus, - type CommandShim, type PeerStatus, - type PluginShim, } from "../../../lib/src/replication/trystero/P2PReplicatorPaneCommon"; + import type { P2PReplicator } from "../CmdP2PReplicator"; import PeerStatusRow from "../P2PReplicator/PeerStatusRow.svelte"; import { EVENT_LAYOUT_READY, eventHub } from "../../../common/events"; import { @@ -23,7 +22,7 @@ import type { LiveSyncBaseCore } from "@/LiveSyncBaseCore"; interface Props { - cmdSync: CommandShim; + cmdSync: P2PReplicator; core: LiveSyncBaseCore; } @@ -95,9 +94,8 @@ }, true ); - cmdSync.setConfig(SETTING_KEY_P2P_DEVICE_NAME, eDeviceName); + core.services.config.setSmallConfig(SETTING_KEY_P2P_DEVICE_NAME, eDeviceName); deviceName = eDeviceName; - // await plugin.saveSettings(); } async function revert() { eP2PEnabled = settings.P2P_Enabled; @@ -115,7 +113,7 @@ const applyLoadSettings = (d: P2PSyncSetting, force: boolean) => { if (force) { 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; eDeviceName = initDeviceName; } @@ -248,7 +246,7 @@ const initialDialogStatusKey = `p2p-dialog-status`; const getDialogStatus = () => { try { - const initialDialogStatus = JSON.parse(cmdSync.getConfig(initialDialogStatusKey) ?? "{}") as { + const initialDialogStatus = JSON.parse(core.services.config.getSmallConfig(initialDialogStatusKey) ?? "{}") as { notice?: boolean; setting?: boolean; }; @@ -265,7 +263,7 @@ notice: isNoticeOpened, setting: isSettingOpened, }; - cmdSync.setConfig(initialDialogStatusKey, JSON.stringify(dialogStatus)); + core.services.config.setSmallConfig(initialDialogStatusKey, JSON.stringify(dialogStatus)); }); let isObsidian = $derived.by(() => { return core.services.API.getPlatform() === "obsidian"; diff --git a/src/features/P2PSync/P2PReplicator/P2PReplicatorPaneView.ts b/src/features/P2PSync/P2PReplicator/P2PReplicatorPaneView.ts index fcde9a2..bd4c106 100644 --- a/src/features/P2PSync/P2PReplicator/P2PReplicatorPaneView.ts +++ b/src/features/P2PSync/P2PReplicator/P2PReplicatorPaneView.ts @@ -46,10 +46,10 @@ export class P2PReplicatorPaneView extends SvelteItemView { } get replicator() { const r = this.core.getAddOn(P2PReplicator.name); - if (!r || !r._replicatorInstance) { + if (!r || !r.liveSyncReplicator) { throw new Error("Replicator not found"); } - return r._replicatorInstance; + return r.liveSyncReplicator; } async replicateFrom(peer: PeerStatus) { await this.replicator.replicateFrom(peer.peerId); diff --git a/src/features/P2PSync/P2PReplicator/PeerStatusRow.svelte b/src/features/P2PSync/P2PReplicator/PeerStatusRow.svelte index 2ee660a..2dd4397 100644 --- a/src/features/P2PSync/P2PReplicator/PeerStatusRow.svelte +++ b/src/features/P2PSync/P2PReplicator/PeerStatusRow.svelte @@ -57,7 +57,7 @@ let isNew = $derived.by(() => peer.accepted === AcceptedStatus.UNKNOWN); function makeDecision(isAccepted: boolean, isTemporary: boolean) { - cmdReplicator._replicatorInstance?.server?.makeDecision({ + cmdReplicator.liveSyncReplicator?.makeDecision({ peerId: peer.peerId, name: peer.name, decision: isAccepted, @@ -65,13 +65,13 @@ }); } function revokeDecision() { - cmdReplicator._replicatorInstance?.server?.revokeDecision({ + cmdReplicator.liveSyncReplicator?.revokeDecision({ peerId: peer.peerId, name: peer.name, }); } const cmdReplicator = getContext<() => P2PReplicator>("getReplicator")(); - const replicator = cmdReplicator._replicatorInstance!; + const replicator = cmdReplicator.liveSyncReplicator; const peerAttrLabels = $derived.by(() => { const attrs = []; @@ -87,14 +87,14 @@ return attrs; }); function startWatching() { - replicator.watchPeer(peer.peerId); + replicator?.watchPeer(peer.peerId); } function stopWatching() { - replicator.unwatchPeer(peer.peerId); + replicator?.unwatchPeer(peer.peerId); } function sync() { - replicator.sync(peer.peerId, false); + void replicator?.sync(peer.peerId, false); } function moreMenu(evt: MouseEvent) { diff --git a/src/lib b/src/lib index 10aa321..b5f22eb 160000 --- a/src/lib +++ b/src/lib @@ -1 +1 @@ -Subproject commit 10aa32108b4b6b2d78e7a45d8c4bd1150c947ac3 +Subproject commit b5f22eb8f379f2471a085f29dd30aaa1553e6a1e diff --git a/test/suite/sync_common.ts b/test/suite/sync_common.ts index f8ee4c2..74da866 100644 --- a/test/suite/sync_common.ts +++ b/test/suite/sync_common.ts @@ -1,6 +1,6 @@ import { expect } from "vitest"; 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 { commands } from "vitest/browser"; @@ -15,14 +15,10 @@ async function waitForP2PPeers(harness: LiveSyncHarness) { if (!(replicator instanceof 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) { fireAndForget(() => commands.acceptWebPeer()); await delay(1000); - const peers = p2pReplicator.knownAdvertisements; + const peers = replicator.knownAdvertisements; if (peers && peers.length > 0) { console.log("P2P peers connected:", peers);