From 6d2a2e94fa13e30b672518f43633336a50fcedbd Mon Sep 17 00:00:00 2001 From: Dwynr Date: Sat, 29 Jun 2024 19:11:05 +0200 Subject: [PATCH] feat: serialize ipc --- src/index.ts | 6 +++++- src/lib/filesystems/local.ts | 13 +++++++----- src/lib/filesystems/remote.ts | 7 ++++--- src/lib/sync.ts | 39 +++++++++++++++++++++++++++-------- src/types.ts | 39 +++++++++++++++++++++++++---------- src/utils.ts | 25 ++++++++++++++++++++++ 6 files changed, 100 insertions(+), 29 deletions(-) diff --git a/src/index.ts b/src/index.ts index b21c498..4dc572d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,7 @@ import { isMainThread, parentPort } from "worker_threads" import { postMessageToMain } from "./lib/ipc" import { Semaphore } from "./semaphore" import { SYNC_INTERVAL } from "./constants" +import { serializeError } from "./utils" /** * SyncWorker @@ -71,7 +72,9 @@ export class SyncWorker { if (e instanceof Error) { postMessageToMain({ type: "error", - data: e + data: { + error: serializeError(e) + } }) } } @@ -150,4 +153,5 @@ export class SyncWorker { } } +export * from "./utils" export default SyncWorker diff --git a/src/lib/filesystems/local.ts b/src/lib/filesystems/local.ts index 628ea32..4cd02bf 100644 --- a/src/lib/filesystems/local.ts +++ b/src/lib/filesystems/local.ts @@ -4,7 +4,8 @@ import { promiseAllSettledChunked, isRelativePathIgnoredByDefault, isDirectoryPathIgnoredByDefault, - isSystemPathIgnoredByDefault + isSystemPathIgnoredByDefault, + serializeError } from "../../utils" import pathModule from "path" import process from "process" @@ -259,15 +260,17 @@ export class LocalFileSystem { * @returns {Promise} */ public async waitForLocalDirectoryChanges(): Promise { + const waitTimeout = SYNC_INTERVAL * 2 + await new Promise(resolve => { - if (Date.now() > this.lastDirectoryChangeTimestamp + SYNC_INTERVAL) { + if (Date.now() > this.lastDirectoryChangeTimestamp + waitTimeout) { resolve() return } const wait = setInterval(() => { - if (Date.now() > this.lastDirectoryChangeTimestamp + SYNC_INTERVAL) { + if (Date.now() > this.lastDirectoryChangeTimestamp + waitTimeout) { clearInterval(wait) resolve() @@ -456,7 +459,7 @@ export class LocalFileSystem { type: "error", relativePath, localPath, - error: err + error: serializeError(err) } }) }, @@ -523,7 +526,7 @@ export class LocalFileSystem { type: "error", relativePath, localPath, - error: e + error: serializeError(e) } }) } diff --git a/src/lib/filesystems/remote.ts b/src/lib/filesystems/remote.ts index 558f664..206b9d8 100644 --- a/src/lib/filesystems/remote.ts +++ b/src/lib/filesystems/remote.ts @@ -12,7 +12,8 @@ import { isNameOverMaxLength, isValidPath, isDirectoryPathIgnoredByDefault, - isRelativePathIgnoredByDefault + isRelativePathIgnoredByDefault, + serializeError } from "../../utils" import { v4 as uuidv4 } from "uuid" import { LOCAL_TRASH_NAME } from "../../constants" @@ -812,7 +813,7 @@ export class RemoteFileSystem { type: "error", relativePath, localPath, - error: err + error: serializeError(err) } }) }, @@ -871,7 +872,7 @@ export class RemoteFileSystem { type: "error", relativePath, localPath, - error: e + error: serializeError(e) } }) } diff --git a/src/lib/sync.ts b/src/lib/sync.ts index 448381b..739c9e3 100644 --- a/src/lib/sync.ts +++ b/src/lib/sync.ts @@ -9,6 +9,7 @@ import State from "./state" import { postMessageToMain } from "./ipc" import { isMainThread, parentPort } from "worker_threads" import Ignorer from "../ignorer" +import { serializeError } from "../utils" /** * Sync @@ -106,9 +107,9 @@ export class Sync { pauseSignal.resume() } else if (message.type === "updateLocalIgnorer" && message.syncPair.uuid === this.syncPair.uuid) { - this.localIgnorer.update(message.data).catch(console.error) + this.localIgnorer.update(message.data?.content).catch(console.error) } else if (message.type === "updateRemoteIgnorer" && message.syncPair.uuid === this.syncPair.uuid) { - this.remoteIgnorer.update(message.data).catch(console.error) + this.remoteIgnorer.update(message.data?.content).catch(console.error) } else if (message.type === "pauseSyncPair" && message.syncPair.uuid === this.syncPair.uuid) { this.paused = true } else if (message.type === "resumeSyncPair" && message.syncPair.uuid === this.syncPair.uuid) { @@ -204,19 +205,28 @@ export class Sync { postMessageToMain({ type: "localTreeErrors", syncPair: this.syncPair, - data: currentLocalTree.errors + data: { + errors: currentLocalTree.errors.map(e => ({ + ...e, + error: serializeError(e.error) + })) + } }) postMessageToMain({ type: "localTreeIgnored", syncPair: this.syncPair, - data: currentLocalTree.ignored + data: { + ignored: currentLocalTree.ignored + } }) postMessageToMain({ type: "remoteTreeIgnored", syncPair: this.syncPair, - data: currentRemoteTree.ignored + data: { + ignored: currentRemoteTree.ignored + } }) postMessageToMain({ @@ -240,7 +250,9 @@ export class Sync { postMessageToMain({ type: "deltas", syncPair: this.syncPair, - data: deltas + data: { + deltas + } }) console.log({ deltas, localErrors: currentLocalTree.errors }) @@ -263,8 +275,15 @@ export class Sync { type: "doneTasks", syncPair: this.syncPair, data: { - tasks: doneTasks, - errors + tasks: doneTasks.map(task => ({ + path: task.path, + type: task.type, + ...(task.type === "uploadFile" ? { item: task.item } : {}) + })), + errors: errors.map(e => ({ + ...e, + error: serializeError(e.error) + })) } }) @@ -315,7 +334,9 @@ export class Sync { postMessageToMain({ type: "cycleError", syncPair: this.syncPair, - data: e + data: { + error: serializeError(e) + } }) } } finally { diff --git a/src/types.ts b/src/types.ts index 77e63b4..7b40967 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,6 +2,7 @@ import { type LocalTreeError, type LocalTreeIgnored } from "./lib/filesystems/lo import { type Delta } from "./lib/deltas" import { type DoneTask, type TaskError } from "./lib/tasks" import { type RemoteTreeIgnored } from "./lib/filesystems/remote" +import { type SerializedError } from "./utils" export type SyncMode = "twoWay" | "localToCloud" | "localBackup" | "cloudToLocal" | "cloudBackup" @@ -78,30 +79,38 @@ export type SyncMessage = type: "error" relativePath: string localPath: string - error: Error + error: SerializedError } } | { type: "localTreeErrors" - data: LocalTreeError[] + data: { + errors: Prettify & { error: SerializedError }>[] + } } | { type: "localTreeIgnored" - data: LocalTreeIgnored[] + data: { + ignored: LocalTreeIgnored[] + } } | { type: "remoteTreeIgnored" - data: RemoteTreeIgnored[] + data: { + ignored: RemoteTreeIgnored[] + } } | { type: "deltas" - data: Delta[] + data: { + deltas: Delta[] + } } | { type: "doneTasks" data: { - tasks: DoneTask[] - errors: TaskError[] + tasks: Prettify>[] + errors: Prettify & { error: SerializedError }>[] } } | { @@ -112,7 +121,9 @@ export type SyncMessage = } | { type: "cycleError" - data: Error + data: { + error: SerializedError + } } | { type: "cycleSuccess" @@ -190,7 +201,9 @@ export type SyncMessage = } | { type: "error" - data: Error + data: { + error: SerializedError + } } | { type: "syncPairsUpdated" @@ -198,12 +211,16 @@ export type SyncMessage = | { type: "updateLocalIgnorer" syncPair: SyncPair - data?: string + data?: { + content?: string + } } | { type: "updateRemoteIgnorer" syncPair: SyncPair - data?: string + data?: { + content?: string + } } | { type: "resetSyncPairCache" diff --git a/src/utils.ts b/src/utils.ts index 9c5fe2a..f7cfbb8 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -184,3 +184,28 @@ export const isDirectoryPathIgnoredByDefault = memoize((path: string): boolean = return false }) + +export type SerializedError = { + name: string + message: string + stack?: string + stringified: string +} + +export function serializeError(error: Error): SerializedError { + return { + name: error.name, + message: error.message, + stack: error.stack, + stringified: `${error.name}: ${error.message}` + } +} + +export function deserializeError(serializedError: SerializedError): Error { + const error = new Error(serializedError.message) + + error.name = serializedError.name + error.stack = serializedError.stack + + return error +}