mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-08-30 15:27:06 +00:00
Migrate LiveSync flows to provider-owned resources
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import type { RemoteDBSettings } from "@vrtmrz/livesync-commonlib/compat/common/types";
|
||||
import type {
|
||||
ConnectionProbeFactory,
|
||||
RemoteConnectionProbe,
|
||||
RemoteConnectionProbeOptions,
|
||||
} from "@vrtmrz/livesync-commonlib/replication";
|
||||
import {
|
||||
LiveSyncCouchDBReplicator,
|
||||
type LiveSyncCouchDBReplicatorEnv,
|
||||
} from "@vrtmrz/livesync-commonlib/compat/replication/couchdb/LiveSyncReplicator";
|
||||
import { LiveSyncJournalReplicator } from "@vrtmrz/livesync-commonlib/compat/replication/journal/LiveSyncJournalReplicator";
|
||||
import type { LiveSyncJournalReplicatorEnv } from "@vrtmrz/livesync-commonlib/compat/replication/journal/LiveSyncJournalReplicatorEnv";
|
||||
import { createReplicatorDisposer, snapshotRemoteSettings } from "./shared";
|
||||
|
||||
export type ConnectionResourceHost = LiveSyncCouchDBReplicatorEnv & LiveSyncJournalReplicatorEnv;
|
||||
|
||||
function createCouchDBConnectionProbe(
|
||||
replicator: LiveSyncCouchDBReplicator,
|
||||
snapshot: RemoteDBSettings
|
||||
): RemoteConnectionProbe {
|
||||
const dispose = createReplicatorDisposer(replicator);
|
||||
return {
|
||||
check: async (options: RemoteConnectionProbeOptions = {}) => {
|
||||
const connection = await replicator.connectRemoteCouchDBWithSetting(
|
||||
snapshot,
|
||||
replicator.isMobile(),
|
||||
options.createIfMissing ?? true,
|
||||
false
|
||||
);
|
||||
if (typeof connection === "string") {
|
||||
return { ok: false, reason: connection };
|
||||
}
|
||||
try {
|
||||
return { ok: true };
|
||||
} finally {
|
||||
await connection.close();
|
||||
}
|
||||
},
|
||||
getStatus: () => replicator.getRemoteStatus(snapshot),
|
||||
dispose,
|
||||
};
|
||||
}
|
||||
|
||||
function createObjectStorageConnectionProbe(
|
||||
replicator: LiveSyncJournalReplicator,
|
||||
snapshot: RemoteDBSettings
|
||||
): RemoteConnectionProbe {
|
||||
const dispose = createReplicatorDisposer(replicator);
|
||||
return {
|
||||
check: async (options: RemoteConnectionProbeOptions = {}) => {
|
||||
try {
|
||||
const connected = await replicator.tryConnectRemote(snapshot, options.showResult ?? false);
|
||||
return connected ? { ok: true } : { ok: false };
|
||||
} catch (error) {
|
||||
return { ok: false, reason: error };
|
||||
}
|
||||
},
|
||||
getStatus: () => replicator.getRemoteStatus(snapshot),
|
||||
dispose,
|
||||
};
|
||||
}
|
||||
|
||||
/** Build an unpublished CouchDB connection resource for one host. */
|
||||
export function createCouchDBConnectionProbeFactory(host: ConnectionResourceHost): ConnectionProbeFactory {
|
||||
return (setting) => {
|
||||
const snapshot = snapshotRemoteSettings(setting);
|
||||
return Promise.resolve(createCouchDBConnectionProbe(new LiveSyncCouchDBReplicator(host), snapshot));
|
||||
};
|
||||
}
|
||||
|
||||
/** Build an unpublished Object Storage connection resource for one host. */
|
||||
export function createObjectStorageConnectionProbeFactory(host: ConnectionResourceHost): ConnectionProbeFactory {
|
||||
return (setting) => {
|
||||
const snapshot = snapshotRemoteSettings(setting);
|
||||
return Promise.resolve(createObjectStorageConnectionProbe(new LiveSyncJournalReplicator(host), snapshot));
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
export {
|
||||
createCouchDBConnectionProbeFactory,
|
||||
createObjectStorageConnectionProbeFactory,
|
||||
type ConnectionResourceHost,
|
||||
} from "./connection";
|
||||
export {
|
||||
createCouchDBPreferredTweakProbeFactory,
|
||||
createObjectStoragePreferredTweakProbeFactory,
|
||||
type PreferredTweakResourceHost,
|
||||
} from "./preferredTweak";
|
||||
export {
|
||||
createCouchDBSecuritySeedResourceFactory,
|
||||
createObjectStorageSecuritySeedResourceFactory,
|
||||
type SecuritySeedResourceHost,
|
||||
} from "./securitySeed";
|
||||
export { createCouchDBSynchronisationInformationResourceFactory } from "./synchronisationInformation";
|
||||
@@ -0,0 +1,43 @@
|
||||
import type { RemoteDBSettings, RemotePreferredTweakResult } from "@vrtmrz/livesync-commonlib/compat/common/types";
|
||||
import type { PreferredTweakProbe, PreferredTweakProbeFactory } from "@vrtmrz/livesync-commonlib/replication";
|
||||
import {
|
||||
LiveSyncCouchDBReplicator,
|
||||
type LiveSyncCouchDBReplicatorEnv,
|
||||
} from "@vrtmrz/livesync-commonlib/compat/replication/couchdb/LiveSyncReplicator";
|
||||
import { LiveSyncJournalReplicator } from "@vrtmrz/livesync-commonlib/compat/replication/journal/LiveSyncJournalReplicator";
|
||||
import type { LiveSyncJournalReplicatorEnv } from "@vrtmrz/livesync-commonlib/compat/replication/journal/LiveSyncJournalReplicatorEnv";
|
||||
import { createReplicatorDisposer, snapshotRemoteSettings, type ResourceReplicator } from "./shared";
|
||||
|
||||
export type PreferredTweakResourceHost = LiveSyncCouchDBReplicatorEnv & LiveSyncJournalReplicatorEnv;
|
||||
|
||||
interface PreferredTweakReplicator extends ResourceReplicator {
|
||||
getRemotePreferredTweakValues(setting: RemoteDBSettings): Promise<RemotePreferredTweakResult>;
|
||||
}
|
||||
|
||||
function createPreferredTweakProbe(
|
||||
replicator: PreferredTweakReplicator,
|
||||
snapshot: RemoteDBSettings
|
||||
): PreferredTweakProbe {
|
||||
return {
|
||||
read: () => replicator.getRemotePreferredTweakValues(snapshot),
|
||||
dispose: createReplicatorDisposer(replicator),
|
||||
};
|
||||
}
|
||||
|
||||
/** Build an unpublished CouchDB preferred-tweak resource for one host. */
|
||||
export function createCouchDBPreferredTweakProbeFactory(host: PreferredTweakResourceHost): PreferredTweakProbeFactory {
|
||||
return (setting) => {
|
||||
const snapshot = snapshotRemoteSettings(setting);
|
||||
return Promise.resolve(createPreferredTweakProbe(new LiveSyncCouchDBReplicator(host), snapshot));
|
||||
};
|
||||
}
|
||||
|
||||
/** Build an unpublished Object Storage preferred-tweak resource for one host. */
|
||||
export function createObjectStoragePreferredTweakProbeFactory(
|
||||
host: PreferredTweakResourceHost
|
||||
): PreferredTweakProbeFactory {
|
||||
return (setting) => {
|
||||
const snapshot = snapshotRemoteSettings(setting);
|
||||
return Promise.resolve(createPreferredTweakProbe(new LiveSyncJournalReplicator(host), snapshot));
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { SecuritySeedResourceFactory } from "@vrtmrz/livesync-commonlib/replication";
|
||||
import {
|
||||
LiveSyncCouchDBReplicator,
|
||||
type LiveSyncCouchDBReplicatorEnv,
|
||||
} from "@vrtmrz/livesync-commonlib/compat/replication/couchdb/LiveSyncReplicator";
|
||||
import { LiveSyncJournalReplicator } from "@vrtmrz/livesync-commonlib/compat/replication/journal/LiveSyncJournalReplicator";
|
||||
import type { LiveSyncJournalReplicatorEnv } from "@vrtmrz/livesync-commonlib/compat/replication/journal/LiveSyncJournalReplicatorEnv";
|
||||
import { createReplicatorDisposer, snapshotRemoteSettings } from "./shared";
|
||||
|
||||
export type SecuritySeedResourceHost = LiveSyncCouchDBReplicatorEnv & LiveSyncJournalReplicatorEnv;
|
||||
|
||||
function createSecuritySeedResourceFactory(
|
||||
createReplicator: () => LiveSyncCouchDBReplicator | LiveSyncJournalReplicator
|
||||
): SecuritySeedResourceFactory {
|
||||
return (setting) => {
|
||||
const snapshot = snapshotRemoteSettings(setting);
|
||||
const replicator = createReplicator();
|
||||
return Promise.resolve({
|
||||
read: () => replicator.getReplicationPBKDF2Salt(snapshot),
|
||||
dispose: createReplicatorDisposer(replicator),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/** Build an unpublished CouchDB Security Seed resource for one host. */
|
||||
export function createCouchDBSecuritySeedResourceFactory(host: SecuritySeedResourceHost): SecuritySeedResourceFactory {
|
||||
return createSecuritySeedResourceFactory(() => new LiveSyncCouchDBReplicator(host));
|
||||
}
|
||||
|
||||
/** Build an unpublished Object Storage Security Seed resource for one host. */
|
||||
export function createObjectStorageSecuritySeedResourceFactory(
|
||||
host: SecuritySeedResourceHost
|
||||
): SecuritySeedResourceFactory {
|
||||
return createSecuritySeedResourceFactory(() => new LiveSyncJournalReplicator(host));
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { RemoteDBSettings } from "@vrtmrz/livesync-commonlib/compat/common/types";
|
||||
|
||||
export interface ResourceReplicator {
|
||||
closeReplication(): void | Promise<void>;
|
||||
}
|
||||
|
||||
/** Create one idempotent asynchronous disposer for a private Replicator. */
|
||||
export function createReplicatorDisposer(replicator: ResourceReplicator): () => Promise<void> {
|
||||
let disposal: Promise<void> | undefined;
|
||||
return () => {
|
||||
if (disposal === undefined) {
|
||||
disposal = Promise.resolve().then(() => replicator.closeReplication());
|
||||
}
|
||||
return disposal;
|
||||
};
|
||||
}
|
||||
|
||||
/** Fence a finite resource from later edits to its source settings object. */
|
||||
export function snapshotRemoteSettings(setting: RemoteDBSettings): RemoteDBSettings {
|
||||
return { ...setting };
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { SynchronisationInformationResourceFactory } from "@vrtmrz/livesync-commonlib/replication";
|
||||
import {
|
||||
LiveSyncCouchDBReplicator,
|
||||
type LiveSyncCouchDBReplicatorEnv,
|
||||
} from "@vrtmrz/livesync-commonlib/compat/replication/couchdb/LiveSyncReplicator";
|
||||
import { checkSyncInfo } from "@vrtmrz/livesync-commonlib/compat/pouchdb/negotiation";
|
||||
import { createReplicatorDisposer, snapshotRemoteSettings } from "./shared";
|
||||
|
||||
/** Build an owned CouchDB synchronisation-information verifier for one host. */
|
||||
export function createCouchDBSynchronisationInformationResourceFactory(
|
||||
host: LiveSyncCouchDBReplicatorEnv
|
||||
): SynchronisationInformationResourceFactory {
|
||||
return (setting) => {
|
||||
const snapshot = snapshotRemoteSettings(setting);
|
||||
const replicator = new LiveSyncCouchDBReplicator(host);
|
||||
return Promise.resolve({
|
||||
check: async () => {
|
||||
const connection = await replicator.connectRemoteCouchDBWithSetting(
|
||||
snapshot,
|
||||
replicator.isMobile(),
|
||||
true
|
||||
);
|
||||
if (typeof connection === "string") {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return await checkSyncInfo(connection.db);
|
||||
} finally {
|
||||
await connection.close();
|
||||
}
|
||||
},
|
||||
dispose: createReplicatorDisposer(replicator),
|
||||
});
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user