Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions examples/callbacks/notify-fetch-data.callback.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { logger } from "examples/drive";
import { getInfoItem } from "examples/info-items-manager";

import { TFetchDataCallback } from "@/types/callbacks.type";
import { sleep } from "@/utils";

type TCallback = (data: boolean, path: string, errorHandler?: () => void) => Promise<{ finished: boolean; progress: number }>;

export const fetchDataCallback = async (id: string, callback: TCallback) => {
export const fetchDataCallback = async (id: string, callback: Parameters<TFetchDataCallback>[1]) => {
logger.info({ fn: "fetchDataCallback", id });
const path = await getInfoItem(id);

Expand Down
7 changes: 6 additions & 1 deletion src/types/callbacks.type.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
export type NapiCallbackFunction = (...args: any[]) => any;

export type TFetchDataCallback = (
id: string,
callback: (data: boolean, path: string, errorHandler?: () => void) => Promise<{ finished: boolean; progress: number }>,
) => void;

export type InputSyncCallbacks = {
fetchDataCallback?: NapiCallbackFunction;
fetchDataCallback: TFetchDataCallback;
validateDataCallback?: NapiCallbackFunction;
cancelFetchDataCallback?: NapiCallbackFunction;
fetchPlaceholdersCallback?: NapiCallbackFunction;
Expand Down
91 changes: 29 additions & 62 deletions src/virtual-drive.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,37 @@
import path, { join, win32 } from "path";
import fs from "fs";
import { Watcher } from "./watcher/watcher";
import { ExtraCallbacks, InputSyncCallbacks } from "./types/callbacks.type";
import { Callbacks } from "./types/callbacks.type";
import { IQueueManager } from "./queue/queueManager";

import { createLogger } from "./logger";
import { Addon } from "./addon-wrapper";
import winston from "winston";

const addon = new Addon();

type Callbacks = InputSyncCallbacks & ExtraCallbacks;
const PLACEHOLDER_ATTRIBUTES = {
FILE_ATTRIBUTE_READONLY: 0x1,
FILE_ATTRIBUTE_HIDDEN: 0x2,
FOLDER_ATTRIBUTE_READONLY: 0x1,
FILE_ATTRIBUTE_NORMAL: 0x1,
};

class VirtualDrive {
PLACEHOLDER_ATTRIBUTES: { [key: string]: number };
syncRootPath: string;
callbacks?: Callbacks;
watcher = new Watcher();
logger: winston.Logger;

private watcher: Watcher;

constructor(syncRootPath: string, loggerPath?: string) {
this.PLACEHOLDER_ATTRIBUTES = {
FILE_ATTRIBUTE_READONLY: 0x1,
FILE_ATTRIBUTE_HIDDEN: 0x2,
FOLDER_ATTRIBUTE_READONLY: 0x1,
FILE_ATTRIBUTE_NORMAL: 0x1,
};
constructor(syncRootPath: string, loggerPath: string) {
this.syncRootPath = this.convertToWindowsPath(syncRootPath);
loggerPath = this.convertToWindowsPath(loggerPath);

this.watcher = new Watcher();
addon.syncRootPath = syncRootPath;
addon.syncRootPath = this.syncRootPath;

this.syncRootPath = syncRootPath;
this.createSyncRootFolder();

let pathElements = this.syncRootPath.split("\\\\");
pathElements.pop();
let parentPath = pathElements.join("\\\\");

this.addLoggerPath(loggerPath ?? parentPath);
this.addLoggerPath(loggerPath);
this.logger = createLogger(loggerPath);
}

addLoggerPath(logPath: string) {
Expand Down Expand Up @@ -63,39 +59,6 @@ class VirtualDrive {
return addon.getPlaceholderWithStatePending();
}

getInputSyncCallbacks(): InputSyncCallbacks {
if (this.callbacks === undefined) {
throw new Error("Callbacks are not defined");
}

const inputSyncCallbackKeys: (keyof InputSyncCallbacks)[] = [
"fetchDataCallback",
"validateDataCallback",
"cancelFetchDataCallback",
"fetchPlaceholdersCallback",
"cancelFetchPlaceholdersCallback",
"notifyFileOpenCompletionCallback",
"notifyFileCloseCompletionCallback",
"notifyDehydrateCallback",
"notifyDehydrateCompletionCallback",
"notifyDeleteCallback",
"notifyDeleteCompletionCallback",
"notifyRenameCallback",
"notifyRenameCompletionCallback",
"noneCallback",
];

const result: InputSyncCallbacks = {};

for (const key of inputSyncCallbackKeys) {
if (this.callbacks[key] !== undefined) {
result[key] = this.callbacks[key];
}
}

return result;
}

createSyncRootFolder() {
if (!fs.existsSync(this.syncRootPath)) {
fs.mkdirSync(this.syncRootPath, { recursive: true });
Expand All @@ -114,8 +77,12 @@ class VirtualDrive {
return addon.deleteFileSyncRoot({ path: this.fixPath(relativePath) });
}

async connectSyncRoot(): Promise<any> {
return addon.connectSyncRoot({ callbacks: this.getInputSyncCallbacks() });
async connectSyncRoot() {
if (this.callbacks === undefined) {
throw new Error("Callbacks are not defined");
}

return addon.connectSyncRoot({ callbacks: this.callbacks });
}

createPlaceholderFile(
Expand Down Expand Up @@ -216,7 +183,7 @@ class VirtualDrive {

this.watcher.queueManager = queueManager;

this.watcher.logger = createLogger(loggerPath);
this.watcher.logger = this.logger;

this.watcher.syncRootPath = path;
this.watcher.options = {
Expand Down Expand Up @@ -260,7 +227,7 @@ class VirtualDrive {
path.basename(fullPath),
itemId,
size,
this.PLACEHOLDER_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL,
PLACEHOLDER_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL,
creationTime,
lastWriteTime,
Date.now(),
Expand Down Expand Up @@ -293,7 +260,7 @@ class VirtualDrive {
itemId,
true,
size,
this.PLACEHOLDER_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL,
PLACEHOLDER_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL,
creationTime,
lastWriteTime,
Date.now(),
Expand Down Expand Up @@ -327,7 +294,7 @@ class VirtualDrive {
itemId,
true,
size,
this.PLACEHOLDER_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL,
PLACEHOLDER_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL,
creationTime,
lastWriteTime,
Date.now(),
Expand All @@ -353,7 +320,7 @@ class VirtualDrive {
itemId,
true,
0,
this.PLACEHOLDER_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL,
PLACEHOLDER_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL,
Date.now(),
Date.now(),
Date.now(),
Expand All @@ -367,7 +334,7 @@ class VirtualDrive {
path.basename(fullPath),
itemId,
size,
this.PLACEHOLDER_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL,
PLACEHOLDER_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL,
creationTime,
lastWriteTime,
Date.now(),
Expand Down
7 changes: 5 additions & 2 deletions src/virtual-drive.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import fs from "fs";
import { v4 } from "uuid";
import { Mock } from "vitest";
import { mockDeep } from "vitest-mock-extended";

import { addon } from "@/addon";

import { Callbacks } from "./types/callbacks.type";
import VirtualDrive from "./virtual-drive";

vi.mock("fs");
Expand Down Expand Up @@ -138,13 +140,14 @@ describe("VirtualDrive", () => {
const providerVersion = "1.0.0";
const providerId = v4();
const logoPath = "C:\\iconPath";
const callbacks = {};
const callbacks = mockDeep<Callbacks>();

// Act
expect(drive.callbacks).toBe(undefined);
await drive.registerSyncRoot(providerName, providerVersion, providerId, callbacks, logoPath);

// Assert
expect(drive.callbacks).toBe(callbacks);
expect(drive.callbacks).not.toBe(undefined);
expect(addon.registerSyncRoot).toHaveBeenCalledWith(syncRootPath, providerName, providerVersion, providerId, logoPath);
});
});
Expand Down
1 change: 0 additions & 1 deletion src/watcher/detect-context-menu-action.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export class DetectContextMenuActionService {
size: curr.size,
ctimeMs: curr.ctimeMs,
mtimeMs: curr.mtimeMs,
blocks: curr.blocks,
},
});

Expand Down
3 changes: 1 addition & 2 deletions src/watcher/events/on-raw.service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { stat } from "fs/promises";
import { extname } from "path";

import { DetectContextMenuActionService } from "../detect-context-menu-action.service";
import { Watcher } from "../watcher";

export class OnRawService {
constructor(private readonly detectContextMenuAction: DetectContextMenuActionService = new DetectContextMenuActionService()) {}
constructor(private readonly detectContextMenuAction = new DetectContextMenuActionService()) {}

async execute({ self, event, path, details }: TProps) {
try {
Expand Down