Route interactive P2P UI through focused views

This commit is contained in:
vorotamoroz
2026-09-01 11:33:54 +00:00
parent f737701695
commit cab6679c2b
5 changed files with 41 additions and 111 deletions
@@ -6,20 +6,20 @@ import type { P2PServiceViews } from "@vrtmrz/livesync-commonlib/p2p";
import { P2POpenReplicationModal } from "./P2POpenReplicationModal";
/**
* Creates an openReplicationUI factory for Obsidian environments.
* Returns a per-replicator closure that opens the P2P Replication modal
* and performs bidirectional sync (pull then push on success) through the
* stable targeted-transfer view. The compatibility Replicator argument is
* intentionally unused here and remains available only to the rebuild factory.
* Create the Obsidian-owned interactive P2P entry for stable service views.
*
* Peer selection belongs to the host UI rather than the concrete compatibility
* Replicator. The returned operation opens the modal and performs bidirectional
* synchronisation, pulling before pushing, through the targeted-transfer view.
*
* Usage:
* const factory = createOpenReplicationUI(app);
* useP2PReplicatorFeature(core, factory);
* const createInteractiveReplication = createOpenReplicationUI(app);
* const openInteractiveReplication = createInteractiveReplication(p2p);
*/
export function createOpenReplicationUI(
app: App
): (replicator: LiveSyncTrysteroReplicator, p2p: P2PServiceViews) => (showResult: boolean) => Promise<boolean | void> {
return (_replicator: LiveSyncTrysteroReplicator, p2p: P2PServiceViews) =>
): (p2p: P2PServiceViews) => (showResult: boolean) => Promise<boolean | void> {
return (p2p: P2PServiceViews) =>
(showResult: boolean): Promise<boolean | void> => {
const logLevel = showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO;
return new Promise<boolean | void>((resolve) => {
@@ -89,7 +89,7 @@ export function createOpenReplicationUI(
*
* Usage:
* const factory = createOpenRebuildUI(app);
* useP2PReplicatorFeature(core, createOpenReplicationUI(app), factory);
* useP2PReplicatorFeature(core, openReplicationUIFactory, factory);
*/
export function createOpenRebuildUI(
app: App
@@ -69,7 +69,7 @@ describe("createOpenReplicationUI", () => {
it("settles a cancelled peer-selection session when the modal closes", async () => {
const p2p = createP2PServiceViews();
const session = createOpenReplicationUI({} as any)(createReplicator(), p2p)(true);
const session = createOpenReplicationUI({} as any)(p2p)(true);
const modal = modalState.instances[0];
expect(modal.p2p).toBe(p2p);
@@ -80,9 +80,8 @@ describe("createOpenReplicationUI", () => {
});
it("keeps repeated synchronisation inside the session boundary until the modal closes", async () => {
const replicator = createReplicator();
const p2p = createP2PServiceViews();
const session = createOpenReplicationUI({} as any)(replicator, p2p)(true);
const session = createOpenReplicationUI({} as any)(p2p)(true);
const modal = modalState.instances[0];
let settled = false;
void session.finally(() => {
@@ -102,9 +101,8 @@ describe("createOpenReplicationUI", () => {
});
it("routes ordinary peer transfer through the stable targeted-transfer view", async () => {
const replicator = createReplicator();
const p2p = createP2PServiceViews();
const session = createOpenReplicationUI({} as any)(replicator, p2p)(true);
const session = createOpenReplicationUI({} as any)(p2p)(true);
const modal = modalState.instances[0];
await modal.callback.onSync("peer-a");
@@ -113,13 +111,10 @@ describe("createOpenReplicationUI", () => {
expect(p2p.targetedTransfer.pullFromPeer).toHaveBeenCalledWith("peer-a", { showNotice: true });
expect(p2p.targetedTransfer.requestPushToPeer).toHaveBeenCalledWith("peer-a");
expect(replicator.replicateFrom).not.toHaveBeenCalled();
expect(replicator.requestSynchroniseToPeer).not.toHaveBeenCalled();
});
it("waits for an in-flight synchronisation when the modal closes", async () => {
let finishPull!: (value: { status: "completed"; ok: true }) => void;
const replicator = createReplicator();
const p2p = createP2PServiceViews();
p2p.targetedTransfer.pullFromPeer.mockImplementation(
async () =>
@@ -127,7 +122,7 @@ describe("createOpenReplicationUI", () => {
finishPull = resolve;
})
);
const session = createOpenReplicationUI({} as any)(replicator, p2p)(true);
const session = createOpenReplicationUI({} as any)(p2p)(true);
const modal = modalState.instances[0];
let settled = false;
void session.finally(() => {
@@ -146,15 +141,13 @@ describe("createOpenReplicationUI", () => {
});
it("closes the P2P connection after a successful sync-and-close action", async () => {
const replicator = createReplicator();
const p2p = createP2PServiceViews();
const session = createOpenReplicationUI({} as any)(replicator, p2p)(true);
const session = createOpenReplicationUI({} as any)(p2p)(true);
const modal = modalState.instances[0];
await modal.callback.onSyncAndClose("peer-a");
expect(p2p.transportLifecycle.disconnect).toHaveBeenCalledOnce();
expect(replicator.close).not.toHaveBeenCalled();
let settled = false;
void session.finally(() => {
settled = true;
@@ -167,10 +160,9 @@ describe("createOpenReplicationUI", () => {
});
it("returns a cancelled peer push as non-success to the presentation boundary", async () => {
const replicator = createReplicator();
const p2p = createP2PServiceViews();
p2p.targetedTransfer.requestPushToPeer.mockResolvedValue({ status: "cancelled" } as never);
const session = createOpenReplicationUI({} as any)(replicator, p2p)(true);
const session = createOpenReplicationUI({} as any)(p2p)(true);
const modal = modalState.instances[0];
const actionResult = await modal.callback.onSync("peer-a");