diff --git a/src/LiveSyncBaseCore.ts b/src/LiveSyncBaseCore.ts index 116d7b06..7a058811 100644 --- a/src/LiveSyncBaseCore.ts +++ b/src/LiveSyncBaseCore.ts @@ -15,13 +15,13 @@ import type { LiveSyncJournalReplicatorEnv } from "@vrtmrz/livesync-commonlib/co import type { LiveSyncReplicatorEnv } from "@vrtmrz/livesync-commonlib/compat/replication/LiveSyncAbstractReplicator"; import { useTargetFilters } from "@vrtmrz/livesync-commonlib/compat/serviceFeatures/targetFilter"; import { useRemoteConfigurationMigration } from "@vrtmrz/livesync-commonlib/compat/serviceFeatures/remoteConfig"; +import { useJournalSyncFeature } from "@vrtmrz/livesync-commonlib/journal-sync"; import type { ServiceContext } from "@vrtmrz/livesync-commonlib/context"; import type { InjectableServiceHub } from "@vrtmrz/livesync-commonlib/compat/services/implements/injectable/InjectableServiceHub"; import { AbstractModule } from "./modules/AbstractModule"; import { ModulePeriodicProcess } from "./modules/core/ModulePeriodicProcess"; import { ModuleReplicator } from "./modules/core/ModuleReplicator"; import { ModuleReplicatorCouchDB } from "./modules/core/ModuleReplicatorCouchDB"; -import { ModuleReplicatorMinIO } from "./modules/core/ModuleReplicatorMinIO"; import { ModuleConflictChecker } from "./modules/coreFeatures/ModuleConflictChecker"; import { ModuleConflictResolver } from "./modules/coreFeatures/ModuleConflictResolver"; import { ModuleResolvingMismatchedTweaks } from "./modules/coreFeatures/ModuleResolveMismatchedTweaks"; @@ -139,7 +139,6 @@ export class LiveSyncBaseCore< public registerModules(extraModules: AbstractModule[] = []) { this._registerModule(new ModuleLiveSyncMain(this)); this._registerModule(new ModuleConflictChecker(this)); - this._registerModule(new ModuleReplicatorMinIO(this)); this._registerModule(new ModuleReplicatorCouchDB(this)); this._registerModule(new ModuleReplicator(this)); this._registerModule(new ModuleConflictResolver(this)); @@ -279,6 +278,8 @@ export class LiveSyncBaseCore< usePrepareDatabaseForUse(this); // Migration to multiple remote configurations useRemoteConfigurationMigration(this); + // Journal providers are selected through the composed remote-provider registry. + useJournalSyncFeature(this); } } diff --git a/src/modules/core/ModuleReplicatorCouchDB.ts b/src/modules/core/ModuleReplicatorCouchDB.ts index d96fb5c0..21dc7dad 100644 --- a/src/modules/core/ModuleReplicatorCouchDB.ts +++ b/src/modules/core/ModuleReplicatorCouchDB.ts @@ -1,5 +1,6 @@ import { fireAndForget } from "octagonal-wheels/promises"; -import { REMOTE_MINIO, REMOTE_P2P, type RemoteDBSettings } from "@vrtmrz/livesync-commonlib/compat/common/types"; +import type { RemoteDBSettings } from "@vrtmrz/livesync-commonlib/compat/common/types"; +import { defaultRemoteProviderRegistry } from "@vrtmrz/livesync-commonlib/remote-configurations"; import { LiveSyncCouchDBReplicator } from "@vrtmrz/livesync-commonlib/compat/replication/couchdb/LiveSyncReplicator"; import type { LiveSyncAbstractReplicator } from "@vrtmrz/livesync-commonlib/compat/replication/LiveSyncAbstractReplicator"; import { AbstractModule } from "@/modules/AbstractModule"; @@ -8,8 +9,7 @@ import type { LiveSyncCore } from "@/main"; export class ModuleReplicatorCouchDB extends AbstractModule { _anyNewReplicator(settingOverride: Partial = {}): Promise { const settings = { ...this.settings, ...settingOverride }; - // If new remote types were added, add them here. Do not use `REMOTE_COUCHDB` directly for the safety valve. - if (settings.remoteType == REMOTE_MINIO || settings.remoteType == REMOTE_P2P) { + if (!defaultRemoteProviderRegistry.isRemoteTypeInFamily(settings.remoteType, "couchdb")) { return Promise.resolve(false); } return Promise.resolve(new LiveSyncCouchDBReplicator(this.core)); @@ -17,7 +17,7 @@ export class ModuleReplicatorCouchDB extends AbstractModule { _everyAfterResumeProcess(): Promise { if (this.services.appLifecycle.isSuspended()) return Promise.resolve(true); if (!this.services.appLifecycle.isReady()) return Promise.resolve(true); - if (this.settings.remoteType != REMOTE_MINIO && this.settings.remoteType != REMOTE_P2P) { + if (defaultRemoteProviderRegistry.isRemoteTypeInFamily(this.settings.remoteType, "couchdb")) { const LiveSyncEnabled = this.settings.liveSync; const continuous = LiveSyncEnabled; const eventualOnStart = !LiveSyncEnabled && this.settings.syncOnStart; diff --git a/src/modules/core/ModuleReplicatorCouchDB.unit.spec.ts b/src/modules/core/ModuleReplicatorCouchDB.unit.spec.ts index c4296e19..682a942b 100644 --- a/src/modules/core/ModuleReplicatorCouchDB.unit.spec.ts +++ b/src/modules/core/ModuleReplicatorCouchDB.unit.spec.ts @@ -1,7 +1,11 @@ import { describe, expect, it, vi } from "vitest"; +import { REMOTE_COUCHDB, REMOTE_MINIO } from "@vrtmrz/livesync-commonlib/compat/common/types"; import { ModuleReplicatorCouchDB } from "./ModuleReplicatorCouchDB.ts"; -function createModule(settings: { liveSync: boolean; syncOnStart: boolean }, isReplicationReady = true) { +function createModule( + settings: { liveSync: boolean; syncOnStart: boolean; remoteType?: typeof REMOTE_COUCHDB | typeof REMOTE_MINIO }, + isReplicationReady = true +) { const openReplication = vi.fn(async () => true); const runFiniteReplicationActivity = vi.fn(async (task: () => unknown) => await task()); const services = { @@ -30,7 +34,7 @@ function createModule(settings: { liveSync: boolean; syncOnStart: boolean }, isR _services: services, services, settings: { - remoteType: "", + remoteType: REMOTE_COUCHDB, ...settings, }, replicator: { openReplication }, @@ -86,4 +90,18 @@ describe("ModuleReplicatorCouchDB resume replication activity", () => { expect(runFiniteReplicationActivity).not.toHaveBeenCalled(); expect(openReplication).not.toHaveBeenCalled(); }); + + it("does not start CouchDB replication for a registered Journal provider", async () => { + const { module, openReplication } = createModule({ + liveSync: true, + syncOnStart: true, + remoteType: REMOTE_MINIO, + }); + + await expect(module._anyNewReplicator()).resolves.toBe(false); + await module._everyAfterResumeProcess(); + await new Promise((resolve) => setTimeout(resolve, 0)); + + expect(openReplication).not.toHaveBeenCalled(); + }); }); diff --git a/src/modules/core/ModuleReplicatorMinIO.ts b/src/modules/core/ModuleReplicatorMinIO.ts deleted file mode 100644 index 68dcc22e..00000000 --- a/src/modules/core/ModuleReplicatorMinIO.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { REMOTE_MINIO, type RemoteDBSettings } from "@vrtmrz/livesync-commonlib/compat/common/types"; -import { LiveSyncJournalReplicator } from "@vrtmrz/livesync-commonlib/compat/replication/journal/LiveSyncJournalReplicator"; -import type { LiveSyncAbstractReplicator } from "@vrtmrz/livesync-commonlib/compat/replication/LiveSyncAbstractReplicator"; -import type { LiveSyncCore } from "@/main"; -import { AbstractModule } from "@/modules/AbstractModule"; - -export class ModuleReplicatorMinIO extends AbstractModule { - _anyNewReplicator(settingOverride: Partial = {}): Promise { - const settings = { ...this.settings, ...settingOverride }; - if (settings.remoteType == REMOTE_MINIO) { - return Promise.resolve(new LiveSyncJournalReplicator(this.core)); - } - return Promise.resolve(false); - } - override onBindFunction(core: LiveSyncCore, services: typeof core.services): void { - services.replicator.getNewReplicator.addHandler(this._anyNewReplicator.bind(this)); - } -}