feat: add unit tests for replicateResultProcessor and refactor replicator logging

- Introduced unit tests for the replicateResultProcessor, covering various scenarios including document enqueuing, snapshot handling, and processing of non-document changes.
- Refactored replicator to utilize a logging function from the host API instead of a global logger, enhancing log management.
- Updated mismatchedTweaksResolver to include logging through the host API, ensuring consistent logging practices across the application.
- Adjusted tests to mock the new logging behavior and verify log outputs.
This commit is contained in:
vorotamoroz
2026-06-26 09:36:48 +00:00
parent f954448ef8
commit 559c3f351b
86 changed files with 2569 additions and 2009 deletions
-16
View File
@@ -1,16 +0,0 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { PeriodicProcessor } from "@/common/PeriodicProcessor";
import type { LiveSyncCore } from "@/main";
import { AbstractModule } from "@/modules/AbstractModule";
export declare class ModulePeriodicProcess extends AbstractModule {
periodicSyncProcessor: PeriodicProcessor;
disablePeriodic(): Promise<boolean>;
resumePeriodic(): Promise<boolean>;
private _allOnUnload;
private _everyBeforeRealizeSetting;
private _everyBeforeSuspendProcess;
private _everyAfterResumeProcess;
private _everyAfterRealizeSetting;
onBindFunction(core: LiveSyncCore, services: typeof core.services): void;
}
-25
View File
@@ -1,25 +0,0 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { AbstractModule } from "@/modules/AbstractModule";
import { type EntryDoc, type RemoteType } from "@lib/common/types";
import type { LiveSyncCore } from "@/main";
import { ReplicateResultProcessor } from "./ReplicateResultProcessor";
export declare class ModuleReplicator extends AbstractModule {
_replicatorType?: RemoteType;
processor: ReplicateResultProcessor;
private _unresolvedErrorManager;
clearErrors(): void;
private _everyOnloadAfterLoadSettings;
_onReplicatorInitialised(): Promise<boolean>;
_everyOnDatabaseInitialized(showNotice: boolean): Promise<boolean>;
_everyBeforeReplicate(showMessage: boolean): Promise<boolean>;
/**
* obsolete method. No longer maintained and will be removed in the future.
* @deprecated v0.24.17
* @param showMessage If true, show message to the user.
*/
cleaned(showMessage: boolean): Promise<void>;
private onReplicationFailed;
_parseReplicationResult(docs: Array<PouchDB.Core.ExistingDocument<EntryDoc>>): Promise<boolean>;
onBindFunction(core: LiveSyncCore, services: typeof core.services): void;
}
-11
View File
@@ -1,11 +0,0 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { type RemoteDBSettings } from "@lib/common/types";
import type { LiveSyncAbstractReplicator } from "@lib/replication/LiveSyncAbstractReplicator";
import { AbstractModule } from "@/modules/AbstractModule";
import type { LiveSyncCore } from "@/main";
export declare class ModuleReplicatorCouchDB extends AbstractModule {
_anyNewReplicator(settingOverride?: Partial<RemoteDBSettings>): Promise<LiveSyncAbstractReplicator | false>;
_everyAfterResumeProcess(): Promise<boolean>;
onBindFunction(core: LiveSyncCore, services: typeof core.services): void;
}
-10
View File
@@ -1,10 +0,0 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { type RemoteDBSettings } from "@lib/common/types";
import type { LiveSyncAbstractReplicator } from "@lib/replication/LiveSyncAbstractReplicator";
import type { LiveSyncCore } from "@/main";
import { AbstractModule } from "@/modules/AbstractModule";
export declare class ModuleReplicatorMinIO extends AbstractModule {
_anyNewReplicator(settingOverride?: Partial<RemoteDBSettings>): Promise<LiveSyncAbstractReplicator | false>;
onBindFunction(core: LiveSyncCore, services: typeof core.services): void;
}
-116
View File
@@ -1,116 +0,0 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { type AnyEntry, type EntryDoc, type LoadedEntry, type MetaEntry } from "@lib/common/types";
import type { ModuleReplicator } from "./ModuleReplicator";
import type { ReactiveSource } from "octagonal-wheels/dataobject/reactive_v2";
import type { LiveSyncBaseCore } from "@/LiveSyncBaseCore";
export declare class ReplicateResultProcessor {
private log;
private logError;
private replicator;
constructor(replicator: ModuleReplicator);
get localDatabase(): import("../../lib/src/pouchdb/LiveSyncLocalDB").LiveSyncLocalDB;
get services(): import("../../lib/src/services/InjectableServices").InjectableServiceHub<import("../../lib/src/services/base/ServiceBase").ServiceContext>;
get core(): LiveSyncBaseCore;
getPath(entry: AnyEntry): string;
suspend(): void;
resume(): void;
private _suspended;
get isSuspended(): boolean;
/**
* Take a snapshot of the current processing state.
* This snapshot is stored in the KV database for recovery on restart.
*/
protected _takeSnapshot(): Promise<void>;
/**
* Trigger taking a snapshot.
*/
protected _triggerTakeSnapshot(): void;
/**
* Throttled version of triggerTakeSnapshot.
*/
protected triggerTakeSnapshot: import("octagonal-wheels/function").ThrottledFunction<() => void>;
/**
* Restore from snapshot.
*/
restoreFromSnapshot(): Promise<void>;
private _restoreFromSnapshot;
/**
* Restore from snapshot only once.
* @returns Promise that resolves when restoration is complete.
*/
restoreFromSnapshotOnce(): Promise<void>;
/**
* Perform the given procedure while counting the concurrency.
* @param proc async procedure to perform
* @param countValue reactive source to count concurrency
* @returns result of the procedure
*/
withCounting<T>(proc: () => Promise<T>, countValue: ReactiveSource<number>): Promise<T>;
/**
* Report the current status.
*/
protected reportStatus(): void;
/**
* Enqueue all the given changes for processing.
* @param changes Changes to enqueue
*/
enqueueAll(changes: PouchDB.Core.ExistingDocument<EntryDoc>[]): void;
/**
* Process the change if it is not a document change.
* @param change Change to process
* @returns True if the change was processed; false otherwise
*/
protected processIfNonDocumentChange(change: PouchDB.Core.ExistingDocument<EntryDoc>): boolean;
/**
* Queue of changes to be processed.
*/
private _queuedChanges;
/**
* List of changes being processed.
*/
private _processingChanges;
/**
* Enqueue the given document change for processing.
* @param doc Document change to enqueue
* @returns
*/
protected enqueueChange(doc: PouchDB.Core.ExistingDocument<EntryDoc>): void;
/**
* Trigger processing of the queued changes.
*/
protected triggerProcessQueue(): void;
/**
* Semaphore to limit concurrent processing.
* This is the per-id semaphore + concurrency-control (max 10 concurrent = 10 documents being processed at the same time).
*/
private _semaphore;
/**
* Flag indicating whether the process queue is currently running.
*/
private _isRunningProcessQueue;
/**
* Process the queued changes.
*/
private runProcessQueue;
/**
* Parse the given document change.
* @param change
* @returns
*/
parseDocumentChange(change: PouchDB.Core.ExistingDocument<EntryDoc>): Promise<void>;
protected applyToDatabase(doc: PouchDB.Core.ExistingDocument<AnyEntry>): Promise<void>;
private _applyToDatabase;
/**
* Phase 3: Apply the given entry to storage.
* @param entry
* @returns
*/
protected applyToStorage(entry: MetaEntry): Promise<void>;
/**
* Check whether processing is required for the given document.
* @param dbDoc Document to check
* @returns True if processing is required; false otherwise
*/
protected checkIsChangeRequiredForDatabaseProcessing(dbDoc: LoadedEntry): Promise<boolean>;
}
@@ -1,15 +0,0 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { AbstractModule } from "@/modules/AbstractModule.ts";
import { type FilePathWithPrefix } from "@lib/common/types";
import { QueueProcessor } from "octagonal-wheels/concurrency/processor";
import type { InjectableServiceHub } from "@lib/services/InjectableServices.ts";
import type { LiveSyncCore } from "@/main.ts";
export declare class ModuleConflictChecker extends AbstractModule {
_queueConflictCheckIfOpen(file: FilePathWithPrefix): Promise<void>;
_queueConflictCheck(file: FilePathWithPrefix): Promise<void>;
_waitForAllConflictProcessed(): Promise<boolean>;
conflictResolveQueue: QueueProcessor<FilePathWithPrefix, unknown>;
conflictCheckQueue: QueueProcessor<FilePathWithPrefix, FilePathWithPrefix>;
onBindFunction(core: LiveSyncCore, services: InjectableServiceHub): void;
}
@@ -1,19 +0,0 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { AbstractModule } from "@/modules/AbstractModule.ts";
import { type diff_check_result, type FilePathWithPrefix } from "@lib/common/types";
import type { InjectableServiceHub } from "@lib/services/InjectableServices.ts";
import type { LiveSyncCore } from "@/main.ts";
declare global {
interface LSEvents {
"conflict-cancelled": FilePathWithPrefix;
}
}
export declare class ModuleConflictResolver extends AbstractModule {
private _resolveConflictByDeletingRev;
checkConflictAndPerformAutoMerge(path: FilePathWithPrefix): Promise<diff_check_result>;
private _resolveConflict;
private _anyResolveConflictByNewest;
private _resolveAllConflictedFilesByNewerOnes;
onBindFunction(core: LiveSyncCore, services: InjectableServiceHub): void;
}
@@ -1,36 +0,0 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { type TweakValues, type ObsidianLiveSyncSettings, type RemoteDBSettings } from "@lib/common/types.ts";
import { AbstractModule } from "@/modules/AbstractModule.ts";
import type { InjectableServiceHub } from "@lib/services/InjectableServices.ts";
import type { LiveSyncCore } from "@/main.ts";
export declare class ModuleResolvingMismatchedTweaks extends AbstractModule {
private _hasNotifiedAutoAcceptCompatibleUndefined;
private _collectMismatchedTweakKeys;
private _selectNewerTweakSide;
private _shouldAutoAcceptCompatibleLossy;
/**
* Hook before saving settings, to check if there are changes in tweak values, and if so,
* update the tweakModified timestamp to current time.
* This allows other devices to know that the tweak values have been changed and decide whether to accept the new values based on the modification time.
* @param next
* @param previous
* @returns
*/
_onBeforeSaveSettingData(next: ObsidianLiveSyncSettings, previous: ObsidianLiveSyncSettings): Promise<{
tweakModified: number;
} | undefined>;
_anyAfterConnectCheckFailed(): Promise<boolean | "CHECKAGAIN" | undefined>;
_checkAndAskResolvingMismatchedTweaks(preferred: TweakValues): Promise<[TweakValues | boolean, boolean]>;
_askResolvingMismatchedTweaks(): Promise<"OK" | "CHECKAGAIN" | "IGNORE">;
_fetchRemotePreferredTweakValues(trialSetting: RemoteDBSettings): Promise<TweakValues | false>;
_checkAndAskUseRemoteConfiguration(trialSetting: RemoteDBSettings): Promise<{
result: false | TweakValues;
requireFetch: boolean;
}>;
_askUseRemoteConfiguration(trialSetting: RemoteDBSettings, preferred: TweakValues): Promise<{
result: false | TweakValues;
requireFetch: boolean;
}>;
onBindFunction(core: LiveSyncCore, services: InjectableServiceHub): void;
}
-8
View File
@@ -1,8 +0,0 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import type { LiveSyncCore } from "@/main";
import { AbstractModule } from "@/modules/AbstractModule";
export declare class ModuleBasicMenu extends AbstractModule {
_everyOnloadStart(): Promise<boolean>;
onBindFunction(core: LiveSyncCore, services: typeof core.services): void;
}
@@ -0,0 +1,12 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { type FilePathWithPrefix } from "@lib/common/types";
import { QueueProcessor } from "octagonal-wheels/concurrency/processor";
import type { NecessaryObsidianFeature } from "@/types";
export type ConflictCheckerHost = NecessaryObsidianFeature<"API" | "conflict" | "vault" | "setting">;
export declare const queueConflictCheckIfOpenHandler: (host: ConflictCheckerHost, file: FilePathWithPrefix) => Promise<void>;
export declare const queueConflictCheckHandler: (host: ConflictCheckerHost, queue: QueueProcessor<FilePathWithPrefix, any>, file: FilePathWithPrefix) => Promise<void>; // eslint-disable-line @typescript-eslint/no-explicit-any -- Only type declaration
export declare function useConflictChecker(host: ConflictCheckerHost): {
conflictCheckQueue: QueueProcessor<FilePathWithPrefix, FilePathWithPrefix>;
conflictResolveQueue: QueueProcessor<FilePathWithPrefix, unknown>;
};
@@ -0,0 +1,16 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { AUTO_MERGED, MISSING_OR_ERROR, type diff_check_result, type FilePathWithPrefix } from "@lib/common/types";
import type { NecessaryObsidianFeature } from "@/types";
declare global {
interface LSEvents {
"conflict-cancelled": FilePathWithPrefix;
}
}
export type ConflictResolverHost = NecessaryObsidianFeature<"API" | "conflict" | "appLifecycle" | "replication" | "vault" | "setting" | "database", "databaseFileAccess" | "fileHandler" | "storageAccess">;
export declare const resolveConflictByDeletingRevHandler: (host: ConflictResolverHost, path: FilePathWithPrefix, deleteRevision: string, subTitle?: string) => Promise<typeof MISSING_OR_ERROR | typeof AUTO_MERGED>;
export declare const checkConflictAndPerformAutoMerge: (host: ConflictResolverHost, path: FilePathWithPrefix) => Promise<diff_check_result>;
export declare const resolveConflictHandler: (host: ConflictResolverHost, filename: FilePathWithPrefix) => Promise<void>;
export declare const resolveConflictByNewestHandler: (host: ConflictResolverHost, filename: FilePathWithPrefix) => Promise<boolean>;
export declare const resolveAllConflictedFilesByNewerOnesHandler: (host: ConflictResolverHost) => Promise<void>;
export declare function useConflictResolver(host: ConflictResolverHost): void;
@@ -0,0 +1,4 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
export { useConflictChecker } from "./conflictChecker";
export { useConflictResolver } from "./conflictResolver";
+1 -1
View File
@@ -4,7 +4,7 @@ import type { NecessaryObsidianServices } from "@/types.ts";
/**
* A union of service keys required by the database maintenance feature.
*/
export type DatabaseMaintenanceServices = "API" | "setting" | "UI" | "database" | "keyValueDB" | "replication" | "replicator";
export type DatabaseMaintenanceServices = "API" | "setting" | "UI" | "database" | "keyValueDB" | "replication" | "replicator" | "vault";
/**
* A union of service module keys required by the database maintenance feature.
*/
@@ -28,3 +28,10 @@ export declare function createConflict(host: DevFeatureHost): Promise<void>;
* @param message - Optional detailed stacktrace or assertion info.
*/
export declare function addTestResult(state: DevFeatureState, name: string, key: string, result: boolean, summary?: string, message?: string): void;
/**
* Dumps information of the specified document for debugging purposes.
*
* @param host - The service feature host context.
* @param file - The file path to dump.
*/
export declare function dumpDocument(host: DevFeatureHost, file: string | undefined): void;
@@ -5,4 +5,4 @@ import type { ConflictResolverServices } from "./types.ts";
* A service feature hook that initialises and manages the Interactive Conflict Resolver.
* Registers conflict resolution commands and handles user-interactive resolution flows.
*/
export declare const useInteractiveConflictResolver: import("@lib/interfaces/ServiceModule.ts").ServiceFeatureFunction<ConflictResolverServices, "databaseFileAccess", void>;
export declare const useInteractiveConflictResolver: import("@/types.ts").ObsidianServiceFeatureFunction<ConflictResolverServices, "databaseFileAccess", "app", void>;
@@ -1,6 +1,6 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { type NecessaryServices } from "@lib/interfaces/ServiceModule";
import type { NecessaryObsidianServices } from "@/types.ts";
/**
* A union of service keys required by the interactive conflict resolver feature.
*/
@@ -12,4 +12,4 @@ export type ConflictResolverModules = "databaseFileAccess";
/**
* The host type representing the injected service container with conflict resolution capabilities.
*/
export type ConflictResolverHost = NecessaryServices<ConflictResolverServices, ConflictResolverModules>;
export type ConflictResolverHost = NecessaryObsidianServices<ConflictResolverServices, ConflictResolverModules, "app">;
+1 -1
View File
@@ -4,4 +4,4 @@ import type { LogFeatureServices } from "./types.ts";
/**
* A service feature hook that initialises and manages logging, status display, and debug report generation.
*/
export declare const useLogFeature: import("@lib/interfaces/ServiceModule.ts").ServiceFeatureFunction<LogFeatureServices, "storageAccess", void>;
export declare const useLogFeature: import("@/types.ts").ObsidianServiceFeatureFunction<LogFeatureServices, "storageAccess", "app" | "liveSyncPlugin", void>;
+2 -2
View File
@@ -1,6 +1,6 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { type NecessaryServices } from "@lib/interfaces/ServiceModule";
import type { NecessaryObsidianServices } from "@/types.ts";
/**
* Service keys required by the logging and status bar feature.
*/
@@ -12,4 +12,4 @@ export type LogFeatureModules = "storageAccess";
/**
* The host type representing the injected service container with logging capabilities.
*/
export type LogFeatureHost = NecessaryServices<LogFeatureServices, LogFeatureModules>;
export type LogFeatureHost = NecessaryObsidianServices<LogFeatureServices, LogFeatureModules, "app" | "liveSyncPlugin">;
+2 -1
View File
@@ -1,3 +1,4 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
export declare const useMigrationFeature: import("@/types.ts").ObsidianServiceFeatureFunction<"path" | "setting" | "UI" | "appLifecycle" | "API" | "database" | "replicator" | "vault" | "keyValueDB", "storageAccess" | "fileHandler" | "rebuilder", never, void>;
import type { MigrationModules, MigrationServices } from "./types.ts";
export declare const useMigrationFeature: import("@/types.ts").ObsidianServiceFeatureFunction<MigrationServices, MigrationModules, never, void>;
@@ -0,0 +1,12 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import type { LogFunction } from "@lib/services/lib/logUtils.ts";
import type { MigrationHost } from "./types.ts";
export declare function migrateUsingDoctor(host: MigrationHost, skipRebuild?: boolean, activateReason?: string, forceRescan?: boolean): Promise<boolean>;
export declare function migrateDisableBulkSend(host: MigrationHost, log: LogFunction): Promise<void>;
export declare function initialMigrationMessage(): Promise<boolean>;
export declare function askAgainForSetupURI(host: MigrationHost): Promise<boolean>;
export declare function hasIncompleteDocs(host: MigrationHost, log: LogFunction, force?: boolean): Promise<boolean>;
export declare function hasCompromisedChunks(host: MigrationHost, log: LogFunction): Promise<boolean>;
export declare function runFirstInitialiseMigration(host: MigrationHost, log: LogFunction): Promise<boolean>;
export declare function bindMigrationRequestEvents(host: MigrationHost, log: LogFunction): Promise<boolean>;
+6
View File
@@ -0,0 +1,6 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import type { NecessaryObsidianServices } from "@/types.ts";
export type MigrationServices = "API" | "appLifecycle" | "setting" | "database" | "path" | "vault" | "replicator" | "UI" | "keyValueDB";
export type MigrationModules = "storageAccess" | "fileHandler" | "rebuilder";
export type MigrationHost = NecessaryObsidianServices<MigrationServices, MigrationModules>;
@@ -5,4 +5,4 @@ import type { DocumentHistoryServices } from "./types.ts";
* A service feature hook that initialises and manages Obsidian Document History commands.
* Registers ribbon commands and listens to history request events.
*/
export declare const useObsidianDocumentHistory: import("@lib/interfaces/ServiceModule.ts").ServiceFeatureFunction<DocumentHistoryServices, never, void>;
export declare const useObsidianDocumentHistory: import("@/types.ts").ObsidianServiceFeatureFunction<DocumentHistoryServices, never, "app" | "liveSyncPlugin", void>;
@@ -1,6 +1,6 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { type NecessaryServices } from "@lib/interfaces/ServiceModule";
import type { NecessaryObsidianServices } from "@/types.ts";
/**
* Service keys required by the Obsidian document history feature.
*/
@@ -12,4 +12,4 @@ export type DocumentHistoryModules = never;
/**
* The host type representing the injected service container with document history capabilities.
*/
export type DocumentHistoryHost = NecessaryServices<DocumentHistoryServices, DocumentHistoryModules>;
export type DocumentHistoryHost = NecessaryObsidianServices<DocumentHistoryServices, DocumentHistoryModules, "app" | "liveSyncPlugin">;
@@ -0,0 +1,9 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import type { LogFunction } from "@lib/services/lib/logUtils.ts";
import type { ObsidianEventsState } from "./state.ts";
import type { ObsidianEventsHost } from "./types.ts";
export declare function registerVaultAndWorkspaceEvents(host: ObsidianEventsHost): Promise<boolean>;
export declare function registerWindowWatchEvents(host: ObsidianEventsHost, log: LogFunction, state: ObsidianEventsState): void;
export declare function onObsidianEventsLayoutReady(host: ObsidianEventsHost, log: LogFunction, state: ObsidianEventsState): Promise<boolean>;
export declare function bindObsidianEventsLifecycle(host: ObsidianEventsHost, log: LogFunction, state: ObsidianEventsState): void;
+1 -1
View File
@@ -5,4 +5,4 @@ import type { ObsidianEventsServices } from "./types.ts";
* A service feature hook that initialises and manages Obsidian application event bindings.
* This hooks into vault file changes, window focus, visibility states, and schedules restarts.
*/
export declare const useObsidianEvents: import("@lib/interfaces/ServiceModule").ServiceFeatureFunction<ObsidianEventsServices, never, void>;
export declare const useObsidianEvents: import("@/types.ts").ObsidianServiceFeatureFunction<ObsidianEventsServices, never, "plugin" | "app", void>;
+2 -2
View File
@@ -1,6 +1,6 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { type NecessaryServices } from "@lib/interfaces/ServiceModule";
import type { NecessaryObsidianServices } from "@/types.ts";
/**
* A union of service keys required by the Obsidian events management feature.
*/
@@ -12,4 +12,4 @@ export type ObsidianEventsModules = never;
/**
* The host type representing the injected service container with Obsidian events capabilities.
*/
export type ObsidianEventsHost = NecessaryServices<ObsidianEventsServices, ObsidianEventsModules>;
export type ObsidianEventsHost = NecessaryObsidianServices<ObsidianEventsServices, ObsidianEventsModules, "app" | "plugin">;
+1 -1
View File
@@ -5,4 +5,4 @@
*
* Provides Obsidian-specific UI elements like ribbon icons and commands.
*/
export declare const useObsidianMenuFeature: import("@/types.ts").ObsidianServiceFeatureFunction<"replication" | "appLifecycle" | "conflict", never, "plugin", void>;
export declare const useObsidianMenuFeature: import("@/types.ts").ObsidianServiceFeatureFunction<"setting" | "replication" | "control" | "appLifecycle" | "API" | "fileProcessing" | "conflict", never, "plugin", void>;
@@ -4,4 +4,4 @@ import type { SettingDialogueServices } from "./types.ts";
/**
* A service feature hook that registers the plug-in setting tab and listens to settings dialogue triggers.
*/
export declare const useObsidianSettingDialogue: import("@lib/interfaces/ServiceModule.ts").ServiceFeatureFunction<SettingDialogueServices, never, void>;
export declare const useObsidianSettingDialogue: import("@/types.ts").ObsidianServiceFeatureFunction<SettingDialogueServices, never, "app" | "liveSyncPlugin", void>;
@@ -1,6 +1,6 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { type NecessaryServices } from "@lib/interfaces/ServiceModule";
import type { NecessaryObsidianServices } from "@/types.ts";
/**
* Service keys required by the Obsidian setting tab dialogue feature.
*/
@@ -12,4 +12,4 @@ export type SettingDialogueModules = never;
/**
* The host type representing the injected service container with setting tab capabilities.
*/
export type SettingDialogueHost = NecessaryServices<SettingDialogueServices, SettingDialogueModules>;
export type SettingDialogueHost = NecessaryObsidianServices<SettingDialogueServices, SettingDialogueModules, "app" | "liveSyncPlugin">;
@@ -0,0 +1,3 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
export { usePeriodicReplication } from "./periodicReplication";
@@ -0,0 +1,11 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { PeriodicProcessor } from "@/common/PeriodicProcessor";
import { type NecessaryObsidianFeature } from "@/types";
export type PeriodicReplicationHost = NecessaryObsidianFeature<"appLifecycle" | "setting" | "replication" | "control" | "API">;
export declare const disablePeriodicHandler: (processor: PeriodicProcessor | undefined) => Promise<boolean>;
export declare const resumePeriodicHandler: (host: PeriodicReplicationHost, processor: PeriodicProcessor) => Promise<boolean>;
export declare function usePeriodicReplication(host: PeriodicReplicationHost): {
disablePeriodic: () => Promise<boolean>;
resumePeriodic: () => Promise<boolean>;
};
+5
View File
@@ -0,0 +1,5 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import type { NecessaryServices } from "@lib/interfaces/ServiceModule.ts";
export type ReplicatorFeatureHost = NecessaryServices<"API" | "replication" | "replicator", never>;
export declare function registerReplicatorCommands(host: ReplicatorFeatureHost): void;
+4
View File
@@ -0,0 +1,4 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
export { useReplicator } from "./replicator";
export { useCouchDBReplicatorFactory, useMinIOReplicatorFactory } from "./replicatorFactories";
@@ -0,0 +1,50 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { type AnyEntry, type EntryDoc, type LoadedEntry, type MetaEntry } from "@lib/common/types";
import { Semaphore } from "octagonal-wheels/concurrency/semaphore_v2";
import type { ReactiveSource } from "octagonal-wheels/dataobject/reactive_v2";
import type { NecessaryObsidianFeature } from "@/types";
import { type LogFunction } from "@lib/services/lib/logUtils";
export declare const KV_KEY_REPLICATION_RESULT_PROCESSOR_SNAPSHOT = "replicationResultProcessorSnapshot";
export type ReplicateResultProcessorHost = NecessaryObsidianFeature<"API" | "appLifecycle" | "database" | "keyValueDB" | "path" | "replication" | "replicator" | "setting" | "vault">;
export type ReplicateResultProcessorSnapshot = {
queued: PouchDB.Core.ExistingDocument<EntryDoc>[];
processing: PouchDB.Core.ExistingDocument<EntryDoc>[];
};
export type ReplicateResultProcessorState = {
queuedChanges: PouchDB.Core.ExistingDocument<EntryDoc>[];
processingChanges: PouchDB.Core.ExistingDocument<EntryDoc>[];
suspended: boolean;
restoreFromSnapshot: Promise<void> | undefined;
semaphore: ReturnType<typeof Semaphore>;
isRunningProcessQueue: boolean;
triggerTakeSnapshot: () => void;
};
export type ReplicateResultProcessor = {
suspend: () => void;
resume: () => void;
enqueueAll: (changes: PouchDB.Core.ExistingDocument<EntryDoc>[]) => void;
restoreFromSnapshotOnce: () => Promise<void>;
};
type ReplicateResultProcessorLog = LogFunction;
export declare function createReplicateResultProcessorLog(host: ReplicateResultProcessorHost): ReplicateResultProcessorLog;
export declare function createReplicateResultProcessorState(triggerTakeSnapshot?: () => void): ReplicateResultProcessorState;
export declare function isReplicateResultProcessorSuspended(host: ReplicateResultProcessorHost, state: ReplicateResultProcessorState): boolean;
export declare function suspendReplicateResultProcessing(state: ReplicateResultProcessorState): void;
export declare function resumeReplicateResultProcessing(host: ReplicateResultProcessorHost, state: ReplicateResultProcessorState, log?: ReplicateResultProcessorLog): void;
export declare function takeReplicateResultProcessorSnapshot(host: ReplicateResultProcessorHost, state: ReplicateResultProcessorState, log?: ReplicateResultProcessorLog): Promise<void>;
export declare function restoreReplicateResultProcessorSnapshot(host: ReplicateResultProcessorHost, state: ReplicateResultProcessorState, log?: ReplicateResultProcessorLog): Promise<void>;
export declare function restoreReplicateResultProcessorSnapshotOnce(host: ReplicateResultProcessorHost, state: ReplicateResultProcessorState, log?: ReplicateResultProcessorLog): Promise<void>;
export declare function withCounting<T>(proc: () => Promise<T>, countValue: ReactiveSource<number>): Promise<T>;
export declare function reportReplicateResultProcessorStatus(host: ReplicateResultProcessorHost, state: ReplicateResultProcessorState): void;
export declare function enqueueAllReplicateResults(host: ReplicateResultProcessorHost, state: ReplicateResultProcessorState, log: ReplicateResultProcessorLog, changes: PouchDB.Core.ExistingDocument<EntryDoc>[]): void;
export declare function processIfNonDocumentChange(host: ReplicateResultProcessorHost, log: ReplicateResultProcessorLog, change: PouchDB.Core.ExistingDocument<EntryDoc>): boolean;
export declare function enqueueReplicateResult(host: ReplicateResultProcessorHost, state: ReplicateResultProcessorState, log: ReplicateResultProcessorLog, doc: PouchDB.Core.ExistingDocument<EntryDoc>): void;
export declare function runReplicateResultProcessQueue(host: ReplicateResultProcessorHost, state: ReplicateResultProcessorState, log?: ReplicateResultProcessorLog): Promise<void>;
export declare function parseReplicateResultDocumentChange(host: ReplicateResultProcessorHost, state: ReplicateResultProcessorState, log: ReplicateResultProcessorLog, change: PouchDB.Core.ExistingDocument<EntryDoc>): Promise<void>;
export declare function applyReplicateResultToDatabase(host: ReplicateResultProcessorHost, state: ReplicateResultProcessorState, log: ReplicateResultProcessorLog, doc: PouchDB.Core.ExistingDocument<AnyEntry>): Promise<void>;
export declare function applyReplicateResultToDatabaseInternal(host: ReplicateResultProcessorHost, log: ReplicateResultProcessorLog, doc_: PouchDB.Core.ExistingDocument<AnyEntry>): Promise<void>;
export declare function applyReplicateResultToStorage(host: ReplicateResultProcessorHost, entry: MetaEntry): Promise<void>;
export declare function checkIsChangeRequiredForDatabaseProcessing(host: ReplicateResultProcessorHost, log: ReplicateResultProcessorLog, dbDoc: LoadedEntry): Promise<boolean>;
export declare function useReplicateResultProcessor(host: ReplicateResultProcessorHost): ReplicateResultProcessor;
export {};
+16
View File
@@ -0,0 +1,16 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { type EntryDoc } from "@lib/common/types";
import { type ReplicateResultProcessor } from "./replicateResultProcessor";
import { UnresolvedErrorManager } from "@lib/services/base/UnresolvedErrorManager";
import { type LogFunction } from "@lib/services/lib/logUtils";
import type { NecessaryObsidianFeature } from "@/types";
export type ReplicatorHost = NecessaryObsidianFeature<"appLifecycle" | "replication" | "replicator" | "setting" | "tweakValue" | "API" | "database" | "databaseEvents" | "keyValueDB" | "path" | "vault" | "UI", "databaseFileAccess" | "rebuilder">;
export declare const everyOnloadAfterLoadSettingsHandler: (host: ReplicatorHost, processor: ReplicateResultProcessor) => Promise<boolean>;
export declare const onReplicatorInitialisedHandler: () => Promise<boolean>;
export declare const everyOnDatabaseInitializedHandler: (processor: ReplicateResultProcessor, showNotice: boolean) => Promise<boolean>;
export declare const everyBeforeReplicateHandler: (unresolvedErrorManager: UnresolvedErrorManager, processor: ReplicateResultProcessor, showMessage: boolean) => Promise<boolean>;
export declare const cleanedHandler: (host: ReplicatorHost, showMessage: boolean, log?: LogFunction) => Promise<void>;
export declare const onReplicationFailedHandler: (host: ReplicatorHost, showMessage?: boolean, log?: LogFunction) => Promise<boolean>;
export declare const parseReplicationResultHandler: (processor: ReplicateResultProcessor, docs: Array<PouchDB.Core.ExistingDocument<EntryDoc>>) => Promise<boolean>;
export declare function useReplicator(host: ReplicatorHost): void;
@@ -0,0 +1,13 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { type RemoteDBSettings } from "@lib/common/types";
import type { LiveSyncAbstractReplicator } from "@lib/replication/LiveSyncAbstractReplicator";
import type { NecessaryObsidianFeature } from "@/types";
type CouchDBReplicatorHost = NecessaryObsidianFeature<"replicator" | "appLifecycle" | "replication" | "setting">;
export declare const createCouchDBReplicatorHandler: (host: CouchDBReplicatorHost, settingOverride?: Partial<RemoteDBSettings>) => Promise<LiveSyncAbstractReplicator | false>;
export declare const resumeCouchDBReplicationHandler: (host: CouchDBReplicatorHost) => Promise<boolean>;
export declare function useCouchDBReplicatorFactory(host: CouchDBReplicatorHost): void;
type MinIOReplicatorHost = NecessaryObsidianFeature<"replicator" | "setting">;
export declare const createMinIOReplicatorHandler: (host: MinIOReplicatorHost, settingOverride?: Partial<RemoteDBSettings>) => Promise<LiveSyncAbstractReplicator | false>;
export declare function useMinIOReplicatorFactory(host: MinIOReplicatorHost): void;
export {};
+3
View File
@@ -0,0 +1,3 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
export { useMismatchedTweaksResolver } from "./mismatchedTweaksResolver";
@@ -0,0 +1,32 @@
// @ts-nocheck
// REPO: https://github.com/vrtmrz/livesync-commonlib Commit hash: 0563f26
import { TweakValuesShouldMatchedTemplate, type TweakValues, type ObsidianLiveSyncSettings, type RemoteDBSettings } from "@lib/common/types.ts";
import type { NecessaryObsidianFeature } from "@/types";
import { type LogFunction } from "@lib/services/lib/logUtils";
export type MismatchedTweaksResolverHost = NecessaryObsidianFeature<"API" | "setting" | "tweakValue" | "replication" | "replicator" | "UI", "rebuilder">;
export declare function valueToString(value: string | number | boolean | object | undefined): string;
export declare const collectMismatchedTweakKeys: (current: TweakValues, preferred: Partial<TweakValues>) => ("liveSync" | "syncOnSave" | "syncOnStart" | "syncOnFileOpen" | "syncOnEditorSave" | "keepReplicationActiveInBackground" | "syncMinimumInterval" | "showVerboseLog" | "lessInformationInLog" | "showLongerLogInsideEditor" | "showStatusOnEditor" | "showStatusOnStatusbar" | "showOnlyIconsOnEditor" | "hideFileWarningNotice" | "networkWarningStyle" | "displayLanguage" | "trashInsteadDelete" | "doNotDeleteFolder" | "batchSave" | "batchSaveMinimumDelay" | "batchSaveMaximumDelay" | "syncMaxSizeInMB" | "useIgnoreFiles" | "ignoreFiles" | "processSizeMismatchedFiles" | "syncOnlyRegEx" | "syncIgnoreRegEx" | "syncAfterMerge" | "resolveConflictsByNewerFile" | "writeDocumentsIfConflicted" | "disableMarkdownAutoMerge" | "configPassphraseStore" | "encryptedPassphrase" | "encryptedCouchDBConnection" | "periodicReplication" | "periodicReplicationInterval" | "syncInternalFiles" | "syncInternalFilesBeforeReplication" | "syncInternalFilesInterval" | "syncInternalFilesIgnorePatterns" | "syncInternalFilesTargetPatterns" | "watchInternalFileChanges" | "suppressNotifyHiddenFilesChange" | "syncInternalFileOverwritePatterns" | "usePluginSync" | "usePluginSettings" | "showOwnPlugins" | "autoSweepPlugins" | "autoSweepPluginsPeriodic" | "notifyPluginOrSettingUpdated" | "deviceAndVaultName" | "usePluginSyncV2" | "usePluginEtc" | "pluginSyncExtendedSetting" | "useAdvancedMode" | "usePowerUserMode" | "useEdgeCaseMode" | "notifyThresholdOfRemoteStorageSize" | "disableWorkerForGeneratingChunks" | "processSmallFilesInUIThread" | "savingDelay" | "gcDelay" | "skipOlderFilesOnSync" | "useIndexedDBAdapter" | "enableDebugTools" | "writeLogToTheFile" | "settingSyncFile" | "writeCredentialsForSettingSync" | "notifyAllSettingSyncFile" | "suspendFileWatching" | "suspendParseReplicationResult" | "doNotSuspendOnFetching" | "maxMTimeForReflectEvents" | "versionUpFlash" | "settingVersion" | "isConfigured" | "lastReadUpdates" | "doctorProcessedVersion" | "remoteConfigurations" | "activeConfigurationId" | "P2P_ActiveRemoteConfigurationId" | "couchDB_URI" | "couchDB_USER" | "couchDB_PASSWORD" | "couchDB_DBNAME" | "couchDB_CustomHeaders" | "useJWT" | "jwtAlgorithm" | "jwtKey" | "jwtKid" | "jwtSub" | "jwtExpDuration" | "useRequestAPI" | "accessKey" | "secretKey" | "bucket" | "region" | "endpoint" | "useCustomRequestHandler" | "bucketCustomHeaders" | "bucketPrefix" | "forcePathStyle" | "remoteType" | "encrypt" | "passphrase" | "usePathObfuscation" | "E2EEAlgorithm" | "hashAlg" | "minimumChunkSize" | "customChunkSize" | "longLineThreshold" | "useSegmenter" | "enableChunkSplitterV2" | "doNotUseFixedRevisionForChunks" | "chunkSplitterVersion" | "useEden" | "maxChunksInEden" | "maxTotalLengthInEden" | "maxAgeInEden" | "tweakModified" | "checkIntegrityOnSave" | "useHistory" | "disableRequestURI" | "sendChunksBulk" | "sendChunksBulkMaxSize" | "useDynamicIterationCount" | "doNotPaceReplication" | "readChunksOnline" | "useOnlyLocalChunk" | "concurrencyOfReadChunksOnline" | "minimumIntervalOfReadChunksOnline" | "enableCompression" | "batch_size" | "batches_limit" | "ignoreVersionCheck" | "disableCheckingConfigMismatch" | "autoAcceptCompatibleTweak" | "hashCacheMaxCount" | "hashCacheMaxAmount" | "permitEmptyPassphrase" | "handleFilenameCaseSensitive" | "checkConflictOnlyOnOpen" | "showMergeDialogOnlyOnActive" | "additionalSuffixOfDatabaseName" | "useTimeouts" | "deleteMetadataOfDeletedFiles" | "automaticallyDeleteMetadataOfDeletedFiles" | "P2P_AutoAccepting" | "P2P_AutoSyncPeers" | "P2P_AutoWatchPeers" | "P2P_SyncOnReplication" | "P2P_RebuildFrom" | "P2P_AutoAcceptingPeers" | "P2P_AutoDenyingPeers" | "P2P_IsHeadless" | "P2P_Enabled" | "P2P_relays" | "P2P_roomID" | "P2P_passphrase" | "P2P_AppID" | "P2P_AutoStart" | "P2P_AutoBroadcast" | "P2P_DevicePeerName" | "P2P_turnServers" | "P2P_turnUsername" | "P2P_turnCredential" | "P2P_useDiagRTC")[];
export declare const selectNewerTweakSide: (current: TweakValues, preferred: Partial<TweakValues>, log?: LogFunction) => "REMOTE" | "CURRENT";
export declare const shouldAutoAcceptCompatibleLossy: (host: MismatchedTweaksResolverHost, state: {
hasNotifiedAutoAcceptCompatibleUndefined: boolean;
}, current: TweakValues, preferred: Partial<TweakValues>, mismatchedKeys: (keyof typeof TweakValuesShouldMatchedTemplate)[]) => Promise<"REMOTE" | "CURRENT" | undefined>;
export declare const onBeforeSaveSettingDataHandler: (next: ObsidianLiveSyncSettings, previous: ObsidianLiveSyncSettings, log?: LogFunction) => Promise<{
tweakModified: number;
} | undefined>;
export declare const anyAfterConnectCheckFailedHandler: (host: MismatchedTweaksResolverHost) => Promise<boolean | "CHECKAGAIN" | undefined>;
export declare const checkAndAskResolvingMismatchedTweaksHandler: (host: MismatchedTweaksResolverHost, state: {
hasNotifiedAutoAcceptCompatibleUndefined: boolean;
}, preferred: TweakValues) => Promise<[TweakValues | boolean, boolean]>;
export declare const askResolvingMismatchedTweaksHandler: (host: MismatchedTweaksResolverHost) => Promise<"OK" | "CHECKAGAIN" | "IGNORE">;
export declare const fetchRemotePreferredTweakValuesHandler: (host: MismatchedTweaksResolverHost, trialSetting: RemoteDBSettings) => Promise<TweakValues | false>;
export declare const checkAndAskUseRemoteConfigurationHandler: (host: MismatchedTweaksResolverHost, trialSetting: RemoteDBSettings) => Promise<{
result: false | TweakValues;
requireFetch: boolean;
}>;
export declare const askUseRemoteConfigurationHandler: (host: MismatchedTweaksResolverHost, state: {
hasNotifiedAutoAcceptCompatibleUndefined: boolean;
}, trialSetting: RemoteDBSettings, preferred: TweakValues) => Promise<{
result: false | TweakValues;
requireFetch: boolean;
}>;
export declare function useMismatchedTweaksResolver(host: MismatchedTweaksResolverHost): void;