diff --git a/src/apps/cli/commands/p2p.ts b/src/apps/cli/commands/p2p.ts index dab475e..b889f51 100644 --- a/src/apps/cli/commands/p2p.ts +++ b/src/apps/cli/commands/p2p.ts @@ -2,6 +2,7 @@ import type { LiveSyncBaseCore } from "../../../LiveSyncBaseCore"; import { P2P_DEFAULT_SETTINGS } from "@lib/common/types"; import type { ServiceContext } from "@lib/services/base/ServiceBase"; import { LiveSyncTrysteroReplicator } from "@lib/replication/trystero/LiveSyncTrysteroReplicator"; +import { addP2PEventHandlers } from "@lib/replication/trystero/P2PReplicatorCore"; type CLIP2PPeer = { peerId: string; @@ -34,7 +35,9 @@ function validateP2PSettings(core: LiveSyncBaseCore) { function createReplicator(core: LiveSyncBaseCore): LiveSyncTrysteroReplicator { validateP2PSettings(core); - return new LiveSyncTrysteroReplicator({ services: core.services }); + const replicator = new LiveSyncTrysteroReplicator({ services: core.services }); + addP2PEventHandlers(replicator); + return replicator; } function getSortedPeers(replicator: LiveSyncTrysteroReplicator): CLIP2PPeer[] { diff --git a/src/apps/webpeer/src/P2PReplicatorShim.ts b/src/apps/webpeer/src/P2PReplicatorShim.ts index 63f2b7e..fd461ef 100644 --- a/src/apps/webpeer/src/P2PReplicatorShim.ts +++ b/src/apps/webpeer/src/P2PReplicatorShim.ts @@ -17,11 +17,7 @@ import { type PeerStatus, type PluginShim, } from "@lib/replication/trystero/P2PReplicatorPaneCommon"; -import { - P2PLogCollector, - type P2PReplicatorBase, - useP2PReplicator, -} from "@lib/replication/trystero/P2PReplicatorCore"; +import { 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"; @@ -34,9 +30,7 @@ import { Menu } from "@lib/services/implements/browser/Menu"; import { SimpleStoreIDBv2 } from "octagonal-wheels/databases/SimpleStoreIDBv2"; 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"; +import { LiveSyncTrysteroReplicator } from "@lib/replication/trystero/LiveSyncTrysteroReplicator"; function addToList(item: string, list: string) { return unique( @@ -82,7 +76,11 @@ export class P2PReplicatorShim implements P2PReplicatorBase { p2pLogCollector!: P2PLogCollector; private _initP2PReplicator() { - const { replicator, p2pLogCollector, storeP2PStatusLine: p2pStatusLine } = useP2PReplicator({ services: this.services } as any); + const { + replicator, + p2pLogCollector, + storeP2PStatusLine: p2pStatusLine, + } = useP2PReplicator({ services: this.services } as any); this._liveSyncReplicator = replicator; this.p2pLogCollector = p2pLogCollector; p2pLogCollector.p2pReplicationLine.onChanged((line) => { diff --git a/src/common/events.ts b/src/common/events.ts index e34346f..985ae94 100644 --- a/src/common/events.ts +++ b/src/common/events.ts @@ -16,9 +16,6 @@ export const EVENT_REQUEST_RELOAD_SETTING_TAB = "reload-setting-tab"; export const EVENT_REQUEST_OPEN_PLUGIN_SYNC_DIALOG = "request-open-plugin-sync-dialog"; -export const EVENT_REQUEST_OPEN_P2P = "request-open-p2p"; -export const EVENT_REQUEST_CLOSE_P2P = "request-close-p2p"; - export const EVENT_REQUEST_RUN_DOCTOR = "request-run-doctor"; export const EVENT_REQUEST_RUN_FIX_INCOMPLETE = "request-run-fix-incomplete"; @@ -36,8 +33,6 @@ declare global { [EVENT_REQUEST_OPEN_SETTING_WIZARD]: undefined; [EVENT_REQUEST_RELOAD_SETTING_TAB]: undefined; [EVENT_LEAF_ACTIVE_CHANGED]: undefined; - [EVENT_REQUEST_CLOSE_P2P]: undefined; - [EVENT_REQUEST_OPEN_P2P]: undefined; [EVENT_REQUEST_OPEN_SETUP_URI]: undefined; [EVENT_REQUEST_COPY_SETUP_URI]: undefined; [EVENT_REQUEST_SHOW_SETUP_QR]: undefined; diff --git a/src/features/P2PSync/CmdP2PReplicator.ts b/src/features/P2PSync/CmdP2PReplicator.ts deleted file mode 100644 index 0325176..0000000 --- a/src/features/P2PSync/CmdP2PReplicator.ts +++ /dev/null @@ -1,188 +0,0 @@ -import { P2PReplicatorPaneView, VIEW_TYPE_P2P } from "./P2PReplicator/P2PReplicatorPaneView.ts"; -import { - AutoAccepting, - LOG_LEVEL_NOTICE, - REMOTE_P2P, - type P2PSyncSetting, - type RemoteDBSettings, -} from "../../lib/src/common/types.ts"; -import { LiveSyncCommands } from "../LiveSyncCommands.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 { Logger } from "octagonal-wheels/common/logger"; -import { - P2PLogCollector, - type P2PReplicatorBase, - useP2PReplicator, -} from "../../lib/src/replication/trystero/P2PReplicatorCore.ts"; -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 type { LiveSyncCore } from "../../main.ts"; -import type { EntryDoc } from "../../lib/src/common/types.ts"; - -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; - } - 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); - this.afterConstructor(); - } - - async handleReplicatedDocuments(docs: EntryDoc[]): Promise { - return await this.services.replication.parseSynchroniseResult( - docs as PouchDB.Core.ExistingDocument[] - ); - } - - _anyNewReplicator(settingOverride: Partial = {}): Promise { - const settings = { ...this.settings, ...settingOverride }; - if (settings.remoteType == REMOTE_P2P) { - return Promise.resolve(new LiveSyncTrysteroReplicator({ services: this.services })); - } - return undefined!; - } - - afterConstructor() { - return; - } - - async open() { - await this._liveSyncReplicator?.open(); - } - - async close() { - await this._liveSyncReplicator?.close(); - } - - getConfig(key: string) { - return this.services.config.getSmallConfig(key); - } - setConfig(key: string, value: string) { - return this.services.config.setSmallConfig(key, value); - } - enableBroadcastCastings() { - return this._liveSyncReplicator?.enableBroadcastChanges(); - } - disableBroadcastCastings() { - return this._liveSyncReplicator?.disableBroadcastChanges(); - } - - init() { - this._simpleStore = this.services.keyValueDB.openSimpleStore("p2p-sync"); - return Promise.resolve(this); - } - - onunload(): void { - void this.close(); - } - - onload(): void | Promise { - eventHub.onEvent(EVENT_REQUEST_OPEN_P2P, () => { - void this.openPane(); - }); - } - - private async _allSuspendExtraSync() { - this.plugin.core.settings.P2P_Enabled = false; - this.plugin.core.settings.P2P_AutoAccepting = AutoAccepting.NONE; - this.plugin.core.settings.P2P_AutoBroadcast = false; - this.plugin.core.settings.P2P_AutoStart = false; - this.plugin.core.settings.P2P_AutoSyncPeers = ""; - this.plugin.core.settings.P2P_AutoWatchPeers = ""; - return await Promise.resolve(true); - } - - async openPane() { - await this.services.API.showWindow(VIEW_TYPE_P2P); - } - - async _everyOnloadStart(): Promise { - this.plugin.registerView( - VIEW_TYPE_P2P, - (leaf) => new P2PReplicatorPaneView(leaf, this.plugin.core, this.plugin) - ); - this.plugin.addCommand({ - id: "open-p2p-replicator", - name: "P2P Sync : Open P2P Replicator", - callback: async () => { - await this.openPane(); - }, - }); - this.plugin.addCommand({ - id: "p2p-establish-connection", - name: "P2P Sync : Connect to the Signalling Server", - checkCallback: (isChecking) => { - if (isChecking) { - return !(this._liveSyncReplicator?.server?.isServing ?? false); - } - void this.open(); - }, - }); - this.plugin.addCommand({ - id: "p2p-close-connection", - name: "P2P Sync : Disconnect from the Signalling Server", - checkCallback: (isChecking) => { - if (isChecking) { - return this._liveSyncReplicator?.server?.isServing ?? false; - } - Logger(`Closing P2P Connection`, LOG_LEVEL_NOTICE); - void this.close(); - }, - }); - this.plugin.addCommand({ - id: "replicate-now-by-p2p", - name: "Replicate now by P2P", - checkCallback: (isChecking) => { - if (isChecking) { - if (this.settings.remoteType == REMOTE_P2P) return false; - if (!this._liveSyncReplicator?.server?.isServing) return false; - return true; - } - void this._liveSyncReplicator?.replicateFromCommand(false); - }, - }); - this.plugin - .addRibbonIcon("waypoints", "P2P Replicator", async () => { - await this.openPane(); - }) - .addClass("livesync-ribbon-replicate-p2p"); - - return await 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.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.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 4c34d64..9dd7c8e 100644 --- a/src/features/P2PSync/P2PReplicator/P2PReplicatorPane.svelte +++ b/src/features/P2PSync/P2PReplicator/P2PReplicatorPane.svelte @@ -6,7 +6,7 @@ ConnectionStatus, type PeerStatus, } from "../../../lib/src/replication/trystero/P2PReplicatorPaneCommon"; - import type { P2PReplicator } from "../CmdP2PReplicator"; + import type { LiveSyncTrysteroReplicator } from "../../../lib/src/replication/trystero/LiveSyncTrysteroReplicator"; import PeerStatusRow from "../P2PReplicator/PeerStatusRow.svelte"; import { EVENT_LAYOUT_READY, eventHub } from "../../../common/events"; import { @@ -22,7 +22,7 @@ import type { LiveSyncBaseCore } from "@/LiveSyncBaseCore"; interface Props { - cmdSync: P2PReplicator; + cmdSync: LiveSyncTrysteroReplicator; core: LiveSyncBaseCore; } @@ -237,10 +237,10 @@ await cmdSync.close(); } function startBroadcasting() { - void cmdSync.enableBroadcastCastings(); + void cmdSync.enableBroadcastChanges(); } function stopBroadcasting() { - void cmdSync.disableBroadcastCastings(); + void cmdSync.disableBroadcastChanges(); } const initialDialogStatusKey = `p2p-dialog-status`; diff --git a/src/features/P2PSync/P2PReplicator/P2PReplicatorPaneView.ts b/src/features/P2PSync/P2PReplicator/P2PReplicatorPaneView.ts index bd4c106..d96445f 100644 --- a/src/features/P2PSync/P2PReplicator/P2PReplicatorPaneView.ts +++ b/src/features/P2PSync/P2PReplicator/P2PReplicatorPaneView.ts @@ -1,19 +1,15 @@ import { Menu, WorkspaceLeaf } from "@/deps.ts"; import ReplicatorPaneComponent from "./P2PReplicatorPane.svelte"; -import type ObsidianLiveSyncPlugin from "../../../main.ts"; import { mount } from "svelte"; -import { SvelteItemView } from "../../../common/SvelteItemView.ts"; -import { eventHub } from "../../../common/events.ts"; +import { SvelteItemView } from "@/common/SvelteItemView.ts"; +import { eventHub } from "@/common/events.ts"; import { unique } from "octagonal-wheels/collection"; -import { LOG_LEVEL_NOTICE, REMOTE_P2P } from "../../../lib/src/common/types.ts"; -import { Logger } from "../../../lib/src/common/logger.ts"; -import { P2PReplicator } from "../CmdP2PReplicator.ts"; -import { - EVENT_P2P_PEER_SHOW_EXTRA_MENU, - type PeerStatus, -} from "../../../lib/src/replication/trystero/P2PReplicatorPaneCommon.ts"; +import { LOG_LEVEL_NOTICE, REMOTE_P2P } from "@lib/common/types.ts"; +import { Logger } from "@lib/common/logger.ts"; +import { EVENT_P2P_PEER_SHOW_EXTRA_MENU, type PeerStatus } from "@lib/replication/trystero/P2PReplicatorPaneCommon.ts"; import type { LiveSyncBaseCore } from "@/LiveSyncBaseCore.ts"; +import type { UseP2PReplicatorResult } from "@lib/replication/trystero/P2PReplicatorCore.ts"; export const VIEW_TYPE_P2P = "p2p-replicator"; function addToList(item: string, list: string) { @@ -35,8 +31,8 @@ function removeFromList(item: string, list: string) { } export class P2PReplicatorPaneView extends SvelteItemView { - // plugin: ObsidianLiveSyncPlugin; core: LiveSyncBaseCore; + private _p2pResult: UseP2PReplicatorResult; override icon = "waypoints"; title: string = ""; override navigation = false; @@ -45,11 +41,7 @@ export class P2PReplicatorPaneView extends SvelteItemView { return "waypoints"; } get replicator() { - const r = this.core.getAddOn(P2PReplicator.name); - if (!r || !r.liveSyncReplicator) { - throw new Error("Replicator not found"); - } - return r.liveSyncReplicator; + return this._p2pResult.replicator; } async replicateFrom(peer: PeerStatus) { await this.replicator.replicateFrom(peer.peerId); @@ -131,10 +123,10 @@ And you can also drop the local database to rebuild from the remote device.`, await this.core.services.setting.applyPartial(currentSetting, true); } m?: Menu; - constructor(leaf: WorkspaceLeaf, core: LiveSyncBaseCore, plugin: ObsidianLiveSyncPlugin) { + constructor(leaf: WorkspaceLeaf, core: LiveSyncBaseCore, p2pResult: UseP2PReplicatorResult) { super(leaf); - // this.plugin = plugin; this.core = core; + this._p2pResult = p2pResult; eventHub.onEvent(EVENT_P2P_PEER_SHOW_EXTRA_MENU, ({ peer, event }) => { if (this.m) { this.m.hide(); @@ -192,14 +184,10 @@ And you can also drop the local database to rebuild from the remote device.`, } } instantiateComponent(target: HTMLElement) { - const cmdSync = this.core.getAddOn(P2PReplicator.name); - if (!cmdSync) { - throw new Error("Replicator not found"); - } return mount(ReplicatorPaneComponent, { target: target, props: { - cmdSync: cmdSync, + cmdSync: this._p2pResult.replicator, core: this.core, }, }); diff --git a/src/features/P2PSync/P2PReplicator/PeerStatusRow.svelte b/src/features/P2PSync/P2PReplicator/PeerStatusRow.svelte index 2dd4397..144ec29 100644 --- a/src/features/P2PSync/P2PReplicator/PeerStatusRow.svelte +++ b/src/features/P2PSync/P2PReplicator/PeerStatusRow.svelte @@ -1,7 +1,7 @@