Move file handling logic inside of client
This commit is contained in:
parent
db8e4bc2e7
commit
fde1fecbb6
7 changed files with 151 additions and 137 deletions
69
frontend/obsidian-plugin/src/obsidian-file-system.ts
Normal file
69
frontend/obsidian-plugin/src/obsidian-file-system.ts
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
import { normalizePath, Stat, Vault } from "obsidian";
|
||||||
|
import { FileSystemOperations, RelativePath } from "sync-client";
|
||||||
|
|
||||||
|
export class ObsidianFileSystemOperations implements FileSystemOperations {
|
||||||
|
public constructor(private readonly vault: Vault) {}
|
||||||
|
|
||||||
|
public async listAllFiles(): Promise<RelativePath[]> {
|
||||||
|
return this.vault.getFiles().map((file) => file.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async read(path: RelativePath): Promise<Uint8Array> {
|
||||||
|
return new Uint8Array(
|
||||||
|
await this.vault.adapter.readBinary(normalizePath(path))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async write(path: RelativePath, content: Uint8Array): Promise<void> {
|
||||||
|
return this.vault.adapter.writeBinary(
|
||||||
|
normalizePath(path),
|
||||||
|
content.buffer as ArrayBuffer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async atomicUpdateText(
|
||||||
|
path: RelativePath,
|
||||||
|
updater: (currentContent: string) => string
|
||||||
|
): Promise<string> {
|
||||||
|
return this.vault.adapter.process(normalizePath(path), updater);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getFileSize(path: RelativePath): Promise<number> {
|
||||||
|
return (await this.statFile(path)).size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getModificationTime(path: RelativePath): Promise<Date> {
|
||||||
|
return new Date((await this.statFile(path)).mtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async exists(path: RelativePath): Promise<boolean> {
|
||||||
|
return this.vault.adapter.exists(normalizePath(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async createDirectory(path: RelativePath): Promise<void> {
|
||||||
|
return this.vault.adapter.mkdir(normalizePath(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async delete(path: RelativePath): Promise<void> {
|
||||||
|
if (!(await this.vault.adapter.trashSystem(normalizePath(path)))) {
|
||||||
|
return this.vault.adapter.remove(normalizePath(path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async rename(
|
||||||
|
oldPath: RelativePath,
|
||||||
|
newPath: RelativePath
|
||||||
|
): Promise<void> {
|
||||||
|
return this.vault.adapter.rename(oldPath, newPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async statFile(path: string): Promise<Stat> {
|
||||||
|
const file = await this.vault.adapter.stat(normalizePath(path));
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
throw new Error(`File not found: ${path}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,12 +6,12 @@ import "../manifest.json";
|
||||||
import { SyncSettingsTab } from "./views/settings-tab";
|
import { SyncSettingsTab } from "./views/settings-tab";
|
||||||
import { HistoryView } from "./views/history-view";
|
import { HistoryView } from "./views/history-view";
|
||||||
import { ObsidianFileEventHandler } from "./obisidan-event-handler";
|
import { ObsidianFileEventHandler } from "./obisidan-event-handler";
|
||||||
import { ObsidianFileOperations } from "./obsidian-file-operations";
|
|
||||||
import { StatusBar } from "./views/status-bar";
|
import { StatusBar } from "./views/status-bar";
|
||||||
|
|
||||||
import { LogsView } from "./views/logs-view";
|
import { LogsView } from "./views/logs-view";
|
||||||
import { StatusDescription } from "./views/status-description";
|
import { StatusDescription } from "./views/status-description";
|
||||||
import { Logger, SyncClient } from "sync-client";
|
import { Logger, SyncClient } from "sync-client";
|
||||||
|
import { ObsidianFileSystemOperations } from "./obsidian-file-system";
|
||||||
|
|
||||||
export default class VaultLinkPlugin extends Plugin {
|
export default class VaultLinkPlugin extends Plugin {
|
||||||
private settingsTab: SyncSettingsTab | undefined;
|
private settingsTab: SyncSettingsTab | undefined;
|
||||||
|
|
@ -21,7 +21,7 @@ export default class VaultLinkPlugin extends Plugin {
|
||||||
Logger.getInstance().info("Starting plugin");
|
Logger.getInstance().info("Starting plugin");
|
||||||
|
|
||||||
this.client = await SyncClient.create(
|
this.client = await SyncClient.create(
|
||||||
new ObsidianFileOperations(this.app.vault),
|
new ObsidianFileSystemOperations(this.app.vault),
|
||||||
{
|
{
|
||||||
load: this.loadData.bind(this),
|
load: this.loadData.bind(this),
|
||||||
save: this.saveData.bind(this)
|
save: this.saveData.bind(this)
|
||||||
|
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
import type { RelativePath } from "src/persistence/database";
|
|
||||||
|
|
||||||
export interface FileOperations {
|
|
||||||
listAllFiles: () => Promise<RelativePath[]>;
|
|
||||||
|
|
||||||
read: (path: RelativePath) => Promise<Uint8Array>;
|
|
||||||
|
|
||||||
getFileSize: (path: RelativePath) => Promise<number>;
|
|
||||||
|
|
||||||
exists: (path: RelativePath) => Promise<boolean>;
|
|
||||||
|
|
||||||
getModificationTime: (path: RelativePath) => Promise<Date>;
|
|
||||||
|
|
||||||
// Create and write the file if it doesn't exist. Otherwise, it has the same behavior as write.
|
|
||||||
// All parent directories are created if they don't exist.
|
|
||||||
create: (path: RelativePath, newContent: Uint8Array) => Promise<void>;
|
|
||||||
|
|
||||||
// Update the file at the given path.
|
|
||||||
// If the file's content is different from `expectedContent`, the a 3-way merge is performed before writing.
|
|
||||||
// If the file no longer exists, the file is not recreated and an empty array is returned.
|
|
||||||
write: (
|
|
||||||
path: RelativePath,
|
|
||||||
expectedContent: Uint8Array,
|
|
||||||
newContent: Uint8Array
|
|
||||||
) => Promise<Uint8Array>;
|
|
||||||
|
|
||||||
remove: (path: RelativePath) => Promise<void>;
|
|
||||||
|
|
||||||
move: (oldPath: RelativePath, newPath: RelativePath) => Promise<void>;
|
|
||||||
|
|
||||||
isFileEligibleForSync: (path: RelativePath) => boolean;
|
|
||||||
}
|
|
||||||
|
|
@ -1,53 +1,56 @@
|
||||||
import type { Stat, Vault } from "obsidian";
|
import { Logger } from "src/tracing/logger";
|
||||||
import { normalizePath } from "obsidian";
|
import { FileSystemOperations } from "./filesystem-operations";
|
||||||
import { Platform } from "obsidian";
|
import { RelativePath } from "src/persistence/database";
|
||||||
import type { FileOperations, RelativePath } from "sync-client";
|
import { isBinary, isFileTypeMergable, mergeText } from "sync_lib";
|
||||||
import { Logger, isFileTypeMergable, mergeText } from "sync-client";
|
|
||||||
|
|
||||||
export class ObsidianFileOperations implements FileOperations {
|
export class FileOperations {
|
||||||
public constructor(private readonly vault: Vault) {}
|
public constructor(private readonly fs: FileSystemOperations) {}
|
||||||
|
|
||||||
public async listAllFiles(): Promise<RelativePath[]> {
|
public async listAllFiles(): Promise<RelativePath[]> {
|
||||||
const files = this.vault.getFiles();
|
const files = await this.fs.listAllFiles();
|
||||||
Logger.getInstance().debug(`Listing all files, found ${files.length}`);
|
Logger.getInstance().debug(`Listing all files, found ${files.length}`);
|
||||||
return files.map((file) => file.path);
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async read(path: RelativePath): Promise<Uint8Array> {
|
public async read(path: RelativePath): Promise<Uint8Array> {
|
||||||
Logger.getInstance().debug(`Reading file: ${path}`);
|
Logger.getInstance().debug(`Reading file: ${path}`);
|
||||||
if (isFileTypeMergable(path)) {
|
const content = await this.fs.read(path);
|
||||||
let text = await this.vault.adapter.read(normalizePath(path));
|
|
||||||
|
|
||||||
text = text.replace(/\r\n/g, "\n");
|
if (isBinary(content)) {
|
||||||
|
return content;
|
||||||
return new TextEncoder().encode(text);
|
|
||||||
}
|
}
|
||||||
return new Uint8Array(
|
|
||||||
await this.vault.adapter.readBinary(normalizePath(path))
|
const decoder = new TextDecoder("utf-8");
|
||||||
);
|
|
||||||
|
let text = decoder.decode(content);
|
||||||
|
text = text.replace(/\r\n/g, "\n");
|
||||||
|
|
||||||
|
return new TextEncoder().encode(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getFileSize(path: RelativePath): Promise<number> {
|
public async getFileSize(path: RelativePath): Promise<number> {
|
||||||
Logger.getInstance().debug(`Getting file size: ${path}`);
|
Logger.getInstance().debug(`Getting file size: ${path}`);
|
||||||
return (await this.statFile(path)).size;
|
return this.fs.getFileSize(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getModificationTime(path: RelativePath): Promise<Date> {
|
public async getModificationTime(path: RelativePath): Promise<Date> {
|
||||||
Logger.getInstance().debug(`Getting modification time: ${path}`);
|
Logger.getInstance().debug(`Getting modification time: ${path}`);
|
||||||
return new Date((await this.statFile(path)).mtime);
|
return this.fs.getModificationTime(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async exists(path: RelativePath): Promise<boolean> {
|
public async exists(path: RelativePath): Promise<boolean> {
|
||||||
Logger.getInstance().debug(`Checking existance of ${path}`);
|
Logger.getInstance().debug(`Checking existance of ${path}`);
|
||||||
return this.vault.adapter.exists(normalizePath(path));
|
return this.fs.exists(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create and write the file if it doesn't exist. Otherwise, it has the same behavior as write.
|
||||||
|
// All parent directories are created if they don't exist.
|
||||||
public async create(
|
public async create(
|
||||||
path: RelativePath,
|
path: RelativePath,
|
||||||
newContent: Uint8Array
|
newContent: Uint8Array
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
Logger.getInstance().debug(`Creating file: ${path}`);
|
Logger.getInstance().debug(`Creating file: ${path}`);
|
||||||
if (await this.vault.adapter.exists(normalizePath(path))) {
|
if (await this.fs.exists(path)) {
|
||||||
Logger.getInstance().debug(
|
Logger.getInstance().debug(
|
||||||
`Didn't expect ${path} to exist, when trying to create it, merging instead`
|
`Didn't expect ${path} to exist, when trying to create it, merging instead`
|
||||||
);
|
);
|
||||||
|
|
@ -55,50 +58,51 @@ export class ObsidianFileOperations implements FileOperations {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.createParentDirectories(normalizePath(path));
|
await this.createParentDirectories(path);
|
||||||
await this.vault.adapter.writeBinary(
|
await this.fs.write(path, newContent);
|
||||||
normalizePath(path),
|
|
||||||
newContent.buffer as ArrayBuffer
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the file at the given path.
|
||||||
|
// If the file's content is different from `expectedContent`, the a 3-way merge is performed before writing.
|
||||||
|
// If the file no longer exists, the file is not recreated and an empty array is returned.
|
||||||
public async write(
|
public async write(
|
||||||
path: RelativePath,
|
path: RelativePath,
|
||||||
expectedContent: Uint8Array,
|
expectedContent: Uint8Array,
|
||||||
newContent: Uint8Array
|
newContent: Uint8Array
|
||||||
): Promise<Uint8Array> {
|
): Promise<Uint8Array> {
|
||||||
Logger.getInstance().debug(`Writing file: ${path}`);
|
Logger.getInstance().debug(`Writing file: ${path}`);
|
||||||
if (!(await this.vault.adapter.exists(normalizePath(path)))) {
|
if (!(await this.fs.exists(path))) {
|
||||||
Logger.getInstance().debug(
|
Logger.getInstance().debug(
|
||||||
`The caller assumed ${path} exists, but it no longer, so we wont recreate it`
|
`The caller assumed ${path} exists, but it no longer, so we wont recreate it`
|
||||||
);
|
);
|
||||||
return new Uint8Array(0);
|
return new Uint8Array(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isFileTypeMergable(path)) {
|
if (
|
||||||
|
!isFileTypeMergable(path) ||
|
||||||
|
isBinary(expectedContent) ||
|
||||||
|
isBinary(newContent)
|
||||||
|
) {
|
||||||
Logger.getInstance().debug(
|
Logger.getInstance().debug(
|
||||||
`The expected content is not mergable, so we won't perform a 3-way merge, just overwrite it`
|
`The expected content is not mergable, so we won't perform a 3-way merge, just overwrite it`
|
||||||
);
|
);
|
||||||
await this.vault.adapter.writeBinary(
|
await this.fs.write(path, newContent);
|
||||||
normalizePath(path),
|
|
||||||
newContent.buffer as ArrayBuffer
|
|
||||||
);
|
|
||||||
return newContent;
|
return newContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
const expetedText = new TextDecoder().decode(expectedContent);
|
const expectedText = new TextDecoder().decode(expectedContent);
|
||||||
const newText = new TextDecoder().decode(newContent);
|
const newText = new TextDecoder().decode(newContent);
|
||||||
|
|
||||||
const resultText = await this.vault.adapter.process(
|
const resultText = await this.fs.atomicUpdateText(
|
||||||
normalizePath(path),
|
path,
|
||||||
(currentText) => {
|
(currentText) => {
|
||||||
currentText = currentText.replace(/\r\n/g, "\n");
|
currentText = currentText.replace(/\r\n/g, "\n");
|
||||||
if (currentText !== expetedText) {
|
if (currentText !== expectedText) {
|
||||||
Logger.getInstance().debug(
|
Logger.getInstance().debug(
|
||||||
`Performing a 3-way merge for ${path} with the expected content`
|
`Performing a 3-way merge for ${path} with the expected content`
|
||||||
);
|
);
|
||||||
|
|
||||||
return mergeText(expetedText, currentText, newText);
|
return mergeText(expectedText, currentText, newText);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.getInstance().debug(
|
Logger.getInstance().debug(
|
||||||
|
|
@ -113,18 +117,13 @@ export class ObsidianFileOperations implements FileOperations {
|
||||||
|
|
||||||
public async remove(path: RelativePath): Promise<void> {
|
public async remove(path: RelativePath): Promise<void> {
|
||||||
Logger.getInstance().debug(`Removing file: ${path}`);
|
Logger.getInstance().debug(`Removing file: ${path}`);
|
||||||
if (await this.vault.adapter.exists(normalizePath(path))) {
|
return this.fs.delete(path);
|
||||||
await this.vault.adapter.trashSystem(normalizePath(path));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async move(
|
public async move(
|
||||||
oldPath: RelativePath,
|
oldPath: RelativePath,
|
||||||
newPath: RelativePath
|
newPath: RelativePath
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
oldPath = normalizePath(oldPath);
|
|
||||||
newPath = normalizePath(newPath);
|
|
||||||
|
|
||||||
Logger.getInstance().debug(`Moving file: ${oldPath} -> ${newPath}`);
|
Logger.getInstance().debug(`Moving file: ${oldPath} -> ${newPath}`);
|
||||||
|
|
||||||
if (oldPath === newPath) {
|
if (oldPath === newPath) {
|
||||||
|
|
@ -132,25 +131,16 @@ export class ObsidianFileOperations implements FileOperations {
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.createParentDirectories(newPath);
|
await this.createParentDirectories(newPath);
|
||||||
await this.vault.adapter.rename(oldPath, newPath);
|
await this.fs.rename(oldPath, newPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public isFileEligibleForSync(path: RelativePath): boolean {
|
public isFileEligibleForSync(path: RelativePath): boolean {
|
||||||
if (Platform.isDesktopApp) {
|
return true;
|
||||||
return true;
|
// if (Platform.isDesktopApp) {
|
||||||
}
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
return isFileTypeMergable(path);
|
// return isFileTypeMergable(path);
|
||||||
}
|
|
||||||
|
|
||||||
private async statFile(path: string): Promise<Stat> {
|
|
||||||
const file = await this.vault.adapter.stat(normalizePath(path));
|
|
||||||
|
|
||||||
if (!file) {
|
|
||||||
throw new Error(`File not found: ${path}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createParentDirectories(path: string): Promise<void> {
|
private async createParentDirectories(path: string): Promise<void> {
|
||||||
|
|
@ -160,8 +150,8 @@ export class ObsidianFileOperations implements FileOperations {
|
||||||
}
|
}
|
||||||
for (let i = 1; i < components.length; i++) {
|
for (let i = 1; i < components.length; i++) {
|
||||||
const parentDir = components.slice(0, i).join("/");
|
const parentDir = components.slice(0, i).join("/");
|
||||||
if (!(await this.vault.adapter.exists(parentDir))) {
|
if (!(await this.fs.exists(parentDir))) {
|
||||||
await this.vault.adapter.mkdir(parentDir);
|
await this.fs.createDirectory(parentDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { RelativePath } from "src/persistence/database";
|
||||||
|
|
||||||
|
export interface FileSystemOperations {
|
||||||
|
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>;
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,3 @@
|
||||||
export { Settings, type SyncSettings } from "./persistence/settings";
|
|
||||||
|
|
||||||
export { type CheckConnectionResult } from "./services/sync-service";
|
|
||||||
|
|
||||||
export { Syncer } from "./sync-operations/syncer";
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
SyncHistory,
|
SyncHistory,
|
||||||
SyncType,
|
SyncType,
|
||||||
|
|
@ -12,17 +6,14 @@ export {
|
||||||
type HistoryStats,
|
type HistoryStats,
|
||||||
type HistoryEntry
|
type HistoryEntry
|
||||||
} from "./tracing/sync-history";
|
} from "./tracing/sync-history";
|
||||||
|
|
||||||
export { Logger, LogLevel } from "./tracing/logger";
|
export { Logger, LogLevel } from "./tracing/logger";
|
||||||
|
|
||||||
export { SyncClient } from "./sync-client";
|
export { SyncClient } from "./sync-client";
|
||||||
export { type FileOperations } from "./file-operations";
|
export { Syncer } from "./sync-operations/syncer";
|
||||||
export { type RelativePath } from "./persistence/database";
|
export type { CheckConnectionResult } from "./services/sync-service";
|
||||||
export type { PersistenceProvider } from "./persistence/persistence";
|
export { Settings, type SyncSettings } from "./persistence/settings";
|
||||||
|
|
||||||
export {
|
export type { RelativePath } from "./persistence/database";
|
||||||
isFileTypeMergable,
|
export type { FileSystemOperations } from "./file-operations/filesystem-operations";
|
||||||
mergeText,
|
export type { PersistenceProvider } from "./persistence/persistence";
|
||||||
bytesToBase64,
|
|
||||||
base64ToBytes,
|
|
||||||
merge
|
|
||||||
} from "sync_lib";
|
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@ import init from "sync_lib";
|
||||||
import wasmBin from "sync_lib/sync_lib_bg.wasm";
|
import wasmBin from "sync_lib/sync_lib_bg.wasm";
|
||||||
import type { PersistenceProvider } from "./persistence/persistence";
|
import type { PersistenceProvider } from "./persistence/persistence";
|
||||||
import { SyncHistory } from "./tracing/sync-history";
|
import { SyncHistory } from "./tracing/sync-history";
|
||||||
import type { FileOperations } from "./file-operations";
|
|
||||||
import { Logger } from "./tracing/logger";
|
import { Logger } from "./tracing/logger";
|
||||||
import { Database } from "./persistence/database";
|
import { Database } from "./persistence/database";
|
||||||
import { Settings } from "./persistence/settings";
|
import { Settings } from "./persistence/settings";
|
||||||
import type { CheckConnectionResult } from "./services/sync-service";
|
import type { CheckConnectionResult } from "./services/sync-service";
|
||||||
import { SyncService } from "./services/sync-service";
|
import { SyncService } from "./services/sync-service";
|
||||||
import { Syncer } from "./sync-operations/syncer";
|
import { Syncer } from "./sync-operations/syncer";
|
||||||
import { applyRemoteChangesLocally } from "./sync-operations/apply-remote-changes-locally";
|
import { FileSystemOperations } from "./file-operations/filesystem-operations";
|
||||||
|
import { FileOperations } from "./file-operations/file-operations";
|
||||||
|
|
||||||
export class SyncClient {
|
export class SyncClient {
|
||||||
private remoteListenerIntervalId: number | null = null;
|
private remoteListenerIntervalId: number | null = null;
|
||||||
|
|
@ -35,7 +35,7 @@ export class SyncClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async create(
|
public static async create(
|
||||||
operations: FileOperations,
|
fs: FileSystemOperations,
|
||||||
persistence: PersistenceProvider
|
persistence: PersistenceProvider
|
||||||
): Promise<SyncClient> {
|
): Promise<SyncClient> {
|
||||||
const history = new SyncHistory();
|
const history = new SyncHistory();
|
||||||
|
|
@ -75,7 +75,7 @@ export class SyncClient {
|
||||||
database,
|
database,
|
||||||
settings,
|
settings,
|
||||||
syncService,
|
syncService,
|
||||||
operations,
|
new FileOperations(fs),
|
||||||
history
|
history
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -90,19 +90,11 @@ export class SyncClient {
|
||||||
void syncer.scheduleSyncForOfflineChanges();
|
void syncer.scheduleSyncForOfflineChanges();
|
||||||
|
|
||||||
client.registerRemoteEventListener(
|
client.registerRemoteEventListener(
|
||||||
settings,
|
|
||||||
database,
|
|
||||||
syncService,
|
|
||||||
syncer,
|
|
||||||
settings.getSettings().fetchChangesUpdateIntervalMs
|
settings.getSettings().fetchChangesUpdateIntervalMs
|
||||||
);
|
);
|
||||||
|
|
||||||
settings.addOnSettingsChangeHandlers((newSettings, oldSettings) => {
|
settings.addOnSettingsChangeHandlers((newSettings, oldSettings) => {
|
||||||
client.registerRemoteEventListener(
|
client.registerRemoteEventListener(
|
||||||
settings,
|
|
||||||
database,
|
|
||||||
syncService,
|
|
||||||
syncer,
|
|
||||||
newSettings.fetchChangesUpdateIntervalMs
|
newSettings.fetchChangesUpdateIntervalMs
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -142,26 +134,13 @@ export class SyncClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerRemoteEventListener(
|
private registerRemoteEventListener(intervalMs: number): void {
|
||||||
settings: Settings,
|
|
||||||
database: Database,
|
|
||||||
syncService: SyncService,
|
|
||||||
syncer: Syncer,
|
|
||||||
intervalMs: number
|
|
||||||
): void {
|
|
||||||
if (this.remoteListenerIntervalId !== null) {
|
if (this.remoteListenerIntervalId !== null) {
|
||||||
window.clearInterval(this.remoteListenerIntervalId);
|
window.clearInterval(this.remoteListenerIntervalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.remoteListenerIntervalId = window.setInterval(
|
this.remoteListenerIntervalId = window.setInterval(
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
() => void this._syncer.applyRemoteChangesLocally(),
|
||||||
async () =>
|
|
||||||
applyRemoteChangesLocally({
|
|
||||||
settings,
|
|
||||||
database,
|
|
||||||
syncService,
|
|
||||||
syncer
|
|
||||||
}),
|
|
||||||
intervalMs
|
intervalMs
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue