UNPKG

projfs-fuse.one

Version:

FUSE3-compatible API for Windows using ProjFS - provides cross-platform virtual filesystem support

176 lines (154 loc) 5.16 kB
/** * ProjFS-FUSE.ONE - FUSE3-compatible API for Windows using ProjFS * * This package provides a FUSE3-compatible interface on Windows by using * Windows Projected File System (ProjFS) as the backend. Applications can * use the same FUSE3 API on both Linux and Windows for cross-platform * virtual filesystem development. * * @author REFINIO GmbH * @license MIT */ import { EventEmitter } from 'events'; import { createRequire } from 'module'; const require = createRequire(import.meta.url); // FUSE3-compatible operation interfaces export interface FuseStats { mtime: Date; atime: Date; ctime: Date; size: number; mode: number; uid: number; gid: number; } export interface FuseOperations { init?: () => void; getattr?: (path: string) => FuseStats | null; readdir?: (path: string) => string[]; read?: (path: string, size: number, offset: number) => Buffer | null; write?: (path: string, buffer: Buffer, offset: number) => number; create?: (path: string, mode: number) => void; unlink?: (path: string) => void; mkdir?: (path: string, mode: number) => void; rmdir?: (path: string) => void; rename?: (oldPath: string, newPath: string) => void; truncate?: (path: string, size: number) => void; open?: (path: string, flags: number) => number; release?: (path: string, fd: number) => void; statfs?: (path: string) => any; } // Load ProjFS-FUSE bridge let projfsFuse: any; try { projfsFuse = require('bindings')('projfs_fuse'); } catch (error: any) { throw new Error(`Failed to load ProjFS-FUSE bridge: ${error.message}`); } /** * ProjFS-FUSE filesystem class * * Provides a FUSE3-compatible interface on Windows using ProjFS as backend. * This allows the same FUSE3 code to work on both Linux and Windows. */ export class ProjFSFuse extends EventEmitter { private mounted = false; private mountPath: string; private operations: FuseOperations; private nativeInstance: any; constructor(mountPath: string, operations: FuseOperations, options: any = {}) { super(); if (process.platform !== 'win32') { throw new Error('ProjFS-FUSE.ONE only works on Windows. For Linux, use fuse3.one'); } this.mountPath = mountPath; this.operations = operations; // Create ProjFS mount instance this.nativeInstance = new projfsFuse.ProjFSMount(mountPath); } /** * Mount the filesystem with FUSE3-compatible operations * * This method adapts FUSE3 operations to ProjFS callbacks automatically */ async mount(): Promise<void> { if (this.mounted) { throw new Error('Filesystem is already mounted'); } try { // Convert FUSE3 operations to ProjFS operations const projfsOperations = this.adaptFuseOperationsToProjFS(this.operations); await this.nativeInstance.mount(projfsOperations); this.mounted = true; this.emit('mount'); } catch (error: any) { throw new Error(`Failed to mount ProjFS-FUSE filesystem: ${error.message}`); } } /** * Unmount the filesystem */ async unmount(): Promise<void> { if (!this.mounted) { return; } try { await this.nativeInstance.unmount(); this.mounted = false; this.emit('unmount'); } catch (error: any) { throw new Error(`Failed to unmount ProjFS-FUSE filesystem: ${error.message}`); } } /** * Check if filesystem is mounted */ isMounted(): boolean { return this.mounted && this.nativeInstance.isMounted(); } /** * Get mount path */ getMountPath(): string { return this.mountPath; } /** * Adapt FUSE3 operations to ProjFS callbacks * * This is the core adapter logic that makes FUSE3 operations work with ProjFS */ private adaptFuseOperationsToProjFS(fuseOps: FuseOperations): any { return { // ProjFS readdir maps directly to FUSE readdir readdir: (path: string): string[] => { if (fuseOps.readdir) { return fuseOps.readdir(path); } return []; }, // Future: Add more operation mappings // getattr -> getPlaceholderInfo // read -> getFileData // etc. }; } } // Export default class for compatibility export default ProjFSFuse; // Export FUSE3-compatible error codes export const FUSE_ERRORS = { EPERM: 1, ENOENT: 2, EIO: 5, EACCES: 13, EEXIST: 17, ENOTDIR: 20, EISDIR: 21, EINVAL: 22, ENOSPC: 28, EROFS: 30, EBUSY: 16, ENOTEMPTY: 39 }; // Export for backwards compatibility with existing FUSE3 code export { ProjFSFuse as Fuse3 };