diff --git a/frontend/obsidian-plugin/src/obisidan-event-handler.ts b/frontend/obsidian-plugin/src/obisidan-event-handler.ts index 4e0e0930..67ae8efe 100644 --- a/frontend/obsidian-plugin/src/obisidan-event-handler.ts +++ b/frontend/obsidian-plugin/src/obisidan-event-handler.ts @@ -1,47 +1,45 @@ -import type { Syncer } from "sync-client"; +import type { SyncClient, Syncer } from "sync-client"; import { Logger } from "sync-client"; import type { TAbstractFile } from "obsidian"; import { TFile } from "obsidian"; export class ObsidianFileEventHandler { - public constructor(private readonly syncer: Syncer) {} + public constructor(private readonly client: SyncClient) {} public async onCreate(file: TAbstractFile): Promise { if (file instanceof TFile) { - Logger.getInstance().info(`File created: ${file.path}`); + this.client.logger.info(`File created: ${file.path}`); - await this.syncer.syncLocallyCreatedFile( + await this.client.syncer.syncLocallyCreatedFile( file.path, new Date(file.stat.ctime) ); } else { - Logger.getInstance().debug(`Folder created: ${file.path}, ignored`); + this.client.logger.debug(`Folder created: ${file.path}, ignored`); } } public async onDelete(file: TAbstractFile): Promise { if (file instanceof TFile) { - Logger.getInstance().info(`File deleted: ${file.path}`); + this.client.logger.info(`File deleted: ${file.path}`); - await this.syncer.syncLocallyDeletedFile(file.path); + await this.client.syncer.syncLocallyDeletedFile(file.path); } else { - Logger.getInstance().debug(`Folder deleted: ${file.path}, ignored`); + this.client.logger.debug(`Folder deleted: ${file.path}, ignored`); } } public async onRename(file: TAbstractFile, oldPath: string): Promise { if (file instanceof TFile) { - Logger.getInstance().info( - `File renamed: ${oldPath} -> ${file.path}` - ); + this.client.logger.info(`File renamed: ${oldPath} -> ${file.path}`); - await this.syncer.syncLocallyUpdatedFile({ + await this.client.syncer.syncLocallyUpdatedFile({ oldPath, relativePath: file.path, updateTime: new Date(file.stat.ctime) }); } else { - Logger.getInstance().debug( + this.client.logger.debug( `Folder renamed: ${oldPath} -> ${file.path}, ignored` ); } @@ -53,16 +51,14 @@ export class ObsidianFileEventHandler { return; } - Logger.getInstance().info(`File modified: ${file.path}`); + this.client.logger.info(`File modified: ${file.path}`); - await this.syncer.syncLocallyUpdatedFile({ + await this.client.syncer.syncLocallyUpdatedFile({ relativePath: file.path, updateTime: new Date(file.stat.ctime) }); } else { - Logger.getInstance().debug( - `Folder modified: ${file.path}, ignored` - ); + this.client.logger.debug(`Folder modified: ${file.path}, ignored`); } } } diff --git a/frontend/obsidian-plugin/src/vault-link-plugin.ts b/frontend/obsidian-plugin/src/vault-link-plugin.ts index a3cb4a07..e4a42411 100644 --- a/frontend/obsidian-plugin/src/vault-link-plugin.ts +++ b/frontend/obsidian-plugin/src/vault-link-plugin.ts @@ -10,7 +10,7 @@ import { StatusBar } from "./views/status-bar"; import { LogsView } from "./views/logs-view"; import { StatusDescription } from "./views/status-description"; -import { Logger, SyncClient } from "sync-client"; +import { SyncClient } from "sync-client"; import { ObsidianFileSystemOperations } from "./obsidian-file-system"; export default class VaultLinkPlugin extends Plugin { @@ -18,8 +18,6 @@ export default class VaultLinkPlugin extends Plugin { private client!: SyncClient; public async onload(): Promise { - Logger.getInstance().info("Starting plugin"); - this.client = await SyncClient.create( new ObsidianFileSystemOperations(this.app.vault), { @@ -28,6 +26,8 @@ export default class VaultLinkPlugin extends Plugin { } ); + this.client.logger.info("Starting plugin"); + const statusDescription = new StatusDescription(this.client); this.settingsTab = new SyncSettingsTab({ @@ -42,12 +42,11 @@ export default class VaultLinkPlugin extends Plugin { this.registerView( HistoryView.TYPE, - (leaf) => - new HistoryView(leaf, this.client.settings, this.client.history) + (leaf) => new HistoryView(leaf, this.client) ); this.registerView( LogsView.TYPE, - (leaf) => new LogsView(this, this.client.settings, leaf) + (leaf) => new LogsView(this, this.client, leaf) ); this.addRibbonIcon( @@ -61,11 +60,10 @@ export default class VaultLinkPlugin extends Plugin { async (_: MouseEvent) => this.activateView(LogsView.TYPE) ); - const eventHandler = new ObsidianFileEventHandler(this.client.syncer); + const eventHandler = new ObsidianFileEventHandler(this.client); this.app.workspace.onLayoutReady(async () => { - Logger.getInstance().info("Initialising sync handlers"); - + this.client.logger.info("Initialising sync handlers"); [ this.app.vault.on( "create", @@ -87,7 +85,7 @@ export default class VaultLinkPlugin extends Plugin { this.registerEvent(event); }); - Logger.getInstance().info("Sync handlers initialised"); + this.client.logger.info("Sync handlers initialised"); void this.client.syncer.scheduleSyncForOfflineChanges(); }); diff --git a/frontend/obsidian-plugin/src/views/history-view.ts b/frontend/obsidian-plugin/src/views/history-view.ts index a0745d2d..3fa4f328 100644 --- a/frontend/obsidian-plugin/src/views/history-view.ts +++ b/frontend/obsidian-plugin/src/views/history-view.ts @@ -2,7 +2,7 @@ import type { IconName, WorkspaceLeaf } from "obsidian"; import { ItemView, setIcon } from "obsidian"; import { intlFormatDistance } from "date-fns"; -import type { SyncHistory, HistoryEntry, Settings } from "sync-client"; +import type { HistoryEntry, SyncClient } from "sync-client"; import { SyncType, SyncSource, SyncStatus, Logger } from "sync-client"; export class HistoryView extends ItemView { @@ -12,15 +12,14 @@ export class HistoryView extends ItemView { public constructor( leaf: WorkspaceLeaf, - private readonly settings: Settings, - private readonly history: SyncHistory + private readonly client: SyncClient ) { super(leaf); this.icon = HistoryView.ICON; - history.addSyncHistoryUpdateListener(() => { + this.client.history.addSyncHistoryUpdateListener(() => { this.updateView().catch((_error: unknown) => { - Logger.getInstance().error("Failed to update history view"); + this.client.logger.error("Failed to update history view"); }); }); } @@ -94,13 +93,13 @@ export class HistoryView extends ItemView { container.empty(); container.createEl("h4", { text: "VaultLink History" }); - const entries = this.history + const entries = this.client.history .getEntries() .reverse() .filter( (entry) => entry.status !== SyncStatus.NO_OP || - this.settings.getSettings().displayNoopSyncEvents + this.client.settings.getSettings().displayNoopSyncEvents ); entries.forEach((entry) => { diff --git a/frontend/obsidian-plugin/src/views/logs-view.ts b/frontend/obsidian-plugin/src/views/logs-view.ts index 79dee71f..66aa30c2 100644 --- a/frontend/obsidian-plugin/src/views/logs-view.ts +++ b/frontend/obsidian-plugin/src/views/logs-view.ts @@ -1,8 +1,7 @@ import type { WorkspaceLeaf } from "obsidian"; import { ItemView } from "obsidian"; import type VaultLinkPlugin from "src/vault-link-plugin"; -import type { Settings } from "sync-client"; -import { Logger } from "sync-client"; +import type { SyncClient } from "sync-client"; export class LogsView extends ItemView { public static readonly TYPE = "logs-view"; @@ -10,20 +9,24 @@ export class LogsView extends ItemView { public constructor( private readonly plugin: VaultLinkPlugin, - private readonly settings: Settings, + private readonly client: SyncClient, leaf: WorkspaceLeaf ) { super(leaf); this.icon = LogsView.ICON; - Logger.getInstance().addOnMessageListener(() => { + this.client.logger.addOnMessageListener(() => { this.updateView(); }); - settings.addOnSettingsChangeHandlers((newSettings, oldSettings) => { - if (newSettings.minimumLogLevel !== oldSettings.minimumLogLevel) { - this.updateView(); + this.client.settings.addOnSettingsChangeHandlers( + (newSettings, oldSettings) => { + if ( + newSettings.minimumLogLevel !== oldSettings.minimumLogLevel + ) { + this.updateView(); + } } - }); + ); } private static formatTimestamp(timestamp: Date): string { @@ -78,8 +81,8 @@ export class LogsView extends ItemView { } ); - const logs = Logger.getInstance().getMessages( - this.settings.getSettings().minimumLogLevel + const logs = this.client.logger.getMessages( + this.client.settings.getSettings().minimumLogLevel ); if (logs.length === 0) { diff --git a/frontend/sync-client/src/file-operations/file-operations.ts b/frontend/sync-client/src/file-operations/file-operations.ts index 76986f9c..fb62c720 100644 --- a/frontend/sync-client/src/file-operations/file-operations.ts +++ b/frontend/sync-client/src/file-operations/file-operations.ts @@ -4,16 +4,19 @@ import { RelativePath } from "src/persistence/database"; import { isBinary, isFileTypeMergable, mergeText } from "sync_lib"; export class FileOperations { - public constructor(private readonly fs: FileSystemOperations) {} + public constructor( + private readonly logger: Logger, + private readonly fs: FileSystemOperations + ) {} public async listAllFiles(): Promise { const files = await this.fs.listAllFiles(); - Logger.getInstance().debug(`Listing all files, found ${files.length}`); + this.logger.debug(`Listing all files, found ${files.length}`); return files; } public async read(path: RelativePath): Promise { - Logger.getInstance().debug(`Reading file: ${path}`); + this.logger.debug(`Reading file: ${path}`); const content = await this.fs.read(path); if (isBinary(content)) { @@ -30,17 +33,17 @@ export class FileOperations { } public async getFileSize(path: RelativePath): Promise { - Logger.getInstance().debug(`Getting file size: ${path}`); + this.logger.debug(`Getting file size: ${path}`); return this.fs.getFileSize(path); } public async getModificationTime(path: RelativePath): Promise { - Logger.getInstance().debug(`Getting modification time: ${path}`); + this.logger.debug(`Getting modification time: ${path}`); return this.fs.getModificationTime(path); } public async exists(path: RelativePath): Promise { - Logger.getInstance().debug(`Checking existance of ${path}`); + this.logger.debug(`Checking existance of ${path}`); return this.fs.exists(path); } @@ -50,9 +53,9 @@ export class FileOperations { path: RelativePath, newContent: Uint8Array ): Promise { - Logger.getInstance().debug(`Creating file: ${path}`); + this.logger.debug(`Creating file: ${path}`); if (await this.fs.exists(path)) { - Logger.getInstance().debug( + this.logger.debug( `Didn't expect ${path} to exist, when trying to create it, merging instead` ); await this.write(path, new Uint8Array(0), newContent); @@ -71,9 +74,9 @@ export class FileOperations { expectedContent: Uint8Array, newContent: Uint8Array ): Promise { - Logger.getInstance().debug(`Writing file: ${path}`); + this.logger.debug(`Writing file: ${path}`); if (!(await this.fs.exists(path))) { - Logger.getInstance().debug( + this.logger.debug( `The caller assumed ${path} exists, but it no longer, so we wont recreate it` ); return new Uint8Array(0); @@ -84,7 +87,7 @@ export class FileOperations { isBinary(expectedContent) || isBinary(newContent) ) { - Logger.getInstance().debug( + this.logger.debug( `The expected content is not mergable, so we won't perform a 3-way merge, just overwrite it` ); await this.fs.write(path, newContent); @@ -99,14 +102,14 @@ export class FileOperations { (currentText) => { currentText = currentText.replace(/\r\n/g, "\n"); if (currentText !== expectedText) { - Logger.getInstance().debug( + this.logger.debug( `Performing a 3-way merge for ${path} with the expected content` ); return mergeText(expectedText, currentText, newText); } - Logger.getInstance().debug( + this.logger.debug( `The current content of ${path} is the same as the expected content, so we will just write the new content` ); @@ -117,7 +120,7 @@ export class FileOperations { } public async remove(path: RelativePath): Promise { - Logger.getInstance().debug(`Removing file: ${path}`); + this.logger.debug(`Removing file: ${path}`); return this.fs.delete(path); } @@ -125,7 +128,7 @@ export class FileOperations { oldPath: RelativePath, newPath: RelativePath ): Promise { - Logger.getInstance().debug(`Moving file: ${oldPath} -> ${newPath}`); + this.logger.debug(`Moving file: ${oldPath} -> ${newPath}`); if (oldPath === newPath) { return; diff --git a/frontend/sync-client/src/persistence/database.ts b/frontend/sync-client/src/persistence/database.ts index 93492b29..dc048adb 100644 --- a/frontend/sync-client/src/persistence/database.ts +++ b/frontend/sync-client/src/persistence/database.ts @@ -20,6 +20,7 @@ export class Database { private lastSeenUpdateId: VaultUpdateId | undefined; public constructor( + private readonly logger: Logger, initialState: Partial | undefined, private readonly saveData: (data: unknown) => Promise ) { @@ -32,10 +33,10 @@ export class Database { this.documents.set(relativePath, metadata as DocumentMetadata); } } - Logger.getInstance().debug(`Loaded ${this.documents.size} documents`); + this.logger.debug(`Loaded ${this.documents.size} documents`); this.lastSeenUpdateId = initialState.lastSeenUpdateId; - Logger.getInstance().debug( + this.logger.debug( `Loaded last seen update id: ${this.lastSeenUpdateId}` ); } diff --git a/frontend/sync-client/src/persistence/settings.ts b/frontend/sync-client/src/persistence/settings.ts index 57762e4a..fa732092 100644 --- a/frontend/sync-client/src/persistence/settings.ts +++ b/frontend/sync-client/src/persistence/settings.ts @@ -33,6 +33,7 @@ export class Settings { ) => void)[] = []; public constructor( + private readonly logger: Logger, initialState: Partial | undefined, private readonly saveData: (data: unknown) => Promise ) { @@ -41,7 +42,7 @@ export class Settings { ...(initialState ?? {}) }; - Logger.getInstance().debug( + this.logger.debug( `Loaded settings: ${JSON.stringify(this.settings, null, 2)}` ); } @@ -70,7 +71,7 @@ export class Settings { value: SyncSettings[T] ): Promise { const newSettings = { ...this.settings, [key]: value }; - Logger.getInstance().debug( + this.logger.debug( `Setting ${key} to ${value}, new settings: ${JSON.stringify( newSettings, null, diff --git a/frontend/sync-client/src/services/sync-service.ts b/frontend/sync-client/src/services/sync-service.ts index 69eb585a..f49a90d2 100644 --- a/frontend/sync-client/src/services/sync-service.ts +++ b/frontend/sync-client/src/services/sync-service.ts @@ -7,7 +7,7 @@ import type { VaultUpdateId } from "../persistence/database"; import { Logger } from "src/tracing/logger"; -import { retriedFetch } from "src/utils/retried-fetch"; +import { retriedFetchFactory } from "src/utils/retried-fetch"; import type { SyncSettings } from "dist/types"; import type { Settings } from "src/persistence/settings"; @@ -19,7 +19,10 @@ export class SyncService { private client!: Client; private clientWithoutRetries!: Client; - public constructor(private readonly settings: Settings) { + public constructor( + private readonly settings: Settings, + private readonly logger: Logger + ) { this.createClient(settings.getSettings()); settings.addOnSettingsChangeHandlers(this.createClient.bind(this)); @@ -73,7 +76,7 @@ export class SyncService { ); } - Logger.getInstance().debug( + this.logger.debug( `Created document ${JSON.stringify(response.data)} with id ${ response.data.documentId }` @@ -124,7 +127,7 @@ export class SyncService { ); } - Logger.getInstance().debug( + this.logger.debug( `Updated document ${JSON.stringify(response.data)} with id ${ response.data.documentId }` @@ -165,7 +168,7 @@ export class SyncService { throw new Error(`Failed to delete document`); } - Logger.getInstance().debug( + this.logger.debug( `Deleted document ${relativePath} with id ${documentId}` ); @@ -198,7 +201,7 @@ export class SyncService { ); } - Logger.getInstance().debug( + this.logger.debug( `Get document ${response.data.relativePath} with id ${response.data.documentId}` ); @@ -229,7 +232,7 @@ export class SyncService { ); } - Logger.getInstance().debug( + this.logger.debug( `Got ${response.data.latestDocuments.length} document metadata` ); @@ -267,9 +270,7 @@ export class SyncService { } }); - Logger.getInstance().debug( - `Ping response: ${JSON.stringify(response.data)}` - ); + this.logger.debug(`Ping response: ${JSON.stringify(response.data)}`); if (!response.data) { throw new Error( @@ -283,7 +284,7 @@ export class SyncService { private createClient(settings: SyncSettings): void { this.client = createClient({ baseUrl: settings.remoteUri, - fetch: retriedFetch + fetch: retriedFetchFactory(this.logger) }); this.clientWithoutRetries = createClient({ diff --git a/frontend/sync-client/src/sync-client.ts b/frontend/sync-client/src/sync-client.ts index 8d735da7..acbe098e 100644 --- a/frontend/sync-client/src/sync-client.ts +++ b/frontend/sync-client/src/sync-client.ts @@ -12,14 +12,15 @@ import { FileSystemOperations } from "./file-operations/filesystem-operations"; import { FileOperations } from "./file-operations/file-operations"; export class SyncClient { - private remoteListenerIntervalId: number | null = null; + private remoteListenerIntervalId: NodeJS.Timeout | null = null; private constructor( private readonly _history: SyncHistory, private readonly _settings: Settings, private readonly _database: Database, private readonly _syncer: Syncer, - private readonly _syncService: SyncService + private readonly _syncService: SyncService, + private readonly _logger: Logger ) {} public get history(): SyncHistory { @@ -34,12 +35,17 @@ export class SyncClient { return this._syncer; } + public get logger(): Logger { + return this._logger; + } + public static async create( fs: FileSystemOperations, persistence: PersistenceProvider ): Promise { - const history = new SyncHistory(); - Logger.getInstance().info("Starting SyncClient"); + const logger = new Logger(); + const history = new SyncHistory(logger); + logger.info("Starting SyncClient"); await init( // eslint-disable-next-line @@ -54,6 +60,7 @@ export class SyncClient { database: undefined }; const database = new Database( + logger, state.database, async (data: unknown): Promise => { state = { ...state, database: data }; @@ -62,6 +69,7 @@ export class SyncClient { ); const settings = new Settings( + logger, state.settings, async (data: unknown): Promise => { state = { ...state, settings: data }; @@ -69,13 +77,14 @@ export class SyncClient { } ); - const syncService = new SyncService(settings); + const syncService = new SyncService(settings, logger); const syncer = new Syncer( + logger, database, settings, syncService, - new FileOperations(fs), + new FileOperations(logger, fs), history ); @@ -84,7 +93,8 @@ export class SyncClient { settings, database, syncer, - syncService + syncService, + logger ); void syncer.scheduleSyncForOfflineChanges(); @@ -102,14 +112,14 @@ export class SyncClient { syncer .scheduleSyncForOfflineChanges() .catch((_error: unknown) => { - Logger.getInstance().error( + logger.error( "Failed to schedule sync for offline changes" ); }); } }); - Logger.getInstance().info("SyncClient loaded"); + logger.info("SyncClient loaded"); return client; } @@ -125,21 +135,21 @@ export class SyncClient { public async reset(): Promise { await this._syncer.reset(); this._history.reset(); - Logger.getInstance().reset(); + this.logger.reset(); } public onunload(): void { if (this.remoteListenerIntervalId !== null) { - window.clearInterval(this.remoteListenerIntervalId); + clearInterval(this.remoteListenerIntervalId); } } private registerRemoteEventListener(intervalMs: number): void { if (this.remoteListenerIntervalId !== null) { - window.clearInterval(this.remoteListenerIntervalId); + clearInterval(this.remoteListenerIntervalId); } - this.remoteListenerIntervalId = window.setInterval( + this.remoteListenerIntervalId = setInterval( () => void this._syncer.applyRemoteChangesLocally(), intervalMs ); diff --git a/frontend/sync-client/src/sync-operations/syncer.ts b/frontend/sync-client/src/sync-operations/syncer.ts index e362fb73..d73e737f 100644 --- a/frontend/sync-client/src/sync-operations/syncer.ts +++ b/frontend/sync-client/src/sync-operations/syncer.ts @@ -29,6 +29,7 @@ export class Syncer { undefined; public constructor( + private readonly logger: Logger, private readonly database: Database, private readonly settings: Settings, private readonly syncService: SyncService, @@ -91,16 +92,14 @@ export class Syncer { public async scheduleSyncForOfflineChanges(): Promise { if (!this.settings.getSettings().isSyncEnabled) { - Logger.getInstance().debug( + this.logger.debug( `Syncing is disabled, not uploading local changes` ); return; } if (this.runningScheduleSyncForOfflineChanges != null) { - Logger.getInstance().debug( - "Uploading local changes is already in progress" - ); + this.logger.debug("Uploading local changes is already in progress"); return this.runningScheduleSyncForOfflineChanges; } @@ -108,11 +107,9 @@ export class Syncer { this.runningScheduleSyncForOfflineChanges = this.internalScheduleSyncForOfflineChanges(); await this.runningScheduleSyncForOfflineChanges; - Logger.getInstance().info( - `All local changes have been applied remotely` - ); + this.logger.info(`All local changes have been applied remotely`); } catch (e) { - Logger.getInstance().error( + this.logger.error( `Not all local changes have been applied remotely: ${e}` ); throw e; @@ -150,7 +147,7 @@ export class Syncer { (item) => item != originalFile ); - Logger.getInstance().debug( + this.logger.debug( `Document ${relativePath} was not found under its current path in the database but was found under a different path ${originalFile[0]}, scheduling sync to move it` ); return this.internalSyncLocallyUpdatedFile({ @@ -167,7 +164,7 @@ export class Syncer { }); } - Logger.getInstance().debug( + this.logger.debug( `Document ${relativePath} not found in database, scheduling sync to create it` ); return this.internalSyncLocallyCreatedFile( @@ -178,7 +175,7 @@ export class Syncer { ); } - Logger.getInstance().debug( + this.logger.debug( `Document ${relativePath} has been updated locally, scheduling sync to update it` ); return this.internalSyncLocallyUpdatedFile({ @@ -194,12 +191,12 @@ export class Syncer { await Promise.all( locallyDeletedFiles.map(async ([relativePath, _]) => { - Logger.getInstance().debug( + this.logger.debug( `Document ${relativePath} has been deleted locally, scheduling sync to delete it` ); if (await this.operations.exists(relativePath)) { - Logger.getInstance().debug( + this.logger.debug( `Document ${relativePath} actually exists locally, skipping` ); return Promise.resolve(); @@ -212,14 +209,14 @@ export class Syncer { public async applyRemoteChangesLocally(): Promise { if (!this.settings.getSettings().isSyncEnabled) { - Logger.getInstance().debug( + this.logger.debug( `Syncing is disabled, not fetching remote changes` ); return; } if (this.runningApplyRemoteChangesLocally != null) { - Logger.getInstance().debug( + this.logger.debug( "Applying remote changes locally is already in progress" ); return this.runningApplyRemoteChangesLocally; @@ -229,13 +226,9 @@ export class Syncer { this.runningApplyRemoteChangesLocally = this.internalApplyRemoteChangesLocally(); await this.runningApplyRemoteChangesLocally; - Logger.getInstance().info( - "All remote changes have been applied locally" - ); + this.logger.info("All remote changes have been applied locally"); } catch (e) { - Logger.getInstance().error( - `Failed to apply remote changes locally: ${e}` - ); + this.logger.error(`Failed to apply remote changes locally: ${e}`); throw e; } finally { this.runningApplyRemoteChangesLocally = undefined; @@ -248,11 +241,11 @@ export class Syncer { ); if (remote.latestDocuments.length === 0) { - Logger.getInstance().debug("No remote changes to apply"); + this.logger.debug("No remote changes to apply"); return; } - Logger.getInstance().info("Applying remote changes locally"); + this.logger.info("Applying remote changes locally"); await Promise.all( remote.latestDocuments.map(async (remoteDocument) => @@ -317,7 +310,7 @@ export class Syncer { const localMetadata = this.database.getDocument(relativePath); if (localMetadata) { - Logger.getInstance().debug( + this.logger.debug( `Document metadata already exists for ${relativePath}, it must have been downloaded from the server` ); @@ -631,7 +624,7 @@ export class Syncer { const [relativePath, metadata] = localMetadata; if (metadata.parentVersionId === remoteVersion.vaultUpdateId) { - Logger.getInstance().debug( + this.logger.debug( `Document ${relativePath} is already up to date` ); return; @@ -658,7 +651,7 @@ export class Syncer { const currentHash = hash(currentContent); if (currentHash !== metadata.hash) { - Logger.getInstance().info( + this.logger.info( `Document ${relativePath} has been updated both remotely and locally, letting the local file update event handle it` ); return; @@ -716,18 +709,18 @@ export class Syncer { fn: () => Promise ): Promise { if (!this.settings.getSettings().isSyncEnabled) { - Logger.getInstance().info( + this.logger.info( `Syncing is disabled, not syncing ${relativePath}` ); return; } if (!this.operations.isFileEligibleForSync(relativePath)) { - Logger.getInstance().info( + this.logger.info( `File ${relativePath} is not eligible for syncing` ); return; } - Logger.getInstance().debug(`Syncing ${relativePath}`); + this.logger.debug(`Syncing ${relativePath}`); await waitForDocumentLock(relativePath); try { diff --git a/frontend/sync-client/src/tracing/sync-history.ts b/frontend/sync-client/src/tracing/sync-history.ts index b64cdd50..f4609d81 100644 --- a/frontend/sync-client/src/tracing/sync-history.ts +++ b/frontend/sync-client/src/tracing/sync-history.ts @@ -47,6 +47,8 @@ export class SyncHistory { error: 0 }; + public constructor(private logger: Logger) {} + public getEntries(): HistoryEntry[] { return [...this.entries]; } @@ -78,16 +80,16 @@ export class SyncHistory { if (entry.status === SyncStatus.SUCCESS) { this.status.success++; - Logger.getInstance().info( + this.logger.info( `History entry: ${entry.relativePath} - ${entry.message}` ); } else if (entry.status === SyncStatus.ERROR) { this.status.error++; - Logger.getInstance().error( + this.logger.error( `Error syncing file: ${entry.relativePath} - ${entry.message}` ); } else { - Logger.getInstance().debug( + this.logger.debug( `No-op syncing file: ${entry.relativePath} - ${entry.message}` ); } diff --git a/frontend/sync-client/src/utils/retried-fetch.ts b/frontend/sync-client/src/utils/retried-fetch.ts index d6694ae7..1a5483c4 100644 --- a/frontend/sync-client/src/utils/retried-fetch.ts +++ b/frontend/sync-client/src/utils/retried-fetch.ts @@ -14,23 +14,25 @@ function getUrlFromInput(input: RequestInfo | URL): string { return input.url; } -export async function retriedFetch( - input: RequestInfo | URL, - init: RequestInitRetryParams = {} -): Promise { - return fetchWithRetry(input, { - retryOn: function (attempt, error, response) { - if (error !== null || !response || response.status >= 500) { - Logger.getInstance().warn( - `Retrying fetch for ${getUrlFromInput(input)}, attempt ${attempt}` - ); +export function retriedFetchFactory(logger: Logger) { + return ( + input: RequestInfo | URL, + init: RequestInitRetryParams = {} + ): Promise => { + return fetchWithRetry(input, { + retryOn: function (attempt, error, response) { + if (error !== null || !response || response.status >= 500) { + logger.warn( + `Retrying fetch for ${getUrlFromInput(input)}, attempt ${attempt}` + ); - return true; - } - return false; - }, - retries: 6, - retryDelay: (attempt) => Math.pow(1.5, attempt) * 500, - ...init - }); + return true; + } + return false; + }, + retries: 6, + retryDelay: (attempt) => Math.pow(1.5, attempt) * 500, + ...init + }); + }; }