diff --git a/src/common/events.ts b/src/common/events.ts index b4aa2d3..0ef7d04 100644 --- a/src/common/events.ts +++ b/src/common/events.ts @@ -21,7 +21,6 @@ export const EVENT_REQUEST_CLOSE_P2P = "request-close-p2p"; export const EVENT_REQUEST_RUN_DOCTOR = "request-run-doctor"; export const EVENT_REQUEST_RUN_FIX_INCOMPLETE = "request-run-fix-incomplete"; -export const EVENT_ON_UNRESOLVED_ERROR = "on-unresolved-error"; export const EVENT_ANALYSE_DB_USAGE = "analyse-db-usage"; export const EVENT_REQUEST_PERFORM_GC_V3 = "request-perform-gc-v3"; @@ -44,7 +43,6 @@ declare global { [EVENT_REQUEST_SHOW_SETUP_QR]: undefined; [EVENT_REQUEST_RUN_DOCTOR]: string; [EVENT_REQUEST_RUN_FIX_INCOMPLETE]: undefined; - [EVENT_ON_UNRESOLVED_ERROR]: undefined; [EVENT_ANALYSE_DB_USAGE]: undefined; [EVENT_REQUEST_CHECK_REMOTE_SIZE]: undefined; [EVENT_REQUEST_PERFORM_GC_V3]: undefined; diff --git a/src/lib b/src/lib index 3ae1cba..75d46c7 160000 --- a/src/lib +++ b/src/lib @@ -1 +1 @@ -Subproject commit 3ae1cbabdae286f994807c9da4ac2e937f70d3ee +Subproject commit 75d46c716320ee60fc728f4f460921ef0fa111c8 diff --git a/src/main.ts b/src/main.ts index 8a8d1bd..2d04a91 100644 --- a/src/main.ts +++ b/src/main.ts @@ -7,10 +7,7 @@ import { } from "./lib/src/common/types.ts"; import { type SimpleStore } from "./lib/src/common/utils.ts"; import { type LiveSyncLocalDBEnv } from "./lib/src/pouchdb/LiveSyncLocalDB.ts"; -import { - LiveSyncAbstractReplicator, - type LiveSyncReplicatorEnv, -} from "./lib/src/replication/LiveSyncAbstractReplicator.js"; +import { type LiveSyncReplicatorEnv } from "./lib/src/replication/LiveSyncAbstractReplicator.js"; import { LiveSyncCommands } from "./features/LiveSyncCommands.ts"; import { HiddenFileSync } from "./features/HiddenFileSync/CmdHiddenFileSync.ts"; import { ConfigSync } from "./features/ConfigSync/CmdConfigSync.ts"; @@ -202,8 +199,10 @@ export default class ObsidianLiveSyncPlugin return this.services.keyValueDB.simpleStore as SimpleStore; } - // initialised at ModuleReplicator - replicator!: LiveSyncAbstractReplicator; + get replicator() { + return this.services.replicator.getActiveReplicator()!; + } + // initialised at ModuleFileAccessObsidian storageAccess!: StorageAccess; // initialised at ModuleDatabaseFileAccess diff --git a/src/modules/core/ModuleRebuilder.ts b/src/modules/core/ModuleRebuilder.ts index d5fc7dc..a38d286 100644 --- a/src/modules/core/ModuleRebuilder.ts +++ b/src/modules/core/ModuleRebuilder.ts @@ -133,9 +133,9 @@ Please enable them from the settings screen after setup is complete.`, await this.core.replicator.tryCreateRemoteDatabase(this.settings); } - private async _resetLocalDatabase(): Promise { + private _onResetLocalDatabase(): Promise { this.core.storageAccess.clearTouched(); - return await this.localDatabase.resetDatabase(); + return Promise.resolve(true); } async suspendAllSync() { @@ -305,7 +305,7 @@ Are you sure you wish to proceed?`; } onBindFunction(core: LiveSyncCore, services: typeof core.services): void { services.appLifecycle.onLoaded.addHandler(this._everyOnload.bind(this)); - services.database.resetDatabase.setHandler(this._resetLocalDatabase.bind(this)); + services.database.onDatabaseReset.addHandler(this._onResetLocalDatabase.bind(this)); services.remote.tryResetDatabase.setHandler(this._tryResetRemoteDatabase.bind(this)); services.remote.tryCreateDatabase.setHandler(this._tryCreateRemoteDatabase.bind(this)); services.setting.suspendAllSync.addHandler(this._allSuspendAllSync.bind(this)); diff --git a/src/modules/core/ModuleReplicator.ts b/src/modules/core/ModuleReplicator.ts index 08af7fa..6a6165f 100644 --- a/src/modules/core/ModuleReplicator.ts +++ b/src/modules/core/ModuleReplicator.ts @@ -1,48 +1,36 @@ -import { fireAndForget, yieldMicrotask } from "octagonal-wheels/promises"; -import type { LiveSyncLocalDB } from "../../lib/src/pouchdb/LiveSyncLocalDB"; +import { fireAndForget } from "octagonal-wheels/promises"; import { AbstractModule } from "../AbstractModule"; -import { - Logger, - LOG_LEVEL_NOTICE, - LOG_LEVEL_INFO, - LOG_LEVEL_VERBOSE, - LEVEL_NOTICE, - LEVEL_INFO, - type LOG_LEVEL, -} from "octagonal-wheels/common/logger"; +import { Logger, LOG_LEVEL_NOTICE, LOG_LEVEL_INFO, LEVEL_NOTICE, type LOG_LEVEL } from "octagonal-wheels/common/logger"; import { isLockAcquired, shareRunningResult, skipIfDuplicated } from "octagonal-wheels/concurrency/lock"; import { balanceChunkPurgedDBs } from "@/lib/src/pouchdb/chunks"; import { purgeUnreferencedChunks } from "@/lib/src/pouchdb/chunks"; import { LiveSyncCouchDBReplicator } from "../../lib/src/replication/couchdb/LiveSyncReplicator"; import { type EntryDoc, type RemoteType } from "../../lib/src/common/types"; import { rateLimitedSharedExecution, scheduleTask, updatePreviousExecutionTime } from "../../common/utils"; -import { EVENT_FILE_SAVED, EVENT_ON_UNRESOLVED_ERROR, EVENT_SETTING_SAVED, eventHub } from "../../common/events"; -import type { LiveSyncAbstractReplicator } from "../../lib/src/replication/LiveSyncAbstractReplicator"; +import { EVENT_FILE_SAVED, EVENT_SETTING_SAVED, eventHub } from "../../common/events"; import { $msg } from "../../lib/src/common/i18n"; -import { clearHandlers } from "../../lib/src/replication/SyncParamsHandler"; import type { LiveSyncCore } from "../../main"; import { ReplicateResultProcessor } from "./ReplicateResultProcessor"; +import { UnresolvedErrorManager } from "@/lib/src/services/base/UnresolvedErrorManager"; +import { clearHandlers } from "@/lib/src/replication/SyncParamsHandler"; const KEY_REPLICATION_ON_EVENT = "replicationOnEvent"; const REPLICATION_ON_EVENT_FORECASTED_TIME = 5000; export class ModuleReplicator extends AbstractModule { _replicatorType?: RemoteType; - _previousErrors = new Set(); + processor: ReplicateResultProcessor = new ReplicateResultProcessor(this); + private _unresolvedErrorManager: UnresolvedErrorManager = new UnresolvedErrorManager( + this.core.services.appLifecycle + ); showError(msg: string, max_log_level: LOG_LEVEL = LEVEL_NOTICE) { - const level = this._previousErrors.has(msg) ? LEVEL_INFO : max_log_level; - this._log(msg, level); - if (!this._previousErrors.has(msg)) { - this._previousErrors.add(msg); - eventHub.emitEvent(EVENT_ON_UNRESOLVED_ERROR); - } + this._unresolvedErrorManager.showError(msg, max_log_level); } clearErrors() { - this._previousErrors.clear(); - eventHub.emitEvent(EVENT_ON_UNRESOLVED_ERROR); + this._unresolvedErrorManager.clearErrors(); } private _everyOnloadAfterLoadSettings(): Promise { @@ -52,9 +40,10 @@ export class ModuleReplicator extends AbstractModule { } }); eventHub.onEvent(EVENT_SETTING_SAVED, (setting) => { - if (this._replicatorType !== setting.remoteType) { - void this.setReplicator(); - } + // ReplicatorService responds to `settingService.onRealiseSetting`. + // if (this._replicatorType !== setting.remoteType) { + // void this.setReplicator(); + // } if (this.core.settings.suspendParseReplicationResult) { this.processor.suspend(); } else { @@ -65,39 +54,17 @@ export class ModuleReplicator extends AbstractModule { return Promise.resolve(true); } - async setReplicator() { - const replicator = await this.services.replicator.getNewReplicator(); - if (!replicator) { - this.showError($msg("Replicator.Message.InitialiseFatalError"), LOG_LEVEL_NOTICE); - return false; - } - if (this.core.replicator) { - await this.core.replicator.closeReplication(); - this._log("Replicator closed for changing", LOG_LEVEL_VERBOSE); - } - this.core.replicator = replicator; - this._replicatorType = this.settings.remoteType; - await yieldMicrotask(); - // Clear any existing sync parameter handlers (means clearing key-deriving salt). + _onReplicatorInitialised(): Promise { + // For now, we only need to clear the error related to replicator initialisation, but in the future, if there are more things to do when the replicator is initialised, we can add them here. clearHandlers(); - return true; + return Promise.resolve(true); } - _getReplicator(): LiveSyncAbstractReplicator { - return this.core.replicator; - } - - _everyOnInitializeDatabase(db: LiveSyncLocalDB): Promise { - return this.setReplicator(); - } _everyOnDatabaseInitialized(showNotice: boolean): Promise { fireAndForget(() => this.processor.restoreFromSnapshotOnce()); return Promise.resolve(true); } - _everyOnResetDatabase(db: LiveSyncLocalDB): Promise { - return this.setReplicator(); - } async ensureReplicatorPBKDF2Salt(showMessage: boolean = false): Promise { // Checking salt const replicator = this.services.replicator.getActiveReplicator(); @@ -324,15 +291,9 @@ Even if you choose to clean up, you will see this option again if you exit Obsid return !checkResult; } - private _reportUnresolvedMessages(): Promise { - return Promise.resolve([...this._previousErrors]); - } - onBindFunction(core: LiveSyncCore, services: typeof core.services): void { - services.replicator.getActiveReplicator.setHandler(this._getReplicator.bind(this)); - services.databaseEvents.onDatabaseInitialisation.addHandler(this._everyOnInitializeDatabase.bind(this)); + services.replicator.onReplicatorInitialised.addHandler(this._onReplicatorInitialised.bind(this)); services.databaseEvents.onDatabaseInitialised.addHandler(this._everyOnDatabaseInitialized.bind(this)); - services.databaseEvents.onResetDatabase.addHandler(this._everyOnResetDatabase.bind(this)); services.appLifecycle.onSettingLoaded.addHandler(this._everyOnloadAfterLoadSettings.bind(this)); services.replication.parseSynchroniseResult.setHandler(this._parseReplicationResult.bind(this)); services.appLifecycle.onSuspending.addHandler(this._everyBeforeSuspendProcess.bind(this)); @@ -342,6 +303,5 @@ Even if you choose to clean up, you will see this option again if you exit Obsid services.replication.replicateByEvent.setHandler(this._replicateByEvent.bind(this)); services.remote.replicateAllToRemote.setHandler(this._replicateAllToServer.bind(this)); services.remote.replicateAllFromRemote.setHandler(this._replicateAllFromServer.bind(this)); - services.appLifecycle.getUnresolvedMessages.addHandler(this._reportUnresolvedMessages.bind(this)); } } diff --git a/src/modules/features/SettingDialogue/ObsidianLiveSyncSettingTab.ts b/src/modules/features/SettingDialogue/ObsidianLiveSyncSettingTab.ts index 2fb26e8..f2ae1e4 100644 --- a/src/modules/features/SettingDialogue/ObsidianLiveSyncSettingTab.ts +++ b/src/modules/features/SettingDialogue/ObsidianLiveSyncSettingTab.ts @@ -424,8 +424,6 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab { //@ts-ignore manifestVersion: string = MANIFEST_VERSION || "-"; - //@ts-ignore - updateInformation: string = UPDATE_INFO || ""; lastVersion = ~~(versionNumberString2Number(this.manifestVersion) / 1000); diff --git a/src/modules/services/ObsidianDatabaseService.ts b/src/modules/services/ObsidianDatabaseService.ts index 1e88cbb..b2e4146 100644 --- a/src/modules/services/ObsidianDatabaseService.ts +++ b/src/modules/services/ObsidianDatabaseService.ts @@ -1,11 +1,16 @@ import { initializeStores } from "@/common/stores"; -import { InjectableDatabaseService } from "@/lib/src/services/implements/injectable/InjectableDatabaseService"; +// import { InjectableDatabaseService } from "@/lib/src/services/implements/injectable/InjectableDatabaseService"; import type { ObsidianServiceContext } from "@/lib/src/services/implements/obsidian/ObsidianServiceContext"; +import { DatabaseService, type DatabaseServiceDependencies } from "@lib/services/base/DatabaseService.ts"; -export class ObsidianDatabaseService extends InjectableDatabaseService { - override onOpenDatabase(vaultName: string): Promise { +export class ObsidianDatabaseService extends DatabaseService { + private __onOpenDatabase(vaultName: string) { initializeStores(vaultName); - return Promise.resolve(); + return Promise.resolve(true); + } + constructor(context: T, dependencies: DatabaseServiceDependencies) { + super(context, dependencies); + this.onOpenDatabase.addHandler(this.__onOpenDatabase.bind(this)); } } diff --git a/src/modules/services/ObsidianServiceHub.ts b/src/modules/services/ObsidianServiceHub.ts index cd49fc8..5870f6c 100644 --- a/src/modules/services/ObsidianServiceHub.ts +++ b/src/modules/services/ObsidianServiceHub.ts @@ -33,7 +33,7 @@ export class ObsidianServiceHub extends InjectableServiceHub