Files
obsidian-livesync/src/common/replicatorResources/connection.ts
T

105 lines
4.1 KiB
TypeScript

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 { LOG_LEVEL_NOTICE, Logger } from "@vrtmrz/livesync-commonlib/compat/common/logger";
import { LiveSyncJournalReplicator } from "@vrtmrz/livesync-commonlib/compat/replication/journal/LiveSyncJournalReplicator";
import { createReplicatorDisposer, snapshotRemoteSettings } from "./shared";
/** Host environment sufficient to construct either central connection probe. */
export type ConnectionResourceHost = LiveSyncCouchDBReplicatorEnv;
function createCouchDBConnectionProbe(
replicator: LiveSyncCouchDBReplicator,
snapshot: RemoteDBSettings,
host: ConnectionResourceHost
): 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") {
if (options.showResult) {
Logger(
host.services.context.translate("liveSyncReplicator.couldNotConnectTo", {
uri: snapshot.couchDB_URI,
name: snapshot.couchDB_DBNAME,
db: connection,
}),
LOG_LEVEL_NOTICE
);
}
return { ok: false, reason: connection };
}
try {
if (options.showResult) {
Logger(`Connected to ${connection.info.db_name} successfully`, LOG_LEVEL_NOTICE);
}
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 probe for one host.
*
* The probe owns both its concrete Replicator and each connection it opens. It
* never publishes that Replicator as the active provider instance. A caller
* may request the established result Notice explicitly; ordinary probes remain
* silent.
*/
export function createCouchDBConnectionProbeFactory(host: ConnectionResourceHost): ConnectionProbeFactory {
return (setting) => {
const snapshot = snapshotRemoteSettings(setting);
return Promise.resolve(createCouchDBConnectionProbe(new LiveSyncCouchDBReplicator(host), snapshot, host));
};
}
/**
* Build an unpublished Object Storage connection probe for one host.
*
* The probe owns its concrete Replicator and never publishes or replaces the
* active provider instance.
*/
export function createObjectStorageConnectionProbeFactory(host: ConnectionResourceHost): ConnectionProbeFactory {
return (setting) => {
const snapshot = snapshotRemoteSettings(setting);
return Promise.resolve(createObjectStorageConnectionProbe(new LiveSyncJournalReplicator(host), snapshot));
};
}