From ff5af8aea5a345d51683370e6c679b19f036f437 Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Fri, 20 Dec 2024 16:14:46 +0000 Subject: [PATCH] Lint files --- plugin/src/database/database.ts | 46 ++++--- plugin/src/events/file-event-handler.ts | 2 +- ...t-handler.ts => obisidan-event-handler.ts} | 69 ++++------ plugin/src/file-operations/file-operations.ts | 18 +-- .../obsidian-file-operations.ts | 49 +++---- plugin/src/logger.ts | 81 ------------ plugin/src/services/sync-service.ts | 120 ++++++++++-------- plugin/src/services/types.ts | 24 +--- plugin/src/sync-operations/locks.ts | 18 ++- plugin/src/utils/hash.ts | 9 +- plugin/src/views/sync-view.ts | 24 ++-- 11 files changed, 184 insertions(+), 276 deletions(-) rename plugin/src/events/{sync-event-handler.ts => obisidan-event-handler.ts} (55%) delete mode 100644 plugin/src/logger.ts diff --git a/plugin/src/database/database.ts b/plugin/src/database/database.ts index 20a4fc65..48c619ac 100644 --- a/plugin/src/database/database.ts +++ b/plugin/src/database/database.ts @@ -1,11 +1,12 @@ -import { Logger } from "src/logger"; -import { DEFAULT_SETTINGS, SyncSettings } from "./sync-settings"; -import { - RelativePath, - DocumentMetadata, - VaultUpdateId, +import type { SyncSettings } from "./sync-settings"; +import { DEFAULT_SETTINGS } from "./sync-settings"; +import type { DocumentId, + DocumentMetadata, + RelativePath, + VaultUpdateId, } from "./document-metadata"; +import { Logger } from "src/tracing/logger"; interface StoredDatabase { documents: Map; @@ -13,27 +14,31 @@ interface StoredDatabase { lastSeenUpdateId: VaultUpdateId | undefined; } +// Todo: split it into settings and documents export class Database { - private _documents: Map = new Map(); + private _documents = new Map(); private _settings: SyncSettings; private _lastSeenUpdateId: VaultUpdateId | undefined; - private onSettingsChangeHandlers: Array< - (newSettings: SyncSettings, oldSettings: SyncSettings) => void - > = []; + private readonly onSettingsChangeHandlers: (( + newSettings: SyncSettings, + oldSettings: SyncSettings + ) => void)[] = []; public constructor( initialState: Partial | undefined, - private saveData: (data: unknown) => Promise + private readonly saveData: (data: unknown) => Promise ) { - initialState = initialState || {}; + initialState ??= {}; if ( + // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions Object.prototype.hasOwnProperty.call(initialState, "documents") && initialState.documents ) { for (const [relativePath, metadata] of Object.entries( initialState.documents )) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion this._documents.set(relativePath, metadata as DocumentMetadata); } } @@ -46,11 +51,10 @@ export class Database { )}` ); - this._settings = Object.assign( - {}, - DEFAULT_SETTINGS, - initialState.settings || {} - ); + this._settings = { + ...DEFAULT_SETTINGS, + ...(initialState.settings ?? {}), + }; Logger.getInstance().debug( `Loaded settings: ${JSON.stringify(this._settings, null, 2)}` @@ -74,15 +78,15 @@ export class Database { public async setSettings(value: SyncSettings): Promise { const oldSettings = this._settings; this._settings = value; - this.onSettingsChangeHandlers.forEach((handler) => - handler(value, oldSettings) - ); + this.onSettingsChangeHandlers.forEach((handler) => { + handler(value, oldSettings); + }); await this.save(); } public addOnSettingsChangeHandlers( handler: (settings: SyncSettings, oldSettings: SyncSettings) => void - ) { + ): void { this.onSettingsChangeHandlers.push(handler); } diff --git a/plugin/src/events/file-event-handler.ts b/plugin/src/events/file-event-handler.ts index 1b8ad207..3c6261d2 100644 --- a/plugin/src/events/file-event-handler.ts +++ b/plugin/src/events/file-event-handler.ts @@ -1,4 +1,4 @@ -import { TAbstractFile } from "obsidian"; +import type { TAbstractFile } from "obsidian"; export interface FileEventHandler { onCreate: (path: TAbstractFile) => Promise; diff --git a/plugin/src/events/sync-event-handler.ts b/plugin/src/events/obisidan-event-handler.ts similarity index 55% rename from plugin/src/events/sync-event-handler.ts rename to plugin/src/events/obisidan-event-handler.ts index d75a0895..81f20028 100644 --- a/plugin/src/events/sync-event-handler.ts +++ b/plugin/src/events/obisidan-event-handler.ts @@ -1,57 +1,48 @@ -import { TAbstractFile, TFile } from "obsidian"; -import { FileEventHandler } from "./file-event-handler"; -import { Logger } from "src/logger"; -import { SyncService } from "src/services/sync-service"; -import { Database } from "src/database/database"; +import type { TAbstractFile } from "obsidian"; +import { TFile } from "obsidian"; +import type { FileEventHandler } from "./file-event-handler"; +import type { SyncService } from "src/services/sync-service"; +import type { Database } from "src/database/database"; import { syncLocallyDeletedFile } from "src/sync-operations/sync-locally-deleted-file"; import { syncLocallyUpdatedFile } from "src/sync-operations/sync-locally-updated-file"; -import { FileOperations } from "src/file-operations/file-operations"; +import type { FileOperations } from "src/file-operations/file-operations"; import { syncLocallyCreatedFile } from "src/sync-operations/sync-locally-created-file"; +import { Logger } from "src/tracing/logger"; +import type { SyncHistory } from "src/tracing/sync-history"; -export class SyncEventHandler implements FileEventHandler { +export class ObsidianFileEventHandler implements FileEventHandler { public constructor( - private database: Database, - private syncServer: SyncService, - private operations: FileOperations + private readonly database: Database, + private readonly syncServer: SyncService, + private readonly operations: FileOperations, + private readonly history: SyncHistory ) {} - async onCreate(file: TAbstractFile): Promise { + public async onCreate(file: TAbstractFile): Promise { if (file instanceof TFile) { Logger.getInstance().info(`File created: ${file.path}`); - if (!this.database.getSettings().isSyncEnabled) { - Logger.getInstance().info( - `Sync is disabled, not syncing ${file.path}` - ); - return; - } - await syncLocallyCreatedFile({ database: this.database, syncServer: this.syncServer, operations: this.operations, updateTime: new Date(file.stat.ctime), - filePath: file.path, + relativePath: file.path, + history: this.history, }); } else { Logger.getInstance().info(`Folder created: ${file.path}, ignored`); } } - async onDelete(file: TAbstractFile): Promise { + public async onDelete(file: TAbstractFile): Promise { if (file instanceof TFile) { Logger.getInstance().info(`File deleted: ${file.path}`); - if (!this.database.getSettings().isSyncEnabled) { - Logger.getInstance().info( - `Sync is disabled, not syncing ${file.path}` - ); - return; - } - await syncLocallyDeletedFile({ database: this.database, syncServer: this.syncServer, + history: this.history, relativePath: file.path, }); } else { @@ -59,25 +50,19 @@ export class SyncEventHandler implements FileEventHandler { } } - async onRename(file: TAbstractFile, oldPath: string): Promise { + public async onRename(file: TAbstractFile, oldPath: string): Promise { if (file instanceof TFile) { Logger.getInstance().info( `File renamed: ${oldPath} -> ${file.path}` ); - if (!this.database.getSettings().isSyncEnabled) { - Logger.getInstance().info( - `Sync is disabled, not syncing ${file.path}` - ); - return; - } - await syncLocallyUpdatedFile({ database: this.database, syncServer: this.syncServer, operations: this.operations, + history: this.history, updateTime: new Date(file.stat.ctime), - filePath: file.path, + relativePath: file.path, oldPath, }); } else { @@ -87,23 +72,17 @@ export class SyncEventHandler implements FileEventHandler { } } - async onModify(file: TAbstractFile): Promise { + public async onModify(file: TAbstractFile): Promise { if (file instanceof TFile) { Logger.getInstance().info(`File modified: ${file.path}`); - if (!this.database.getSettings().isSyncEnabled) { - Logger.getInstance().info( - `Sync is disabled, not syncing ${file.path}` - ); - return; - } - await syncLocallyUpdatedFile({ database: this.database, syncServer: this.syncServer, operations: this.operations, + history: this.history, updateTime: new Date(file.stat.ctime), - filePath: file.path, + relativePath: file.path, }); } else { Logger.getInstance().info(`Folder modified: ${file.path}, ignored`); diff --git a/plugin/src/file-operations/file-operations.ts b/plugin/src/file-operations/file-operations.ts index affa71c3..1470d79d 100644 --- a/plugin/src/file-operations/file-operations.ts +++ b/plugin/src/file-operations/file-operations.ts @@ -1,22 +1,22 @@ -import { RelativePath } from "src/database/document-metadata"; +import type { RelativePath } from "src/database/document-metadata"; export interface FileOperations { - listAllFiles(): Promise; + listAllFiles: () => Promise; - read(path: RelativePath): Promise; + read: (path: RelativePath) => Promise; - getModificationTime(path: RelativePath): Promise; + getModificationTime: (path: RelativePath) => Promise; - create(path: RelativePath, newContent: Uint8Array): Promise; + create: (path: RelativePath, newContent: Uint8Array) => Promise; // Writes new content to the file at the given path. If the file's content has changed since the expectedContent was read, the write will merge the changes. - write( + write: ( path: RelativePath, expectedContent: Uint8Array, newContent: Uint8Array - ): Promise; + ) => Promise; - remove(path: RelativePath): Promise; + remove: (path: RelativePath) => Promise; - move(oldPath: RelativePath, newPath: RelativePath): Promise; + move: (oldPath: RelativePath, newPath: RelativePath) => Promise; } diff --git a/plugin/src/file-operations/obsidian-file-operations.ts b/plugin/src/file-operations/obsidian-file-operations.ts index 213b794b..28c044f0 100644 --- a/plugin/src/file-operations/obsidian-file-operations.ts +++ b/plugin/src/file-operations/obsidian-file-operations.ts @@ -1,30 +1,33 @@ -import { normalizePath, Vault } from "obsidian"; -import { FileOperations } from "./file-operations"; +import type { Vault } from "obsidian"; +import { normalizePath } from "obsidian"; +import type { FileOperations } from "./file-operations"; import * as lib from "../../../backend/sync_lib/pkg/sync_lib.js"; import { isEqualBytes } from "src/utils/is-equal-bytes"; -import { RelativePath } from "src/database/document-metadata"; +import type { RelativePath } from "src/database/document-metadata"; export class ObsidianFileOperations implements FileOperations { - public constructor(private vault: Vault) {} + public constructor(private readonly vault: Vault) {} - async listAllFiles(): Promise { + public async listAllFiles(): Promise { const files = this.vault.getFiles(); return files.map((file) => file.path); } - async read(path: RelativePath): Promise { + public async read(path: RelativePath): Promise { return new Uint8Array( await this.vault.adapter.readBinary(normalizePath(path)) ); } - async getModificationTime(path: RelativePath): Promise { - return new Date( - (await this.vault.adapter.stat(normalizePath(path)))!.mtime - ); + public async getModificationTime(path: RelativePath): Promise { + const file = await this.vault.adapter.stat(normalizePath(path)); + if (!file) { + throw new Error(`File not found: ${path}`); + } + return new Date(file.mtime); } - async write( + public async write( path: RelativePath, expectedContent: Uint8Array, newContent: Uint8Array @@ -44,17 +47,16 @@ export class ObsidianFileOperations implements FileOperations { await this.vault.adapter.writeBinary(normalizePath(path), result); return result; - } else { - await this.vault.adapter.writeBinary( - normalizePath(path), - newContent - ); - - return newContent; } + await this.vault.adapter.writeBinary(normalizePath(path), newContent); + + return newContent; } - async create(path: RelativePath, newContent: Uint8Array): Promise { + public async create( + path: RelativePath, + newContent: Uint8Array + ): Promise { if (await this.vault.adapter.exists(normalizePath(path))) { await this.write(path, new Uint8Array(0), newContent); return; @@ -63,18 +65,21 @@ export class ObsidianFileOperations implements FileOperations { await this.vault.adapter.writeBinary(normalizePath(path), newContent); } - async remove(path: RelativePath): Promise { + public async remove(path: RelativePath): Promise { if (await this.vault.adapter.exists(normalizePath(path))) { return this.vault.adapter.remove(normalizePath(path)); } } - async move(oldPath: RelativePath, newPath: RelativePath): Promise { + public async move( + oldPath: RelativePath, + newPath: RelativePath + ): Promise { if (oldPath === newPath) { return; } - this.vault.adapter.rename( + await this.vault.adapter.rename( normalizePath(oldPath), normalizePath(newPath) ); diff --git a/plugin/src/logger.ts b/plugin/src/logger.ts deleted file mode 100644 index b02a2495..00000000 --- a/plugin/src/logger.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Notice } from "obsidian"; - -export enum LogLevel { - DEBUG, - INFO, - WARNING, - ERROR, -} - -class LogLine { - public constructor(public level: LogLevel, public message: string) {} - - public toString(): string { - return `${this.formatLevel()}: ${this.message}`; - } - - private formatLevel(): string { - switch (this.level) { - case LogLevel.DEBUG: - return "DEBUG"; - case LogLevel.INFO: - return "INFO"; - case LogLevel.WARNING: - return "WARNING"; - case LogLevel.ERROR: - return "ERROR"; - default: - return "UNKNOWN"; - } - } -} - -export class Logger { - private static readonly MAX_MESSAGES = 1000; - - private static instance: Logger; - private messages: LogLine[] = []; - - private constructor() {} - - static getInstance(): Logger { - if (!Logger.instance) { - Logger.instance = new Logger(); - } - return Logger.instance; - } - - public debug(message: string): void { - this.pushMessage(message, LogLevel.DEBUG); - console.debug(message); - } - - public info(message: string): void { - this.pushMessage(message, LogLevel.INFO); - console.log(message); - } - - public warn(message: string): void { - this.pushMessage(message, LogLevel.WARNING); - console.warn(message); - } - - public error(message: string): void { - this.pushMessage(message, LogLevel.ERROR); - console.error(message); - new Notice(message); - } - - public getMessages(mininumSeverity: LogLevel): LogLine[] { - return this.messages.filter( - (message) => message.level >= mininumSeverity - ); - } - - private pushMessage(message: string, level: LogLevel): void { - this.messages.push(new LogLine(level, message)); - if (this.messages.length > Logger.MAX_MESSAGES) { - this.messages.shift(); - } - } -} diff --git a/plugin/src/services/sync-service.ts b/plugin/src/services/sync-service.ts index 472c29b9..5a4f9636 100644 --- a/plugin/src/services/sync-service.ts +++ b/plugin/src/services/sync-service.ts @@ -1,16 +1,17 @@ import * as lib from "../../../backend/sync_lib/pkg/sync_lib.js"; -import createClient, { Client } from "openapi-fetch"; -import type { components, paths } from "./types.js"; // generated by openapi-typescript -import { Logger } from "src/logger"; -import { Database } from "src/database/database"; -import { SyncSettings } from "src/database/sync-settings"; -import { - VaultUpdateId, - RelativePath, +import type { Client } from "openapi-fetch"; +import createClient from "openapi-fetch"; +import type { components, paths } from "./types.js"; // Generated by openapi-typescript +import type { Database } from "src/database/database"; +import type { SyncSettings } from "src/database/sync-settings"; +import type { DocumentId, + RelativePath, + VaultUpdateId, } from "src/database/document-metadata"; import PQueue from "p-queue"; +import { Logger } from "src/tracing/logger.js"; export interface RequestCountStatus { waiting: number; @@ -21,16 +22,17 @@ export interface RequestCountStatus { export class SyncService { private client: Client; - private promiseQueue: PQueue; - private requestCountListeners: Array<(status: RequestCountStatus) => void> = - []; - private status: RequestCountStatus = { + private readonly promiseQueue: PQueue; + private readonly requestCountListeners: (( + status: RequestCountStatus + ) => void)[] = []; + private readonly status: RequestCountStatus = { waiting: 0, success: 0, failure: 0, }; - public constructor(private database: Database) { + public constructor(private readonly database: Database) { this.createClient(database.getSettings()); this.promiseQueue = new PQueue({ concurrency: database.getSettings().uploadConcurrency, @@ -64,36 +66,21 @@ export class SyncService { listener({ ...this.status }); } - private emitRequestCountChange(): void { - this.requestCountListeners.forEach((listener) => - listener({ ...this.status }) - ); - } - - private createClient(settings: SyncSettings) { - this.client = createClient({ - baseUrl: settings.remoteUri, - }); - } - - private enqueue(fn: () => Promise): Promise { - return this.promiseQueue.add(fn) as Promise; - } - public async ping(): Promise { - const response = await this.enqueue(() => + const response = await this.enqueue(async () => this.client.GET("/ping", { params: { header: { - authorization: - "Bearer " + this.database.getSettings().token, + authorization: `Bearer ${ + this.database.getSettings().token + }`, }, }, }) ); Logger.getInstance().debug( - "Ping response: " + JSON.stringify(response.data) + `Ping response: ${JSON.stringify(response.data)}` ); if (!response.data) { @@ -112,15 +99,16 @@ export class SyncService { contentBytes: Uint8Array; createdDate: Date; }): Promise { - const response = await this.enqueue(() => + const response = await this.enqueue(async () => this.client.POST("/vaults/{vault_id}/documents", { params: { path: { vault_id: this.database.getSettings().vaultName, }, header: { - authorization: - "Bearer " + this.database.getSettings().token, + authorization: `Bearer ${ + this.database.getSettings().token + }`, }, }, body: { @@ -136,7 +124,7 @@ export class SyncService { } Logger.getInstance().debug( - "Created document " + JSON.stringify(response.data) + `Created document ${JSON.stringify(response.data)}` ); return response.data; @@ -155,7 +143,7 @@ export class SyncService { contentBytes: Uint8Array; createdDate: Date; }): Promise { - const response = await this.enqueue(() => + const response = await this.enqueue(async () => this.client.PUT("/vaults/{vault_id}/documents/{document_id}", { params: { path: { @@ -163,8 +151,9 @@ export class SyncService { document_id: documentId, }, header: { - authorization: - "Bearer " + this.database.getSettings().token, + authorization: `Bearer ${ + this.database.getSettings().token + }`, }, }, body: { @@ -181,7 +170,7 @@ export class SyncService { } Logger.getInstance().debug( - "Updated document " + JSON.stringify(response.data) + `Updated document ${JSON.stringify(response.data)}` ); return response.data; @@ -196,7 +185,7 @@ export class SyncService { relativePath: RelativePath; createdDate: Date; }): Promise { - const response = await this.enqueue(() => + const response = await this.enqueue(async () => this.client.DELETE("/vaults/{vault_id}/documents/{document_id}", { params: { path: { @@ -204,8 +193,9 @@ export class SyncService { document_id: documentId, }, header: { - authorization: - "Bearer " + this.database.getSettings().token, + authorization: `Bearer ${ + this.database.getSettings().token + }`, }, }, body: { @@ -220,7 +210,7 @@ export class SyncService { } Logger.getInstance().debug( - "Updated document " + JSON.stringify(response.data) + `Updated document ${JSON.stringify(response.data)}` ); return response.data; @@ -231,7 +221,7 @@ export class SyncService { }: { documentId: DocumentId; }): Promise { - const response = await this.enqueue(() => + const response = await this.enqueue(async () => this.client.GET("/vaults/{vault_id}/documents/{document_id}", { params: { path: { @@ -239,8 +229,9 @@ export class SyncService { document_id: documentId, }, header: { - authorization: - "Bearer " + this.database.getSettings().token, + authorization: `Bearer ${ + this.database.getSettings().token + }`, }, }, }) @@ -251,7 +242,7 @@ export class SyncService { } Logger.getInstance().debug( - "Get document " + JSON.stringify(response.data) + `Get document ${JSON.stringify(response.data)}` ); return response.data; @@ -260,15 +251,16 @@ export class SyncService { public async getAll( since?: VaultUpdateId ): Promise { - const response = await this.enqueue(() => + const response = await this.enqueue(async () => this.client.GET("/vaults/{vault_id}/documents", { params: { path: { vault_id: this.database.getSettings().vaultName, }, header: { - authorization: - "Bearer " + this.database.getSettings().token, + authorization: `Bearer ${ + this.database.getSettings().token + }`, }, query: { since_update_id: since, @@ -277,14 +269,32 @@ export class SyncService { }) ); - if (!response.data) { - throw new Error(`Failed to get documents: ${response.error}`); + const { error } = response; + if (error) { + throw new Error(`Failed to get documents: ${error}`); } Logger.getInstance().debug( - "Get document " + JSON.stringify(response.data) + `Get document ${JSON.stringify(response.data)}` ); return response.data; } + + private emitRequestCountChange(): void { + this.requestCountListeners.forEach((listener) => { + listener({ ...this.status }); + }); + } + + private createClient(settings: SyncSettings): void { + this.client = createClient({ + baseUrl: settings.remoteUri, + }); + } + + private async enqueue(fn: () => Promise): Promise { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + return this.promiseQueue.add(fn) as Promise; + } } diff --git a/plugin/src/services/types.ts b/plugin/src/services/types.ts index dbfa8acb..09f50f13 100644 --- a/plugin/src/services/types.ts +++ b/plugin/src/services/types.ts @@ -23,9 +23,7 @@ export interface paths { requestBody?: never; responses: { 200: { - headers: { - [name: string]: unknown; - }; + headers: Record; content: { "application/json": components["schemas"]["PingResponse"]; }; @@ -63,9 +61,7 @@ export interface paths { requestBody?: never; responses: { 200: { - headers: { - [name: string]: unknown; - }; + headers: Record; content: { "application/json": components["schemas"]["FetchLatestDocumentsResponse"]; }; @@ -91,9 +87,7 @@ export interface paths { }; responses: { 200: { - headers: { - [name: string]: unknown; - }; + headers: Record; content: { "application/json": components["schemas"]["DocumentVersion"]; }; @@ -128,9 +122,7 @@ export interface paths { requestBody?: never; responses: { 200: { - headers: { - [name: string]: unknown; - }; + headers: Record; content: { "application/json": components["schemas"]["DocumentVersion"]; }; @@ -156,9 +148,7 @@ export interface paths { }; responses: { 200: { - headers: { - [name: string]: unknown; - }; + headers: Record; content: { "application/json": components["schemas"]["DocumentVersion"]; }; @@ -186,9 +176,7 @@ export interface paths { responses: { /** @description no content */ 200: { - headers: { - [name: string]: unknown; - }; + headers: Record; content?: never; }; }; diff --git a/plugin/src/sync-operations/locks.ts b/plugin/src/sync-operations/locks.ts index 4ce06cad..8a28249e 100644 --- a/plugin/src/sync-operations/locks.ts +++ b/plugin/src/sync-operations/locks.ts @@ -1,7 +1,7 @@ -import { RelativePath } from "src/database/document-metadata"; +import type { RelativePath } from "src/database/document-metadata"; -const locked = new Set(); -const waiters = new Map void>>(); +const locked = new Set(), + waiters = new Map void)[]>(); export function tryLockDocument(relativePath: RelativePath): boolean { if (locked.has(relativePath)) { @@ -12,17 +12,21 @@ export function tryLockDocument(relativePath: RelativePath): boolean { return true; } -export function waitForDocumentLock(relativePath: RelativePath): Promise { +export async function waitForDocumentLock( + relativePath: RelativePath +): Promise { if (tryLockDocument(relativePath)) { return Promise.resolve(); } return new Promise((resolve) => { - if (!waiters.has(relativePath)) { - waiters.set(relativePath, []); + let waiting = waiters.get(relativePath); + if (!waiting) { + waiting = []; + waiters.set(relativePath, waiting); } - waiters.get(relativePath)!.push(resolve); + waiting.push(resolve); }); } diff --git a/plugin/src/utils/hash.ts b/plugin/src/utils/hash.ts index 92f92e5a..10f20d1d 100644 --- a/plugin/src/utils/hash.ts +++ b/plugin/src/utils/hash.ts @@ -1,11 +1,12 @@ // https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript export function hash(content: Uint8Array): string { - let hash = 0; + let result = 0; + // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < content.length; i++) { - hash = (hash << 5) - hash + content[i]; - hash |= 0; // convert to 32bit integer + result = (result << 5) - result + content[i]; + result |= 0; // Convert to 32bit integer } - return hash.toString(16); + return Math.abs(result).toString(16); } export const EMPTY_HASH = hash(new Uint8Array(0)); diff --git a/plugin/src/views/sync-view.ts b/plugin/src/views/sync-view.ts index afd4f26c..5d81c37a 100644 --- a/plugin/src/views/sync-view.ts +++ b/plugin/src/views/sync-view.ts @@ -1,42 +1,40 @@ -import { ItemView, WorkspaceLeaf } from "obsidian"; -import { Logger, LogLevel } from "src/logger"; +import type { WorkspaceLeaf } from "obsidian"; +import { ItemView } from "obsidian"; +import { LogLevel, Logger } from "src/tracing/logger"; export class SyncView extends ItemView { - public static TYPE = "example-view"; + public static readonly TYPE = "example-view"; public constructor(leaf: WorkspaceLeaf) { super(leaf); } - getViewType() { + public getViewType(): string { return SyncView.TYPE; } - getDisplayText() { + public getDisplayText(): string { return "Example view"; } - async onOpen() { + public async onOpen(): Promise { const container = this.containerEl.children[1]; container.empty(); container.createEl("h4", { text: "Example view" }); - setInterval(() => this.updateView(), 1000); + // eslint-disable-next-line @typescript-eslint/no-misused-promises + setInterval(async () => this.updateView(), 1000); } - async updateView() { + public async updateView(): Promise { const container = this.containerEl.children[1]; container.empty(); const messages = Logger.getInstance() - .getMessages(LogLevel.INFO) + .getMessages(LogLevel.DEBUG) .map((message) => message.toString()) .join("\n"); container.createEl("pre", { text: messages }); } - - async onClose() { - // Nothing to clean up. - } }