Lint & format

This commit is contained in:
Andras Schmelczer 2025-02-22 17:25:26 +00:00
parent 27423bf3cd
commit ca225a71be
No known key found for this signature in database
GPG key ID: FC8F2C3D3D1A718C
17 changed files with 94 additions and 83 deletions

View file

@ -1,5 +1,4 @@
import type { SyncClient, Syncer } from "sync-client";
import { Logger } from "sync-client";
import type { SyncClient } from "sync-client";
import type { TAbstractFile } from "obsidian";
import { TFile } from "obsidian";

View file

@ -1,5 +1,6 @@
import { normalizePath, Stat, Vault } from "obsidian";
import { FileSystemOperations, RelativePath } from "sync-client";
import type { Stat, Vault } from "obsidian";
import { normalizePath } from "obsidian";
import type { FileSystemOperations, RelativePath } from "sync-client";
export class ObsidianFileSystemOperations implements FileSystemOperations {
public constructor(private readonly vault: Vault) {}
@ -17,6 +18,7 @@ export class ObsidianFileSystemOperations implements FileSystemOperations {
public async write(path: RelativePath, content: Uint8Array): Promise<void> {
return this.vault.adapter.writeBinary(
normalizePath(path),
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
content.buffer as ArrayBuffer
);
}

View file

@ -3,7 +3,7 @@ import { ItemView, setIcon } from "obsidian";
import { intlFormatDistance } from "date-fns";
import type { HistoryEntry, SyncClient } from "sync-client";
import { SyncType, SyncSource, SyncStatus, Logger } from "sync-client";
import { SyncType, SyncSource, SyncStatus } from "sync-client";
export class HistoryView extends ItemView {
public static readonly TYPE = "history-view";
@ -60,6 +60,7 @@ export class HistoryView extends ItemView {
}
element.createEl("span", {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
text: entry.relativePath
});

View file

@ -1,6 +1,6 @@
import { Logger } from "src/tracing/logger";
import { FileSystemOperations } from "./filesystem-operations";
import { RelativePath } from "src/persistence/database";
import type { Logger } from "src/tracing/logger";
import type { FileSystemOperations } from "./filesystem-operations";
import type { RelativePath } from "src/persistence/database";
import { isBinary, isFileTypeMergable, mergeText } from "sync_lib";
export class FileOperations {
@ -138,7 +138,7 @@ export class FileOperations {
await this.fs.rename(oldPath, newPath);
}
public isFileEligibleForSync(path: RelativePath): boolean {
public isFileEligibleForSync(_path: RelativePath): boolean {
return true;
// TODO: figure this out
// if (Platform.isDesktopApp) {

View file

@ -1,17 +1,17 @@
import { RelativePath } from "src/persistence/database";
import type { RelativePath } from "src/persistence/database";
export interface FileSystemOperations {
listAllFiles(): Promise<RelativePath[]>;
read(path: RelativePath): Promise<Uint8Array>;
write(path: RelativePath, content: Uint8Array): Promise<void>;
atomicUpdateText(
listAllFiles: () => Promise<RelativePath[]>;
read: (path: RelativePath) => Promise<Uint8Array>;
write: (path: RelativePath, content: Uint8Array) => Promise<void>;
atomicUpdateText: (
path: RelativePath,
updater: (currentContent: string) => string
): Promise<string>;
getFileSize(path: RelativePath): Promise<number>;
getModificationTime(path: RelativePath): Promise<Date>;
exists(path: RelativePath): Promise<boolean>;
createDirectory(path: RelativePath): Promise<void>;
delete(path: RelativePath): Promise<void>;
rename(oldPath: RelativePath, newPath: RelativePath): Promise<void>;
) => Promise<string>;
getFileSize: (path: RelativePath) => Promise<number>;
getModificationTime: (path: RelativePath) => Promise<Date>;
exists: (path: RelativePath) => Promise<boolean>;
createDirectory: (path: RelativePath) => Promise<void>;
delete: (path: RelativePath) => Promise<void>;
rename: (oldPath: RelativePath, newPath: RelativePath) => Promise<void>;
}

View file

@ -8,7 +8,7 @@ export interface DocumentMetadata {
hash: string;
}
import { Logger } from "src/tracing/logger";
import type { Logger } from "src/tracing/logger";
export interface StoredDatabase {
documents: Map<RelativePath, DocumentMetadata>;

View file

@ -1,4 +1,5 @@
import { Logger, LogLevel } from "src/tracing/logger";
import type { Logger } from "src/tracing/logger";
import { LogLevel } from "src/tracing/logger";
export interface SyncSettings {
remoteUri: string;

View file

@ -6,7 +6,7 @@ import type {
RelativePath,
VaultUpdateId
} from "../persistence/database";
import { Logger } from "src/tracing/logger";
import type { Logger } from "src/tracing/logger";
import { retriedFetchFactory } from "src/utils/retried-fetch";
import type { SyncSettings } from "dist/types";
import type { Settings } from "src/persistence/settings";

View file

@ -8,7 +8,7 @@ import { Settings } from "./persistence/settings";
import type { CheckConnectionResult } from "./services/sync-service";
import { SyncService } from "./services/sync-service";
import { Syncer } from "./sync-operations/syncer";
import { FileSystemOperations } from "./file-operations/filesystem-operations";
import type { FileSystemOperations } from "./file-operations/filesystem-operations";
import { FileOperations } from "./file-operations/file-operations";
export class SyncClient {
@ -39,6 +39,10 @@ export class SyncClient {
return this._logger;
}
public get documentCount(): number {
return this._database.getDocuments().size;
}
public static async create(
fs: FileSystemOperations,
persistence: PersistenceProvider
@ -124,10 +128,6 @@ export class SyncClient {
return client;
}
public get documentCount(): number {
return this._database.getDocuments().size;
}
public async checkConnection(): Promise<CheckConnectionResult> {
return this._syncService.checkConnection();
}

View file

@ -1,20 +1,16 @@
import type {
Database,
DocumentMetadata,
RelativePath
} from "../persistence/database";
import type { Database, RelativePath } from "../persistence/database";
import type { SyncService } from "src/services/sync-service";
import { Logger } from "src/tracing/logger";
import type { Logger } from "src/tracing/logger";
import type { SyncHistory } from "src/tracing/sync-history";
import { SyncSource, SyncStatus, SyncType } from "src/tracing/sync-history";
import { unlockDocument, waitForDocumentLock } from "./document-lock";
import PQueue from "p-queue";
import { EMPTY_HASH, hash } from "src/utils/hash";
import { hash } from "src/utils/hash";
import type { components } from "src/services/types";
import { deserialize } from "src/utils/deserialize";
import type { Settings } from "src/persistence/settings";
import { FileOperations } from "src/file-operations/file-operations";
import type { FileOperations } from "src/file-operations/file-operations";
import { findMatchingFileBasedOnHash } from "src/utils/find-matching-file-based-on-hash";
export class Syncer {
@ -75,7 +71,7 @@ export class Syncer {
);
}
public waitForSyncQueue(): Promise<void> {
public async waitForSyncQueue(): Promise<void> {
return this.syncQueue.onEmpty();
}

View file

@ -1,5 +1,5 @@
import type { RelativePath } from "src/persistence/database";
import { Logger } from "./logger";
import type { Logger } from "./logger";
export interface CommonHistoryEntry {
status: SyncStatus;
@ -47,7 +47,7 @@ export class SyncHistory {
error: 0
};
public constructor(private logger: Logger) {}
public constructor(private readonly logger: Logger) {}
public getEntries(): HistoryEntry[] {
return [...this.entries];

View file

@ -1,4 +1,4 @@
import { DocumentMetadata, RelativePath } from "src/persistence/database";
import type { DocumentMetadata, RelativePath } from "src/persistence/database";
import { EMPTY_HASH } from "./hash";
export function findMatchingFileBasedOnHash(

View file

@ -1,6 +1,6 @@
import * as fetchRetryFactory from "fetch-retry";
import type { RequestInitRetryParams } from "fetch-retry";
import { Logger } from "src/tracing/logger";
import type { Logger } from "src/tracing/logger";
const fetchWithRetry = fetchRetryFactory.default(fetch);
@ -15,7 +15,7 @@ function getUrlFromInput(input: RequestInfo | URL): string {
}
export function retriedFetchFactory(logger: Logger) {
return (
return async (
input: RequestInfo | URL,
init: RequestInitRetryParams<typeof fetch> = {}
): Promise<Response> => {

View file

@ -1,14 +1,15 @@
import { choose } from "../utils/choose";
import { v4 as uuidv4 } from "uuid";
import { assert } from "../utils/assert";
import { LogLevel, SyncSettings } from "sync-client";
import type { SyncSettings } from "sync-client";
import { LogLevel } from "sync-client";
import { MockClient } from "./mock-client";
import chalk from "chalk";
import { sleep } from "../utils/sleep";
export class MockAgent extends MockClient {
private writtenContents: Array<string> = [];
private pendingActions: Array<Promise<unknown>> = [];
private readonly writtenContents: string[] = [];
private readonly pendingActions: Promise<unknown>[] = [];
public constructor(
globalFiles: Record<string, Uint8Array>,
@ -48,8 +49,8 @@ export class MockAgent extends MockClient {
}
public async act(): Promise<void> {
let options: Array<() => Promise<unknown>> = [
() => {
const options: (() => Promise<unknown>)[] = [
async (): Promise<unknown> => {
const file = this.getFileName();
this.client.logger.info(`Decided to create file ${file}`);
return this.create(
@ -57,7 +58,7 @@ export class MockAgent extends MockClient {
new TextEncoder().encode(this.getContent())
);
},
() => {
async (): Promise<unknown> => {
this.client.logger.info(
`Decided to change fetchChangesUpdateIntervalMs`
);
@ -66,21 +67,21 @@ export class MockAgent extends MockClient {
Math.random() * 1000
);
},
() => {
async (): Promise<unknown> => {
this.client.logger.info(`Decided to disable sync`);
return this.client.settings.setSetting("isSyncEnabled", false);
},
() => {
async (): Promise<unknown> => {
this.client.logger.info(`Decided to enable sync`);
return this.client.settings.setSetting("isSyncEnabled", true);
}
];
let files = await this.listAllFiles();
const files = await this.listAllFiles();
if (files.length > 0) {
options.push(
() => {
async (): Promise<unknown> => {
const file = choose(files);
const newName = this.getFileName();
@ -89,7 +90,7 @@ export class MockAgent extends MockClient {
);
return this.rename(file, newName);
},
() => {
async (): Promise<unknown> => {
const file = choose(files);
this.client.logger.info(`Decided to update file ${file}`);
@ -101,23 +102,13 @@ export class MockAgent extends MockClient {
);
if (this.doDeletes) {
options.push(() => this.delete(choose(files)));
options.push(async () => this.delete(choose(files)));
}
}
this.pendingActions.push(choose(options)());
}
private getContent() {
const uuid = uuidv4();
this.writtenContents.push(uuid);
return uuid;
}
private getFileName() {
return `${this.name}-${uuidv4()}.md`;
}
public async finish(): Promise<void> {
await Promise.all(this.pendingActions);
await this.client.settings.setSetting("isSyncEnabled", true);
@ -178,7 +169,7 @@ export class MockAgent extends MockClient {
`Content ${content} found in ${found.length} files`
);
const file = found[0];
const [file] = found;
assert(
new TextDecoder().decode(file).split(content).length === 2,
`Content ${content} found more than once in a file`
@ -186,4 +177,14 @@ export class MockAgent extends MockClient {
}
}
}
private getContent(): string {
const uuid = uuidv4();
this.writtenContents.push(uuid);
return uuid;
}
private getFileName(): string {
return `${this.name}-${uuidv4()}.md`;
}
}

View file

@ -1,9 +1,9 @@
import {
SyncClient,
import type {
RelativePath,
FileSystemOperations,
SyncSettings
} from "sync-client";
import { SyncClient } from "sync-client";
import { assert } from "../utils/assert";
export class MockClient implements FileSystemOperations {
@ -15,7 +15,7 @@ export class MockClient implements FileSystemOperations {
private readonly initialSettings: Partial<SyncSettings>
) {}
public async init() {
public async init(): Promise<void> {
let _data: unknown = "";
this.client = await SyncClient.create(this, {
@ -23,12 +23,14 @@ export class MockClient implements FileSystemOperations {
save: async (data: unknown) => void (_data = data)
});
Object.keys(this.initialSettings).forEach((key) => {
this.client.settings.setSetting(
key as keyof SyncSettings,
this.initialSettings[key as keyof SyncSettings]
);
});
await Promise.all(
Object.keys(this.initialSettings).map(async (key) => {
return this.client.settings.setSetting(
key as keyof SyncSettings,
this.initialSettings[key as keyof SyncSettings]
);
})
);
assert(
(await this.client.checkConnection()).isSuccessful,
@ -37,7 +39,7 @@ export class MockClient implements FileSystemOperations {
}
public async listAllFiles(): Promise<RelativePath[]> {
return Object.keys(this.localFiles) as RelativePath[];
return Object.keys(this.localFiles);
}
public async read(path: RelativePath): Promise<Uint8Array> {
@ -77,7 +79,9 @@ export class MockClient implements FileSystemOperations {
this.client.syncer.syncLocallyCreatedFile(path, new Date());
}
public async createDirectory(path: RelativePath): Promise<void> {}
public async createDirectory(path: RelativePath): Promise<void> {
// This doesn't mean anything in our virtual FS representation
}
public async atomicUpdateText(
path: RelativePath,

View file

@ -1,4 +1,4 @@
import { SyncSettings } from "sync-client";
import type { SyncSettings } from "sync-client";
import { MockAgent } from "./agent/mock-agent";
import { sleep } from "./utils/sleep";
import { v4 as uuidv4 } from "uuid";
@ -55,14 +55,14 @@ async function runTest(): Promise<void> {
)
];
await Promise.all(clients.map((client) => client.init()));
await Promise.all(clients.map(async (client) => client.init()));
for (let i = 0; i < iterations; i++) {
await Promise.all(clients.map((client) => client.act()));
await Promise.all(clients.map(async (client) => client.act()));
await sleep(100);
}
await Promise.all(clients.map((client) => client.finish()));
await Promise.all(clients.map(async (client) => client.finish()));
console.info("Agents finished successfully");
@ -83,4 +83,11 @@ async function runTest(): Promise<void> {
console.info("Test completed successfully");
}
runTest();
runTest()
.then(() => {
process.exit(0);
})
.catch((err: unknown) => {
console.error(err);
process.exit(1);
});

View file

@ -1,3 +1,3 @@
export function sleep(ms: number): Promise<void> {
export async function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}