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)); }; }