@componentor/fs 3.0.50 → 3.0.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +125 -25
- package/dist/index.js.map +1 -1
- package/dist/workers/async-relay.worker.js +5 -2
- package/dist/workers/async-relay.worker.js.map +1 -1
- package/dist/workers/repair.worker.js +90 -14
- package/dist/workers/repair.worker.js.map +1 -1
- package/dist/workers/server.worker.js +90 -14
- package/dist/workers/server.worker.js.map +1 -1
- package/dist/workers/sync-relay.worker.js +107 -16
- package/dist/workers/sync-relay.worker.js.map +1 -1
- package/package.json +1 -1
- package/readme.md +13 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/src/vfs/layout.ts","../../src/src/errors.ts","../../src/src/vfs/engine.ts","../../src/src/opfs-engine.ts","../../src/src/protocol/opcodes.ts","../../src/src/workers/sync-relay.worker.ts"],"sourcesContent":["/**\n * VFS Binary Layout Constants\n *\n * Defines the on-disk structure of the virtual filesystem binary file.\n * All reads/writes go through a FileSystemSyncAccessHandle.\n */\n\n// Magic number: \"VFS!\" in ASCII\nexport const VFS_MAGIC = 0x56465321;\nexport const VFS_VERSION = 1;\n\n// Default sizes\nexport const DEFAULT_BLOCK_SIZE = 4096;\nexport const DEFAULT_INODE_COUNT = 100000;\nexport const INODE_SIZE = 64; // bytes per inode entry\n\n// Superblock layout (64 bytes)\nexport const SUPERBLOCK = {\n SIZE: 64,\n MAGIC: 0, // uint32 - 0x56465321\n VERSION: 4, // uint32\n INODE_COUNT: 8, // uint32 - total inodes allocated\n BLOCK_SIZE: 12, // uint32 - data block size (default 4096)\n TOTAL_BLOCKS: 16, // uint32 - total data blocks\n FREE_BLOCKS: 20, // uint32 - available data blocks\n INODE_OFFSET: 24, // float64 - byte offset to inode table\n PATH_OFFSET: 32, // float64 - byte offset to path table\n DATA_OFFSET: 40, // float64 - byte offset to data region\n BITMAP_OFFSET: 48, // float64 - byte offset to free block bitmap\n PATH_USED: 56, // uint32 - bytes used in path table\n RESERVED: 60, // uint32\n} as const;\n\n// Inode entry layout (64 bytes each)\nexport const INODE = {\n TYPE: 0, // uint8 - 0=free, 1=file, 2=directory, 3=symlink\n FLAGS: 1, // uint8[3] - reserved\n PATH_OFFSET: 4, // uint32 - byte offset into path table\n PATH_LENGTH: 8, // uint16 - length of path string\n NLINK: 10, // uint16 - hard link count\n MODE: 12, // uint32 - permissions (e.g. 0o100644)\n SIZE: 16, // float64 - file content size in bytes (using f64 for >4GB)\n FIRST_BLOCK: 24, // uint32 - index of first data block\n BLOCK_COUNT: 28, // uint32 - number of contiguous data blocks\n MTIME: 32, // float64 - last modification time (ms since epoch)\n CTIME: 40, // float64 - creation/change time (ms since epoch)\n ATIME: 48, // float64 - last access time (ms since epoch)\n UID: 56, // uint32 - owner\n GID: 60, // uint32 - group\n} as const;\n\n// Inode type constants\nexport const INODE_TYPE = {\n FREE: 0,\n FILE: 1,\n DIRECTORY: 2,\n SYMLINK: 3,\n} as const;\n\n// Default file modes\nexport const DEFAULT_FILE_MODE = 0o100644;\nexport const DEFAULT_DIR_MODE = 0o040755;\nexport const DEFAULT_SYMLINK_MODE = 0o120777;\nexport const DEFAULT_UMASK = 0o022;\n\n// POSIX file type bits\nexport const S_IFMT = 0o170000;\nexport const S_IFREG = 0o100000;\nexport const S_IFDIR = 0o040000;\nexport const S_IFLNK = 0o120000;\n\n// Max symlink depth for cycle detection\nexport const MAX_SYMLINK_DEPTH = 40;\n\n// Path table compaction threshold (25% dead space)\nexport const PATH_COMPACTION_THRESHOLD = 0.25;\n\n// Initial path table size (256KB)\nexport const INITIAL_PATH_TABLE_SIZE = 256 * 1024;\n\n// Initial data blocks (1024 blocks = 4MB with 4KB blocks)\nexport const INITIAL_DATA_BLOCKS = 1024;\n\n/**\n * Calculate section offsets for a fresh VFS.\n */\nexport function calculateLayout(inodeCount: number = DEFAULT_INODE_COUNT, blockSize: number = DEFAULT_BLOCK_SIZE, totalBlocks: number = INITIAL_DATA_BLOCKS) {\n const inodeTableOffset = SUPERBLOCK.SIZE;\n const inodeTableSize = inodeCount * INODE_SIZE;\n const pathTableOffset = inodeTableOffset + inodeTableSize;\n const pathTableSize = INITIAL_PATH_TABLE_SIZE;\n const bitmapOffset = pathTableOffset + pathTableSize;\n const bitmapSize = Math.ceil(totalBlocks / 8);\n // Align data region to block boundary\n const dataOffset = Math.ceil((bitmapOffset + bitmapSize) / blockSize) * blockSize;\n const totalSize = dataOffset + totalBlocks * blockSize;\n\n return {\n inodeTableOffset,\n inodeTableSize,\n pathTableOffset,\n pathTableSize,\n bitmapOffset,\n bitmapSize,\n dataOffset,\n totalSize,\n totalBlocks,\n };\n}\n","/**\n * Node.js compatible filesystem error classes\n */\n\nexport class FSError extends Error {\n code: string;\n errno: number;\n syscall?: string;\n path?: string;\n\n constructor(code: string, errno: number, message: string, syscall?: string, path?: string) {\n super(message);\n this.name = 'FSError';\n this.code = code;\n this.errno = errno;\n this.syscall = syscall;\n this.path = path;\n }\n}\n\nexport const ErrorCodes = {\n ENOENT: -2,\n EEXIST: -17,\n EISDIR: -21,\n ENOTDIR: -20,\n ENOTEMPTY: -39,\n EACCES: -13,\n EBADF: -9,\n EINVAL: -22,\n EMFILE: -24,\n ENOSPC: -28,\n EPERM: -1,\n ENOSYS: -38,\n ELOOP: -40,\n} as const;\n\n/** Binary protocol status codes → error code mapping */\nexport const STATUS_TO_CODE: Record<number, string> = {\n 0: 'OK',\n 1: 'ENOENT',\n 2: 'EEXIST',\n 3: 'EISDIR',\n 4: 'ENOTDIR',\n 5: 'ENOTEMPTY',\n 6: 'EACCES',\n 7: 'EINVAL',\n 8: 'EBADF',\n 9: 'ELOOP',\n 10: 'ENOSPC',\n};\n\n/** Error code → binary protocol status mapping */\nexport const CODE_TO_STATUS: Record<string, number> = {\n OK: 0,\n ENOENT: 1,\n EEXIST: 2,\n EISDIR: 3,\n ENOTDIR: 4,\n ENOTEMPTY: 5,\n EACCES: 6,\n EINVAL: 7,\n EBADF: 8,\n ELOOP: 9,\n ENOSPC: 10,\n};\n\nexport function createError(code: string, syscall: string, path: string): FSError {\n const errno = ErrorCodes[code as keyof typeof ErrorCodes] ?? -1;\n const messages: Record<string, string> = {\n ENOENT: 'no such file or directory',\n EEXIST: 'file already exists',\n EISDIR: 'illegal operation on a directory',\n ENOTDIR: 'not a directory',\n ENOTEMPTY: 'directory not empty',\n EACCES: 'permission denied',\n EINVAL: 'invalid argument',\n EBADF: 'bad file descriptor',\n ELOOP: 'too many symbolic links encountered',\n ENOSPC: 'no space left on device',\n };\n const msg = messages[code] ?? 'unknown error';\n return new FSError(code, errno, `${code}: ${msg}, ${syscall} '${path}'`, syscall, path);\n}\n\nexport function statusToError(status: number, syscall: string, path: string): FSError {\n const code = STATUS_TO_CODE[status] ?? 'EINVAL';\n return createError(code, syscall, path);\n}\n","/**\n * VFS Engine — operates on a FileSystemSyncAccessHandle\n *\n * Manages the binary VFS layout: superblock, inode table, path table,\n * free block bitmap, and data region. All operations are synchronous\n * and run inside the server worker.\n */\n\nimport {\n VFS_MAGIC, VFS_VERSION, SUPERBLOCK, INODE, INODE_SIZE, INODE_TYPE,\n DEFAULT_BLOCK_SIZE, DEFAULT_INODE_COUNT, DEFAULT_FILE_MODE, DEFAULT_DIR_MODE,\n DEFAULT_SYMLINK_MODE, DEFAULT_UMASK, S_IFMT, S_IFREG, S_IFDIR, S_IFLNK,\n MAX_SYMLINK_DEPTH, INITIAL_DATA_BLOCKS, INITIAL_PATH_TABLE_SIZE,\n calculateLayout,\n} from './layout.js';\nimport { CODE_TO_STATUS } from '../errors.js';\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\ninterface Inode {\n type: number;\n pathOffset: number;\n pathLength: number;\n mode: number;\n size: number;\n firstBlock: number;\n blockCount: number;\n mtime: number;\n ctime: number;\n atime: number;\n uid: number;\n gid: number;\n nlink: number;\n}\n\ninterface FdEntry {\n tabId: string;\n inodeIdx: number;\n position: number;\n flags: number;\n implicitPath?: string; // set when fd was opened via opendir on an implicit directory\n}\n\nexport class VFSEngine {\n private handle!: FileSystemSyncAccessHandle;\n private pathIndex = new Map<string, number>(); // path → inode index\n private inodeCount = 0;\n private blockSize = DEFAULT_BLOCK_SIZE;\n private totalBlocks = 0;\n private freeBlocks = 0;\n private inodeTableOffset = 0;\n private pathTableOffset = 0;\n private pathTableUsed = 0;\n private pathTableSize = 0;\n private bitmapOffset = 0;\n private dataOffset = 0;\n private umask = DEFAULT_UMASK;\n private processUid = 0;\n private processGid = 0;\n private strictPermissions = false;\n private debug = false;\n\n // File descriptor table\n private fdTable = new Map<number, FdEntry>();\n private nextFd = 3; // 0=stdin, 1=stdout, 2=stderr reserved\n\n // Reusable buffers to avoid allocations\n private inodeBuf = new Uint8Array(INODE_SIZE);\n private inodeView = new DataView(this.inodeBuf.buffer);\n\n // In-memory inode cache — eliminates disk reads for hot inodes\n private inodeCache = new Map<number, Inode>();\n private superblockBuf = new Uint8Array(SUPERBLOCK.SIZE);\n private superblockView = new DataView(this.superblockBuf.buffer);\n\n // In-memory bitmap cache — eliminates bitmap reads from OPFS\n private bitmap: Uint8Array | null = null;\n private bitmapDirtyLo = Infinity; // lowest dirty byte index\n private bitmapDirtyHi = -1; // highest dirty byte index (inclusive)\n private superblockDirty = false;\n\n // Free inode hint — skip O(n) scan\n private freeInodeHint = 0;\n\n // Implicit directory support — tracks all directory prefixes implied by file paths.\n // Rebuilt lazily when pathIndex changes (tracked via generation counter).\n // Map value is the stable timestamp (ms since epoch) assigned when the implicit\n // dir was first discovered, so that stat() returns consistent mtime/ctime/atime\n // across repeated calls.\n private implicitDirs = new Map<string, number>();\n private implicitDirsGen = -1; // generation when implicitDirs was last rebuilt\n private pathIndexGen = 0; // bumped on every pathIndex mutation\n\n // Configurable upper bounds\n private maxInodes = 4_000_000;\n private maxBlocks = 4_000_000;\n private maxPathTable = 256 * 1024 * 1024; // 256MB\n private maxVFSSize = 100 * 1024 * 1024 * 1024; // 100GB\n\n init(\n handle: FileSystemSyncAccessHandle,\n opts?: {\n uid?: number; gid?: number; umask?: number; strictPermissions?: boolean; debug?: boolean;\n limits?: { maxInodes?: number; maxBlocks?: number; maxPathTable?: number; maxVFSSize?: number };\n }\n ): void {\n this.handle = handle;\n this.processUid = opts?.uid ?? 0;\n this.processGid = opts?.gid ?? 0;\n this.umask = opts?.umask ?? DEFAULT_UMASK;\n this.strictPermissions = opts?.strictPermissions ?? false;\n this.debug = opts?.debug ?? false;\n if (opts?.limits) {\n if (opts.limits.maxInodes != null) this.maxInodes = opts.limits.maxInodes;\n if (opts.limits.maxBlocks != null) this.maxBlocks = opts.limits.maxBlocks;\n if (opts.limits.maxPathTable != null) this.maxPathTable = opts.limits.maxPathTable;\n if (opts.limits.maxVFSSize != null) this.maxVFSSize = opts.limits.maxVFSSize;\n }\n\n const size = handle.getSize();\n\n if (size === 0) {\n this.format();\n } else {\n try {\n this.mount();\n } catch (err) {\n // Ensure all mount errors are prefixed with \"Corrupt VFS:\" so the\n // sync-relay handler recognizes them as corruption (not OPFS contention)\n // and triggers fallback instead of infinite retry.\n const msg = (err as Error).message ?? String(err);\n if (msg.startsWith('Corrupt VFS:')) throw err;\n throw new Error(`Corrupt VFS: ${msg}`);\n }\n }\n }\n\n /** Release the sync access handle (call on fatal error or shutdown) */\n closeHandle(): void {\n try {\n this.handle?.close();\n } catch (_) {\n // Ignore — handle may already be closed\n }\n }\n\n /** Format a fresh VFS */\n private format(): void {\n const layout = calculateLayout(DEFAULT_INODE_COUNT, DEFAULT_BLOCK_SIZE, INITIAL_DATA_BLOCKS);\n\n this.inodeCount = DEFAULT_INODE_COUNT;\n this.blockSize = DEFAULT_BLOCK_SIZE;\n this.totalBlocks = layout.totalBlocks;\n this.freeBlocks = layout.totalBlocks;\n this.inodeTableOffset = layout.inodeTableOffset;\n this.pathTableOffset = layout.pathTableOffset;\n this.pathTableSize = layout.pathTableSize;\n this.pathTableUsed = 0;\n this.bitmapOffset = layout.bitmapOffset;\n this.dataOffset = layout.dataOffset;\n\n // Grow file to total size\n this.handle.truncate(layout.totalSize);\n\n // Write superblock\n this.writeSuperblock();\n\n // Zero out inode table (type=0 means free)\n const zeroBuf = new Uint8Array(layout.inodeTableSize);\n this.handle.write(zeroBuf, { at: this.inodeTableOffset });\n\n // Zero out bitmap and cache in memory\n this.bitmap = new Uint8Array(layout.bitmapSize);\n this.handle.write(this.bitmap, { at: this.bitmapOffset });\n\n // Create root directory inode\n this.createInode('/', INODE_TYPE.DIRECTORY, DEFAULT_DIR_MODE, 0);\n\n // Re-write superblock with updated pathTableUsed (createInode appended \"/\" to path table)\n this.writeSuperblock();\n this.handle.flush();\n }\n\n /** Mount an existing VFS from disk — validates superblock integrity */\n private mount(): void {\n const fileSize = this.handle.getSize();\n if (fileSize < SUPERBLOCK.SIZE) {\n throw new Error(`Corrupt VFS: file too small (${fileSize} bytes, need at least ${SUPERBLOCK.SIZE})`);\n }\n\n this.handle.read(this.superblockBuf, { at: 0 });\n const v = this.superblockView;\n\n // Validate magic\n const magic = v.getUint32(SUPERBLOCK.MAGIC, true);\n if (magic !== VFS_MAGIC) {\n throw new Error(`Corrupt VFS: bad magic 0x${magic.toString(16)} (expected 0x${VFS_MAGIC.toString(16)})`);\n }\n\n // Validate version\n const version = v.getUint32(SUPERBLOCK.VERSION, true);\n if (version !== VFS_VERSION) {\n throw new Error(`Corrupt VFS: unsupported version ${version} (expected ${VFS_VERSION})`);\n }\n\n // Read superblock fields\n const inodeCount = v.getUint32(SUPERBLOCK.INODE_COUNT, true);\n const blockSize = v.getUint32(SUPERBLOCK.BLOCK_SIZE, true);\n const totalBlocks = v.getUint32(SUPERBLOCK.TOTAL_BLOCKS, true);\n const freeBlocks = v.getUint32(SUPERBLOCK.FREE_BLOCKS, true);\n const inodeTableOffset = v.getFloat64(SUPERBLOCK.INODE_OFFSET, true);\n const pathTableOffset = v.getFloat64(SUPERBLOCK.PATH_OFFSET, true);\n const dataOffset = v.getFloat64(SUPERBLOCK.DATA_OFFSET, true);\n const bitmapOffset = v.getFloat64(SUPERBLOCK.BITMAP_OFFSET, true);\n const pathUsed = v.getUint32(SUPERBLOCK.PATH_USED, true);\n\n // Validate field sanity\n if (blockSize === 0 || (blockSize & (blockSize - 1)) !== 0) {\n throw new Error(`Corrupt VFS: invalid block size ${blockSize} (must be power of 2)`);\n }\n if (inodeCount === 0) {\n throw new Error('Corrupt VFS: inode count is 0');\n }\n if (freeBlocks > totalBlocks) {\n throw new Error(`Corrupt VFS: free blocks (${freeBlocks}) exceeds total blocks (${totalBlocks})`);\n }\n\n // Sane upper bounds — prevent huge allocations from corrupt values.\n // Configurable via opts.limits in init().\n if (inodeCount > this.maxInodes) {\n throw new Error(`Corrupt VFS: inode count ${inodeCount} exceeds maximum ${this.maxInodes}`);\n }\n if (totalBlocks > this.maxBlocks) {\n throw new Error(`Corrupt VFS: total blocks ${totalBlocks} exceeds maximum ${this.maxBlocks}`);\n }\n if (fileSize > this.maxVFSSize) {\n throw new Error(`Corrupt VFS: file size ${fileSize} exceeds maximum ${this.maxVFSSize}`);\n }\n\n // Validate all offsets are finite positive integers\n if (!Number.isFinite(inodeTableOffset) || inodeTableOffset < 0 ||\n !Number.isFinite(pathTableOffset) || pathTableOffset < 0 ||\n !Number.isFinite(bitmapOffset) || bitmapOffset < 0 ||\n !Number.isFinite(dataOffset) || dataOffset < 0) {\n throw new Error(`Corrupt VFS: non-finite or negative section offset`);\n }\n\n // Validate section ordering: superblock < inodes < paths < bitmap < data\n if (inodeTableOffset !== SUPERBLOCK.SIZE) {\n throw new Error(`Corrupt VFS: inode table offset ${inodeTableOffset} (expected ${SUPERBLOCK.SIZE})`);\n }\n const expectedPathOffset = inodeTableOffset + inodeCount * INODE_SIZE;\n if (pathTableOffset !== expectedPathOffset) {\n throw new Error(`Corrupt VFS: path table offset ${pathTableOffset} (expected ${expectedPathOffset})`);\n }\n if (bitmapOffset <= pathTableOffset) {\n throw new Error(`Corrupt VFS: bitmap offset ${bitmapOffset} must be after path table ${pathTableOffset}`);\n }\n if (dataOffset <= bitmapOffset) {\n throw new Error(`Corrupt VFS: data offset ${dataOffset} must be after bitmap ${bitmapOffset}`);\n }\n const pathTableSize = bitmapOffset - pathTableOffset;\n if (pathUsed > pathTableSize) {\n throw new Error(`Corrupt VFS: path used (${pathUsed}) exceeds path table size (${pathTableSize})`);\n }\n if (pathTableSize > this.maxPathTable) {\n throw new Error(`Corrupt VFS: path table size ${pathTableSize} exceeds maximum ${this.maxPathTable}`);\n }\n\n // Validate file is large enough for the declared layout\n const expectedMinSize = dataOffset + totalBlocks * blockSize;\n if (expectedMinSize > this.maxVFSSize) {\n throw new Error(`Corrupt VFS: computed layout size ${expectedMinSize} exceeds maximum ${this.maxVFSSize}`);\n }\n if (fileSize < expectedMinSize) {\n throw new Error(`Corrupt VFS: file size ${fileSize} too small for layout (need ${expectedMinSize})`);\n }\n\n // All checks passed — commit to engine state\n this.inodeCount = inodeCount;\n this.blockSize = blockSize;\n this.totalBlocks = totalBlocks;\n this.freeBlocks = freeBlocks;\n this.inodeTableOffset = inodeTableOffset;\n this.pathTableOffset = pathTableOffset;\n this.dataOffset = dataOffset;\n this.bitmapOffset = bitmapOffset;\n this.pathTableUsed = pathUsed;\n this.pathTableSize = pathTableSize;\n\n // Load bitmap into memory\n const bitmapSize = Math.ceil(this.totalBlocks / 8);\n this.bitmap = new Uint8Array(bitmapSize);\n this.handle.read(this.bitmap, { at: this.bitmapOffset });\n\n this.rebuildIndex();\n\n // Verify root directory exists\n if (!this.pathIndex.has('/')) {\n throw new Error('Corrupt VFS: root directory \"/\" not found in inode table');\n }\n }\n\n private writeSuperblock(): void {\n const v = this.superblockView;\n v.setUint32(SUPERBLOCK.MAGIC, VFS_MAGIC, true);\n v.setUint32(SUPERBLOCK.VERSION, VFS_VERSION, true);\n v.setUint32(SUPERBLOCK.INODE_COUNT, this.inodeCount, true);\n v.setUint32(SUPERBLOCK.BLOCK_SIZE, this.blockSize, true);\n v.setUint32(SUPERBLOCK.TOTAL_BLOCKS, this.totalBlocks, true);\n v.setUint32(SUPERBLOCK.FREE_BLOCKS, this.freeBlocks, true);\n v.setFloat64(SUPERBLOCK.INODE_OFFSET, this.inodeTableOffset, true);\n v.setFloat64(SUPERBLOCK.PATH_OFFSET, this.pathTableOffset, true);\n v.setFloat64(SUPERBLOCK.DATA_OFFSET, this.dataOffset, true);\n v.setFloat64(SUPERBLOCK.BITMAP_OFFSET, this.bitmapOffset, true);\n v.setUint32(SUPERBLOCK.PATH_USED, this.pathTableUsed, true);\n this.handle.write(this.superblockBuf, { at: 0 });\n }\n\n /** Flush pending bitmap and superblock writes to disk (one write each) */\n private markBitmapDirty(lo: number, hi: number): void {\n if (lo < this.bitmapDirtyLo) this.bitmapDirtyLo = lo;\n if (hi > this.bitmapDirtyHi) this.bitmapDirtyHi = hi;\n }\n\n private commitPending(): void {\n // Trim trailing free blocks before flushing bitmap/superblock\n if (this.blocksFreedsinceTrim) {\n this.trimTrailingBlocks();\n this.blocksFreedsinceTrim = false;\n }\n\n if (this.bitmapDirtyHi >= 0) {\n const lo = this.bitmapDirtyLo;\n const hi = this.bitmapDirtyHi;\n this.handle.write(this.bitmap!.subarray(lo, hi + 1), { at: this.bitmapOffset + lo });\n this.bitmapDirtyLo = Infinity;\n this.bitmapDirtyHi = -1;\n }\n if (this.superblockDirty) {\n this.writeSuperblock();\n this.superblockDirty = false;\n }\n }\n\n /** Shrink the OPFS file by removing trailing free blocks from the data region.\n * Scans bitmap from end to find the last used block, then truncates. */\n private trimTrailingBlocks(): void {\n const bitmap = this.bitmap!;\n\n // Find the last used block by scanning bitmap from the end\n let lastUsed = -1;\n for (let byteIdx = Math.ceil(this.totalBlocks / 8) - 1; byteIdx >= 0; byteIdx--) {\n if (bitmap[byteIdx] !== 0) {\n // Find highest set bit in this byte\n for (let bit = 7; bit >= 0; bit--) {\n const blockIdx = byteIdx * 8 + bit;\n if (blockIdx < this.totalBlocks && (bitmap[byteIdx] & (1 << bit))) {\n lastUsed = blockIdx;\n break;\n }\n }\n break;\n }\n }\n\n const newTotal = Math.max(lastUsed + 1, INITIAL_DATA_BLOCKS);\n if (newTotal >= this.totalBlocks) return; // nothing to trim\n\n // Truncate the OPFS file\n this.handle.truncate(this.dataOffset + newTotal * this.blockSize);\n\n // Shrink in-memory bitmap\n const newBitmapSize = Math.ceil(newTotal / 8);\n this.bitmap = bitmap.slice(0, newBitmapSize);\n\n // Update counters\n const trimmed = this.totalBlocks - newTotal;\n this.freeBlocks -= trimmed; // these free blocks no longer exist\n this.totalBlocks = newTotal;\n this.superblockDirty = true;\n\n // Re-mark entire bitmap dirty so the smaller bitmap is flushed\n this.bitmapDirtyLo = 0;\n this.bitmapDirtyHi = newBitmapSize - 1;\n }\n\n /** Rebuild in-memory path→inode index from disk.\n * Bulk-reads the entire inode table + path table in 2 I/O calls,\n * then parses in memory (avoids 10k+ individual reads). */\n private rebuildIndex(): void {\n this.pathIndex.clear();\n this.inodeCache.clear();\n\n // Bulk read entire inode table (e.g. 640KB for 10k inodes)\n const inodeTableSize = this.inodeCount * INODE_SIZE;\n const inodeBuf = new Uint8Array(inodeTableSize);\n this.handle.read(inodeBuf, { at: this.inodeTableOffset });\n const inodeView = new DataView(inodeBuf.buffer);\n\n // Bulk read used portion of path table\n const pathBuf = this.pathTableUsed > 0 ? new Uint8Array(this.pathTableUsed) : null;\n if (pathBuf) {\n this.handle.read(pathBuf, { at: this.pathTableOffset });\n }\n\n for (let i = 0; i < this.inodeCount; i++) {\n const off = i * INODE_SIZE;\n const type = inodeView.getUint8(off + INODE.TYPE);\n if (type === INODE_TYPE.FREE) continue;\n\n // Validate inode type\n if (type < INODE_TYPE.FILE || type > INODE_TYPE.SYMLINK) {\n throw new Error(`Corrupt VFS: inode ${i} has invalid type ${type}`);\n }\n\n const pathOffset = inodeView.getUint32(off + INODE.PATH_OFFSET, true);\n const pathLength = inodeView.getUint16(off + INODE.PATH_LENGTH, true);\n const size = inodeView.getFloat64(off + INODE.SIZE, true);\n const firstBlock = inodeView.getUint32(off + INODE.FIRST_BLOCK, true);\n const blockCount = inodeView.getUint32(off + INODE.BLOCK_COUNT, true);\n\n // Validate path bounds\n if (pathLength === 0 || pathOffset + pathLength > this.pathTableUsed) {\n throw new Error(`Corrupt VFS: inode ${i} path out of bounds (offset=${pathOffset}, len=${pathLength}, tableUsed=${this.pathTableUsed})`);\n }\n\n // Validate data bounds for files/symlinks\n if (type !== INODE_TYPE.DIRECTORY) {\n if (size < 0 || !isFinite(size)) {\n throw new Error(`Corrupt VFS: inode ${i} has invalid size ${size}`);\n }\n if (blockCount > 0 && firstBlock + blockCount > this.totalBlocks) {\n throw new Error(`Corrupt VFS: inode ${i} data blocks out of range (first=${firstBlock}, count=${blockCount}, total=${this.totalBlocks})`);\n }\n }\n\n const inode: Inode = {\n type,\n pathOffset,\n pathLength,\n nlink: inodeView.getUint16(off + INODE.NLINK, true) || 1,\n mode: inodeView.getUint32(off + INODE.MODE, true),\n size,\n firstBlock,\n blockCount,\n mtime: inodeView.getFloat64(off + INODE.MTIME, true),\n ctime: inodeView.getFloat64(off + INODE.CTIME, true),\n atime: inodeView.getFloat64(off + INODE.ATIME, true),\n uid: inodeView.getUint32(off + INODE.UID, true),\n gid: inodeView.getUint32(off + INODE.GID, true),\n };\n this.inodeCache.set(i, inode);\n\n // Decode path from in-memory path table buffer (no disk read)\n let path: string;\n if (pathBuf) {\n path = decoder.decode(pathBuf.subarray(inode.pathOffset, inode.pathOffset + inode.pathLength));\n } else {\n path = this.readPath(inode.pathOffset, inode.pathLength);\n }\n\n // Validate path format\n if (!path.startsWith('/') || path.includes('\\0')) {\n throw new Error(`Corrupt VFS: inode ${i} has invalid path \"${path.substring(0, 50)}\"`);\n }\n\n this.pathIndex.set(path, i);\n }\n this.pathIndexGen++;\n }\n\n // ========== Low-level inode I/O ==========\n\n private readInode(idx: number): Inode {\n const cached = this.inodeCache.get(idx);\n if (cached) return cached;\n\n const offset = this.inodeTableOffset + idx * INODE_SIZE;\n this.handle.read(this.inodeBuf, { at: offset });\n const v = this.inodeView;\n const inode: Inode = {\n type: v.getUint8(INODE.TYPE),\n pathOffset: v.getUint32(INODE.PATH_OFFSET, true),\n pathLength: v.getUint16(INODE.PATH_LENGTH, true),\n nlink: v.getUint16(INODE.NLINK, true) || 1,\n mode: v.getUint32(INODE.MODE, true),\n size: v.getFloat64(INODE.SIZE, true),\n firstBlock: v.getUint32(INODE.FIRST_BLOCK, true),\n blockCount: v.getUint32(INODE.BLOCK_COUNT, true),\n mtime: v.getFloat64(INODE.MTIME, true),\n ctime: v.getFloat64(INODE.CTIME, true),\n atime: v.getFloat64(INODE.ATIME, true),\n uid: v.getUint32(INODE.UID, true),\n gid: v.getUint32(INODE.GID, true),\n };\n this.inodeCache.set(idx, inode);\n return inode;\n }\n\n private writeInode(idx: number, inode: Inode): void {\n // Maintain inode cache\n if (inode.type === INODE_TYPE.FREE) {\n this.inodeCache.delete(idx);\n } else {\n this.inodeCache.set(idx, inode);\n }\n\n const v = this.inodeView;\n v.setUint8(INODE.TYPE, inode.type);\n v.setUint8(INODE.FLAGS, 0);\n v.setUint8(INODE.FLAGS + 1, 0);\n v.setUint8(INODE.FLAGS + 2, 0);\n v.setUint32(INODE.PATH_OFFSET, inode.pathOffset, true);\n v.setUint16(INODE.PATH_LENGTH, inode.pathLength, true);\n v.setUint16(INODE.NLINK, inode.nlink, true);\n v.setUint32(INODE.MODE, inode.mode, true);\n v.setFloat64(INODE.SIZE, inode.size, true);\n v.setUint32(INODE.FIRST_BLOCK, inode.firstBlock, true);\n v.setUint32(INODE.BLOCK_COUNT, inode.blockCount, true);\n v.setFloat64(INODE.MTIME, inode.mtime, true);\n v.setFloat64(INODE.CTIME, inode.ctime, true);\n v.setFloat64(INODE.ATIME, inode.atime, true);\n v.setUint32(INODE.UID, inode.uid, true);\n v.setUint32(INODE.GID, inode.gid, true);\n\n const offset = this.inodeTableOffset + idx * INODE_SIZE;\n this.handle.write(this.inodeBuf, { at: offset });\n }\n\n // ========== Path table I/O ==========\n\n private readPath(offset: number, length: number): string {\n const buf = new Uint8Array(length);\n this.handle.read(buf, { at: this.pathTableOffset + offset });\n return decoder.decode(buf);\n }\n\n private appendPath(path: string): { offset: number; length: number } {\n const bytes = encoder.encode(path);\n const offset = this.pathTableUsed;\n\n // Check if path table needs to grow\n if (offset + bytes.byteLength > this.pathTableSize) {\n this.growPathTable(offset + bytes.byteLength);\n }\n\n this.handle.write(bytes, { at: this.pathTableOffset + offset });\n this.pathTableUsed += bytes.byteLength;\n\n // Defer superblock write — committed in commitPending()\n this.superblockDirty = true;\n\n return { offset, length: bytes.byteLength };\n }\n\n private growPathTable(needed: number): void {\n // Double the path table or grow to fit needed, whichever is larger\n const newSize = Math.max(this.pathTableSize * 2, needed + INITIAL_PATH_TABLE_SIZE);\n const growth = newSize - this.pathTableSize;\n\n // Grow file first so the shifted data has somewhere to land.\n const newTotalSize = this.handle.getSize() + growth;\n this.handle.truncate(newTotalSize);\n\n // Shift the data region forward by `growth` bytes. We must NOT allocate\n // a single buffer the size of the whole data section — when the VFS\n // holds a large install (pnpm linking ~1300 Directus packages puts the\n // data section in the hundreds of MB) the one-shot\n // new Uint8Array(dataSize)\n // failed with \"Array buffer allocation failed\" because Chrome refuses\n // allocations near the 2 GB cap even with OS memory to spare.\n //\n // Copy back-to-front through a small scratch buffer so we never\n // overwrite bytes we haven't relocated yet, and the peak allocation\n // stays bounded at CHUNK regardless of how big the VFS has grown.\n const dataSize = this.totalBlocks * this.blockSize;\n const CHUNK = 4 * 1024 * 1024; // 4 MB\n const scratch = new Uint8Array(Math.min(CHUNK, Math.max(dataSize, 1)));\n let remaining = dataSize;\n while (remaining > 0) {\n const chunk = Math.min(remaining, CHUNK);\n const srcAt = this.dataOffset + (remaining - chunk);\n const dstAt = this.dataOffset + growth + (remaining - chunk);\n const slice = chunk < scratch.length ? scratch.subarray(0, chunk) : scratch;\n this.handle.read(slice, { at: srcAt });\n this.handle.write(slice, { at: dstAt });\n remaining -= chunk;\n }\n\n // Write the (in-memory) bitmap to its new offset.\n const newBitmapOffset = this.bitmapOffset + growth;\n const newDataOffset = this.dataOffset + growth;\n this.handle.write(this.bitmap!, { at: newBitmapOffset });\n\n // Update offsets\n this.pathTableSize = newSize;\n this.bitmapOffset = newBitmapOffset;\n this.dataOffset = newDataOffset;\n\n // Mark superblock dirty (will be written in commitPending)\n this.superblockDirty = true;\n }\n\n // ========== Bitmap I/O ==========\n\n // Write `length` zero bytes at absolute file offset `at` via a small\n // reusable scratch buffer. Used to materialize POSIX \"holes\" when a\n // write starts past the current file size — those bytes must read as\n // zeros rather than whatever stale data happened to live in the\n // underlying storage blocks.\n private zeroFileRange(at: number, length: number): void {\n if (length <= 0) return;\n const CHUNK = 4 * 1024 * 1024;\n const zeros = new Uint8Array(Math.min(length, CHUNK));\n let written = 0;\n while (written < length) {\n const n = Math.min(CHUNK, length - written);\n const slice = n < zeros.length ? zeros.subarray(0, n) : zeros;\n this.handle.write(slice, { at: at + written });\n written += n;\n }\n }\n\n private allocateBlocks(count: number): number {\n if (count === 0) return 0;\n\n const bitmap = this.bitmap!;\n let run = 0;\n let start = 0;\n\n for (let i = 0; i < this.totalBlocks; i++) {\n const byteIdx = i >>> 3;\n const bitIdx = i & 7;\n const used = (bitmap[byteIdx] >>> bitIdx) & 1;\n\n if (used) {\n run = 0;\n start = i + 1;\n } else {\n run++;\n if (run === count) {\n // Mark blocks as used in memory\n for (let j = start; j <= i; j++) {\n const bj = j >>> 3;\n const bi = j & 7;\n bitmap[bj] |= (1 << bi);\n }\n this.markBitmapDirty(start >>> 3, i >>> 3);\n this.freeBlocks -= count;\n this.superblockDirty = true;\n return start;\n }\n }\n }\n\n // No contiguous space — grow data region\n return this.growAndAllocate(count);\n }\n\n private growAndAllocate(count: number): number {\n const oldTotal = this.totalBlocks;\n // Grow by at least doubling or enough for the request\n const newTotal = Math.max(oldTotal * 2, oldTotal + count);\n const addedBlocks = newTotal - oldTotal;\n\n // Grow the file\n const newFileSize = this.dataOffset + newTotal * this.blockSize;\n this.handle.truncate(newFileSize);\n\n // Grow in-memory bitmap\n const newBitmapSize = Math.ceil(newTotal / 8);\n const newBitmap = new Uint8Array(newBitmapSize);\n newBitmap.set(this.bitmap!);\n this.bitmap = newBitmap;\n\n this.totalBlocks = newTotal;\n this.freeBlocks += addedBlocks;\n\n // Allocate from the newly freed area\n const start = oldTotal;\n for (let j = start; j < start + count; j++) {\n const bj = j >>> 3;\n const bi = j & 7;\n this.bitmap[bj] |= (1 << bi);\n }\n\n this.markBitmapDirty(start >>> 3, (start + count - 1) >>> 3);\n this.freeBlocks -= count;\n this.superblockDirty = true;\n\n return start;\n }\n\n private blocksFreedsinceTrim = false;\n\n private freeBlockRange(start: number, count: number): void {\n if (count === 0) return;\n const bitmap = this.bitmap!;\n\n for (let i = start; i < start + count; i++) {\n const byteIdx = i >>> 3;\n const bitIdx = i & 7;\n bitmap[byteIdx] &= ~(1 << bitIdx);\n }\n\n this.markBitmapDirty(start >>> 3, (start + count - 1) >>> 3);\n this.freeBlocks += count;\n this.superblockDirty = true;\n this.blocksFreedsinceTrim = true;\n }\n\n // updateSuperblockFreeBlocks is no longer needed — superblock writes are coalesced via commitPending()\n\n // ========== Inode allocation ==========\n\n private findFreeInode(): number {\n // Start from hint to skip already-used entries\n for (let i = this.freeInodeHint; i < this.inodeCount; i++) {\n // Check cache first — cached entries are never FREE\n if (this.inodeCache.has(i)) continue;\n\n const offset = this.inodeTableOffset + i * INODE_SIZE;\n const typeBuf = new Uint8Array(1);\n this.handle.read(typeBuf, { at: offset });\n if (typeBuf[0] === INODE_TYPE.FREE) {\n this.freeInodeHint = i + 1;\n return i;\n }\n }\n // All inodes used — grow inode table\n const idx = this.growInodeTable();\n this.freeInodeHint = idx + 1;\n return idx;\n }\n\n private growInodeTable(): number {\n const oldCount = this.inodeCount;\n const newCount = oldCount * 2;\n const growth = (newCount - oldCount) * INODE_SIZE;\n\n // Read everything after inode table\n const afterInodeOffset = this.inodeTableOffset + oldCount * INODE_SIZE;\n const afterSize = this.handle.getSize() - afterInodeOffset;\n const afterBuf = new Uint8Array(afterSize);\n this.handle.read(afterBuf, { at: afterInodeOffset });\n\n // Grow file\n this.handle.truncate(this.handle.getSize() + growth);\n\n // Write back shifted content\n this.handle.write(afterBuf, { at: afterInodeOffset + growth });\n\n // Zero out new inode entries\n const zeroes = new Uint8Array(growth);\n this.handle.write(zeroes, { at: afterInodeOffset });\n\n // Update offsets\n this.pathTableOffset += growth;\n this.bitmapOffset += growth;\n this.dataOffset += growth;\n this.inodeCount = newCount;\n\n this.superblockDirty = true;\n\n return oldCount; // First new free inode\n }\n\n // ========== Data I/O ==========\n\n private readData(firstBlock: number, blockCount: number, size: number): Uint8Array {\n const buf = new Uint8Array(size);\n const offset = this.dataOffset + firstBlock * this.blockSize;\n this.handle.read(buf, { at: offset });\n return buf;\n }\n\n private writeData(firstBlock: number, data: Uint8Array): void {\n const offset = this.dataOffset + firstBlock * this.blockSize;\n this.handle.write(data, { at: offset });\n }\n\n // ========== Path resolution ==========\n\n private resolvePath(path: string, depth: number = 0): number | undefined {\n if (depth > MAX_SYMLINK_DEPTH) return undefined; // ELOOP\n\n const idx = this.pathIndex.get(path);\n if (idx === undefined) {\n // Path not found directly — try component resolution (handles intermediate symlinks)\n return this.resolvePathComponents(path, true, depth);\n }\n\n const inode = this.readInode(idx);\n if (inode.type === INODE_TYPE.SYMLINK) {\n // Follow symlink\n const target = decoder.decode(this.readData(inode.firstBlock, inode.blockCount, inode.size));\n const resolved = target.startsWith('/') ? target : this.resolveRelative(path, target);\n return this.resolvePath(resolved, depth + 1);\n }\n\n return idx;\n }\n\n /** Resolve symlinks in intermediate path components */\n private resolvePathComponents(path: string, followLast: boolean = true, depth: number = 0): number | undefined {\n const result = this.resolvePathFull(path, followLast, depth);\n return result?.idx;\n }\n\n /**\n * Resolve a path following symlinks, returning both the inode index AND the\n * fully resolved path. This is needed by readdir: when listing a symlinked\n * directory, we must search for children under the resolved target path\n * (where files actually exist in pathIndex), not under the symlink path.\n */\n private resolvePathFull(path: string, followLast: boolean = true, depth: number = 0): { idx: number; resolvedPath: string } | undefined {\n if (depth > MAX_SYMLINK_DEPTH) return undefined; // ELOOP\n\n const parts = path.split('/').filter(Boolean);\n let current = '/';\n\n for (let i = 0; i < parts.length; i++) {\n const isLast = i === parts.length - 1;\n current = current === '/' ? '/' + parts[i] : current + '/' + parts[i];\n\n const idx = this.pathIndex.get(current);\n if (idx === undefined) return undefined;\n\n const inode = this.readInode(idx);\n if (inode.type === INODE_TYPE.SYMLINK && (!isLast || followLast)) {\n const target = decoder.decode(this.readData(inode.firstBlock, inode.blockCount, inode.size));\n const resolved = target.startsWith('/') ? target : this.resolveRelative(current, target);\n\n if (isLast) {\n // Use resolvePathFull (not resolvePath) so intermediate symlinks\n // in the resolved target path are also followed\n return this.resolvePathFull(resolved, true, depth + 1);\n }\n\n // Reconstruct remaining path with resolved symlink\n const remaining = parts.slice(i + 1).join('/');\n const newPath = resolved + (remaining ? '/' + remaining : '');\n return this.resolvePathFull(newPath, followLast, depth + 1);\n }\n }\n\n const finalIdx = this.pathIndex.get(current);\n if (finalIdx === undefined) return undefined;\n return { idx: finalIdx, resolvedPath: current };\n }\n\n private resolveRelative(from: string, target: string): string {\n const dir = from.substring(0, from.lastIndexOf('/')) || '/';\n const parts = (dir + '/' + target).split('/').filter(Boolean);\n const resolved: string[] = [];\n for (const p of parts) {\n if (p === '.') continue;\n if (p === '..') { resolved.pop(); continue; }\n resolved.push(p);\n }\n return '/' + resolved.join('/');\n }\n\n // ========== Core inode creation helper ==========\n\n private createInode(path: string, type: number, mode: number, size: number, data?: Uint8Array): number {\n const idx = this.findFreeInode();\n const { offset: pathOff, length: pathLen } = this.appendPath(path);\n const now = Date.now();\n\n let firstBlock = 0;\n let blockCount = 0;\n\n if (data && data.byteLength > 0) {\n blockCount = Math.ceil(data.byteLength / this.blockSize);\n firstBlock = this.allocateBlocks(blockCount);\n this.writeData(firstBlock, data);\n }\n\n const inode: Inode = {\n type,\n pathOffset: pathOff,\n pathLength: pathLen,\n nlink: type === INODE_TYPE.DIRECTORY ? 2 : 1,\n mode,\n size,\n firstBlock,\n blockCount,\n mtime: now,\n ctime: now,\n atime: now,\n uid: this.processUid,\n gid: this.processGid,\n };\n\n this.writeInode(idx, inode);\n this.pathIndex.set(path, idx);\n this.pathIndexGen++;\n\n return idx;\n }\n\n // ========== Public API — called by server worker dispatch ==========\n\n /** Normalize a path: ensure leading /, resolve . and .. */\n normalizePath(p: string): string {\n if (p.charCodeAt(0) !== 47) p = '/' + p; // 47 = '/'\n // Fast path: already normalized (no '.', '..', '//', trailing '/')\n if (p.length === 1) return p; // \"/\"\n if (p.indexOf('/.') === -1 && p.indexOf('//') === -1 && p.charCodeAt(p.length - 1) !== 47) {\n return p;\n }\n // Slow path: full normalize\n const parts = p.split('/').filter(Boolean);\n const resolved: string[] = [];\n for (const part of parts) {\n if (part === '.') continue;\n if (part === '..') { resolved.pop(); continue; }\n resolved.push(part);\n }\n return '/' + resolved.join('/');\n }\n\n // ---- READ ----\n read(path: string): { status: number; data: Uint8Array | null } {\n const t0 = this.debug ? performance.now() : 0;\n path = this.normalizePath(path);\n\n // Fast path: direct index lookup (skips component-by-component walk)\n let idx = this.pathIndex.get(path);\n if (idx !== undefined) {\n const inode = this.inodeCache.get(idx);\n if (inode) {\n // Symlink? Fall through to full resolve\n if (inode.type === INODE_TYPE.SYMLINK) {\n idx = this.resolvePathComponents(path, true);\n } else if (inode.type === INODE_TYPE.DIRECTORY) {\n return { status: CODE_TO_STATUS.EISDIR, data: null };\n } else {\n // Hot path: cached inode, no symlinks\n const data = inode.size > 0\n ? this.readData(inode.firstBlock, inode.blockCount, inode.size)\n : new Uint8Array(0);\n if (this.debug) {\n const t1 = performance.now();\n console.log(`[VFS read] path=${path} size=${inode.size} TOTAL=${(t1-t0).toFixed(3)}ms (fast)`);\n }\n return { status: 0, data };\n }\n }\n }\n\n // Slow path: full component resolution (handles symlinks, uncached inodes)\n if (idx === undefined) idx = this.resolvePathComponents(path, true);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT, data: null };\n\n const inode = this.readInode(idx);\n if (inode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EISDIR, data: null };\n\n const data = inode.size > 0\n ? this.readData(inode.firstBlock, inode.blockCount, inode.size)\n : new Uint8Array(0);\n\n if (this.debug) {\n const t1 = performance.now();\n console.log(`[VFS read] path=${path} size=${inode.size} TOTAL=${(t1-t0).toFixed(3)}ms (slow path)`);\n }\n\n return { status: 0, data };\n }\n\n // ---- WRITE ----\n write(path: string, data: Uint8Array, flags: number = 0): { status: number } {\n const t0 = this.debug ? performance.now() : 0;\n path = this.normalizePath(path);\n const t1 = this.debug ? performance.now() : 0;\n\n // Ensure parent directory exists\n const parentStatus = this.ensureParent(path);\n if (parentStatus !== 0) return { status: parentStatus };\n const t2 = this.debug ? performance.now() : 0;\n\n const existingIdx = this.resolvePathComponents(path, true);\n const t3 = this.debug ? performance.now() : 0;\n\n let tAlloc = t3, tData = t3, tInode = t3;\n\n if (existingIdx !== undefined) {\n // Update existing file\n const inode = this.readInode(existingIdx);\n if (inode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EISDIR };\n\n const neededBlocks = Math.ceil(data.byteLength / this.blockSize);\n\n if (neededBlocks <= inode.blockCount) {\n // Fits in current blocks\n tAlloc = this.debug ? performance.now() : 0;\n this.writeData(inode.firstBlock, data);\n tData = this.debug ? performance.now() : 0;\n if (neededBlocks < inode.blockCount) {\n this.freeBlockRange(inode.firstBlock + neededBlocks, inode.blockCount - neededBlocks);\n }\n } else {\n // Need more blocks — free old, allocate new\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n const newFirst = this.allocateBlocks(neededBlocks);\n tAlloc = this.debug ? performance.now() : 0;\n this.writeData(newFirst, data);\n tData = this.debug ? performance.now() : 0;\n inode.firstBlock = newFirst;\n }\n\n inode.size = data.byteLength;\n inode.blockCount = neededBlocks;\n inode.mtime = Date.now();\n this.writeInode(existingIdx, inode);\n tInode = this.debug ? performance.now() : 0;\n } else {\n // Refuse to create a regular file at a path that is an implicit\n // directory (children exist beneath it but no inode for the path\n // itself). Without this guard we'd register a FILE inode at `path`\n // while its descendants stay in pathIndex — the resulting \"file with\n // children\" state breaks every subsequent read of `path` and its\n // subtree.\n if (this.isImplicitDirectory(path)) return { status: CODE_TO_STATUS.EISDIR };\n // Create new file\n const mode = DEFAULT_FILE_MODE & ~(this.umask & 0o777);\n this.createInode(path, INODE_TYPE.FILE, mode, data.byteLength, data);\n tAlloc = this.debug ? performance.now() : 0;\n tData = tAlloc;\n tInode = tAlloc;\n }\n\n // Always commit pending superblock/bitmap changes (matches unlink, mkdir, etc.)\n // Without this, PATH_USED won't be persisted for newly created files,\n // causing \"path out of bounds\" corruption on reload.\n this.commitPending();\n if (flags & 1) {\n this.handle.flush();\n }\n const tFlush = this.debug ? performance.now() : 0;\n\n if (this.debug) {\n const existing = existingIdx !== undefined;\n console.log(`[VFS write] path=${path} size=${data.byteLength} ${existing ? 'UPDATE' : 'CREATE'} normalize=${(t1-t0).toFixed(3)}ms parent=${(t2-t1).toFixed(3)}ms resolve=${(t3-t2).toFixed(3)}ms alloc=${(tAlloc-t3).toFixed(3)}ms data=${(tData-tAlloc).toFixed(3)}ms inode=${(tInode-tData).toFixed(3)}ms flush=${(tFlush-tInode).toFixed(3)}ms TOTAL=${(tFlush-t0).toFixed(3)}ms`);\n }\n\n return { status: 0 };\n }\n\n // ---- APPEND ----\n append(path: string, data: Uint8Array): { status: number } {\n path = this.normalizePath(path);\n const existingIdx = this.resolvePathComponents(path, true);\n\n if (existingIdx === undefined) {\n // Create new file with the data\n return this.write(path, data);\n }\n\n const inode = this.readInode(existingIdx);\n if (inode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EISDIR };\n\n // Avoid materializing the whole (existing + data) file in a single\n // Uint8Array — that blew up with \"Array buffer allocation failed\" on\n // large appends (e.g. appending a few MB to a multi-hundred-MB file).\n //\n // Strategy: allocate a new block run sized to the total, copy the\n // existing contents over in bounded chunks, then write the caller's\n // `data` at the end. Peak allocation stays at 4 MB regardless of\n // file size.\n const combinedSize = inode.size + data.byteLength;\n const neededBlocks = Math.ceil(combinedSize / this.blockSize);\n const newFirst = this.allocateBlocks(neededBlocks);\n const newBase = this.dataOffset + newFirst * this.blockSize;\n if (inode.size > 0) {\n const oldBase = this.dataOffset + inode.firstBlock * this.blockSize;\n const CHUNK = 4 * 1024 * 1024; // 4 MB\n const scratch = new Uint8Array(Math.min(CHUNK, inode.size));\n let copied = 0;\n while (copied < inode.size) {\n const n = Math.min(CHUNK, inode.size - copied);\n const slice = n < scratch.length ? scratch.subarray(0, n) : scratch;\n this.handle.read(slice, { at: oldBase + copied });\n this.handle.write(slice, { at: newBase + copied });\n copied += n;\n }\n }\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n this.handle.write(data, { at: newBase + inode.size });\n\n inode.firstBlock = newFirst;\n inode.blockCount = neededBlocks;\n inode.size = combinedSize;\n inode.mtime = Date.now();\n this.writeInode(existingIdx, inode);\n\n this.commitPending();\n return { status: 0 };\n }\n\n // ---- UNLINK ----\n unlink(path: string): { status: number } {\n path = this.normalizePath(path);\n const idx = this.pathIndex.get(path);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n const inode = this.readInode(idx);\n if (inode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EISDIR };\n\n // Decrement nlink; only free data when it reaches 0\n inode.nlink = Math.max(0, inode.nlink - 1);\n\n // Free data blocks\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n\n // Mark inode as free\n inode.type = INODE_TYPE.FREE;\n this.writeInode(idx, inode);\n\n // Remove from index\n this.pathIndex.delete(path);\n this.pathIndexGen++;\n // Reset free inode hint\n if (idx < this.freeInodeHint) this.freeInodeHint = idx;\n\n this.commitPending();\n return { status: 0 };\n }\n\n // ---- STAT ----\n stat(path: string): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) {\n // Check for implicit directory (exists because files exist under it)\n if (this.isImplicitDirectory(path)) {\n return this.encodeImplicitDirStatResponse(path);\n }\n return { status: CODE_TO_STATUS.ENOENT, data: null };\n }\n\n return this.encodeStatResponse(idx);\n }\n\n // ---- LSTAT (no symlink follow for the FINAL component) ----\n lstat(path: string): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n // Use resolvePathComponents with followLast=false — follows intermediate\n // symlinks but returns the symlink inode itself for the last component.\n // Direct pathIndex.get(path) fails for paths through symlinked directories\n // because children are stored under the symlink target path in pathIndex.\n let idx = this.resolvePathComponents(path, false);\n if (idx === undefined) {\n // Fallback: followLast=false can fail for paths through symlink chains\n // when pathIndex stores files under their resolved (real) path.\n // Try with followLast=true — if it resolves, use the result regardless\n // of whether the final component is a symlink or not. lstat on an\n // existing symlink should return the symlink's own stats, not ENOENT.\n idx = this.resolvePathComponents(path, true);\n if (idx === undefined) {\n // Check for implicit directory\n if (this.isImplicitDirectory(path)) {\n return this.encodeImplicitDirStatResponse(path);\n }\n return { status: CODE_TO_STATUS.ENOENT, data: null };\n }\n }\n\n return this.encodeStatResponse(idx);\n }\n\n private encodeStatResponse(idx: number): { status: number; data: Uint8Array } {\n const inode = this.readInode(idx);\n\n // Compute nlink for directories: 2 + number of child subdirectories\n // (including implicit subdirectories so nlink stays consistent with\n // what readdir reports).\n let nlink = inode.nlink;\n if (inode.type === INODE_TYPE.DIRECTORY) {\n const path = this.readPath(inode.pathOffset, inode.pathLength);\n const children = this.getDirectChildrenWithImplicit(path);\n let subdirCount = 0;\n for (const child of children) {\n if (child.type === 'implicit') {\n subdirCount++;\n } else {\n const childIdx = this.pathIndex.get(child.path);\n if (childIdx !== undefined) {\n const childInode = this.readInode(childIdx);\n if (childInode.type === INODE_TYPE.DIRECTORY) subdirCount++;\n }\n }\n }\n nlink = 2 + subdirCount;\n }\n\n // Encode stat into binary: type(1) + mode(4) + size(8) + mtime(8) + ctime(8) + atime(8) + uid(4) + gid(4) + ino(4) + nlink(4) = 53 bytes\n const buf = new Uint8Array(53);\n const view = new DataView(buf.buffer);\n view.setUint8(0, inode.type);\n view.setUint32(1, inode.mode, true);\n view.setFloat64(5, inode.size, true);\n view.setFloat64(13, inode.mtime, true);\n view.setFloat64(21, inode.ctime, true);\n view.setFloat64(29, inode.atime, true);\n view.setUint32(37, inode.uid, true);\n view.setUint32(41, inode.gid, true);\n view.setUint32(45, idx, true); // ino = inode index\n view.setUint32(49, nlink, true);\n\n return { status: 0, data: buf };\n }\n\n // ---- MKDIR ----\n mkdir(path: string, flags: number = 0): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n const recursive = (flags & 1) !== 0;\n\n if (recursive) {\n return this.mkdirRecursive(path);\n }\n\n // Check if already exists (explicit or implicit)\n if (this.pathIndex.has(path) || this.isImplicitDirectory(path)) {\n return { status: CODE_TO_STATUS.EEXIST, data: null };\n }\n\n // Ensure parent exists\n const parentStatus = this.ensureParent(path);\n if (parentStatus !== 0) return { status: parentStatus, data: null };\n\n const mode = DEFAULT_DIR_MODE & ~(this.umask & 0o777);\n this.createInode(path, INODE_TYPE.DIRECTORY, mode, 0);\n\n this.commitPending();\n // Non-recursive mkdir returns undefined (null data) per Node.js spec\n return { status: 0, data: null };\n }\n\n private mkdirRecursive(path: string): { status: number; data: Uint8Array | null } {\n const parts = path.split('/').filter(Boolean);\n let current = '';\n let firstCreated: string | null = null;\n\n for (const part of parts) {\n current += '/' + part;\n\n if (this.pathIndex.has(current)) {\n const idx = this.pathIndex.get(current)!;\n const inode = this.readInode(idx);\n if (inode.type !== INODE_TYPE.DIRECTORY) {\n return { status: CODE_TO_STATUS.ENOTDIR, data: null };\n }\n continue;\n }\n\n const mode = DEFAULT_DIR_MODE & ~(this.umask & 0o777);\n this.createInode(current, INODE_TYPE.DIRECTORY, mode, 0);\n if (!firstCreated) firstCreated = current;\n }\n\n this.commitPending();\n const result = firstCreated ? encoder.encode(firstCreated) : undefined;\n return { status: 0, data: result ?? null };\n }\n\n // ---- RMDIR ----\n rmdir(path: string, flags: number = 0): { status: number } {\n path = this.normalizePath(path);\n const recursive = (flags & 1) !== 0;\n const idx = this.pathIndex.get(path);\n if (idx === undefined) {\n // Check for implicit directory — a dir that exists because files\n // exist under it but no explicit inode was created.\n if (this.isImplicitDirectory(path)) {\n const children = this.getDirectChildrenWithImplicit(path);\n if (children.length > 0) {\n if (!recursive) return { status: CODE_TO_STATUS.ENOTEMPTY };\n // Recursive: delete all real descendants; the implicit dir\n // disappears automatically when its children are gone.\n for (const desc of this.getAllDescendants(path)) {\n const descIdx = this.pathIndex.get(desc)!;\n const descInode = this.readInode(descIdx);\n this.freeBlockRange(descInode.firstBlock, descInode.blockCount);\n descInode.type = INODE_TYPE.FREE;\n this.writeInode(descIdx, descInode);\n this.pathIndex.delete(desc);\n }\n this.pathIndexGen++;\n this.commitPending();\n }\n // Empty implicit dir or just-emptied: no-op — it vanishes on its own.\n return { status: 0 };\n }\n return { status: CODE_TO_STATUS.ENOENT };\n }\n\n const inode = this.readInode(idx);\n if (inode.type !== INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.ENOTDIR };\n\n // Check for children\n const children = this.getDirectChildren(path);\n\n if (children.length > 0) {\n if (!recursive) return { status: CODE_TO_STATUS.ENOTEMPTY };\n\n // Recursive delete\n for (const child of this.getAllDescendants(path)) {\n const childIdx = this.pathIndex.get(child)!;\n const childInode = this.readInode(childIdx);\n this.freeBlockRange(childInode.firstBlock, childInode.blockCount);\n childInode.type = INODE_TYPE.FREE;\n this.writeInode(childIdx, childInode);\n this.pathIndex.delete(child);\n }\n }\n\n // Remove the directory itself\n inode.type = INODE_TYPE.FREE;\n this.writeInode(idx, inode);\n this.pathIndex.delete(path);\n this.pathIndexGen++;\n if (idx < this.freeInodeHint) this.freeInodeHint = idx;\n\n this.commitPending();\n return { status: 0 };\n }\n\n // ---- READDIR ----\n readdir(path: string, flags: number = 0): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n const resolved = this.resolvePathFull(path, true);\n\n // Determine the effective directory path for child lookup\n let effectiveDirPath: string;\n\n if (resolved) {\n const inode = this.readInode(resolved.idx);\n if (inode.type !== INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.ENOTDIR, data: null };\n // Use the resolved path for child lookup — when path is a symlink,\n // the actual children are stored under the target path in pathIndex.\n effectiveDirPath = resolved.resolvedPath;\n } else if (this.isImplicitDirectory(path)) {\n effectiveDirPath = path;\n } else {\n return { status: CODE_TO_STATUS.ENOENT, data: null };\n }\n\n const withFileTypes = (flags & 1) !== 0;\n // Use getDirectChildrenWithImplicit to discover both real and implicit children\n const children = this.getDirectChildrenWithImplicit(effectiveDirPath);\n\n if (withFileTypes) {\n // Encode as: count(u32) + entries[name_len(u16) + name(bytes) + type(u8)]\n let totalSize = 4;\n const entries: { name: Uint8Array; type: number }[] = [];\n\n for (const child of children) {\n const name = child.path.substring(child.path.lastIndexOf('/') + 1);\n const nameBytes = encoder.encode(name);\n let type: number;\n if (child.type === 'implicit') {\n type = INODE_TYPE.DIRECTORY;\n } else {\n const childIdx = this.pathIndex.get(child.path)!;\n const childInode = this.readInode(childIdx);\n type = childInode.type;\n }\n entries.push({ name: nameBytes, type });\n totalSize += 2 + nameBytes.byteLength + 1; // nameLen + name + type\n }\n\n const buf = new Uint8Array(totalSize);\n const view = new DataView(buf.buffer);\n view.setUint32(0, entries.length, true);\n let offset = 4;\n\n for (const entry of entries) {\n view.setUint16(offset, entry.name.byteLength, true);\n offset += 2;\n buf.set(entry.name, offset);\n offset += entry.name.byteLength;\n buf[offset++] = entry.type;\n }\n\n return { status: 0, data: buf };\n }\n\n // Simple name list: count(u32) + entries[name_len(u16) + name(bytes)]\n let totalSize = 4;\n const nameEntries: Uint8Array[] = [];\n\n for (const child of children) {\n const name = child.path.substring(child.path.lastIndexOf('/') + 1);\n const nameBytes = encoder.encode(name);\n nameEntries.push(nameBytes);\n totalSize += 2 + nameBytes.byteLength;\n }\n\n const buf = new Uint8Array(totalSize);\n const view = new DataView(buf.buffer);\n view.setUint32(0, nameEntries.length, true);\n let offset = 4;\n\n for (const nameBytes of nameEntries) {\n view.setUint16(offset, nameBytes.byteLength, true);\n offset += 2;\n buf.set(nameBytes, offset);\n offset += nameBytes.byteLength;\n }\n\n return { status: 0, data: buf };\n }\n\n // ---- RENAME ----\n rename(oldPath: string, newPath: string): { status: number } {\n oldPath = this.normalizePath(oldPath);\n newPath = this.normalizePath(newPath);\n\n const idx = this.pathIndex.get(oldPath);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n // Same path → no-op (matches Node.js semantics)\n if (oldPath === newPath) return { status: 0 };\n\n // Ensure parent of new path exists\n const parentStatus = this.ensureParent(newPath);\n if (parentStatus !== 0) return { status: parentStatus };\n\n // If target exists, remove it. For directory targets we MUST recursively\n // free every descendant inode and drop every descendant pathIndex entry —\n // otherwise the source's children get added on top, leaving a mix of\n // source children + leftover target children pointing at zombie inodes\n // (the target's old children still appear in pathIndex, while their\n // inodes are not freed so blocks are leaked too).\n //\n // Concrete consequence of the old behavior: Vite's deps optimization\n // commit (`.vite/deps_temp_<hash>` → `.vite/deps`) on the second run\n // returned success but produced a corrupt deps directory — subsequent\n // requests for `vue.js`, `@unhead/vue`, etc. resolved to stale chunks\n // from the previous round (or 404'd entirely).\n //\n // The target may also be an *implicit* directory (no inode of its own,\n // but children exist under it — the state produced by bulk OPFS import).\n // In that case there's no inode to free, but the descendants must still\n // be cleaned up for the same reason.\n const existingIdx = this.pathIndex.get(newPath);\n const targetIsImplicitDir =\n existingIdx === undefined && this.isImplicitDirectory(newPath);\n\n if (existingIdx !== undefined || targetIsImplicitDir) {\n let cleanDescendants = targetIsImplicitDir;\n\n if (existingIdx !== undefined) {\n const existingInode = this.readInode(existingIdx);\n cleanDescendants = existingInode.type === INODE_TYPE.DIRECTORY;\n this.freeBlockRange(existingInode.firstBlock, existingInode.blockCount);\n existingInode.type = INODE_TYPE.FREE;\n this.writeInode(existingIdx, existingInode);\n this.pathIndex.delete(newPath);\n if (existingIdx < this.freeInodeHint) this.freeInodeHint = existingIdx;\n }\n\n if (cleanDescendants) {\n // Free every descendant inode and remove its pathIndex entry.\n // Use getAllDescendants for the deepest-first ordering (matches\n // rmdir's recursive path) — though for a flat free pass order\n // doesn't affect correctness here.\n for (const desc of this.getAllDescendants(newPath)) {\n const descIdx = this.pathIndex.get(desc)!;\n const descInode = this.readInode(descIdx);\n this.freeBlockRange(descInode.firstBlock, descInode.blockCount);\n descInode.type = INODE_TYPE.FREE;\n this.writeInode(descIdx, descInode);\n this.pathIndex.delete(desc);\n if (descIdx < this.freeInodeHint) this.freeInodeHint = descIdx;\n }\n }\n }\n\n // Update inode with new path\n const inode = this.readInode(idx);\n const { offset: pathOff, length: pathLen } = this.appendPath(newPath);\n inode.pathOffset = pathOff;\n inode.pathLength = pathLen;\n inode.mtime = Date.now();\n this.writeInode(idx, inode);\n\n // Update index\n this.pathIndex.delete(oldPath);\n this.pathIndex.set(newPath, idx);\n this.pathIndexGen++;\n\n // If it's a directory, rename all descendants\n if (inode.type === INODE_TYPE.DIRECTORY) {\n const prefix = oldPath === '/' ? '/' : oldPath + '/';\n const toRename: [string, number][] = [];\n\n for (const [p, i] of this.pathIndex) {\n if (p.startsWith(prefix)) {\n toRename.push([p, i]);\n }\n }\n\n for (const [p, i] of toRename) {\n const suffix = p.substring(oldPath.length);\n const childNewPath = newPath + suffix;\n const childInode = this.readInode(i);\n const { offset: cpo, length: cpl } = this.appendPath(childNewPath);\n childInode.pathOffset = cpo;\n childInode.pathLength = cpl;\n this.writeInode(i, childInode);\n this.pathIndex.delete(p);\n this.pathIndex.set(childNewPath, i);\n }\n }\n\n this.commitPending();\n return { status: 0 };\n }\n\n // ---- EXISTS ----\n exists(path: string): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n const buf = new Uint8Array(1);\n buf[0] = (idx !== undefined || this.isImplicitDirectory(path)) ? 1 : 0;\n return { status: 0, data: buf };\n }\n\n // ---- TRUNCATE ----\n truncate(path: string, len: number = 0): { status: number } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n const inode = this.readInode(idx);\n if (inode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EISDIR };\n\n if (len === 0) {\n // Free all blocks\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n inode.firstBlock = 0;\n inode.blockCount = 0;\n inode.size = 0;\n } else if (len < inode.size) {\n // Shrink\n const neededBlocks = Math.ceil(len / this.blockSize);\n if (neededBlocks < inode.blockCount) {\n this.freeBlockRange(inode.firstBlock + neededBlocks, inode.blockCount - neededBlocks);\n }\n inode.blockCount = neededBlocks;\n inode.size = len;\n } else if (len > inode.size) {\n // Grow with POSIX zero-fill semantics. Old code staged the entire\n // new file as a single `new Uint8Array(len)` — OOMs for large\n // truncates and allocates way more than necessary. Instead, copy\n // old contents in bounded chunks and zero-fill the extension\n // directly on disk.\n const neededBlocks = Math.ceil(len / this.blockSize);\n if (neededBlocks > inode.blockCount) {\n // Allocate-then-copy-then-free so the old range is guaranteed\n // not to overlap the new one. See `fwrite` for the same pattern.\n const newFirst = this.allocateBlocks(neededBlocks);\n const newBase = this.dataOffset + newFirst * this.blockSize;\n if (inode.size > 0) {\n const oldBase = this.dataOffset + inode.firstBlock * this.blockSize;\n const CHUNK = 4 * 1024 * 1024; // 4 MB\n const scratch = new Uint8Array(Math.min(CHUNK, inode.size));\n let copied = 0;\n while (copied < inode.size) {\n const n = Math.min(CHUNK, inode.size - copied);\n const slice = n < scratch.length ? scratch.subarray(0, n) : scratch;\n this.handle.read(slice, { at: oldBase + copied });\n this.handle.write(slice, { at: newBase + copied });\n copied += n;\n }\n }\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n this.zeroFileRange(newBase + inode.size, len - inode.size);\n inode.firstBlock = newFirst;\n } else {\n // Same block count, just growing `size`. The tail of the last\n // existing block still contains whatever stale data was there\n // before — zero it so the extended region reads as zeros.\n this.zeroFileRange(\n this.dataOffset + inode.firstBlock * this.blockSize + inode.size,\n len - inode.size,\n );\n }\n inode.blockCount = neededBlocks;\n inode.size = len;\n }\n\n inode.mtime = Date.now();\n this.writeInode(idx, inode);\n\n this.commitPending();\n return { status: 0 };\n }\n\n // ---- COPY ----\n copy(srcPath: string, destPath: string, flags: number = 0): { status: number } {\n srcPath = this.normalizePath(srcPath);\n destPath = this.normalizePath(destPath);\n\n const srcIdx = this.resolvePathComponents(srcPath, true);\n if (srcIdx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n const srcInode = this.readInode(srcIdx);\n if (srcInode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EISDIR };\n\n // COPYFILE_EXCL check\n if ((flags & 1) && (this.pathIndex.has(destPath) || this.isImplicitDirectory(destPath))) {\n return { status: CODE_TO_STATUS.EEXIST };\n }\n\n // Self-copy — no-op.\n if (srcPath === destPath) return { status: 0 };\n\n const srcSize = srcInode.size;\n const srcFirstBlock = srcInode.firstBlock;\n\n // Stage 1: create the destination as an empty file. This goes through\n // the normal `write` path which handles parent-directory creation,\n // freeing any pre-existing blocks at `destPath`, and registering the\n // inode in `pathIndex`. Doing this first also means any side effects\n // (e.g. a `growPathTable` shift of the data region) happen BEFORE we\n // start allocating destination blocks, so the relative block indices\n // we capture below stay valid.\n const emptyStatus = this.write(destPath, new Uint8Array(0));\n if (emptyStatus.status !== 0) return emptyStatus;\n\n if (srcSize === 0) return { status: 0 };\n\n // Stage 2: allocate a destination block run sized to the source, then\n // copy the bytes directly between block ranges via the file handle in\n // bounded chunks. No full-file buffer is ever allocated — peak scratch\n // stays at 4 MB regardless of how big the source file is.\n const destIdx = this.resolvePathComponents(destPath, true);\n if (destIdx === undefined) return { status: CODE_TO_STATUS.EIO };\n const destInode = this.readInode(destIdx);\n\n const neededBlocks = Math.ceil(srcSize / this.blockSize);\n const newFirst = this.allocateBlocks(neededBlocks);\n const newBase = this.dataOffset + newFirst * this.blockSize;\n const srcBase = this.dataOffset + srcFirstBlock * this.blockSize;\n\n const CHUNK = 4 * 1024 * 1024; // 4 MB\n const scratch = new Uint8Array(Math.min(CHUNK, srcSize));\n let copied = 0;\n while (copied < srcSize) {\n const n = Math.min(CHUNK, srcSize - copied);\n const slice = n < scratch.length ? scratch.subarray(0, n) : scratch;\n this.handle.read(slice, { at: srcBase + copied });\n this.handle.write(slice, { at: newBase + copied });\n copied += n;\n }\n\n destInode.firstBlock = newFirst;\n destInode.blockCount = neededBlocks;\n destInode.size = srcSize;\n destInode.mtime = Date.now();\n this.writeInode(destIdx, destInode);\n this.commitPending();\n return { status: 0 };\n }\n\n // ---- ACCESS ----\n access(path: string, mode: number = 0): { status: number } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) {\n // Check for implicit directory\n if (this.isImplicitDirectory(path)) return { status: 0 };\n return { status: CODE_TO_STATUS.ENOENT };\n }\n\n if (mode === 0) return { status: 0 }; // F_OK — just check existence\n\n if (!this.strictPermissions) return { status: 0 }; // Relaxed mode\n\n const inode = this.readInode(idx);\n // Check permission bits against process identity\n const filePerm = this.getEffectivePermission(inode);\n\n if ((mode & 4) && !(filePerm & 4)) return { status: CODE_TO_STATUS.EACCES }; // R_OK\n if ((mode & 2) && !(filePerm & 2)) return { status: CODE_TO_STATUS.EACCES }; // W_OK\n if ((mode & 1) && !(filePerm & 1)) return { status: CODE_TO_STATUS.EACCES }; // X_OK\n\n return { status: 0 };\n }\n\n private getEffectivePermission(inode: Inode): number {\n const modeBits = inode.mode & 0o777;\n if (this.processUid === inode.uid) return (modeBits >>> 6) & 7;\n if (this.processGid === inode.gid) return (modeBits >>> 3) & 7;\n return modeBits & 7;\n }\n\n // ---- REALPATH ----\n realpath(path: string): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) {\n // Check for implicit directory\n if (this.isImplicitDirectory(path)) {\n return { status: 0, data: encoder.encode(path) };\n }\n return { status: CODE_TO_STATUS.ENOENT, data: null };\n }\n\n // Find the resolved path for this inode\n const inode = this.readInode(idx);\n const resolvedPath = this.readPath(inode.pathOffset, inode.pathLength);\n return { status: 0, data: encoder.encode(resolvedPath) };\n }\n\n // ---- CHMOD ----\n chmod(path: string, mode: number): { status: number } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n const inode = this.readInode(idx);\n // Preserve file type bits, update permission bits\n inode.mode = (inode.mode & S_IFMT) | (mode & 0o7777);\n inode.ctime = Date.now();\n this.writeInode(idx, inode);\n\n return { status: 0 };\n }\n\n // ---- CHOWN ----\n chown(path: string, uid: number, gid: number): { status: number } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n const inode = this.readInode(idx);\n inode.uid = uid;\n inode.gid = gid;\n inode.ctime = Date.now();\n this.writeInode(idx, inode);\n\n return { status: 0 };\n }\n\n // ---- UTIMES ----\n utimes(path: string, atime: number, mtime: number): { status: number } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n const inode = this.readInode(idx);\n inode.atime = atime;\n inode.mtime = mtime;\n inode.ctime = Date.now();\n this.writeInode(idx, inode);\n\n return { status: 0 };\n }\n\n // ---- SYMLINK ----\n symlink(target: string, linkPath: string): { status: number } {\n linkPath = this.normalizePath(linkPath);\n if (this.pathIndex.has(linkPath) || this.isImplicitDirectory(linkPath)) {\n return { status: CODE_TO_STATUS.EEXIST };\n }\n\n const parentStatus = this.ensureParent(linkPath);\n if (parentStatus !== 0) return { status: parentStatus };\n\n const targetBytes = encoder.encode(target);\n this.createInode(linkPath, INODE_TYPE.SYMLINK, DEFAULT_SYMLINK_MODE, targetBytes.byteLength, targetBytes);\n\n this.commitPending();\n return { status: 0 };\n }\n\n // ---- READLINK ----\n readlink(path: string): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n const idx = this.pathIndex.get(path);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT, data: null };\n\n const inode = this.readInode(idx);\n if (inode.type !== INODE_TYPE.SYMLINK) return { status: CODE_TO_STATUS.EINVAL, data: null };\n\n const target = this.readData(inode.firstBlock, inode.blockCount, inode.size);\n return { status: 0, data: target };\n }\n\n // ---- LINK (hard link — copies the file data, tracks nlink) ----\n link(existingPath: string, newPath: string): { status: number } {\n existingPath = this.normalizePath(existingPath);\n newPath = this.normalizePath(newPath);\n\n const srcIdx = this.resolvePathComponents(existingPath, true);\n if (srcIdx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n const srcInode = this.readInode(srcIdx);\n if (srcInode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EPERM };\n\n if (this.pathIndex.has(newPath) || this.isImplicitDirectory(newPath)) {\n return { status: CODE_TO_STATUS.EEXIST };\n }\n\n // Copy file data to new inode\n const result = this.copy(existingPath, newPath);\n if (result.status !== 0) return result;\n\n // Increment nlink on source\n srcInode.nlink++;\n this.writeInode(srcIdx, srcInode);\n\n // Set nlink on destination to match source\n const destIdx = this.pathIndex.get(newPath);\n if (destIdx !== undefined) {\n const destInode = this.readInode(destIdx);\n destInode.nlink = srcInode.nlink;\n this.writeInode(destIdx, destInode);\n }\n\n return { status: 0 };\n }\n\n // ---- OPEN (file descriptor) ----\n open(path: string, flags: number, tabId: string): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n\n const hasCreate = (flags & 64) !== 0; // O_CREAT\n const hasTrunc = (flags & 512) !== 0; // O_TRUNC\n const hasExcl = (flags & 128) !== 0; // O_EXCL\n\n let idx = this.resolvePathComponents(path, true);\n\n if (idx === undefined) {\n if (!hasCreate) return { status: CODE_TO_STATUS.ENOENT, data: null };\n // Create file\n const mode = DEFAULT_FILE_MODE & ~(this.umask & 0o777);\n idx = this.createInode(path, INODE_TYPE.FILE, mode, 0);\n } else if (hasExcl && hasCreate) {\n return { status: CODE_TO_STATUS.EEXIST, data: null };\n }\n\n if (hasTrunc) {\n this.truncate(path, 0);\n }\n\n const fd = this.nextFd++;\n this.fdTable.set(fd, { tabId, inodeIdx: idx, position: 0, flags });\n\n const buf = new Uint8Array(4);\n new DataView(buf.buffer).setUint32(0, fd, true);\n return { status: 0, data: buf };\n }\n\n // ---- CLOSE ----\n close(fd: number): { status: number } {\n if (!this.fdTable.has(fd)) return { status: CODE_TO_STATUS.EBADF };\n this.fdTable.delete(fd);\n return { status: 0 };\n }\n\n // ---- FREAD ----\n fread(fd: number, length: number, position: number | null): { status: number; data: Uint8Array | null } {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: CODE_TO_STATUS.EBADF, data: null };\n\n const inode = this.readInode(entry.inodeIdx);\n const pos = position ?? entry.position;\n const readLen = Math.min(length, inode.size - pos);\n\n if (readLen <= 0) return { status: 0, data: new Uint8Array(0) };\n\n // Read from specific offset within the file's data blocks\n const dataOffset = this.dataOffset + inode.firstBlock * this.blockSize + pos;\n const buf = new Uint8Array(readLen);\n this.handle.read(buf, { at: dataOffset });\n\n // Update position\n if (position === null) {\n entry.position += readLen;\n }\n\n return { status: 0, data: buf };\n }\n\n // ---- FWRITE ----\n fwrite(fd: number, data: Uint8Array, position: number | null): { status: number; data: Uint8Array | null } {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: CODE_TO_STATUS.EBADF, data: null };\n\n const inode = this.readInode(entry.inodeIdx);\n const isAppend = (entry.flags & 1024) !== 0; // O_APPEND\n const pos = isAppend ? inode.size : (position ?? entry.position);\n const endPos = pos + data.byteLength;\n\n // Check if we need to grow\n if (endPos > inode.size) {\n const neededBlocks = Math.ceil(endPos / this.blockSize);\n if (neededBlocks > inode.blockCount) {\n // Grow by relocating to a larger block run. We used to stage the\n // entire new file contents in a single `new Uint8Array(endPos)`\n // and then call `writeData` once — that blew up with\n // \"Array buffer allocation failed\" on multi-hundred-MB writes\n // because Chrome refuses contiguous allocations near ~2 GB even\n // with plenty of OS RAM. Instead, allocate new blocks, copy the\n // old contents forward in chunks via the underlying file handle\n // (which is O(N) bytes but with a bounded scratch buffer), then\n // free the old blocks and write just the caller's `data` at its\n // offset inside the new region.\n const newFirst = this.allocateBlocks(neededBlocks);\n const newBase = this.dataOffset + newFirst * this.blockSize;\n const oldBase = this.dataOffset + inode.firstBlock * this.blockSize;\n // Copy oldData from old block run to new block run in chunks.\n if (inode.size > 0) {\n const CHUNK = 4 * 1024 * 1024; // 4 MB\n const scratch = new Uint8Array(Math.min(CHUNK, inode.size));\n let copied = 0;\n while (copied < inode.size) {\n const n = Math.min(CHUNK, inode.size - copied);\n const slice = n < scratch.length ? scratch.subarray(0, n) : scratch;\n this.handle.read(slice, { at: oldBase + copied });\n this.handle.write(slice, { at: newBase + copied });\n copied += n;\n }\n }\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n // POSIX \"hole\" — if the caller is writing past the current EOF\n // with a gap in between, those bytes must read back as zeros\n // rather than whatever stale data lives in the freshly allocated\n // blocks. `allocateBlocks` only flips bitmap bits, it never\n // zeroes the underlying storage.\n if (pos > inode.size) {\n this.zeroFileRange(newBase + inode.size, pos - inode.size);\n }\n // Write the caller's new data at its offset inside the new region.\n this.handle.write(data, { at: newBase + pos });\n inode.firstBlock = newFirst;\n inode.blockCount = neededBlocks;\n } else {\n // Fits within existing blocks. Same hole semantics as above —\n // stale bytes in the tail of the last allocated block (past the\n // old file size) must be zeroed before the caller's write lands.\n if (pos > inode.size) {\n this.zeroFileRange(\n this.dataOffset + inode.firstBlock * this.blockSize + inode.size,\n pos - inode.size,\n );\n }\n const dataOffset = this.dataOffset + inode.firstBlock * this.blockSize + pos;\n this.handle.write(data, { at: dataOffset });\n }\n inode.size = endPos;\n } else {\n // Write within existing bounds\n const dataOffset = this.dataOffset + inode.firstBlock * this.blockSize + pos;\n this.handle.write(data, { at: dataOffset });\n }\n\n inode.mtime = Date.now();\n this.writeInode(entry.inodeIdx, inode);\n\n // Update position\n if (position === null) {\n entry.position = endPos;\n }\n\n this.commitPending();\n const buf = new Uint8Array(4);\n new DataView(buf.buffer).setUint32(0, data.byteLength, true);\n return { status: 0, data: buf };\n }\n\n // ---- FSTAT ----\n fstat(fd: number): { status: number; data: Uint8Array | null } {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: CODE_TO_STATUS.EBADF, data: null };\n if (entry.implicitPath) return this.encodeImplicitDirStatResponse(entry.implicitPath);\n return this.encodeStatResponse(entry.inodeIdx);\n }\n\n // ---- FTRUNCATE ----\n ftruncate(fd: number, len: number = 0): { status: number } {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: CODE_TO_STATUS.EBADF };\n\n const inode = this.readInode(entry.inodeIdx);\n const path = this.readPath(inode.pathOffset, inode.pathLength);\n return this.truncate(path, len);\n }\n\n // ---- FSYNC ----\n fsync(): { status: number } {\n this.commitPending();\n this.handle.flush();\n return { status: 0 };\n }\n\n // ---- FCHMOD ----\n // fd-based chmod: look up the inode directly from the fd table and mutate\n // its mode bits. Native Node does the same thing at the libuv layer.\n fchmod(fd: number, mode: number): { status: number } {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: CODE_TO_STATUS.EBADF };\n if (entry.implicitPath) return { status: 0 }; // no-op for implicit dirs\n const inode = this.readInode(entry.inodeIdx);\n inode.mode = (inode.mode & S_IFMT) | (mode & 0o7777);\n inode.ctime = Date.now();\n this.writeInode(entry.inodeIdx, inode);\n return { status: 0 };\n }\n\n // ---- FCHOWN ----\n fchown(fd: number, uid: number, gid: number): { status: number } {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: CODE_TO_STATUS.EBADF };\n if (entry.implicitPath) return { status: 0 }; // no-op for implicit dirs\n const inode = this.readInode(entry.inodeIdx);\n inode.uid = uid;\n inode.gid = gid;\n inode.ctime = Date.now();\n this.writeInode(entry.inodeIdx, inode);\n return { status: 0 };\n }\n\n // ---- FUTIMES ----\n futimes(fd: number, atime: number, mtime: number): { status: number } {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: CODE_TO_STATUS.EBADF };\n if (entry.implicitPath) return { status: 0 }; // no-op for implicit dirs\n const inode = this.readInode(entry.inodeIdx);\n inode.atime = atime;\n inode.mtime = mtime;\n inode.ctime = Date.now();\n this.writeInode(entry.inodeIdx, inode);\n return { status: 0 };\n }\n\n // ---- OPENDIR ----\n opendir(path: string, tabId: string): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) {\n // Check for implicit directory\n if (this.isImplicitDirectory(path)) {\n // Create fd with synthetic inode index -1 and the path stored so\n // fd-based operations (fstat, fchmod, etc.) can handle it.\n const fd = this.nextFd++;\n this.fdTable.set(fd, { tabId, inodeIdx: -1, position: 0, flags: 0, implicitPath: path });\n const buf = new Uint8Array(4);\n new DataView(buf.buffer).setUint32(0, fd, true);\n return { status: 0, data: buf };\n }\n return { status: CODE_TO_STATUS.ENOENT, data: null };\n }\n\n const inode = this.readInode(idx);\n if (inode.type !== INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.ENOTDIR, data: null };\n\n // Use fd table for dir handles too\n const fd = this.nextFd++;\n this.fdTable.set(fd, { tabId, inodeIdx: idx, position: 0, flags: 0 });\n\n const buf = new Uint8Array(4);\n new DataView(buf.buffer).setUint32(0, fd, true);\n return { status: 0, data: buf };\n }\n\n // ---- MKDTEMP ----\n mkdtemp(prefix: string): { status: number; data: Uint8Array | null } {\n const suffix = Math.random().toString(36).substring(2, 8);\n const path = this.normalizePath(prefix + suffix);\n\n // Ensure parent directories exist\n const parentStatus = this.ensureParent(path);\n if (parentStatus !== 0) {\n // Auto-create parent directories for mkdtemp\n const parentPath = path.substring(0, path.lastIndexOf('/'));\n if (parentPath) {\n this.mkdirRecursive(parentPath);\n }\n }\n\n const mode = DEFAULT_DIR_MODE & ~(this.umask & 0o777);\n this.createInode(path, INODE_TYPE.DIRECTORY, mode, 0);\n\n this.commitPending();\n return { status: 0, data: encoder.encode(path) };\n }\n\n // ========== Helpers ==========\n\n private getDirectChildren(dirPath: string): string[] {\n const prefix = dirPath === '/' ? '/' : dirPath + '/';\n const children: string[] = [];\n\n for (const path of this.pathIndex.keys()) {\n if (path === dirPath) continue;\n if (!path.startsWith(prefix)) continue;\n // Direct child: no more slashes after prefix\n const rest = path.substring(prefix.length);\n if (!rest.includes('/')) {\n children.push(path);\n }\n }\n\n return children.sort();\n }\n\n /**\n * Rebuild the set of all implicit directory paths.\n * An implicit directory is any ancestor path of a file/symlink in pathIndex\n * that doesn't itself have an explicit inode entry.\n * Only rebuilt when pathIndex has changed (tracked via generation counter).\n */\n private rebuildImplicitDirs(): void {\n if (this.implicitDirsGen === this.pathIndexGen) return;\n\n const now = Date.now();\n const prev = this.implicitDirs;\n this.implicitDirs = new Map<string, number>();\n for (const filePath of this.pathIndex.keys()) {\n // Walk up from each path, adding all ancestor dirs that aren't explicit\n let pos = filePath.length;\n while (true) {\n pos = filePath.lastIndexOf('/', pos - 1);\n if (pos <= 0) break; // reached root\n const ancestor = filePath.substring(0, pos);\n if (this.implicitDirs.has(ancestor)) break; // already tracked all ancestors from here up\n if (!this.pathIndex.has(ancestor)) {\n // Preserve timestamp if this implicit dir was already known,\n // otherwise stamp it with \"now\" so stat() stays stable.\n this.implicitDirs.set(ancestor, prev.get(ancestor) ?? now);\n }\n }\n }\n\n this.implicitDirsGen = this.pathIndexGen;\n }\n\n /**\n * Check if a path is an implicit directory (exists because files exist under it,\n * but no explicit directory inode was created for it).\n */\n private isImplicitDirectory(path: string): boolean {\n if (path === '/') return false; // root always has an explicit inode\n this.rebuildImplicitDirs();\n return this.implicitDirs.has(path);\n }\n\n /**\n * Get direct children of a directory path, including implicit subdirectories.\n * Returns unique child full paths. Each entry is tagged with whether it's a\n * real inode or an implicit directory.\n */\n private getDirectChildrenWithImplicit(dirPath: string): { path: string; type: 'real' | 'implicit' }[] {\n const prefix = dirPath === '/' ? '/' : dirPath + '/';\n const childNames = new Map<string, 'real' | 'implicit'>();\n\n for (const path of this.pathIndex.keys()) {\n if (path === dirPath) continue;\n if (!path.startsWith(prefix)) continue;\n const rest = path.substring(prefix.length);\n const slashPos = rest.indexOf('/');\n if (slashPos === -1) {\n // Direct child file/dir — it's a real inode\n childNames.set(rest, 'real');\n } else {\n // Deeper descendant — the first segment is an implicit subdirectory\n const childName = rest.substring(0, slashPos);\n if (!childNames.has(childName)) {\n // Only mark as implicit if there's no real inode for it\n const childFullPath = prefix + childName;\n childNames.set(childName, this.pathIndex.has(childFullPath) ? 'real' : 'implicit');\n }\n }\n }\n\n const result: { path: string; type: 'real' | 'implicit' }[] = [];\n for (const [name, type] of childNames) {\n result.push({ path: prefix + name, type });\n }\n result.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);\n return result;\n }\n\n /**\n * Encode a synthetic stat response for an implicit directory.\n * Returns directory stats with default mode, zero size, current timestamps.\n */\n private encodeImplicitDirStatResponse(path: string): { status: number; data: Uint8Array } {\n // Use the stable timestamp assigned when this implicit dir was first\n // discovered, so repeated stat() calls return the same mtime/ctime/atime.\n this.rebuildImplicitDirs();\n const ts = this.implicitDirs.get(path) ?? Date.now();\n const mode = DEFAULT_DIR_MODE & ~(this.umask & 0o777);\n\n // Count implicit subdirectories for nlink\n const children = this.getDirectChildrenWithImplicit(path);\n let subdirCount = 0;\n for (const child of children) {\n if (child.type === 'implicit') {\n subdirCount++;\n } else {\n const childIdx = this.pathIndex.get(child.path);\n if (childIdx !== undefined) {\n const childInode = this.readInode(childIdx);\n if (childInode.type === INODE_TYPE.DIRECTORY) subdirCount++;\n }\n }\n }\n const nlink = 2 + subdirCount;\n\n // Encode stat: type(1) + mode(4) + size(8) + mtime(8) + ctime(8) + atime(8) + uid(4) + gid(4) + ino(4) + nlink(4) = 53 bytes\n const buf = new Uint8Array(53);\n const view = new DataView(buf.buffer);\n view.setUint8(0, INODE_TYPE.DIRECTORY);\n view.setUint32(1, mode, true);\n view.setFloat64(5, 0, true); // size = 0\n view.setFloat64(13, ts, true); // mtime\n view.setFloat64(21, ts, true); // ctime\n view.setFloat64(29, ts, true); // atime\n view.setUint32(37, this.processUid, true);\n view.setUint32(41, this.processGid, true);\n view.setUint32(45, 0, true); // ino = 0 (synthetic)\n view.setUint32(49, nlink, true);\n\n return { status: 0, data: buf };\n }\n\n private getAllDescendants(dirPath: string): string[] {\n const prefix = dirPath === '/' ? '/' : dirPath + '/';\n const descendants: string[] = [];\n\n for (const path of this.pathIndex.keys()) {\n if (path.startsWith(prefix)) descendants.push(path);\n }\n\n // Sort by depth (deepest first) for safe deletion\n return descendants.sort((a, b) => {\n const da = a.split('/').length;\n const db = b.split('/').length;\n return db - da;\n });\n }\n\n private ensureParent(path: string): number {\n const lastSlash = path.lastIndexOf('/');\n if (lastSlash <= 0) return 0; // Parent is root, always exists\n\n const parentPath = path.substring(0, lastSlash);\n const parentIdx = this.pathIndex.get(parentPath);\n if (parentIdx === undefined) {\n // Check for implicit directory\n if (this.isImplicitDirectory(parentPath)) return 0;\n return CODE_TO_STATUS.ENOENT;\n }\n\n const parentInode = this.readInode(parentIdx);\n if (parentInode.type !== INODE_TYPE.DIRECTORY) return CODE_TO_STATUS.ENOTDIR;\n\n return 0;\n }\n\n /** Clean up all fds owned by a tab */\n cleanupTab(tabId: string): void {\n for (const [fd, entry] of this.fdTable) {\n if (entry.tabId === tabId) {\n this.fdTable.delete(fd);\n }\n }\n }\n\n /** Get all file paths and their data for OPFS sync */\n getAllFiles(): { path: string; idx: number }[] {\n const files: { path: string; idx: number }[] = [];\n for (const [path, idx] of this.pathIndex) {\n files.push({ path, idx });\n }\n return files;\n }\n\n /** Get file path for a file descriptor (used by OPFS sync for FD-based ops) */\n getPathForFd(fd: number): string | null {\n const entry = this.fdTable.get(fd);\n if (!entry) return null;\n const inode = this.readInode(entry.inodeIdx);\n return this.readPath(inode.pathOffset, inode.pathLength);\n }\n\n /** Get file data by inode index */\n getInodeData(idx: number): { type: number; data: Uint8Array; mtime: number } {\n const inode = this.readInode(idx);\n const data = inode.size > 0\n ? this.readData(inode.firstBlock, inode.blockCount, inode.size)\n : new Uint8Array(0);\n return { type: inode.type, data, mtime: inode.mtime };\n }\n\n /** Export all files/dirs/symlinks from the VFS */\n exportAll(): Array<{ path: string; type: number; data: Uint8Array | null; mode: number; mtime: number }> {\n const result: Array<{ path: string; type: number; data: Uint8Array | null; mode: number; mtime: number }> = [];\n for (const [path, idx] of this.pathIndex) {\n const inode = this.readInode(idx);\n let data: Uint8Array | null = null;\n if (inode.type === INODE_TYPE.FILE || inode.type === INODE_TYPE.SYMLINK) {\n data = inode.size > 0\n ? this.readData(inode.firstBlock, inode.blockCount, inode.size)\n : new Uint8Array(0);\n }\n result.push({ path, type: inode.type, data, mode: inode.mode, mtime: inode.mtime });\n }\n // Sort directories first so parents are created before children\n result.sort((a, b) => {\n if (a.type === INODE_TYPE.DIRECTORY && b.type !== INODE_TYPE.DIRECTORY) return -1;\n if (a.type !== INODE_TYPE.DIRECTORY && b.type === INODE_TYPE.DIRECTORY) return 1;\n return a.path.localeCompare(b.path);\n });\n return result;\n }\n\n flush(): void {\n this.handle.flush();\n }\n}\n","/**\n * OPFS Engine — operates directly on real OPFS files.\n *\n * Drop-in async replacement for VFSEngine. Used when mode='opfs' or as\n * fallback when VFS binary corruption is detected in hybrid mode.\n *\n * All methods are async because OPFS directory operations require async APIs.\n * File content operations use createSyncAccessHandle for speed.\n *\n * Limitations compared to VFSEngine:\n * - No symlinks (OPFS doesn't support them)\n * - No permissions/ownership (OPFS doesn't support them)\n * - Slower directory operations (async OPFS API calls)\n */\n\nconst encoder = new TextEncoder();\n\n// Match VFS inode types for stat encoding\nconst TYPE_FILE = 1;\nconst TYPE_DIRECTORY = 2;\n\n// Match binary protocol status codes from errors.ts\nconst OK = 0;\nconst ENOENT = 1;\nconst EEXIST = 2;\nconst EISDIR = 3;\nconst ENOTDIR = 4;\nconst ENOTEMPTY = 5;\nconst EINVAL = 7;\nconst EBADF = 8;\n\ninterface OPFSResult {\n status: number;\n data?: Uint8Array | null;\n}\n\ninterface FdEntry {\n handle: FileSystemSyncAccessHandle;\n path: string;\n position: number;\n flags: number;\n}\n\nexport class OPFSEngine {\n private rootDir!: FileSystemDirectoryHandle;\n private fdTable = new Map<number, FdEntry>();\n private nextFd = 3;\n private nextIno = 1;\n private processUid = 0;\n private processGid = 0;\n\n async init(\n rootDir: FileSystemDirectoryHandle,\n opts?: { uid?: number; gid?: number },\n ): Promise<void> {\n this.rootDir = rootDir;\n this.processUid = opts?.uid ?? 0;\n this.processGid = opts?.gid ?? 0;\n }\n\n cleanupTab(_tabId: string): void {\n for (const [fd, entry] of this.fdTable) {\n try { entry.handle.close(); } catch {}\n this.fdTable.delete(fd);\n }\n }\n\n getPathForFd(fd: number): string | null {\n return this.fdTable.get(fd)?.path ?? null;\n }\n\n // ========== Path helpers ==========\n\n private normalizePath(path: string): string {\n if (!path.startsWith('/')) path = '/' + path;\n while (path.length > 1 && path.endsWith('/')) path = path.slice(0, -1);\n const parts = path.split('/');\n const resolved: string[] = [];\n for (const part of parts) {\n if (part === '' || part === '.') continue;\n if (part === '..') { resolved.pop(); continue; }\n resolved.push(part);\n }\n return '/' + resolved.join('/');\n }\n\n /** Navigate to the parent directory of a path, returning the parent handle and child name. */\n private async navigateToParent(\n path: string,\n ): Promise<{ dir: FileSystemDirectoryHandle; name: string } | null> {\n const parts = path.split('/').filter(Boolean);\n if (parts.length === 0) return null;\n const name = parts.pop()!;\n let dir = this.rootDir;\n for (const part of parts) {\n try {\n dir = await dir.getDirectoryHandle(part);\n } catch {\n return null;\n }\n }\n return { dir, name };\n }\n\n /** Navigate to a directory by path. */\n private async navigateToDir(path: string): Promise<FileSystemDirectoryHandle | null> {\n if (path === '/') return this.rootDir;\n const parts = path.split('/').filter(Boolean);\n let dir = this.rootDir;\n for (const part of parts) {\n try {\n dir = await dir.getDirectoryHandle(part);\n } catch {\n return null;\n }\n }\n return dir;\n }\n\n /** Get a file or directory handle for a path. */\n private async getEntry(\n path: string,\n ): Promise<{ handle: FileSystemFileHandle | FileSystemDirectoryHandle; kind: 'file' | 'directory' } | null> {\n if (path === '/') return { handle: this.rootDir, kind: 'directory' };\n const nav = await this.navigateToParent(path);\n if (!nav) return null;\n try {\n return { handle: await nav.dir.getFileHandle(nav.name), kind: 'file' };\n } catch {\n try {\n return { handle: await nav.dir.getDirectoryHandle(nav.name), kind: 'directory' };\n } catch {\n return null;\n }\n }\n }\n\n /** Ensure all parent directories exist (recursive mkdir for parents). */\n private async ensureParent(path: string): Promise<FileSystemDirectoryHandle | null> {\n const parts = path.split('/').filter(Boolean);\n parts.pop(); // remove the leaf\n let dir = this.rootDir;\n for (const part of parts) {\n try {\n dir = await dir.getDirectoryHandle(part, { create: true });\n } catch {\n return null;\n }\n }\n return dir;\n }\n\n private encodeStat(\n kind: 'file' | 'directory',\n size: number,\n mtime: number,\n ino: number,\n ): Uint8Array {\n const buf = new Uint8Array(53);\n const view = new DataView(buf.buffer);\n view.setUint8(0, kind === 'file' ? TYPE_FILE : TYPE_DIRECTORY);\n view.setUint32(1, kind === 'file' ? 0o100644 : 0o040755, true);\n view.setFloat64(5, size, true);\n view.setFloat64(13, mtime, true);\n view.setFloat64(21, mtime, true);\n view.setFloat64(29, mtime, true);\n view.setUint32(37, this.processUid, true);\n view.setUint32(41, this.processGid, true);\n view.setUint32(45, ino, true);\n view.setUint32(49, kind === 'directory' ? 2 : 1, true); // nlink\n return buf;\n }\n\n // ========== FS Operations ==========\n\n async read(path: string): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const nav = await this.navigateToParent(path);\n if (!nav) return { status: ENOENT, data: null };\n try {\n const fh = await nav.dir.getFileHandle(nav.name);\n const file = await fh.getFile();\n return { status: OK, data: new Uint8Array(await file.arrayBuffer()) };\n } catch {\n return { status: ENOENT, data: null };\n }\n }\n\n async write(path: string, data: Uint8Array, _flags?: number): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const parentDir = await this.ensureParent(path);\n if (!parentDir) return { status: ENOENT, data: null };\n const name = path.split('/').filter(Boolean).pop()!;\n try {\n const fh = await parentDir.getFileHandle(name, { create: true });\n const sh = await (fh as any).createSyncAccessHandle();\n try {\n sh.truncate(0);\n if (data.byteLength > 0) sh.write(data, { at: 0 });\n sh.flush();\n } finally {\n sh.close();\n }\n return { status: OK, data: null };\n } catch {\n return { status: ENOENT, data: null };\n }\n }\n\n async append(path: string, data: Uint8Array): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const parentDir = await this.ensureParent(path);\n if (!parentDir) return { status: ENOENT, data: null };\n const name = path.split('/').filter(Boolean).pop()!;\n try {\n const fh = await parentDir.getFileHandle(name, { create: true });\n const sh = await (fh as any).createSyncAccessHandle();\n try {\n const size: number = sh.getSize();\n sh.write(data, { at: size });\n sh.flush();\n } finally {\n sh.close();\n }\n return { status: OK, data: null };\n } catch {\n return { status: ENOENT, data: null };\n }\n }\n\n async unlink(path: string): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const nav = await this.navigateToParent(path);\n if (!nav) return { status: ENOENT, data: null };\n try {\n // Verify it exists and is a file\n await nav.dir.getFileHandle(nav.name);\n await nav.dir.removeEntry(nav.name);\n return { status: OK, data: null };\n } catch {\n return { status: ENOENT, data: null };\n }\n }\n\n async stat(path: string): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const entry = await this.getEntry(path);\n if (!entry) return { status: ENOENT, data: null };\n if (entry.kind === 'file') {\n const file = await (entry.handle as FileSystemFileHandle).getFile();\n return { status: OK, data: this.encodeStat('file', file.size, file.lastModified, this.nextIno++) };\n }\n return { status: OK, data: this.encodeStat('directory', 0, Date.now(), this.nextIno++) };\n }\n\n async lstat(path: string): Promise<OPFSResult> {\n return this.stat(path);\n }\n\n async mkdir(path: string, flags: number = 0): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const recursive = (flags & 1) !== 0;\n\n if (recursive) {\n const parts = path.split('/').filter(Boolean);\n let dir = this.rootDir;\n let firstCreated: string | null = null;\n let current = '';\n for (const part of parts) {\n current += '/' + part;\n let existed = true;\n try {\n dir = await dir.getDirectoryHandle(part);\n } catch {\n existed = false;\n dir = await dir.getDirectoryHandle(part, { create: true });\n }\n if (!existed && !firstCreated) firstCreated = current;\n }\n return { status: OK, data: firstCreated ? encoder.encode(firstCreated) : null };\n }\n\n const nav = await this.navigateToParent(path);\n if (!nav) return { status: ENOENT, data: null };\n try {\n // Check if already exists\n try {\n await nav.dir.getDirectoryHandle(nav.name);\n return { status: EEXIST, data: null };\n } catch {\n // doesn't exist — create it\n }\n await nav.dir.getDirectoryHandle(nav.name, { create: true });\n // Non-recursive mkdir returns undefined (null data) per Node.js spec\n return { status: OK, data: null };\n } catch {\n return { status: ENOENT, data: null };\n }\n }\n\n async rmdir(path: string, flags: number = 0): Promise<OPFSResult> {\n path = this.normalizePath(path);\n if (path === '/') return { status: EINVAL, data: null };\n const recursive = (flags & 1) !== 0;\n const nav = await this.navigateToParent(path);\n if (!nav) return { status: ENOENT, data: null };\n try {\n // Verify it's a directory\n await nav.dir.getDirectoryHandle(nav.name);\n await nav.dir.removeEntry(nav.name, { recursive });\n return { status: OK, data: null };\n } catch (err: any) {\n if (err.name === 'InvalidModificationError') return { status: ENOTEMPTY, data: null };\n return { status: ENOENT, data: null };\n }\n }\n\n async readdir(path: string, flags: number = 0): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const dir = await this.navigateToDir(path);\n if (!dir) return { status: ENOENT, data: null };\n\n // Verify it's a directory (navigateToDir already guarantees this)\n const withFileTypes = (flags & 1) !== 0;\n const entries: { name: string; kind: string }[] = [];\n\n for await (const [name, handle] of (dir as any).entries()) {\n entries.push({ name, kind: handle.kind });\n }\n\n if (withFileTypes) {\n let totalSize = 4;\n const encoded: { nameBytes: Uint8Array; type: number }[] = [];\n for (const e of entries) {\n const nameBytes = encoder.encode(e.name);\n encoded.push({ nameBytes, type: e.kind === 'file' ? TYPE_FILE : TYPE_DIRECTORY });\n totalSize += 2 + nameBytes.byteLength + 1;\n }\n\n const buf = new Uint8Array(totalSize);\n const view = new DataView(buf.buffer);\n view.setUint32(0, encoded.length, true);\n let offset = 4;\n for (const e of encoded) {\n view.setUint16(offset, e.nameBytes.byteLength, true);\n offset += 2;\n buf.set(e.nameBytes, offset);\n offset += e.nameBytes.byteLength;\n buf[offset++] = e.type;\n }\n return { status: OK, data: buf };\n }\n\n // Simple name list\n let totalSize = 4;\n const nameEntries: Uint8Array[] = [];\n for (const e of entries) {\n const nameBytes = encoder.encode(e.name);\n nameEntries.push(nameBytes);\n totalSize += 2 + nameBytes.byteLength;\n }\n\n const buf = new Uint8Array(totalSize);\n const view = new DataView(buf.buffer);\n view.setUint32(0, nameEntries.length, true);\n let offset = 4;\n for (const nameBytes of nameEntries) {\n view.setUint16(offset, nameBytes.byteLength, true);\n offset += 2;\n buf.set(nameBytes, offset);\n offset += nameBytes.byteLength;\n }\n return { status: OK, data: buf };\n }\n\n async rename(oldPath: string, newPath: string): Promise<OPFSResult> {\n oldPath = this.normalizePath(oldPath);\n newPath = this.normalizePath(newPath);\n\n const entry = await this.getEntry(oldPath);\n if (!entry) return { status: ENOENT, data: null };\n\n if (entry.kind === 'file') {\n // File rename: read → write new → delete old\n const fh = entry.handle as FileSystemFileHandle;\n const file = await fh.getFile();\n const data = new Uint8Array(await file.arrayBuffer());\n const writeResult = await this.write(newPath, data);\n if (writeResult.status !== OK) return writeResult;\n await this.unlink(oldPath);\n } else {\n // Directory rename: recursive copy → delete old\n await this.mkdir(newPath, 1);\n await this.copyDirectoryContents(oldPath, newPath);\n await this.rmdir(oldPath, 1);\n }\n return { status: OK, data: null };\n }\n\n private async copyDirectoryContents(srcPath: string, dstPath: string): Promise<void> {\n const srcDir = await this.navigateToDir(srcPath);\n if (!srcDir) return;\n\n for await (const [name, handle] of (srcDir as any).entries()) {\n const srcChild = srcPath === '/' ? `/${name}` : `${srcPath}/${name}`;\n const dstChild = dstPath === '/' ? `/${name}` : `${dstPath}/${name}`;\n\n if (handle.kind === 'directory') {\n await this.mkdir(dstChild, 1);\n await this.copyDirectoryContents(srcChild, dstChild);\n } else {\n const file = await (handle as FileSystemFileHandle).getFile();\n const data = new Uint8Array(await file.arrayBuffer());\n await this.write(dstChild, data);\n }\n }\n }\n\n async exists(path: string): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const entry = await this.getEntry(path);\n return { status: OK, data: new Uint8Array([entry ? 1 : 0]) };\n }\n\n async truncate(path: string, len: number): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const nav = await this.navigateToParent(path);\n if (!nav) return { status: ENOENT, data: null };\n try {\n const fh = await nav.dir.getFileHandle(nav.name);\n const sh = await (fh as any).createSyncAccessHandle();\n try {\n sh.truncate(len);\n sh.flush();\n } finally {\n sh.close();\n }\n return { status: OK, data: null };\n } catch {\n return { status: ENOENT, data: null };\n }\n }\n\n async copy(src: string, dest: string, _flags?: number): Promise<OPFSResult> {\n src = this.normalizePath(src);\n dest = this.normalizePath(dest);\n const readResult = await this.read(src);\n if (readResult.status !== OK) return readResult;\n return this.write(dest, readResult.data ?? new Uint8Array(0));\n }\n\n async access(path: string, _mode?: number): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const entry = await this.getEntry(path);\n if (!entry) return { status: ENOENT, data: null };\n return { status: OK, data: null };\n }\n\n async realpath(path: string): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const entry = await this.getEntry(path);\n if (!entry) return { status: ENOENT, data: null };\n return { status: OK, data: encoder.encode(path) };\n }\n\n // OPFS doesn't support permissions/ownership/timestamps — these succeed as\n // no-ops when the target exists, mirroring the VFS engine's behavior so\n // callers can write code that works in both modes.\n\n async chmod(path: string, _mode: number): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const entry = await this.getEntry(path);\n if (!entry) return { status: ENOENT, data: null };\n return { status: OK, data: null };\n }\n\n async chown(path: string, _uid: number, _gid: number): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const entry = await this.getEntry(path);\n if (!entry) return { status: ENOENT, data: null };\n return { status: OK, data: null };\n }\n\n async utimes(path: string, _atime: number, _mtime: number): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const entry = await this.getEntry(path);\n if (!entry) return { status: ENOENT, data: null };\n return { status: OK, data: null };\n }\n\n // fd-based variants: validate the fd and succeed. There's nowhere to store\n // mode/uid/gid/timestamps in OPFS, so they're accepted and discarded.\n async fchmod(fd: number, _mode: number): Promise<OPFSResult> {\n return this.fdTable.has(fd) ? { status: OK, data: null } : { status: EBADF, data: null };\n }\n\n async fchown(fd: number, _uid: number, _gid: number): Promise<OPFSResult> {\n return this.fdTable.has(fd) ? { status: OK, data: null } : { status: EBADF, data: null };\n }\n\n async futimes(fd: number, _atime: number, _mtime: number): Promise<OPFSResult> {\n return this.fdTable.has(fd) ? { status: OK, data: null } : { status: EBADF, data: null };\n }\n\n // OPFS has no symlinks or hard links\n\n async symlink(_target: string, _linkPath: string): Promise<OPFSResult> {\n return { status: EINVAL, data: null };\n }\n\n async readlink(_path: string): Promise<OPFSResult> {\n return { status: EINVAL, data: null };\n }\n\n async link(existingPath: string, newPath: string): Promise<OPFSResult> {\n return this.copy(existingPath, newPath);\n }\n\n // ========== File descriptor operations ==========\n\n async open(path: string, flags: number, _tabId: string): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const hasCreate = (flags & 64) !== 0; // O_CREAT\n const hasTrunc = (flags & 512) !== 0; // O_TRUNC\n const hasExcl = (flags & 128) !== 0; // O_EXCL\n\n const parentDir = await this.ensureParent(path);\n if (!parentDir) return { status: ENOENT, data: null };\n const name = path.split('/').filter(Boolean).pop()!;\n\n try {\n // Check existence\n let exists = true;\n try {\n await parentDir.getFileHandle(name);\n } catch {\n exists = false;\n }\n\n if (!exists && !hasCreate) return { status: ENOENT, data: null };\n if (exists && hasExcl && hasCreate) return { status: EEXIST, data: null };\n\n const fh = await parentDir.getFileHandle(name, { create: hasCreate });\n const sh = await (fh as any).createSyncAccessHandle();\n\n if (hasTrunc) {\n sh.truncate(0);\n sh.flush();\n }\n\n const fd = this.nextFd++;\n this.fdTable.set(fd, { handle: sh, path, position: 0, flags });\n\n const buf = new Uint8Array(4);\n new DataView(buf.buffer).setUint32(0, fd, true);\n return { status: OK, data: buf };\n } catch {\n return { status: ENOENT, data: null };\n }\n }\n\n async close(fd: number): Promise<OPFSResult> {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: EBADF, data: null };\n try { entry.handle.close(); } catch {}\n this.fdTable.delete(fd);\n return { status: OK, data: null };\n }\n\n async fread(fd: number, length: number, position: number | null): Promise<OPFSResult> {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: EBADF, data: null };\n\n const pos = position ?? entry.position;\n const size: number = entry.handle.getSize();\n const readLen = Math.min(length, size - pos);\n if (readLen <= 0) return { status: OK, data: new Uint8Array(0) };\n\n const buf = new Uint8Array(readLen);\n entry.handle.read(buf, { at: pos });\n\n if (position === null) {\n entry.position += readLen;\n }\n return { status: OK, data: buf };\n }\n\n async fwrite(fd: number, data: Uint8Array, position: number | null): Promise<OPFSResult> {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: EBADF, data: null };\n\n const isAppend = (entry.flags & 1024) !== 0; // O_APPEND\n const pos = isAppend ? entry.handle.getSize() : (position ?? entry.position);\n\n entry.handle.write(data, { at: pos });\n\n if (position === null) {\n entry.position = pos + data.byteLength;\n }\n\n const buf = new Uint8Array(4);\n new DataView(buf.buffer).setUint32(0, data.byteLength, true);\n return { status: OK, data: buf };\n }\n\n async fstat(fd: number): Promise<OPFSResult> {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: EBADF, data: null };\n\n const size: number = entry.handle.getSize();\n return { status: OK, data: this.encodeStat('file', size, Date.now(), fd) };\n }\n\n async ftruncate(fd: number, len: number = 0): Promise<OPFSResult> {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: EBADF, data: null };\n entry.handle.truncate(len);\n entry.handle.flush();\n return { status: OK, data: null };\n }\n\n async fsync(): Promise<OPFSResult> {\n for (const [, entry] of this.fdTable) {\n try { entry.handle.flush(); } catch {}\n }\n return { status: OK, data: null };\n }\n\n async opendir(path: string, _tabId: string): Promise<OPFSResult> {\n return this.readdir(path, 1);\n }\n\n async mkdtemp(prefix: string): Promise<OPFSResult> {\n const random = Math.random().toString(36).substring(2, 8);\n const path = this.normalizePath(prefix + random);\n return this.mkdir(path, 1);\n }\n}\n","/**\n * Binary protocol operation codes and header encoding/decoding.\n * All inter-worker messages use this minimal binary protocol — no JSON, no strings.\n */\n\n// Operation codes\nexport const OP = {\n READ: 1,\n WRITE: 2,\n UNLINK: 3,\n STAT: 4,\n LSTAT: 5,\n MKDIR: 6,\n RMDIR: 7,\n READDIR: 8,\n RENAME: 9,\n EXISTS: 10,\n TRUNCATE: 11,\n APPEND: 12,\n COPY: 13,\n ACCESS: 14,\n REALPATH: 15,\n CHMOD: 16,\n CHOWN: 17,\n UTIMES: 18,\n SYMLINK: 19,\n READLINK: 20,\n LINK: 21,\n OPEN: 22,\n CLOSE: 23,\n FREAD: 24,\n FWRITE: 25,\n FSTAT: 26,\n FTRUNCATE: 27,\n FSYNC: 28,\n OPENDIR: 29,\n MKDTEMP: 30,\n FCHMOD: 31,\n FCHOWN: 32,\n FUTIMES: 33,\n} as const;\n\nexport type OpCode = (typeof OP)[keyof typeof OP];\n\n// Response status codes\nexport const STATUS = {\n OK: 0,\n ENOENT: 1,\n EEXIST: 2,\n EISDIR: 3,\n ENOTDIR: 4,\n ENOTEMPTY: 5,\n EACCES: 6,\n EINVAL: 7,\n EBADF: 8,\n ELOOP: 9,\n ENOSPC: 10,\n} as const;\n\n// SAB layout offsets\nexport const SAB_OFFSETS = {\n CONTROL: 0, // Int32 - signal (0=idle, 1=request, 2=response, 3=chunk, 4=ack)\n OPCODE: 4, // Int32 - operation code\n STATUS: 8, // Int32 - response status / error\n CHUNK_LEN: 12, // Int32 - bytes in this chunk\n TOTAL_LEN: 16, // BigUint64 - full data size across all chunks\n CHUNK_IDX: 24, // Int32 - 0-based chunk index\n RESERVED: 28, // Int32 - reserved\n HEADER_SIZE: 32, // Data payload starts here\n} as const;\n\n// SAB control signals\nexport const SIGNAL = {\n IDLE: 0,\n REQUEST: 1,\n RESPONSE: 2,\n CHUNK: 3,\n CHUNK_ACK: 4,\n} as const;\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/**\n * Encode a request into an ArrayBuffer for MessageChannel transfer.\n *\n * Request format (16-byte header + path + data):\n * bytes 0-3: operation (uint32)\n * bytes 4-7: flags (uint32)\n * bytes 8-11: pathLen (uint32)\n * bytes 12-15: dataLen (uint32)\n * bytes 16+: path (UTF-8)\n * bytes 16+pathLen: data payload\n */\nexport function encodeRequest(\n op: number,\n path: string,\n flags: number = 0,\n data?: Uint8Array\n): ArrayBuffer {\n const pathBytes = encoder.encode(path);\n const dataLen = data ? data.byteLength : 0;\n const totalLen = 16 + pathBytes.byteLength + dataLen;\n const buf = new ArrayBuffer(totalLen);\n const view = new DataView(buf);\n\n view.setUint32(0, op, true);\n view.setUint32(4, flags, true);\n view.setUint32(8, pathBytes.byteLength, true);\n view.setUint32(12, dataLen, true);\n\n const bytes = new Uint8Array(buf);\n bytes.set(pathBytes, 16);\n if (data) {\n bytes.set(data, 16 + pathBytes.byteLength);\n }\n\n return buf;\n}\n\n/**\n * Decode a request ArrayBuffer.\n */\nexport function decodeRequest(buf: ArrayBuffer): {\n op: number;\n flags: number;\n path: string;\n data: Uint8Array | null;\n} {\n // Minimum header: 16 bytes (op + flags + pathLen + dataLen)\n if (buf.byteLength < 16) {\n throw new Error(`Request buffer too small: ${buf.byteLength} < 16 bytes (possible SAB race)`);\n }\n\n const view = new DataView(buf);\n const op = view.getUint32(0, true);\n const flags = view.getUint32(4, true);\n const pathLen = view.getUint32(8, true);\n const dataLen = view.getUint32(12, true);\n\n // Validate payload fits in buffer\n const expectedMin = 16 + pathLen + dataLen;\n if (buf.byteLength < expectedMin) {\n throw new Error(`Request buffer truncated: ${buf.byteLength} < ${expectedMin} bytes (op=${op}, pathLen=${pathLen}, dataLen=${dataLen})`);\n }\n\n const bytes = new Uint8Array(buf);\n const path = decoder.decode(bytes.subarray(16, 16 + pathLen));\n const data = dataLen > 0\n ? bytes.subarray(16 + pathLen, 16 + pathLen + dataLen)\n : null;\n\n return { op, flags, path, data };\n}\n\n/**\n * Encode a response into an ArrayBuffer.\n *\n * Response format (8-byte header + data):\n * bytes 0-3: status (uint32)\n * bytes 4-7: dataLen (uint32)\n * bytes 8+: data payload\n */\nexport function encodeResponse(status: number, data?: Uint8Array): ArrayBuffer {\n const dataLen = data ? data.byteLength : 0;\n const buf = new ArrayBuffer(8 + dataLen);\n const view = new DataView(buf);\n\n view.setUint32(0, status, true);\n view.setUint32(4, dataLen, true);\n\n if (data) {\n new Uint8Array(buf).set(data, 8);\n }\n\n return buf;\n}\n\n/**\n * Decode a response ArrayBuffer.\n */\nexport function decodeResponse(buf: ArrayBuffer): {\n status: number;\n data: Uint8Array | null;\n} {\n const view = new DataView(buf);\n const status = view.getUint32(0, true);\n const dataLen = view.getUint32(4, true);\n\n const data = dataLen > 0\n ? new Uint8Array(buf, 8, dataLen)\n : null;\n\n return { status, data };\n}\n\n/**\n * Encode a two-path request (rename, copy, symlink, link).\n * Data payload contains: [pathLen2:u32] [path2 bytes]\n */\nexport function encodeTwoPathRequest(\n op: number,\n path1: string,\n path2: string,\n flags: number = 0\n): ArrayBuffer {\n const path2Bytes = encoder.encode(path2);\n const payload = new Uint8Array(4 + path2Bytes.byteLength);\n const pv = new DataView(payload.buffer);\n pv.setUint32(0, path2Bytes.byteLength, true);\n payload.set(path2Bytes, 4);\n\n return encodeRequest(op, path1, flags, payload);\n}\n\n/**\n * Decode the second path from a two-path request's data payload.\n */\nexport function decodeSecondPath(data: Uint8Array): string {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const pathLen = view.getUint32(0, true);\n return decoder.decode(data.subarray(4, 4 + pathLen));\n}\n","/**\n * Sync Relay Worker — the VFS engine owner and primary request processor.\n *\n * Operates in one of two modes:\n *\n * LEADER MODE (primary tab):\n * - Owns the VFS engine and OPFS sync access handle\n * - Processes own tab's sync requests via syncSAB (fastest path, no hops)\n * - Processes own tab's async requests via asyncSAB (no MessagePort hop)\n * - Accepts MessagePort connections from secondary tabs\n * - Yields periodically to process port messages when clients are connected\n * - When no clients: pure blocking loop — zero overhead\n *\n * FOLLOWER MODE (secondary tabs):\n * - Does NOT own VFS engine\n * - Connects to leader's sync-relay via MessagePort (through service worker)\n * - Relays own tab's sync + async SAB requests via MessagePort to leader\n * - Same SAB protocol with own main thread, but forwards to leader for processing\n *\n * Priority order: syncSAB > asyncSAB > client port messages\n */\n\nimport { VFSEngine } from '../vfs/engine.js';\nimport { OPFSEngine } from '../opfs-engine.js';\nimport { SAB_OFFSETS, SIGNAL, OP, decodeRequest, decodeSecondPath, encodeResponse } from '../protocol/opcodes.js';\nimport { VFS_MAGIC, VFS_VERSION, SUPERBLOCK, INODE_SIZE } from '../vfs/layout.js';\n\nconst engine = new VFSEngine();\nlet opfsEngine: OPFSEngine | null = null;\nlet opfsMode = false;\n\n// Guards: prevent duplicate init and double-ready\nlet leaderInitialized = false;\nlet readySent = false;\nlet debug = false;\nlet leaderLoopRunning = false;\n\n// OPFS Sync Worker (leader mode only — mirrors VFS to real OPFS files)\nlet opfsSyncPort: MessagePort | null = null;\nlet opfsSyncEnabled = false;\nconst suppressPaths = new Set<string>(); // break external→engine→notify loop\n\n// Watch broadcast (leader mode only — fires on every VFS mutation)\nlet watchBc: BroadcastChannel | null = null;\n\n// Own tab's sync SAB\nlet sab: SharedArrayBuffer;\nlet ctrl: Int32Array;\nlet readySab: SharedArrayBuffer;\nlet readySignal: Int32Array;\n\n// Own tab's async SAB (shared with async-relay worker)\nlet asyncSab: SharedArrayBuffer | null = null;\nlet asyncCtrl: Int32Array | null = null;\n\n// Tab identity\nlet tabId: string = '';\n\nconst HEADER_SIZE = SAB_OFFSETS.HEADER_SIZE;\n\n// ========== Leader mode: client port management ==========\n\nconst clientPorts = new Map<string, MessagePort>();\nconst portQueue: Array<{ port: MessagePort; tabId: string; id: string; buffer: ArrayBuffer }> = [];\n\n// Fast macrotask yield via MessageChannel self-post (~0.1ms)\nconst yieldChannel = new MessageChannel();\nyieldChannel.port2.start();\n\nfunction yieldToEventLoop(): Promise<void> {\n return new Promise(resolve => {\n yieldChannel.port2.onmessage = () => resolve();\n yieldChannel.port1.postMessage(null);\n });\n}\n\nfunction registerClientPort(clientTabId: string, port: MessagePort): void {\n port.onmessage = async (e: MessageEvent) => {\n if (e.data.buffer instanceof ArrayBuffer) {\n if (leaderLoopRunning) {\n // Leader loop will drain the queue\n portQueue.push({\n port,\n tabId: clientTabId,\n id: e.data.id,\n buffer: e.data.buffer,\n });\n } else {\n // No leader loop (no-SAB mode): handle directly\n const result = opfsMode\n ? await handleRequestOPFS(clientTabId, e.data.buffer)\n : handleRequest(clientTabId, e.data.buffer);\n const response = encodeResponse(result.status, result.data);\n port.postMessage({ id: e.data.id, buffer: response }, [response]);\n if (!opfsMode && result._op !== undefined) notifyOPFSSync(result._op, result._path!, result._newPath);\n }\n }\n };\n port.start();\n clientPorts.set(clientTabId, port);\n}\n\nfunction removeClientPort(clientTabId: string): void {\n const port = clientPorts.get(clientTabId);\n if (port) {\n port.close();\n clientPorts.delete(clientTabId);\n }\n if (opfsMode) {\n opfsEngine?.cleanupTab(clientTabId);\n } else {\n engine.cleanupTab(clientTabId);\n }\n}\n\nfunction drainPortQueue(): void {\n while (portQueue.length > 0) {\n const msg = portQueue.shift()!;\n const result = handleRequest(msg.tabId, msg.buffer);\n const response = encodeResponse(result.status, result.data);\n msg.port.postMessage({ id: msg.id, buffer: response }, [response]);\n if (result._op !== undefined) notifyOPFSSync(result._op, result._path!, result._newPath);\n }\n}\n\nasync function drainPortQueueAsync(): Promise<void> {\n while (portQueue.length > 0) {\n const msg = portQueue.shift()!;\n const result = await handleRequestOPFS(msg.tabId, msg.buffer);\n const response = encodeResponse(result.status, result.data);\n msg.port.postMessage({ id: msg.id, buffer: response }, [response]);\n }\n}\n\n// ========== Follower mode: leader port ==========\n\nlet leaderPort: MessagePort | null = null;\nlet pendingResolve: ((buf: ArrayBuffer) => void) | null = null;\n\n// No-SAB mode: async-relay port (for forwarding in follower mode)\nlet asyncRelayPort: MessagePort | null = null;\n\nfunction forwardToLeader(payload: Uint8Array): Promise<ArrayBuffer> {\n return new Promise(resolve => {\n pendingResolve = resolve;\n const buf = payload.buffer.byteLength === payload.byteLength\n ? payload.buffer\n : payload.slice().buffer;\n leaderPort!.postMessage(\n { id: tabId, tabId, buffer: buf },\n [buf]\n );\n });\n}\n\nfunction onLeaderMessage(e: MessageEvent): void {\n if (e.data.buffer instanceof ArrayBuffer) {\n if (pendingResolve) {\n // SAB follower: resolve sync relay promise\n const resolve = pendingResolve;\n pendingResolve = null;\n resolve(e.data.buffer);\n } else if (asyncRelayPort) {\n // No-SAB follower: forward response back to async-relay\n asyncRelayPort.postMessage({ id: e.data.id, buffer: e.data.buffer }, [e.data.buffer]);\n }\n }\n}\n\n// ========== Request dispatch (leader mode) ==========\n\nconst OP_NAMES: Record<number, string> = {\n 1: 'READ', 2: 'WRITE', 3: 'UNLINK', 4: 'STAT', 5: 'LSTAT', 6: 'MKDIR',\n 7: 'RMDIR', 8: 'READDIR', 9: 'RENAME', 10: 'EXISTS', 11: 'TRUNCATE',\n 12: 'APPEND', 13: 'COPY', 14: 'ACCESS', 15: 'REALPATH', 16: 'CHMOD',\n 17: 'CHOWN', 18: 'UTIMES', 19: 'SYMLINK', 20: 'READLINK', 21: 'LINK',\n 22: 'OPEN', 23: 'CLOSE', 24: 'FREAD', 25: 'FWRITE', 26: 'FSTAT',\n 27: 'FTRUNCATE', 28: 'FSYNC', 29: 'OPENDIR', 30: 'MKDTEMP',\n};\n\nfunction handleRequest(reqTabId: string, buffer: ArrayBuffer): { status: number; data?: Uint8Array; _op?: number; _path?: string; _newPath?: string } {\n const t0 = debug ? performance.now() : 0;\n let op: number, flags: number, path: string, data: Uint8Array | null;\n try {\n ({ op, flags, path, data } = decodeRequest(buffer));\n } catch (err: any) {\n console.error(`[sync-relay] decodeRequest failed (bufLen=${buffer.byteLength}): ${err.message}`);\n return { status: -1 };\n }\n const t1 = debug ? performance.now() : 0;\n\n let result: { status: number; data?: Uint8Array | null };\n let syncOp: number | undefined;\n let syncPath: string | undefined;\n let syncNewPath: string | undefined;\n\n switch (op) {\n case OP.READ:\n result = engine.read(path);\n break;\n\n case OP.WRITE:\n result = engine.write(path, data ?? new Uint8Array(0), flags);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n\n case OP.APPEND:\n result = engine.append(path, data ?? new Uint8Array(0));\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n\n case OP.UNLINK:\n result = engine.unlink(path);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n\n case OP.STAT:\n result = engine.stat(path);\n break;\n\n case OP.LSTAT:\n result = engine.lstat(path);\n break;\n\n case OP.MKDIR:\n result = engine.mkdir(path, flags);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n\n case OP.RMDIR:\n result = engine.rmdir(path, flags);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n\n case OP.READDIR:\n result = engine.readdir(path, flags);\n break;\n\n case OP.RENAME: {\n const newPath = data ? decodeSecondPath(data) : '';\n result = engine.rename(path, newPath);\n if (result.status === 0) { syncOp = op; syncPath = path; syncNewPath = newPath; }\n break;\n }\n\n case OP.EXISTS:\n result = engine.exists(path);\n break;\n\n case OP.TRUNCATE: {\n const len = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getFloat64(0, true) : 0;\n result = engine.truncate(path, len);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n }\n\n case OP.COPY: {\n const destPath = data ? decodeSecondPath(data) : '';\n result = engine.copy(path, destPath, flags);\n if (result.status === 0) { syncOp = op; syncPath = destPath; }\n break;\n }\n\n case OP.ACCESS:\n result = engine.access(path, flags);\n break;\n\n case OP.REALPATH:\n result = engine.realpath(path);\n break;\n\n case OP.CHMOD: {\n const chmodMode = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) : 0;\n result = engine.chmod(path, chmodMode);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n }\n\n case OP.CHOWN: {\n if (!data || data.byteLength < 8) {\n result = { status: 7 }; // EINVAL\n break;\n }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const uid = dv.getUint32(0, true);\n const gid = dv.getUint32(4, true);\n result = engine.chown(path, uid, gid);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n }\n\n case OP.UTIMES: {\n if (!data || data.byteLength < 16) {\n result = { status: 7 }; // EINVAL\n break;\n }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const atime = dv.getFloat64(0, true);\n const mtime = dv.getFloat64(8, true);\n result = engine.utimes(path, atime, mtime);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n }\n\n case OP.SYMLINK: {\n const target = data ? new TextDecoder().decode(data) : '';\n result = engine.symlink(target, path);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n }\n\n case OP.READLINK:\n result = engine.readlink(path);\n break;\n\n case OP.LINK: {\n const newPath = data ? decodeSecondPath(data) : '';\n result = engine.link(path, newPath);\n if (result.status === 0) { syncOp = op; syncPath = newPath; }\n break;\n }\n\n case OP.OPEN:\n result = engine.open(path, flags, reqTabId);\n break;\n\n case OP.CLOSE: {\n const fd = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) : 0;\n result = engine.close(fd);\n break;\n }\n\n case OP.FREAD: {\n if (!data || data.byteLength < 16) {\n result = { status: 7 };\n break;\n }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const fd = dv.getUint32(0, true);\n const length = dv.getUint32(4, true);\n const pos = dv.getFloat64(8, true);\n result = engine.fread(fd, length, pos === -1 ? null : pos);\n break;\n }\n\n case OP.FWRITE: {\n if (!data || data.byteLength < 12) {\n result = { status: 7 };\n break;\n }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const fd = dv.getUint32(0, true);\n const pos = dv.getFloat64(4, true);\n const writeData = data.subarray(12);\n result = engine.fwrite(fd, writeData, pos === -1 ? null : pos);\n if (result.status === 0) { syncOp = op; syncPath = engine.getPathForFd(fd) ?? undefined; }\n break;\n }\n\n case OP.FSTAT: {\n const fd = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) : 0;\n result = engine.fstat(fd);\n break;\n }\n\n case OP.FTRUNCATE: {\n if (!data || data.byteLength < 12) {\n result = { status: 7 };\n break;\n }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const fd = dv.getUint32(0, true);\n const len = dv.getFloat64(4, true);\n result = engine.ftruncate(fd, len);\n if (result.status === 0) { syncOp = op; syncPath = engine.getPathForFd(fd) ?? undefined; }\n break;\n }\n\n case OP.FSYNC:\n result = engine.fsync();\n break;\n\n case OP.OPENDIR:\n result = engine.opendir(path, reqTabId);\n break;\n\n case OP.MKDTEMP:\n result = engine.mkdtemp(path);\n if (result.status === 0 && result.data) {\n syncOp = op;\n syncPath = new TextDecoder().decode(result.data instanceof Uint8Array ? result.data : new Uint8Array(0));\n }\n break;\n\n case OP.FCHMOD: {\n // Payload: [fd: u32][mode: u32]\n if (!data || data.byteLength < 8) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const fd = dv.getUint32(0, true);\n const mode = dv.getUint32(4, true);\n result = engine.fchmod(fd, mode);\n if (result.status === 0) {\n syncOp = OP.CHMOD;\n syncPath = engine.getPathForFd(fd) ?? undefined;\n }\n break;\n }\n\n case OP.FCHOWN: {\n // Payload: [fd: u32][uid: u32][gid: u32]\n if (!data || data.byteLength < 12) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const fd = dv.getUint32(0, true);\n const uid = dv.getUint32(4, true);\n const gid = dv.getUint32(8, true);\n result = engine.fchown(fd, uid, gid);\n if (result.status === 0) {\n syncOp = OP.CHOWN;\n syncPath = engine.getPathForFd(fd) ?? undefined;\n }\n break;\n }\n\n case OP.FUTIMES: {\n // Payload: [fd: u32][pad: u32][atime: f64][mtime: f64]\n if (!data || data.byteLength < 24) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const fd = dv.getUint32(0, true);\n const atime = dv.getFloat64(8, true);\n const mtime = dv.getFloat64(16, true);\n result = engine.futimes(fd, atime, mtime);\n if (result.status === 0) {\n syncOp = OP.UTIMES;\n syncPath = engine.getPathForFd(fd) ?? undefined;\n }\n break;\n }\n\n default:\n result = { status: 7 }; // EINVAL — unknown op\n }\n\n if (debug) {\n const t2 = performance.now();\n console.log(`[sync-relay] op=${OP_NAMES[op] ?? op} path=${path} decode=${(t1-t0).toFixed(3)}ms engine=${(t2-t1).toFixed(3)}ms TOTAL=${(t2-t0).toFixed(3)}ms`);\n }\n\n const ret: { status: number; data?: Uint8Array; _op?: number; _path?: string; _newPath?: string } = {\n status: result.status,\n data: result.data instanceof Uint8Array ? result.data : undefined,\n };\n if (syncOp !== undefined && syncPath) {\n // OPFS sync metadata (only used when opfsSyncEnabled, but callers guard via notifyOPFSSync)\n ret._op = syncOp;\n ret._path = syncPath;\n ret._newPath = syncNewPath;\n // Watch broadcast (always, for all tabs)\n broadcastWatch(syncOp, syncPath, syncNewPath);\n }\n return ret;\n}\n\n// ========== OPFS mode: async request handler ==========\n\nasync function handleRequestOPFS(reqTabId: string, buffer: ArrayBuffer): Promise<{ status: number; data?: Uint8Array; _op?: number; _path?: string; _newPath?: string }> {\n const oe = opfsEngine!;\n let op: number, flags: number, path: string, data: Uint8Array | null;\n try {\n ({ op, flags, path, data } = decodeRequest(buffer));\n } catch (err: any) {\n console.error(`[sync-relay] decodeRequest failed in OPFS handler (bufLen=${buffer.byteLength}): ${err.message}`);\n return { status: -1 };\n }\n\n let result: { status: number; data?: Uint8Array | null };\n let syncPath: string | undefined;\n let syncNewPath: string | undefined;\n\n switch (op) {\n case OP.READ:\n result = await oe.read(path);\n break;\n case OP.WRITE:\n result = await oe.write(path, data ?? new Uint8Array(0), flags);\n syncPath = path;\n break;\n case OP.APPEND:\n result = await oe.append(path, data ?? new Uint8Array(0));\n syncPath = path;\n break;\n case OP.UNLINK:\n result = await oe.unlink(path);\n syncPath = path;\n break;\n case OP.STAT:\n result = await oe.stat(path);\n break;\n case OP.LSTAT:\n result = await oe.lstat(path);\n break;\n case OP.MKDIR:\n result = await oe.mkdir(path, flags);\n syncPath = path;\n break;\n case OP.RMDIR:\n result = await oe.rmdir(path, flags);\n syncPath = path;\n break;\n case OP.READDIR:\n result = await oe.readdir(path, flags);\n break;\n case OP.RENAME: {\n const newPath = data ? decodeSecondPath(data) : '';\n result = await oe.rename(path, newPath);\n syncPath = path; syncNewPath = newPath;\n break;\n }\n case OP.EXISTS:\n result = await oe.exists(path);\n break;\n case OP.TRUNCATE: {\n const len = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getFloat64(0, true) : 0;\n result = await oe.truncate(path, len);\n syncPath = path;\n break;\n }\n case OP.COPY: {\n const destPath = data ? decodeSecondPath(data) : '';\n result = await oe.copy(path, destPath, flags);\n syncPath = destPath;\n break;\n }\n case OP.ACCESS:\n result = await oe.access(path, flags);\n break;\n case OP.REALPATH:\n result = await oe.realpath(path);\n break;\n case OP.CHMOD: {\n const chmodMode = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) : 0;\n result = await oe.chmod(path, chmodMode);\n break;\n }\n case OP.CHOWN: {\n if (!data || data.byteLength < 8) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n result = await oe.chown(path, dv.getUint32(0, true), dv.getUint32(4, true));\n break;\n }\n case OP.UTIMES: {\n if (!data || data.byteLength < 16) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n result = await oe.utimes(path, dv.getFloat64(0, true), dv.getFloat64(8, true));\n break;\n }\n case OP.SYMLINK: {\n const target = data ? new TextDecoder().decode(data) : '';\n result = await oe.symlink(target, path);\n break;\n }\n case OP.READLINK:\n result = await oe.readlink(path);\n break;\n case OP.LINK: {\n const newPath = data ? decodeSecondPath(data) : '';\n result = await oe.link(path, newPath);\n syncPath = newPath;\n break;\n }\n case OP.OPEN:\n result = await oe.open(path, flags, reqTabId);\n break;\n case OP.CLOSE: {\n const fd = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) : 0;\n result = await oe.close(fd);\n break;\n }\n case OP.FREAD: {\n if (!data || data.byteLength < 16) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const pos = dv.getFloat64(8, true);\n result = await oe.fread(dv.getUint32(0, true), dv.getUint32(4, true), pos === -1 ? null : pos);\n break;\n }\n case OP.FWRITE: {\n if (!data || data.byteLength < 12) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const fd = dv.getUint32(0, true);\n const pos = dv.getFloat64(4, true);\n result = await oe.fwrite(fd, data.subarray(12), pos === -1 ? null : pos);\n syncPath = oe.getPathForFd(fd) ?? undefined;\n break;\n }\n case OP.FSTAT: {\n const fd = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) : 0;\n result = await oe.fstat(fd);\n break;\n }\n case OP.FTRUNCATE: {\n if (!data || data.byteLength < 12) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n result = await oe.ftruncate(dv.getUint32(0, true), dv.getFloat64(4, true));\n syncPath = oe.getPathForFd(dv.getUint32(0, true)) ?? undefined;\n break;\n }\n case OP.FSYNC:\n result = await oe.fsync();\n break;\n case OP.OPENDIR:\n result = await oe.opendir(path, reqTabId);\n break;\n case OP.MKDTEMP:\n result = await oe.mkdtemp(path);\n if (result.status === 0 && result.data) {\n syncPath = new TextDecoder().decode(result.data instanceof Uint8Array ? result.data : new Uint8Array(0));\n }\n break;\n case OP.FCHMOD: {\n if (!data || data.byteLength < 8) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n result = await oe.fchmod(dv.getUint32(0, true), dv.getUint32(4, true));\n break;\n }\n case OP.FCHOWN: {\n if (!data || data.byteLength < 12) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n result = await oe.fchown(dv.getUint32(0, true), dv.getUint32(4, true), dv.getUint32(8, true));\n break;\n }\n case OP.FUTIMES: {\n if (!data || data.byteLength < 24) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n result = await oe.futimes(dv.getUint32(0, true), dv.getFloat64(8, true), dv.getFloat64(16, true));\n break;\n }\n default:\n result = { status: 7 };\n }\n\n // Fallback to VfsEngine for read-only operations that failed in OPFS.\n // OPFS doesn't support symlinks, so paths through pnpm symlinks resolve in\n // VfsEngine (which has the symlink→target mapping) but not in OPFSEngine.\n // This handles: readdir, stat, lstat, read, exists, access, realpath, readlink\n //\n // For most ops, OPFS returns ENOENT (status=1) when path not found.\n // But EXISTS is special: it returns OK (status=0) with data=[0] for non-existent paths.\n // So we also trigger fallback for EXISTS when the result indicates \"not found\".\n const ENOENT_STATUS = 1; // CODE_TO_STATUS.ENOENT\n const READ_OPS: number[] = [OP.READ, OP.STAT, OP.LSTAT, OP.READDIR, OP.EXISTS, OP.ACCESS, OP.REALPATH, OP.READLINK];\n const isExistsNotFound = op === OP.EXISTS && result.status === 0 && result.data instanceof Uint8Array && result.data[0] === 0;\n if ((result.status === ENOENT_STATUS || isExistsNotFound) && READ_OPS.includes(op)) {\n const vfsResult = (() => {\n switch (op) {\n case OP.READ: return engine.read(path);\n case OP.STAT: return engine.stat(path);\n case OP.LSTAT: return engine.lstat(path);\n case OP.READDIR: return engine.readdir(path, flags);\n case OP.EXISTS: return engine.exists(path);\n case OP.ACCESS: return engine.access(path, flags);\n case OP.REALPATH: return engine.realpath(path);\n case OP.READLINK: return engine.readlink(path);\n default: return null;\n }\n })();\n if (vfsResult && vfsResult.status !== ENOENT_STATUS) {\n result = vfsResult;\n }\n }\n\n const ret: { status: number; data?: Uint8Array; _op?: number; _path?: string; _newPath?: string } = {\n status: result.status,\n data: result.data instanceof Uint8Array ? result.data : undefined,\n };\n if (result.status === 0 && syncPath) {\n // Watch broadcast (OPFS mode doesn't need OPFS sync since it IS OPFS)\n broadcastWatch(op, syncPath, syncNewPath);\n }\n return ret;\n}\n\n// ========== SAB I/O helpers ==========\n\n/**\n * Read the full request/response payload from a SAB. Handles multi-chunk assembly.\n * Returns an owned Uint8Array (not a view into the SAB).\n */\nfunction readPayload(targetSab: SharedArrayBuffer, targetCtrl: Int32Array): Uint8Array {\n const totalLenView = new BigUint64Array(targetSab, SAB_OFFSETS.TOTAL_LEN, 1);\n const maxChunk = targetSab.byteLength - HEADER_SIZE;\n\n const chunkLen = Atomics.load(targetCtrl, 3);\n const totalLen = Number(Atomics.load(totalLenView, 0));\n\n // Guard against zero/negative chunk lengths (SAB race or stale data)\n if (chunkLen <= 0 || chunkLen > maxChunk) {\n console.error(`[sync-relay] readPayload: invalid chunkLen=${chunkLen} (maxChunk=${maxChunk}, totalLen=${totalLen})`);\n return new Uint8Array(0);\n }\n\n if (totalLen <= maxChunk) {\n // Fast path: single chunk\n return new Uint8Array(targetSab, HEADER_SIZE, chunkLen).slice();\n }\n\n // Guard against corrupt TOTAL_LEN causing OOM\n if (totalLen > activeLimits.maxPayload || totalLen <= 0) {\n console.error(`[sync-relay] readPayload: totalLen=${totalLen} exceeds limit (${activeLimits.maxPayload}) or invalid`);\n return new Uint8Array(0);\n }\n\n // Multi-chunk: assemble full buffer\n const fullBuffer = new Uint8Array(totalLen);\n let offset = 0;\n\n // Read first chunk (already in SAB)\n fullBuffer.set(new Uint8Array(targetSab, HEADER_SIZE, chunkLen), offset);\n offset += chunkLen;\n\n // Ack and wait for more chunks\n while (offset < totalLen) {\n Atomics.store(targetCtrl, 0, SIGNAL.CHUNK_ACK);\n Atomics.notify(targetCtrl, 0);\n Atomics.wait(targetCtrl, 0, SIGNAL.CHUNK_ACK); // Wait for next chunk\n const nextLen = Atomics.load(targetCtrl, 3);\n if (nextLen <= 0 || nextLen > maxChunk) {\n console.error(`[sync-relay] readPayload: invalid nextLen=${nextLen} at offset=${offset}`);\n return fullBuffer.slice(0, offset); // return what we have so far\n }\n fullBuffer.set(new Uint8Array(targetSab, HEADER_SIZE, nextLen), offset);\n offset += nextLen;\n }\n\n return fullBuffer;\n}\n\n/**\n * Write status + data directly into a SAB (no intermediate encodeResponse buffer).\n * Saves one full copy of the data compared to encodeResponse + writeResponse.\n */\nfunction writeDirectResponse(\n targetSab: SharedArrayBuffer,\n targetCtrl: Int32Array,\n status: number,\n data?: Uint8Array\n): void {\n const dataLen = data ? data.byteLength : 0;\n const totalLen = 8 + dataLen;\n const maxChunk = targetSab.byteLength - HEADER_SIZE;\n\n if (totalLen <= maxChunk) {\n // Fast path: write 8-byte header + data directly into SAB\n const hdr = new DataView(targetSab, HEADER_SIZE, 8);\n hdr.setUint32(0, status, true);\n hdr.setUint32(4, dataLen, true);\n if (data && dataLen > 0) {\n new Uint8Array(targetSab, HEADER_SIZE + 8, dataLen).set(data);\n }\n Atomics.store(targetCtrl, 3, totalLen);\n const totalView = new BigUint64Array(targetSab, SAB_OFFSETS.TOTAL_LEN, 1);\n Atomics.store(totalView, 0, BigInt(totalLen));\n Atomics.store(targetCtrl, 0, SIGNAL.RESPONSE);\n Atomics.notify(targetCtrl, 0);\n } else {\n // Multi-chunk: fall back to encoded buffer + chunked write\n const response = encodeResponse(status, data);\n writeResponse(targetSab, targetCtrl, new Uint8Array(response));\n }\n}\n\n/**\n * Write a response payload to a SAB and signal RESPONSE. Handles multi-chunk.\n */\nfunction writeResponse(targetSab: SharedArrayBuffer, targetCtrl: Int32Array, responseData: Uint8Array): void {\n const maxChunk = targetSab.byteLength - HEADER_SIZE;\n\n if (responseData.byteLength <= maxChunk) {\n // Fast path: single chunk\n new Uint8Array(targetSab, HEADER_SIZE, responseData.byteLength).set(responseData);\n Atomics.store(targetCtrl, 3, responseData.byteLength);\n const totalView = new BigUint64Array(targetSab, SAB_OFFSETS.TOTAL_LEN, 1);\n Atomics.store(totalView, 0, BigInt(responseData.byteLength));\n Atomics.store(targetCtrl, 0, SIGNAL.RESPONSE);\n Atomics.notify(targetCtrl, 0);\n } else {\n // Multi-chunk response\n const totalView = new BigUint64Array(targetSab, SAB_OFFSETS.TOTAL_LEN, 1);\n Atomics.store(totalView, 0, BigInt(responseData.byteLength));\n let sent = 0;\n while (sent < responseData.byteLength) {\n const chunkSize = Math.min(maxChunk, responseData.byteLength - sent);\n new Uint8Array(targetSab, HEADER_SIZE, chunkSize).set(\n responseData.subarray(sent, sent + chunkSize)\n );\n Atomics.store(targetCtrl, 3, chunkSize);\n Atomics.store(targetCtrl, 6, Math.floor(sent / maxChunk));\n\n const isLast = sent + chunkSize >= responseData.byteLength;\n Atomics.store(targetCtrl, 0, isLast ? SIGNAL.RESPONSE : SIGNAL.CHUNK);\n Atomics.notify(targetCtrl, 0);\n\n if (!isLast) {\n Atomics.wait(targetCtrl, 0, SIGNAL.CHUNK); // Wait for reader ack\n }\n sent += chunkSize;\n }\n }\n}\n\n// ========== Leader mode: main loop ==========\n\nasync function leaderLoop(): Promise<void> {\n leaderLoopRunning = true;\n while (true) {\n // === Inner tight loop: process all pending work without yielding ===\n let processed = true;\n let tightOps = 0;\n while (processed) {\n processed = false;\n\n // Periodic yield: during sustained load the inner loop never exits,\n // starving MessagePort handlers (external OPFS changes, client ports).\n // Yield every 100 ops to let the event loop process pending messages.\n if (++tightOps >= 100) {\n tightOps = 0;\n await yieldToEventLoop();\n }\n\n // Priority 1: own tab's sync requests (fastest path)\n if (Atomics.load(ctrl, 0) === SIGNAL.REQUEST) {\n const lt0 = debug ? performance.now() : 0;\n const payload = readPayload(sab, ctrl);\n const lt1 = debug ? performance.now() : 0;\n const reqResult = handleRequest(tabId, payload.buffer as ArrayBuffer);\n const lt2 = debug ? performance.now() : 0;\n writeDirectResponse(sab, ctrl, reqResult.status, reqResult.data);\n if (reqResult._op !== undefined) notifyOPFSSync(reqResult._op, reqResult._path!, reqResult._newPath);\n const lt3 = debug ? performance.now() : 0;\n if (debug) {\n console.log(`[leaderLoop] readPayload=${(lt1-lt0).toFixed(3)}ms handleRequest=${(lt2-lt1).toFixed(3)}ms writeResponse=${(lt3-lt2).toFixed(3)}ms TOTAL=${(lt3-lt0).toFixed(3)}ms`);\n }\n // Wait for main thread to consume response (10ms safety timeout).\n // Main thread sets IDLE without notify — worker stays asleep until the\n // NEXT request's notify wakes it. This gives ONE wake per operation.\n const waitResult = Atomics.wait(ctrl, 0, SIGNAL.RESPONSE, 100);\n if (waitResult === 'timed-out') {\n Atomics.store(ctrl, 0, SIGNAL.IDLE);\n }\n processed = true;\n continue;\n }\n\n // Priority 2: own tab's async requests\n if (asyncCtrl && Atomics.load(asyncCtrl, 0) === SIGNAL.REQUEST) {\n const payload = readPayload(asyncSab!, asyncCtrl);\n const asyncResult = handleRequest(tabId, payload.buffer as ArrayBuffer);\n writeDirectResponse(asyncSab!, asyncCtrl, asyncResult.status, asyncResult.data);\n if (asyncResult._op !== undefined) notifyOPFSSync(asyncResult._op, asyncResult._path!, asyncResult._newPath);\n // Wait for async-relay to consume response and reset to IDLE.\n // writeResponse handles multi-chunk handshake internally; when it\n // returns the async-relay has all data but may need one more tick\n // to set IDLE. Use Atomics.wait with a reasonable timeout.\n if (Atomics.load(asyncCtrl, 0) !== SIGNAL.IDLE) {\n Atomics.wait(asyncCtrl, 0, SIGNAL.RESPONSE, 5000);\n }\n processed = true;\n continue;\n }\n\n // Priority 3: client requests already queued from previous yields\n if (portQueue.length > 0) {\n drainPortQueue();\n processed = true;\n continue;\n }\n }\n\n // === All queues empty — yield to process MessagePort events ===\n // Always yield: external OPFS changes arrive via opfsSyncPort.onmessage,\n // client registrations via self.onmessage — both need the event loop.\n await yieldToEventLoop();\n\n // If no clients and no new SAB work, block briefly for next request\n if (clientPorts.size === 0 && !opfsSyncEnabled) {\n const currentSignal = Atomics.load(ctrl, 0);\n if (currentSignal !== SIGNAL.REQUEST) {\n Atomics.wait(ctrl, 0, currentSignal, 50);\n }\n }\n }\n}\n\n// ========== OPFS mode: leader loop (async handleRequest) ==========\n\nasync function leaderLoopOPFS(): Promise<void> {\n leaderLoopRunning = true;\n while (true) {\n let processed = true;\n let tightOps = 0;\n while (processed) {\n processed = false;\n\n if (++tightOps >= 100) {\n tightOps = 0;\n await yieldToEventLoop();\n }\n\n // Priority 1: own tab's sync requests\n if (Atomics.load(ctrl, 0) === SIGNAL.REQUEST) {\n const payload = readPayload(sab, ctrl);\n const reqResult = await handleRequestOPFS(tabId, payload.buffer as ArrayBuffer);\n writeDirectResponse(sab, ctrl, reqResult.status, reqResult.data);\n const waitResult = Atomics.wait(ctrl, 0, SIGNAL.RESPONSE, 100);\n if (waitResult === 'timed-out') {\n Atomics.store(ctrl, 0, SIGNAL.IDLE);\n }\n processed = true;\n continue;\n }\n\n // Priority 2: own tab's async requests\n if (asyncCtrl && Atomics.load(asyncCtrl, 0) === SIGNAL.REQUEST) {\n const payload = readPayload(asyncSab!, asyncCtrl);\n const asyncResult = await handleRequestOPFS(tabId, payload.buffer as ArrayBuffer);\n writeDirectResponse(asyncSab!, asyncCtrl, asyncResult.status, asyncResult.data);\n const waitResult = Atomics.wait(asyncCtrl, 0, SIGNAL.RESPONSE, 100);\n if (waitResult === 'timed-out') {\n Atomics.store(asyncCtrl, 0, SIGNAL.IDLE);\n }\n processed = true;\n continue;\n }\n\n // Priority 3: client requests\n if (portQueue.length > 0) {\n await drainPortQueueAsync();\n processed = true;\n continue;\n }\n }\n\n await yieldToEventLoop();\n\n if (clientPorts.size === 0) {\n const currentSignal = Atomics.load(ctrl, 0);\n if (currentSignal !== SIGNAL.REQUEST) {\n Atomics.wait(ctrl, 0, currentSignal, 50);\n }\n }\n }\n}\n\n// ========== Follower mode: relay loop ==========\n\nasync function followerLoop(): Promise<void> {\n while (true) {\n // Check own sync SAB\n if (Atomics.load(ctrl, 0) === SIGNAL.REQUEST) {\n const payload = readPayload(sab, ctrl);\n const response = await forwardToLeader(payload);\n writeResponse(sab, ctrl, new Uint8Array(response));\n // Wait for main thread to consume response (safety timeout to prevent deadlock —\n // main thread stores IDLE without notify)\n const result = Atomics.wait(ctrl, 0, SIGNAL.RESPONSE, 100);\n if (result === 'timed-out') {\n Atomics.store(ctrl, 0, SIGNAL.IDLE);\n }\n continue;\n }\n\n // Check own async SAB\n if (asyncCtrl && Atomics.load(asyncCtrl, 0) === SIGNAL.REQUEST) {\n const payload = readPayload(asyncSab!, asyncCtrl);\n const response = await forwardToLeader(payload);\n writeResponse(asyncSab!, asyncCtrl, new Uint8Array(response));\n const result = Atomics.wait(asyncCtrl, 0, SIGNAL.RESPONSE, 100);\n if (result === 'timed-out') {\n Atomics.store(asyncCtrl, 0, SIGNAL.IDLE);\n }\n continue;\n }\n\n // Wait for SAB notification or timeout; yield on idle to process onmessage\n // (e.g. leader-port reconnection). Requests wake via Atomics.notify on ctrl.\n const waitResult = Atomics.wait(ctrl, 0, SIGNAL.IDLE, 50);\n if (waitResult === 'timed-out') {\n await yieldToEventLoop();\n }\n }\n}\n\n// ========== OPFS + VFS engine initialization (leader only) ==========\n\n// ========== OPFS directory scanning (for auto-populate on fresh VFS) ==========\n\nconst OPFS_SKIP = new Set(['.vfs.bin', '.vfs.bin.tmp']);\n\n// Chunk size for streamed population of fresh VFS from existing OPFS.\n// Caps peak memory during init at this size per file instead of\n// materializing every OPFS file into the heap simultaneously.\nconst OPFS_POPULATE_CHUNK = 2 * 1024 * 1024;\n\n// Populate a fresh VFS from an existing OPFS tree, streaming one file at\n// a time through the engine. Directories are created before their files,\n// files are written via truncate + chunked append so peak memory is\n// bounded by OPFS_POPULATE_CHUNK rather than the sum of all file sizes.\nasync function populateVFSFromOPFS(\n dir: FileSystemDirectoryHandle,\n prefix: string,\n): Promise<void> {\n const subdirs: Array<{ name: string; handle: FileSystemDirectoryHandle }> = [];\n const files: Array<{ name: string; handle: FileSystemFileHandle }> = [];\n for await (const [name, handle] of (dir as any).entries()) {\n if (prefix === '' && OPFS_SKIP.has(name)) continue;\n if (handle.kind === 'directory') {\n subdirs.push({ name, handle: handle as FileSystemDirectoryHandle });\n } else {\n files.push({ name, handle: handle as FileSystemFileHandle });\n }\n }\n\n // Create directories at this level first so file writes below (and\n // recursive calls) can rely on their parents existing.\n for (const { name } of subdirs) {\n const fullPath = prefix ? `${prefix}/${name}` : `/${name}`;\n engine.mkdir(fullPath, 0o040755);\n }\n\n // Stream each file through a single reusable chunk buffer.\n for (const { name, handle } of files) {\n const fullPath = prefix ? `${prefix}/${name}` : `/${name}`;\n let access: FileSystemSyncAccessHandle | null = null;\n try {\n access = await (handle as unknown as { createSyncAccessHandle: () => Promise<FileSystemSyncAccessHandle> }).createSyncAccessHandle();\n const size = access.getSize();\n // Create as empty, then append in chunks. engine.write(fullPath, empty)\n // establishes the inode; engine.append grows it without reallocation.\n engine.write(fullPath, new Uint8Array(0));\n if (size > 0) {\n const chunk = new Uint8Array(Math.min(size, OPFS_POPULATE_CHUNK));\n let offset = 0;\n while (offset < size) {\n const len = Math.min(chunk.length, size - offset);\n const view = len === chunk.length ? chunk : chunk.subarray(0, len);\n access.read(view, { at: offset });\n engine.append(fullPath, view);\n offset += len;\n }\n }\n } finally {\n if (access) { try { access.close(); } catch { /* ignore */ } }\n }\n }\n\n // Recurse into subdirectories.\n for (const { name, handle } of subdirs) {\n const fullPath = prefix ? `${prefix}/${name}` : `/${name}`;\n await populateVFSFromOPFS(handle, fullPath);\n }\n}\n\n/**\n * Quick superblock validation — reads only 64 bytes to detect corruption\n * BEFORE engine.init() runs. Prevents hangs from corrupt values causing\n * huge allocations or blocking Atomics loops.\n * Returns null if valid, or an error description string if corrupt.\n */\ninterface ResolvedLimits {\n maxInodes: number;\n maxBlocks: number;\n maxPathTable: number;\n maxVFSSize: number;\n maxPayload: number;\n}\n\nconst DEFAULT_LIMITS: ResolvedLimits = {\n maxInodes: 4_000_000,\n maxBlocks: 4_000_000,\n maxPathTable: 256 * 1024 * 1024,\n maxVFSSize: 100 * 1024 * 1024 * 1024,\n maxPayload: 2 * 1024 * 1024 * 1024,\n};\n\nfunction resolveLimits(input?: Partial<ResolvedLimits>): ResolvedLimits {\n return { ...DEFAULT_LIMITS, ...input };\n}\n\n// Active limits for this worker instance\nlet activeLimits: ResolvedLimits = { ...DEFAULT_LIMITS };\n\nfunction quickValidateVFS(handle: FileSystemSyncAccessHandle, fileSize: number, limits: ResolvedLimits): string | null {\n if (fileSize < SUPERBLOCK.SIZE) return `file too small (${fileSize} bytes)`;\n\n const buf = new Uint8Array(SUPERBLOCK.SIZE);\n handle.read(buf, { at: 0 });\n const v = new DataView(buf.buffer);\n\n const magic = v.getUint32(SUPERBLOCK.MAGIC, true);\n if (magic !== VFS_MAGIC) return `bad magic 0x${magic.toString(16)}`;\n const version = v.getUint32(SUPERBLOCK.VERSION, true);\n if (version !== VFS_VERSION) return `unsupported version ${version}`;\n\n const inodeCount = v.getUint32(SUPERBLOCK.INODE_COUNT, true);\n const blockSize = v.getUint32(SUPERBLOCK.BLOCK_SIZE, true);\n const totalBlocks = v.getUint32(SUPERBLOCK.TOTAL_BLOCKS, true);\n const freeBlocks = v.getUint32(SUPERBLOCK.FREE_BLOCKS, true);\n const inodeTableOffset = v.getFloat64(SUPERBLOCK.INODE_OFFSET, true);\n const pathTableOffset = v.getFloat64(SUPERBLOCK.PATH_OFFSET, true);\n const dataOffset = v.getFloat64(SUPERBLOCK.DATA_OFFSET, true);\n const bitmapOffset = v.getFloat64(SUPERBLOCK.BITMAP_OFFSET, true);\n const pathUsed = v.getUint32(SUPERBLOCK.PATH_USED, true);\n\n // Basic field sanity\n if (blockSize === 0 || (blockSize & (blockSize - 1)) !== 0) return `invalid block size ${blockSize}`;\n if (inodeCount === 0) return 'inode count is 0';\n if (inodeCount > limits.maxInodes) return `inode count ${inodeCount} exceeds maximum ${limits.maxInodes}`;\n if (totalBlocks > limits.maxBlocks) return `total blocks ${totalBlocks} exceeds maximum ${limits.maxBlocks}`;\n if (freeBlocks > totalBlocks) return `free blocks (${freeBlocks}) exceeds total (${totalBlocks})`;\n\n // Offsets must be finite positive numbers\n if (!Number.isFinite(inodeTableOffset) || inodeTableOffset < 0 ||\n !Number.isFinite(pathTableOffset) || pathTableOffset < 0 ||\n !Number.isFinite(bitmapOffset) || bitmapOffset < 0 ||\n !Number.isFinite(dataOffset) || dataOffset < 0) return 'non-finite or negative section offset';\n\n // Section ordering\n if (inodeTableOffset !== SUPERBLOCK.SIZE) return `inode table offset ${inodeTableOffset} (expected ${SUPERBLOCK.SIZE})`;\n const expectedPathOffset = inodeTableOffset + inodeCount * INODE_SIZE;\n if (pathTableOffset !== expectedPathOffset) return `path table offset ${pathTableOffset} (expected ${expectedPathOffset})`;\n if (bitmapOffset <= pathTableOffset) return 'bitmap offset must be after path table';\n if (dataOffset <= bitmapOffset) return 'data offset must be after bitmap';\n\n // Path table bounds\n const pathTableSize = bitmapOffset - pathTableOffset;\n if (pathUsed > pathTableSize) return `path used (${pathUsed}) exceeds path table size (${pathTableSize})`;\n if (pathTableSize > limits.maxPathTable) return `path table size ${pathTableSize} exceeds maximum ${limits.maxPathTable}`;\n\n // File size vs declared layout\n const expectedMinSize = dataOffset + totalBlocks * blockSize;\n if (expectedMinSize > limits.maxVFSSize) return `computed layout size ${expectedMinSize} exceeds maximum ${limits.maxVFSSize}`;\n if (fileSize < expectedMinSize) return `file size ${fileSize} too small for layout (need ${expectedMinSize})`;\n\n return null;\n}\n\nasync function initEngine(config: {\n root: string;\n ns: string;\n opfsSync: boolean;\n opfsSyncRoot?: string;\n uid: number;\n gid: number;\n umask: number;\n strictPermissions: boolean;\n debug?: boolean;\n limits?: Partial<ResolvedLimits>;\n}): Promise<void> {\n debug = config.debug ?? false;\n activeLimits = resolveLimits(config.limits);\n\n // Navigate to configured OPFS root\n let rootDir = await navigator.storage.getDirectory();\n\n if (config.root && config.root !== '/') {\n const segments = config.root.split('/').filter(Boolean);\n for (const segment of segments) {\n rootDir = await rootDir.getDirectoryHandle(segment, { create: true });\n }\n }\n\n // Open VFS binary file with exclusive sync access\n const vfsFileHandle = await rootDir.getFileHandle('.vfs.bin', { create: true });\n const vfsHandle = await vfsFileHandle.createSyncAccessHandle();\n\n // Pre-validate vfs.bin BEFORE engine.init() to prevent hangs from corrupt data\n // causing huge allocations or blocking Atomics loops. Throws early so the caller\n // can offer repair instead of silently losing data.\n const vfsSize = vfsHandle.getSize();\n if (vfsSize > 0) {\n const validationError = quickValidateVFS(vfsHandle, vfsSize, activeLimits);\n if (validationError) {\n try { vfsHandle.close(); } catch (_) {}\n throw new Error(`Corrupt VFS: ${validationError}`);\n }\n }\n\n const wasFresh = vfsSize === 0;\n\n // Initialize VFS engine — release handle on corruption/failure\n try {\n engine.init(vfsHandle, {\n uid: config.uid,\n gid: config.gid,\n umask: config.umask,\n strictPermissions: config.strictPermissions,\n debug: config.debug,\n limits: activeLimits,\n });\n } catch (err) {\n // Release the exclusive sync handle so it can be re-acquired\n try { vfsHandle.close(); } catch (_) {}\n throw err;\n }\n\n // Auto-populate fresh VFS from existing OPFS files (streamed one file\n // at a time — see populateVFSFromOPFS for why).\n if (wasFresh) {\n await populateVFSFromOPFS(rootDir, '');\n engine.flush();\n }\n\n // Spawn OPFS sync worker (mirrors VFS mutations to real OPFS files)\n if (config.opfsSync) {\n opfsSyncEnabled = true;\n const mc = new MessageChannel();\n opfsSyncPort = mc.port1;\n opfsSyncPort.onmessage = (e) => handleExternalChange(e.data);\n opfsSyncPort.start();\n\n const workerUrl = new URL('./opfs-sync.worker.js', import.meta.url);\n const syncWorker = new Worker(workerUrl, { type: 'module' });\n syncWorker.postMessage(\n { type: 'init', root: config.opfsSyncRoot ?? config.root },\n [mc.port2],\n );\n }\n\n // Watch broadcast channel — fires on every VFS mutation for fs.watch() support\n watchBc = new BroadcastChannel(`${config.ns}-watch`);\n}\n\n/** Initialize OPFS-direct mode engine (no VFS binary) */\nasync function initOPFSEngine(config: {\n root: string;\n ns: string;\n uid: number;\n gid: number;\n debug?: boolean;\n}): Promise<void> {\n debug = config.debug ?? false;\n opfsMode = true;\n\n // Navigate to configured OPFS root\n let rootDir = await navigator.storage.getDirectory();\n if (config.root && config.root !== '/') {\n const segments = config.root.split('/').filter(Boolean);\n for (const segment of segments) {\n rootDir = await rootDir.getDirectoryHandle(segment, { create: true });\n }\n }\n\n opfsEngine = new OPFSEngine();\n await opfsEngine.init(rootDir, {\n uid: config.uid,\n gid: config.gid,\n });\n\n // Watch broadcast channel for fs.watch() support\n watchBc = new BroadcastChannel(`${config.ns}-watch`);\n}\n\n// ========== Watch broadcast (fire-and-forget, after SAB response) ==========\n\nfunction broadcastWatch(op: number, path: string, newPath?: string): void {\n if (!watchBc) return;\n\n // Mirror Node/libuv semantics:\n // 'change' — contents or metadata of an existing entry changed\n // 'rename' — an entry was created, removed, or moved in its parent\n let eventType: 'change' | 'rename';\n switch (op) {\n case OP.WRITE:\n case OP.APPEND:\n case OP.TRUNCATE:\n case OP.FWRITE:\n case OP.FTRUNCATE:\n case OP.CHMOD:\n case OP.CHOWN:\n case OP.UTIMES:\n case OP.COPY: // target file's contents were overwritten → 'change'\n eventType = 'change';\n break;\n case OP.UNLINK:\n case OP.RMDIR:\n case OP.RENAME:\n case OP.MKDIR:\n case OP.MKDTEMP:\n case OP.SYMLINK:\n case OP.LINK:\n eventType = 'rename';\n break;\n default:\n return;\n }\n\n watchBc.postMessage({ eventType, path });\n if (op === OP.RENAME && newPath) {\n watchBc.postMessage({ eventType: 'rename', path: newPath });\n }\n}\n\n// ========== OPFS sync notification (fire-and-forget, after SAB response) ==========\n//\n// Per-path debounce coalescer. Without this, every FWRITE/WRITE/FTRUNCATE\n// triggers a full-file `engine.read(path)` here — which allocates a\n// `new Uint8Array(inode.size)` on every call. For a file grown chunk-by-\n// chunk (e.g. formidable writing a 100 MB upload via a 64 KB stream),\n// that's ~1500 full-file reads totalling many GB of allocations, and the\n// largest allocation (the final full file size) eventually fails with\n// \"Array buffer allocation failed\" under memory pressure.\n//\n// Instead, coalesce bursts: any write-op schedules a sync 50 ms later,\n// and subsequent write-ops to the same path reset the timer. At most\n// ONE full-file read per burst, reading the file once at its final size.\nconst pendingPathSyncs = new Map<string, ReturnType<typeof setTimeout>>();\nconst SYNC_DEBOUNCE_MS = 50;\n\nfunction flushPathSync(path: string): void {\n pendingPathSyncs.delete(path);\n if (!opfsSyncPort) return;\n try {\n const result = engine.read(path);\n if (result.status !== 0) return;\n const ts = Date.now();\n if (result.data && result.data.byteLength > 0) {\n const buf = result.data.buffer.byteLength === result.data.byteLength\n ? result.data.buffer\n : result.data.slice().buffer;\n opfsSyncPort.postMessage({ op: 'write', path, data: buf, ts } as const, [buf as ArrayBuffer]);\n } else {\n opfsSyncPort.postMessage({ op: 'write', path, data: new ArrayBuffer(0), ts });\n }\n } catch { /* best effort — don't crash the relay on sync failures */ }\n}\n\nfunction schedulePathSync(path: string): void {\n const prev = pendingPathSyncs.get(path);\n if (prev) clearTimeout(prev);\n pendingPathSyncs.set(path, setTimeout(() => flushPathSync(path), SYNC_DEBOUNCE_MS));\n}\n\nfunction notifyOPFSSync(op: number, path: string, newPath?: string): void {\n if (!opfsSyncPort) return;\n if (suppressPaths.has(path)) {\n suppressPaths.delete(path);\n return;\n }\n\n const ts = Date.now();\n\n switch (op) {\n case OP.WRITE:\n case OP.APPEND:\n case OP.TRUNCATE:\n case OP.FWRITE:\n case OP.FTRUNCATE:\n case OP.COPY:\n case OP.LINK: {\n // Coalesce bursts of writes to the same path — flush once after a\n // short idle period so large chunked writes don't cause N\n // full-file reads that exhaust the worker's heap.\n schedulePathSync(path);\n break;\n }\n case OP.SYMLINK: {\n // OPFS has no symlinks — mirror as regular file with the target's\n // content. Route through the same debounced flusher so this also\n // benefits from coalescing if the symlink target is being actively\n // written in the same burst.\n schedulePathSync(path);\n break;\n }\n case OP.UNLINK:\n case OP.RMDIR: {\n // Cancel any pending debounced sync for this path — the file no\n // longer exists, we'd just fail the read.\n const pending = pendingPathSyncs.get(path);\n if (pending) { clearTimeout(pending); pendingPathSyncs.delete(path); }\n opfsSyncPort.postMessage({ op: 'delete', path, ts });\n break;\n }\n case OP.MKDIR:\n case OP.MKDTEMP:\n opfsSyncPort.postMessage({ op: 'mkdir', path, ts });\n break;\n case OP.RENAME:\n if (newPath) {\n // Reroute any pending sync on the old path to the new path so\n // the content ends up at the final location after the burst.\n const pending = pendingPathSyncs.get(path);\n if (pending) {\n clearTimeout(pending);\n pendingPathSyncs.delete(path);\n schedulePathSync(newPath);\n }\n opfsSyncPort.postMessage({ op: 'rename', path, newPath, ts });\n }\n break;\n }\n}\n\nfunction handleExternalChange(msg: { op: string; path: string; newPath?: string; data?: ArrayBuffer }): void {\n switch (msg.op) {\n case 'external-write': {\n suppressPaths.add(msg.path);\n const result = engine.write(msg.path, new Uint8Array(msg.data!), 0);\n if (result.status === 0) broadcastWatch(OP.WRITE, msg.path);\n console.log('[sync-relay] external-write:', msg.path, `${msg.data?.byteLength ?? 0}B`, `status=${result.status}`);\n break;\n }\n case 'external-delete': {\n suppressPaths.add(msg.path);\n const result = engine.unlink(msg.path);\n if (result.status !== 0) {\n const rmdirResult = engine.rmdir(msg.path, 1);\n if (rmdirResult.status === 0) broadcastWatch(OP.RMDIR, msg.path);\n console.log('[sync-relay] external-delete (rmdir):', msg.path, `status=${rmdirResult.status}`);\n } else {\n broadcastWatch(OP.UNLINK, msg.path);\n console.log('[sync-relay] external-delete:', msg.path, `status=${result.status}`);\n }\n break;\n }\n case 'external-rename':\n suppressPaths.add(msg.path);\n if (msg.newPath) {\n suppressPaths.add(msg.newPath);\n const result = engine.rename(msg.path, msg.newPath);\n if (result.status === 0) broadcastWatch(OP.RENAME, msg.path, msg.newPath);\n console.log('[sync-relay] external-rename:', msg.path, '→', msg.newPath, `status=${result.status}`);\n }\n break;\n }\n}\n\n// ========== Message handling ==========\n\nself.onmessage = async (e: MessageEvent) => {\n const msg = e.data;\n\n // --- Async port registration (no-SAB mode: async-relay connects via MessagePort) ---\n if (msg.type === 'async-port') {\n const port = msg.port ?? e.ports[0];\n if (port) {\n asyncRelayPort = port;\n port.onmessage = async (ev: MessageEvent) => {\n if (ev.data.buffer instanceof ArrayBuffer) {\n if (leaderInitialized) {\n // Leader mode: handle locally (engine available)\n const result = opfsMode\n ? await handleRequestOPFS(tabId || 'nosab', ev.data.buffer)\n : handleRequest(tabId || 'nosab', ev.data.buffer);\n const response = encodeResponse(result.status, result.data);\n port.postMessage({ id: ev.data.id, buffer: response }, [response]);\n if (!opfsMode && result._op !== undefined) notifyOPFSSync(result._op, result._path!, result._newPath);\n } else if (leaderPort) {\n // Follower mode: forward to leader via leader port\n const buf = ev.data.buffer;\n leaderPort.postMessage({ id: ev.data.id, tabId, buffer: buf }, [buf]);\n }\n }\n };\n port.start();\n }\n return;\n }\n\n // --- Leader mode init ---\n if (msg.type === 'init-leader') {\n if (leaderInitialized) return; // Prevent duplicate init during async gap\n leaderInitialized = true;\n\n tabId = msg.tabId;\n const hasSAB = msg.sab != null;\n\n if (hasSAB) {\n sab = msg.sab;\n readySab = msg.readySab;\n ctrl = new Int32Array(sab, 0, 8);\n readySignal = new Int32Array(readySab, 0, 1);\n }\n\n if (msg.asyncSab) {\n asyncSab = msg.asyncSab;\n asyncCtrl = new Int32Array(msg.asyncSab, 0, 8);\n }\n\n try {\n await initEngine(msg.config);\n } catch (err) {\n // OPFS handle unavailable — tell main thread to fall back\n leaderInitialized = false; // Allow retry\n (self as unknown as Worker).postMessage({\n type: 'init-failed',\n error: (err as Error).message,\n });\n return;\n }\n\n // Signal ready to main thread\n if (!readySent) {\n readySent = true;\n if (hasSAB) {\n Atomics.store(readySignal, 0, 1);\n Atomics.notify(readySignal, 0);\n }\n (self as unknown as Worker).postMessage({ type: 'ready' });\n }\n\n // Start leader loop only when SABs are available (it uses Atomics.wait)\n if (hasSAB) {\n leaderLoop();\n }\n // When no SAB, requests arrive only via MessagePorts (async-port handler above)\n return;\n }\n\n // --- OPFS-direct mode init ---\n if (msg.type === 'init-opfs') {\n // Reset guards for re-init (corruption fallback or mode=opfs)\n leaderInitialized = true;\n readySent = false;\n\n tabId = msg.tabId;\n const hasSAB = msg.sab != null;\n\n if (hasSAB) {\n sab = msg.sab;\n readySab = msg.readySab;\n ctrl = new Int32Array(sab, 0, 8);\n readySignal = new Int32Array(readySab, 0, 1);\n }\n\n if (msg.asyncSab) {\n asyncSab = msg.asyncSab;\n asyncCtrl = new Int32Array(msg.asyncSab, 0, 8);\n }\n\n try {\n await initOPFSEngine(msg.config);\n } catch (err) {\n leaderInitialized = false;\n (self as unknown as Worker).postMessage({\n type: 'init-failed',\n error: (err as Error).message,\n });\n return;\n }\n\n // Signal ready\n if (!readySent) {\n readySent = true;\n if (hasSAB) {\n Atomics.store(readySignal, 0, 1);\n Atomics.notify(readySignal, 0);\n }\n (self as unknown as Worker).postMessage({ type: 'ready', mode: 'opfs' });\n }\n\n if (hasSAB) {\n leaderLoopOPFS();\n }\n return;\n }\n\n // --- Follower mode init ---\n if (msg.type === 'init-follower') {\n tabId = msg.tabId;\n const hasSAB = msg.sab != null;\n\n if (hasSAB) {\n sab = msg.sab;\n readySab = msg.readySab;\n ctrl = new Int32Array(sab, 0, 8);\n readySignal = new Int32Array(readySab, 0, 1);\n }\n\n if (msg.asyncSab) {\n asyncSab = msg.asyncSab;\n asyncCtrl = new Int32Array(msg.asyncSab, 0, 8);\n }\n\n // Leader port will be sent separately\n return;\n }\n\n // --- Leader port (follower mode / reconnection) ---\n if (msg.type === 'leader-port') {\n // If already running as leader, ignore stale follower port\n if (leaderInitialized) return;\n\n const newPort = msg.port ?? e.ports[0];\n if (!newPort) return;\n\n // Reconnection: close old port and unblock any pending forwardToLeader()\n if (leaderPort) {\n leaderPort.close();\n if (pendingResolve) {\n // Resolve with EIO error response to unblock followerLoop\n const errorBuf = encodeResponse(5); // EIO\n pendingResolve(errorBuf);\n pendingResolve = null;\n }\n }\n\n leaderPort = newPort;\n newPort.onmessage = onLeaderMessage;\n newPort.start();\n\n if (!readySent) {\n // First time: signal ready and start follower loop\n readySent = true;\n if (readySignal) {\n Atomics.store(readySignal, 0, 1);\n Atomics.notify(readySignal, 0);\n }\n (self as unknown as Worker).postMessage({ type: 'ready' });\n if (ctrl) {\n followerLoop();\n }\n // When no SAB (no crossOriginIsolated), follower can't relay sync requests.\n // Only promises work — async-relay uses MessagePort to leader's sync-relay.\n }\n // If followerLoop is already running, it will pick up the new port on next iteration\n return;\n }\n\n // --- Client port registration (leader mode, during yields) ---\n if (msg.type === 'client-port') {\n registerClientPort(msg.tabId, msg.port ?? e.ports[0]);\n return;\n }\n\n // --- Client disconnection (leader mode) ---\n if (msg.type === 'client-lost') {\n removeClientPort(msg.tabId);\n return;\n }\n};\n"],"mappings":"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","names":["inode","data","children","totalSize","buf","view","offset","tabId","fd","encoder","encoder","totalSize","buf","view","offset","encoder","decoder","decoder","decoder"]}
|
|
1
|
+
{"version":3,"sources":["../../src/src/vfs/layout.ts","../../src/src/errors.ts","../../src/src/vfs/engine.ts","../../src/src/opfs-engine.ts","../../src/src/protocol/opcodes.ts","../../src/src/workers/sync-relay.worker.ts"],"sourcesContent":["/**\n * VFS Binary Layout Constants\n *\n * Defines the on-disk structure of the virtual filesystem binary file.\n * All reads/writes go through a FileSystemSyncAccessHandle.\n */\n\n// Magic number: \"VFS!\" in ASCII\nexport const VFS_MAGIC = 0x56465321;\nexport const VFS_VERSION = 1;\n\n// Default sizes\nexport const DEFAULT_BLOCK_SIZE = 4096;\nexport const DEFAULT_INODE_COUNT = 100000;\nexport const INODE_SIZE = 64; // bytes per inode entry\n\n// Superblock layout (64 bytes)\nexport const SUPERBLOCK = {\n SIZE: 64,\n MAGIC: 0, // uint32 - 0x56465321\n VERSION: 4, // uint32\n INODE_COUNT: 8, // uint32 - total inodes allocated\n BLOCK_SIZE: 12, // uint32 - data block size (default 4096)\n TOTAL_BLOCKS: 16, // uint32 - total data blocks\n FREE_BLOCKS: 20, // uint32 - available data blocks\n INODE_OFFSET: 24, // float64 - byte offset to inode table\n PATH_OFFSET: 32, // float64 - byte offset to path table\n DATA_OFFSET: 40, // float64 - byte offset to data region\n BITMAP_OFFSET: 48, // float64 - byte offset to free block bitmap\n PATH_USED: 56, // uint32 - bytes used in path table\n RESERVED: 60, // uint32\n} as const;\n\n// Inode entry layout (64 bytes each)\nexport const INODE = {\n TYPE: 0, // uint8 - 0=free, 1=file, 2=directory, 3=symlink\n FLAGS: 1, // uint8[3] - reserved\n PATH_OFFSET: 4, // uint32 - byte offset into path table\n PATH_LENGTH: 8, // uint16 - length of path string\n NLINK: 10, // uint16 - hard link count\n MODE: 12, // uint32 - permissions (e.g. 0o100644)\n SIZE: 16, // float64 - file content size in bytes (using f64 for >4GB)\n FIRST_BLOCK: 24, // uint32 - index of first data block\n BLOCK_COUNT: 28, // uint32 - number of contiguous data blocks\n MTIME: 32, // float64 - last modification time (ms since epoch)\n CTIME: 40, // float64 - creation/change time (ms since epoch)\n ATIME: 48, // float64 - last access time (ms since epoch)\n UID: 56, // uint32 - owner\n GID: 60, // uint32 - group\n} as const;\n\n// Inode type constants\nexport const INODE_TYPE = {\n FREE: 0,\n FILE: 1,\n DIRECTORY: 2,\n SYMLINK: 3,\n} as const;\n\n// Default file modes\nexport const DEFAULT_FILE_MODE = 0o100644;\nexport const DEFAULT_DIR_MODE = 0o040755;\nexport const DEFAULT_SYMLINK_MODE = 0o120777;\nexport const DEFAULT_UMASK = 0o022;\n\n// POSIX file type bits\nexport const S_IFMT = 0o170000;\nexport const S_IFREG = 0o100000;\nexport const S_IFDIR = 0o040000;\nexport const S_IFLNK = 0o120000;\n\n// Max symlink depth for cycle detection\nexport const MAX_SYMLINK_DEPTH = 40;\n\n// Path table compaction threshold (25% dead space)\nexport const PATH_COMPACTION_THRESHOLD = 0.25;\n\n// Initial path table size (256KB)\nexport const INITIAL_PATH_TABLE_SIZE = 256 * 1024;\n\n// Initial data blocks (1024 blocks = 4MB with 4KB blocks)\nexport const INITIAL_DATA_BLOCKS = 1024;\n\n/**\n * Calculate section offsets for a fresh VFS.\n */\nexport function calculateLayout(inodeCount: number = DEFAULT_INODE_COUNT, blockSize: number = DEFAULT_BLOCK_SIZE, totalBlocks: number = INITIAL_DATA_BLOCKS) {\n const inodeTableOffset = SUPERBLOCK.SIZE;\n const inodeTableSize = inodeCount * INODE_SIZE;\n const pathTableOffset = inodeTableOffset + inodeTableSize;\n const pathTableSize = INITIAL_PATH_TABLE_SIZE;\n const bitmapOffset = pathTableOffset + pathTableSize;\n const bitmapSize = Math.ceil(totalBlocks / 8);\n // Align data region to block boundary\n const dataOffset = Math.ceil((bitmapOffset + bitmapSize) / blockSize) * blockSize;\n const totalSize = dataOffset + totalBlocks * blockSize;\n\n return {\n inodeTableOffset,\n inodeTableSize,\n pathTableOffset,\n pathTableSize,\n bitmapOffset,\n bitmapSize,\n dataOffset,\n totalSize,\n totalBlocks,\n };\n}\n","/**\n * Node.js compatible filesystem error classes\n */\n\nexport class FSError extends Error {\n code: string;\n errno: number;\n syscall?: string;\n path?: string;\n\n constructor(code: string, errno: number, message: string, syscall?: string, path?: string) {\n super(message);\n this.name = 'FSError';\n this.code = code;\n this.errno = errno;\n this.syscall = syscall;\n this.path = path;\n }\n}\n\nexport const ErrorCodes = {\n ENOENT: -2,\n EEXIST: -17,\n EISDIR: -21,\n ENOTDIR: -20,\n ENOTEMPTY: -39,\n EACCES: -13,\n EBADF: -9,\n EINVAL: -22,\n EMFILE: -24,\n ENOSPC: -28,\n EPERM: -1,\n ENOSYS: -38,\n ELOOP: -40,\n} as const;\n\n/** Binary protocol status codes → error code mapping */\nexport const STATUS_TO_CODE: Record<number, string> = {\n 0: 'OK',\n 1: 'ENOENT',\n 2: 'EEXIST',\n 3: 'EISDIR',\n 4: 'ENOTDIR',\n 5: 'ENOTEMPTY',\n 6: 'EACCES',\n 7: 'EINVAL',\n 8: 'EBADF',\n 9: 'ELOOP',\n 10: 'ENOSPC',\n};\n\n/** Error code → binary protocol status mapping */\nexport const CODE_TO_STATUS: Record<string, number> = {\n OK: 0,\n ENOENT: 1,\n EEXIST: 2,\n EISDIR: 3,\n ENOTDIR: 4,\n ENOTEMPTY: 5,\n EACCES: 6,\n EINVAL: 7,\n EBADF: 8,\n ELOOP: 9,\n ENOSPC: 10,\n};\n\nexport function createError(code: string, syscall: string, path: string): FSError {\n const errno = ErrorCodes[code as keyof typeof ErrorCodes] ?? -1;\n const messages: Record<string, string> = {\n ENOENT: 'no such file or directory',\n EEXIST: 'file already exists',\n EISDIR: 'illegal operation on a directory',\n ENOTDIR: 'not a directory',\n ENOTEMPTY: 'directory not empty',\n EACCES: 'permission denied',\n EINVAL: 'invalid argument',\n EBADF: 'bad file descriptor',\n ELOOP: 'too many symbolic links encountered',\n ENOSPC: 'no space left on device',\n };\n const msg = messages[code] ?? 'unknown error';\n return new FSError(code, errno, `${code}: ${msg}, ${syscall} '${path}'`, syscall, path);\n}\n\nexport function statusToError(status: number, syscall: string, path: string): FSError {\n const code = STATUS_TO_CODE[status] ?? 'EINVAL';\n return createError(code, syscall, path);\n}\n","/**\n * VFS Engine — operates on a FileSystemSyncAccessHandle\n *\n * Manages the binary VFS layout: superblock, inode table, path table,\n * free block bitmap, and data region. All operations are synchronous\n * and run inside the server worker.\n */\n\nimport {\n VFS_MAGIC, VFS_VERSION, SUPERBLOCK, INODE, INODE_SIZE, INODE_TYPE,\n DEFAULT_BLOCK_SIZE, DEFAULT_INODE_COUNT, DEFAULT_FILE_MODE, DEFAULT_DIR_MODE,\n DEFAULT_SYMLINK_MODE, DEFAULT_UMASK, S_IFMT, S_IFREG, S_IFDIR, S_IFLNK,\n MAX_SYMLINK_DEPTH, INITIAL_DATA_BLOCKS, INITIAL_PATH_TABLE_SIZE,\n calculateLayout,\n} from './layout.js';\nimport { CODE_TO_STATUS } from '../errors.js';\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\ninterface Inode {\n type: number;\n pathOffset: number;\n pathLength: number;\n mode: number;\n size: number;\n firstBlock: number;\n blockCount: number;\n mtime: number;\n ctime: number;\n atime: number;\n uid: number;\n gid: number;\n nlink: number;\n}\n\ninterface FdEntry {\n tabId: string;\n inodeIdx: number;\n position: number;\n flags: number;\n implicitPath?: string; // set when fd was opened via opendir on an implicit directory\n}\n\nexport class VFSEngine {\n private handle!: FileSystemSyncAccessHandle;\n private pathIndex = new Map<string, number>(); // path → inode index\n private inodeCount = 0;\n private blockSize = DEFAULT_BLOCK_SIZE;\n private totalBlocks = 0;\n private freeBlocks = 0;\n private inodeTableOffset = 0;\n private pathTableOffset = 0;\n private pathTableUsed = 0;\n private pathTableSize = 0;\n private bitmapOffset = 0;\n private dataOffset = 0;\n private umask = DEFAULT_UMASK;\n private processUid = 0;\n private processGid = 0;\n private strictPermissions = false;\n private debug = false;\n\n // File descriptor table\n private fdTable = new Map<number, FdEntry>();\n private nextFd = 3; // 0=stdin, 1=stdout, 2=stderr reserved\n\n // Reusable buffers to avoid allocations\n private inodeBuf = new Uint8Array(INODE_SIZE);\n private inodeView = new DataView(this.inodeBuf.buffer);\n\n // In-memory inode cache — eliminates disk reads for hot inodes\n private inodeCache = new Map<number, Inode>();\n private superblockBuf = new Uint8Array(SUPERBLOCK.SIZE);\n private superblockView = new DataView(this.superblockBuf.buffer);\n\n // In-memory bitmap cache — eliminates bitmap reads from OPFS\n private bitmap: Uint8Array | null = null;\n private bitmapDirtyLo = Infinity; // lowest dirty byte index\n private bitmapDirtyHi = -1; // highest dirty byte index (inclusive)\n private superblockDirty = false;\n\n // Free inode hint — skip O(n) scan\n private freeInodeHint = 0;\n\n // Implicit directory support — tracks all directory prefixes implied by file paths.\n // Rebuilt lazily when pathIndex changes (tracked via generation counter).\n // Map value is the stable timestamp (ms since epoch) assigned when the implicit\n // dir was first discovered, so that stat() returns consistent mtime/ctime/atime\n // across repeated calls.\n private implicitDirs = new Map<string, number>();\n private implicitDirsGen = -1; // generation when implicitDirs was last rebuilt\n private pathIndexGen = 0; // bumped on every pathIndex mutation\n\n // Incrementally maintained \"number of pathIndex entries that have this\n // path as a strict ancestor\" map. Lets `isImplicitDirectory` answer in\n // O(1) — an implicit dir P is exactly !pathIndex.has(P) && descCount[P] > 0.\n // Without this, every `isImplicitDirectory` call triggered an O(N×depth)\n // rebuild of `implicitDirs`, and the 3.0.49 fix put one of those calls on\n // the hot path of every fresh write/symlink/link/copy — making batch\n // writes O(N²) on total path count.\n private descCount = new Map<string, number>();\n // descCount is in sync with pathIndex iff descCountGen >= pathIndexGen.\n // Helpers `setPathIndex`/`deletePathIndex` keep them in sync. Code that\n // mutates `pathIndex` directly (only test scaffolding does this in\n // practice — see the implicit-directory tests in vfs-engine.test.ts)\n // bumps `pathIndexGen` without going through the helpers, which leaves\n // descCount stale; `isImplicitDirectory` notices the mismatch and\n // recomputes descCount on demand.\n private descCountGen = 0;\n\n // Configurable upper bounds\n private maxInodes = 4_000_000;\n private maxBlocks = 4_000_000;\n private maxPathTable = 256 * 1024 * 1024; // 256MB\n private maxVFSSize = 100 * 1024 * 1024 * 1024; // 100GB\n\n init(\n handle: FileSystemSyncAccessHandle,\n opts?: {\n uid?: number; gid?: number; umask?: number; strictPermissions?: boolean; debug?: boolean;\n limits?: { maxInodes?: number; maxBlocks?: number; maxPathTable?: number; maxVFSSize?: number };\n }\n ): void {\n this.handle = handle;\n this.processUid = opts?.uid ?? 0;\n this.processGid = opts?.gid ?? 0;\n this.umask = opts?.umask ?? DEFAULT_UMASK;\n this.strictPermissions = opts?.strictPermissions ?? false;\n this.debug = opts?.debug ?? false;\n if (opts?.limits) {\n if (opts.limits.maxInodes != null) this.maxInodes = opts.limits.maxInodes;\n if (opts.limits.maxBlocks != null) this.maxBlocks = opts.limits.maxBlocks;\n if (opts.limits.maxPathTable != null) this.maxPathTable = opts.limits.maxPathTable;\n if (opts.limits.maxVFSSize != null) this.maxVFSSize = opts.limits.maxVFSSize;\n }\n\n const size = handle.getSize();\n\n if (size === 0) {\n this.format();\n } else {\n try {\n this.mount();\n } catch (err) {\n // Ensure all mount errors are prefixed with \"Corrupt VFS:\" so the\n // sync-relay handler recognizes them as corruption (not OPFS contention)\n // and triggers fallback instead of infinite retry.\n const msg = (err as Error).message ?? String(err);\n if (msg.startsWith('Corrupt VFS:')) throw err;\n throw new Error(`Corrupt VFS: ${msg}`);\n }\n }\n }\n\n /** Release the sync access handle (call on fatal error or shutdown) */\n closeHandle(): void {\n try {\n this.handle?.close();\n } catch (_) {\n // Ignore — handle may already be closed\n }\n }\n\n /** Format a fresh VFS */\n private format(): void {\n const layout = calculateLayout(DEFAULT_INODE_COUNT, DEFAULT_BLOCK_SIZE, INITIAL_DATA_BLOCKS);\n\n this.inodeCount = DEFAULT_INODE_COUNT;\n this.blockSize = DEFAULT_BLOCK_SIZE;\n this.totalBlocks = layout.totalBlocks;\n this.freeBlocks = layout.totalBlocks;\n this.inodeTableOffset = layout.inodeTableOffset;\n this.pathTableOffset = layout.pathTableOffset;\n this.pathTableSize = layout.pathTableSize;\n this.pathTableUsed = 0;\n this.bitmapOffset = layout.bitmapOffset;\n this.dataOffset = layout.dataOffset;\n\n // Grow file to total size\n this.handle.truncate(layout.totalSize);\n\n // Write superblock\n this.writeSuperblock();\n\n // Zero out inode table (type=0 means free)\n const zeroBuf = new Uint8Array(layout.inodeTableSize);\n this.handle.write(zeroBuf, { at: this.inodeTableOffset });\n\n // Zero out bitmap and cache in memory\n this.bitmap = new Uint8Array(layout.bitmapSize);\n this.handle.write(this.bitmap, { at: this.bitmapOffset });\n\n // Create root directory inode\n this.createInode('/', INODE_TYPE.DIRECTORY, DEFAULT_DIR_MODE, 0);\n\n // Re-write superblock with updated pathTableUsed (createInode appended \"/\" to path table)\n this.writeSuperblock();\n this.handle.flush();\n }\n\n /** Mount an existing VFS from disk — validates superblock integrity */\n private mount(): void {\n const fileSize = this.handle.getSize();\n if (fileSize < SUPERBLOCK.SIZE) {\n throw new Error(`Corrupt VFS: file too small (${fileSize} bytes, need at least ${SUPERBLOCK.SIZE})`);\n }\n\n this.handle.read(this.superblockBuf, { at: 0 });\n const v = this.superblockView;\n\n // Validate magic\n const magic = v.getUint32(SUPERBLOCK.MAGIC, true);\n if (magic !== VFS_MAGIC) {\n throw new Error(`Corrupt VFS: bad magic 0x${magic.toString(16)} (expected 0x${VFS_MAGIC.toString(16)})`);\n }\n\n // Validate version\n const version = v.getUint32(SUPERBLOCK.VERSION, true);\n if (version !== VFS_VERSION) {\n throw new Error(`Corrupt VFS: unsupported version ${version} (expected ${VFS_VERSION})`);\n }\n\n // Read superblock fields\n const inodeCount = v.getUint32(SUPERBLOCK.INODE_COUNT, true);\n const blockSize = v.getUint32(SUPERBLOCK.BLOCK_SIZE, true);\n const totalBlocks = v.getUint32(SUPERBLOCK.TOTAL_BLOCKS, true);\n const freeBlocks = v.getUint32(SUPERBLOCK.FREE_BLOCKS, true);\n const inodeTableOffset = v.getFloat64(SUPERBLOCK.INODE_OFFSET, true);\n const pathTableOffset = v.getFloat64(SUPERBLOCK.PATH_OFFSET, true);\n const dataOffset = v.getFloat64(SUPERBLOCK.DATA_OFFSET, true);\n const bitmapOffset = v.getFloat64(SUPERBLOCK.BITMAP_OFFSET, true);\n const pathUsed = v.getUint32(SUPERBLOCK.PATH_USED, true);\n\n // Validate field sanity\n if (blockSize === 0 || (blockSize & (blockSize - 1)) !== 0) {\n throw new Error(`Corrupt VFS: invalid block size ${blockSize} (must be power of 2)`);\n }\n if (inodeCount === 0) {\n throw new Error('Corrupt VFS: inode count is 0');\n }\n if (freeBlocks > totalBlocks) {\n throw new Error(`Corrupt VFS: free blocks (${freeBlocks}) exceeds total blocks (${totalBlocks})`);\n }\n\n // Sane upper bounds — prevent huge allocations from corrupt values.\n // Configurable via opts.limits in init().\n if (inodeCount > this.maxInodes) {\n throw new Error(`Corrupt VFS: inode count ${inodeCount} exceeds maximum ${this.maxInodes}`);\n }\n if (totalBlocks > this.maxBlocks) {\n throw new Error(`Corrupt VFS: total blocks ${totalBlocks} exceeds maximum ${this.maxBlocks}`);\n }\n if (fileSize > this.maxVFSSize) {\n throw new Error(`Corrupt VFS: file size ${fileSize} exceeds maximum ${this.maxVFSSize}`);\n }\n\n // Validate all offsets are finite positive integers\n if (!Number.isFinite(inodeTableOffset) || inodeTableOffset < 0 ||\n !Number.isFinite(pathTableOffset) || pathTableOffset < 0 ||\n !Number.isFinite(bitmapOffset) || bitmapOffset < 0 ||\n !Number.isFinite(dataOffset) || dataOffset < 0) {\n throw new Error(`Corrupt VFS: non-finite or negative section offset`);\n }\n\n // Validate section ordering: superblock < inodes < paths < bitmap < data\n if (inodeTableOffset !== SUPERBLOCK.SIZE) {\n throw new Error(`Corrupt VFS: inode table offset ${inodeTableOffset} (expected ${SUPERBLOCK.SIZE})`);\n }\n const expectedPathOffset = inodeTableOffset + inodeCount * INODE_SIZE;\n if (pathTableOffset !== expectedPathOffset) {\n throw new Error(`Corrupt VFS: path table offset ${pathTableOffset} (expected ${expectedPathOffset})`);\n }\n if (bitmapOffset <= pathTableOffset) {\n throw new Error(`Corrupt VFS: bitmap offset ${bitmapOffset} must be after path table ${pathTableOffset}`);\n }\n if (dataOffset <= bitmapOffset) {\n throw new Error(`Corrupt VFS: data offset ${dataOffset} must be after bitmap ${bitmapOffset}`);\n }\n const pathTableSize = bitmapOffset - pathTableOffset;\n if (pathUsed > pathTableSize) {\n throw new Error(`Corrupt VFS: path used (${pathUsed}) exceeds path table size (${pathTableSize})`);\n }\n if (pathTableSize > this.maxPathTable) {\n throw new Error(`Corrupt VFS: path table size ${pathTableSize} exceeds maximum ${this.maxPathTable}`);\n }\n\n // Validate file is large enough for the declared layout\n const expectedMinSize = dataOffset + totalBlocks * blockSize;\n if (expectedMinSize > this.maxVFSSize) {\n throw new Error(`Corrupt VFS: computed layout size ${expectedMinSize} exceeds maximum ${this.maxVFSSize}`);\n }\n if (fileSize < expectedMinSize) {\n throw new Error(`Corrupt VFS: file size ${fileSize} too small for layout (need ${expectedMinSize})`);\n }\n\n // All checks passed — commit to engine state\n this.inodeCount = inodeCount;\n this.blockSize = blockSize;\n this.totalBlocks = totalBlocks;\n this.freeBlocks = freeBlocks;\n this.inodeTableOffset = inodeTableOffset;\n this.pathTableOffset = pathTableOffset;\n this.dataOffset = dataOffset;\n this.bitmapOffset = bitmapOffset;\n this.pathTableUsed = pathUsed;\n this.pathTableSize = pathTableSize;\n\n // Load bitmap into memory\n const bitmapSize = Math.ceil(this.totalBlocks / 8);\n this.bitmap = new Uint8Array(bitmapSize);\n this.handle.read(this.bitmap, { at: this.bitmapOffset });\n\n this.rebuildIndex();\n\n // Verify root directory exists\n if (!this.pathIndex.has('/')) {\n throw new Error('Corrupt VFS: root directory \"/\" not found in inode table');\n }\n }\n\n private writeSuperblock(): void {\n const v = this.superblockView;\n v.setUint32(SUPERBLOCK.MAGIC, VFS_MAGIC, true);\n v.setUint32(SUPERBLOCK.VERSION, VFS_VERSION, true);\n v.setUint32(SUPERBLOCK.INODE_COUNT, this.inodeCount, true);\n v.setUint32(SUPERBLOCK.BLOCK_SIZE, this.blockSize, true);\n v.setUint32(SUPERBLOCK.TOTAL_BLOCKS, this.totalBlocks, true);\n v.setUint32(SUPERBLOCK.FREE_BLOCKS, this.freeBlocks, true);\n v.setFloat64(SUPERBLOCK.INODE_OFFSET, this.inodeTableOffset, true);\n v.setFloat64(SUPERBLOCK.PATH_OFFSET, this.pathTableOffset, true);\n v.setFloat64(SUPERBLOCK.DATA_OFFSET, this.dataOffset, true);\n v.setFloat64(SUPERBLOCK.BITMAP_OFFSET, this.bitmapOffset, true);\n v.setUint32(SUPERBLOCK.PATH_USED, this.pathTableUsed, true);\n this.handle.write(this.superblockBuf, { at: 0 });\n }\n\n /** Flush pending bitmap and superblock writes to disk (one write each) */\n private markBitmapDirty(lo: number, hi: number): void {\n if (lo < this.bitmapDirtyLo) this.bitmapDirtyLo = lo;\n if (hi > this.bitmapDirtyHi) this.bitmapDirtyHi = hi;\n }\n\n private commitPending(): void {\n // Trim trailing free blocks before flushing bitmap/superblock\n if (this.blocksFreedsinceTrim) {\n this.trimTrailingBlocks();\n this.blocksFreedsinceTrim = false;\n }\n\n if (this.bitmapDirtyHi >= 0) {\n const lo = this.bitmapDirtyLo;\n const hi = this.bitmapDirtyHi;\n this.handle.write(this.bitmap!.subarray(lo, hi + 1), { at: this.bitmapOffset + lo });\n this.bitmapDirtyLo = Infinity;\n this.bitmapDirtyHi = -1;\n }\n if (this.superblockDirty) {\n this.writeSuperblock();\n this.superblockDirty = false;\n }\n }\n\n /** Shrink the OPFS file by removing trailing free blocks from the data region.\n * Scans bitmap from end to find the last used block, then truncates. */\n private trimTrailingBlocks(): void {\n const bitmap = this.bitmap!;\n\n // Find the last used block by scanning bitmap from the end\n let lastUsed = -1;\n for (let byteIdx = Math.ceil(this.totalBlocks / 8) - 1; byteIdx >= 0; byteIdx--) {\n if (bitmap[byteIdx] !== 0) {\n // Find highest set bit in this byte\n for (let bit = 7; bit >= 0; bit--) {\n const blockIdx = byteIdx * 8 + bit;\n if (blockIdx < this.totalBlocks && (bitmap[byteIdx] & (1 << bit))) {\n lastUsed = blockIdx;\n break;\n }\n }\n break;\n }\n }\n\n const newTotal = Math.max(lastUsed + 1, INITIAL_DATA_BLOCKS);\n if (newTotal >= this.totalBlocks) return; // nothing to trim\n\n // Truncate the OPFS file\n this.handle.truncate(this.dataOffset + newTotal * this.blockSize);\n\n // Shrink in-memory bitmap\n const newBitmapSize = Math.ceil(newTotal / 8);\n this.bitmap = bitmap.slice(0, newBitmapSize);\n\n // Update counters\n const trimmed = this.totalBlocks - newTotal;\n this.freeBlocks -= trimmed; // these free blocks no longer exist\n this.totalBlocks = newTotal;\n this.superblockDirty = true;\n\n // Re-mark entire bitmap dirty so the smaller bitmap is flushed\n this.bitmapDirtyLo = 0;\n this.bitmapDirtyHi = newBitmapSize - 1;\n }\n\n /** Rebuild in-memory path→inode index from disk.\n * Bulk-reads the entire inode table + path table in 2 I/O calls,\n * then parses in memory (avoids 10k+ individual reads). */\n private rebuildIndex(): void {\n this.pathIndex.clear();\n this.inodeCache.clear();\n\n // Bulk read entire inode table (e.g. 640KB for 10k inodes)\n const inodeTableSize = this.inodeCount * INODE_SIZE;\n const inodeBuf = new Uint8Array(inodeTableSize);\n this.handle.read(inodeBuf, { at: this.inodeTableOffset });\n const inodeView = new DataView(inodeBuf.buffer);\n\n // Bulk read used portion of path table\n const pathBuf = this.pathTableUsed > 0 ? new Uint8Array(this.pathTableUsed) : null;\n if (pathBuf) {\n this.handle.read(pathBuf, { at: this.pathTableOffset });\n }\n\n for (let i = 0; i < this.inodeCount; i++) {\n const off = i * INODE_SIZE;\n const type = inodeView.getUint8(off + INODE.TYPE);\n if (type === INODE_TYPE.FREE) continue;\n\n // Validate inode type\n if (type < INODE_TYPE.FILE || type > INODE_TYPE.SYMLINK) {\n throw new Error(`Corrupt VFS: inode ${i} has invalid type ${type}`);\n }\n\n const pathOffset = inodeView.getUint32(off + INODE.PATH_OFFSET, true);\n const pathLength = inodeView.getUint16(off + INODE.PATH_LENGTH, true);\n const size = inodeView.getFloat64(off + INODE.SIZE, true);\n const firstBlock = inodeView.getUint32(off + INODE.FIRST_BLOCK, true);\n const blockCount = inodeView.getUint32(off + INODE.BLOCK_COUNT, true);\n\n // Validate path bounds\n if (pathLength === 0 || pathOffset + pathLength > this.pathTableUsed) {\n throw new Error(`Corrupt VFS: inode ${i} path out of bounds (offset=${pathOffset}, len=${pathLength}, tableUsed=${this.pathTableUsed})`);\n }\n\n // Validate data bounds for files/symlinks\n if (type !== INODE_TYPE.DIRECTORY) {\n if (size < 0 || !isFinite(size)) {\n throw new Error(`Corrupt VFS: inode ${i} has invalid size ${size}`);\n }\n if (blockCount > 0 && firstBlock + blockCount > this.totalBlocks) {\n throw new Error(`Corrupt VFS: inode ${i} data blocks out of range (first=${firstBlock}, count=${blockCount}, total=${this.totalBlocks})`);\n }\n }\n\n const inode: Inode = {\n type,\n pathOffset,\n pathLength,\n nlink: inodeView.getUint16(off + INODE.NLINK, true) || 1,\n mode: inodeView.getUint32(off + INODE.MODE, true),\n size,\n firstBlock,\n blockCount,\n mtime: inodeView.getFloat64(off + INODE.MTIME, true),\n ctime: inodeView.getFloat64(off + INODE.CTIME, true),\n atime: inodeView.getFloat64(off + INODE.ATIME, true),\n uid: inodeView.getUint32(off + INODE.UID, true),\n gid: inodeView.getUint32(off + INODE.GID, true),\n };\n this.inodeCache.set(i, inode);\n\n // Decode path from in-memory path table buffer (no disk read)\n let path: string;\n if (pathBuf) {\n path = decoder.decode(pathBuf.subarray(inode.pathOffset, inode.pathOffset + inode.pathLength));\n } else {\n path = this.readPath(inode.pathOffset, inode.pathLength);\n }\n\n // Validate path format\n if (!path.startsWith('/') || path.includes('\\0')) {\n throw new Error(`Corrupt VFS: inode ${i} has invalid path \"${path.substring(0, 50)}\"`);\n }\n\n this.setPathIndex(path, i);\n }\n this.pathIndexGen++;\n }\n\n // ========== Low-level inode I/O ==========\n\n private readInode(idx: number): Inode {\n const cached = this.inodeCache.get(idx);\n if (cached) return cached;\n\n const offset = this.inodeTableOffset + idx * INODE_SIZE;\n this.handle.read(this.inodeBuf, { at: offset });\n const v = this.inodeView;\n const inode: Inode = {\n type: v.getUint8(INODE.TYPE),\n pathOffset: v.getUint32(INODE.PATH_OFFSET, true),\n pathLength: v.getUint16(INODE.PATH_LENGTH, true),\n nlink: v.getUint16(INODE.NLINK, true) || 1,\n mode: v.getUint32(INODE.MODE, true),\n size: v.getFloat64(INODE.SIZE, true),\n firstBlock: v.getUint32(INODE.FIRST_BLOCK, true),\n blockCount: v.getUint32(INODE.BLOCK_COUNT, true),\n mtime: v.getFloat64(INODE.MTIME, true),\n ctime: v.getFloat64(INODE.CTIME, true),\n atime: v.getFloat64(INODE.ATIME, true),\n uid: v.getUint32(INODE.UID, true),\n gid: v.getUint32(INODE.GID, true),\n };\n this.inodeCache.set(idx, inode);\n return inode;\n }\n\n private writeInode(idx: number, inode: Inode): void {\n // Maintain inode cache\n if (inode.type === INODE_TYPE.FREE) {\n this.inodeCache.delete(idx);\n } else {\n this.inodeCache.set(idx, inode);\n }\n\n const v = this.inodeView;\n v.setUint8(INODE.TYPE, inode.type);\n v.setUint8(INODE.FLAGS, 0);\n v.setUint8(INODE.FLAGS + 1, 0);\n v.setUint8(INODE.FLAGS + 2, 0);\n v.setUint32(INODE.PATH_OFFSET, inode.pathOffset, true);\n v.setUint16(INODE.PATH_LENGTH, inode.pathLength, true);\n v.setUint16(INODE.NLINK, inode.nlink, true);\n v.setUint32(INODE.MODE, inode.mode, true);\n v.setFloat64(INODE.SIZE, inode.size, true);\n v.setUint32(INODE.FIRST_BLOCK, inode.firstBlock, true);\n v.setUint32(INODE.BLOCK_COUNT, inode.blockCount, true);\n v.setFloat64(INODE.MTIME, inode.mtime, true);\n v.setFloat64(INODE.CTIME, inode.ctime, true);\n v.setFloat64(INODE.ATIME, inode.atime, true);\n v.setUint32(INODE.UID, inode.uid, true);\n v.setUint32(INODE.GID, inode.gid, true);\n\n const offset = this.inodeTableOffset + idx * INODE_SIZE;\n this.handle.write(this.inodeBuf, { at: offset });\n }\n\n // ========== Path table I/O ==========\n\n private readPath(offset: number, length: number): string {\n const buf = new Uint8Array(length);\n this.handle.read(buf, { at: this.pathTableOffset + offset });\n return decoder.decode(buf);\n }\n\n private appendPath(path: string): { offset: number; length: number } {\n const bytes = encoder.encode(path);\n const offset = this.pathTableUsed;\n\n // Check if path table needs to grow\n if (offset + bytes.byteLength > this.pathTableSize) {\n this.growPathTable(offset + bytes.byteLength);\n }\n\n this.handle.write(bytes, { at: this.pathTableOffset + offset });\n this.pathTableUsed += bytes.byteLength;\n\n // Defer superblock write — committed in commitPending()\n this.superblockDirty = true;\n\n return { offset, length: bytes.byteLength };\n }\n\n private growPathTable(needed: number): void {\n // Double the path table or grow to fit needed, whichever is larger\n const newSize = Math.max(this.pathTableSize * 2, needed + INITIAL_PATH_TABLE_SIZE);\n const growth = newSize - this.pathTableSize;\n\n // Grow file first so the shifted data has somewhere to land.\n const newTotalSize = this.handle.getSize() + growth;\n this.handle.truncate(newTotalSize);\n\n // Shift the data region forward by `growth` bytes. We must NOT allocate\n // a single buffer the size of the whole data section — when the VFS\n // holds a large install (pnpm linking ~1300 Directus packages puts the\n // data section in the hundreds of MB) the one-shot\n // new Uint8Array(dataSize)\n // failed with \"Array buffer allocation failed\" because Chrome refuses\n // allocations near the 2 GB cap even with OS memory to spare.\n //\n // Copy back-to-front through a small scratch buffer so we never\n // overwrite bytes we haven't relocated yet, and the peak allocation\n // stays bounded at CHUNK regardless of how big the VFS has grown.\n const dataSize = this.totalBlocks * this.blockSize;\n const CHUNK = 4 * 1024 * 1024; // 4 MB\n const scratch = new Uint8Array(Math.min(CHUNK, Math.max(dataSize, 1)));\n let remaining = dataSize;\n while (remaining > 0) {\n const chunk = Math.min(remaining, CHUNK);\n const srcAt = this.dataOffset + (remaining - chunk);\n const dstAt = this.dataOffset + growth + (remaining - chunk);\n const slice = chunk < scratch.length ? scratch.subarray(0, chunk) : scratch;\n this.handle.read(slice, { at: srcAt });\n this.handle.write(slice, { at: dstAt });\n remaining -= chunk;\n }\n\n // Write the (in-memory) bitmap to its new offset.\n const newBitmapOffset = this.bitmapOffset + growth;\n const newDataOffset = this.dataOffset + growth;\n this.handle.write(this.bitmap!, { at: newBitmapOffset });\n\n // Update offsets\n this.pathTableSize = newSize;\n this.bitmapOffset = newBitmapOffset;\n this.dataOffset = newDataOffset;\n\n // Mark superblock dirty (will be written in commitPending)\n this.superblockDirty = true;\n }\n\n // ========== Bitmap I/O ==========\n\n // Write `length` zero bytes at absolute file offset `at` via a small\n // reusable scratch buffer. Used to materialize POSIX \"holes\" when a\n // write starts past the current file size — those bytes must read as\n // zeros rather than whatever stale data happened to live in the\n // underlying storage blocks.\n private zeroFileRange(at: number, length: number): void {\n if (length <= 0) return;\n const CHUNK = 4 * 1024 * 1024;\n const zeros = new Uint8Array(Math.min(length, CHUNK));\n let written = 0;\n while (written < length) {\n const n = Math.min(CHUNK, length - written);\n const slice = n < zeros.length ? zeros.subarray(0, n) : zeros;\n this.handle.write(slice, { at: at + written });\n written += n;\n }\n }\n\n private allocateBlocks(count: number): number {\n if (count === 0) return 0;\n\n const bitmap = this.bitmap!;\n let run = 0;\n let start = 0;\n\n for (let i = 0; i < this.totalBlocks; i++) {\n const byteIdx = i >>> 3;\n const bitIdx = i & 7;\n const used = (bitmap[byteIdx] >>> bitIdx) & 1;\n\n if (used) {\n run = 0;\n start = i + 1;\n } else {\n run++;\n if (run === count) {\n // Mark blocks as used in memory\n for (let j = start; j <= i; j++) {\n const bj = j >>> 3;\n const bi = j & 7;\n bitmap[bj] |= (1 << bi);\n }\n this.markBitmapDirty(start >>> 3, i >>> 3);\n this.freeBlocks -= count;\n this.superblockDirty = true;\n return start;\n }\n }\n }\n\n // No contiguous space — grow data region\n return this.growAndAllocate(count);\n }\n\n private growAndAllocate(count: number): number {\n const oldTotal = this.totalBlocks;\n // Grow by at least doubling or enough for the request\n const newTotal = Math.max(oldTotal * 2, oldTotal + count);\n const addedBlocks = newTotal - oldTotal;\n\n // Grow the file\n const newFileSize = this.dataOffset + newTotal * this.blockSize;\n this.handle.truncate(newFileSize);\n\n // Grow in-memory bitmap\n const newBitmapSize = Math.ceil(newTotal / 8);\n const newBitmap = new Uint8Array(newBitmapSize);\n newBitmap.set(this.bitmap!);\n this.bitmap = newBitmap;\n\n this.totalBlocks = newTotal;\n this.freeBlocks += addedBlocks;\n\n // Allocate from the newly freed area\n const start = oldTotal;\n for (let j = start; j < start + count; j++) {\n const bj = j >>> 3;\n const bi = j & 7;\n this.bitmap[bj] |= (1 << bi);\n }\n\n this.markBitmapDirty(start >>> 3, (start + count - 1) >>> 3);\n this.freeBlocks -= count;\n this.superblockDirty = true;\n\n return start;\n }\n\n private blocksFreedsinceTrim = false;\n\n private freeBlockRange(start: number, count: number): void {\n if (count === 0) return;\n const bitmap = this.bitmap!;\n\n for (let i = start; i < start + count; i++) {\n const byteIdx = i >>> 3;\n const bitIdx = i & 7;\n bitmap[byteIdx] &= ~(1 << bitIdx);\n }\n\n this.markBitmapDirty(start >>> 3, (start + count - 1) >>> 3);\n this.freeBlocks += count;\n this.superblockDirty = true;\n this.blocksFreedsinceTrim = true;\n }\n\n // updateSuperblockFreeBlocks is no longer needed — superblock writes are coalesced via commitPending()\n\n // ========== Inode allocation ==========\n\n private findFreeInode(): number {\n // Start from hint to skip already-used entries\n for (let i = this.freeInodeHint; i < this.inodeCount; i++) {\n // Check cache first — cached entries are never FREE\n if (this.inodeCache.has(i)) continue;\n\n const offset = this.inodeTableOffset + i * INODE_SIZE;\n const typeBuf = new Uint8Array(1);\n this.handle.read(typeBuf, { at: offset });\n if (typeBuf[0] === INODE_TYPE.FREE) {\n this.freeInodeHint = i + 1;\n return i;\n }\n }\n // All inodes used — grow inode table\n const idx = this.growInodeTable();\n this.freeInodeHint = idx + 1;\n return idx;\n }\n\n private growInodeTable(): number {\n const oldCount = this.inodeCount;\n const newCount = oldCount * 2;\n const growth = (newCount - oldCount) * INODE_SIZE;\n\n // Read everything after inode table\n const afterInodeOffset = this.inodeTableOffset + oldCount * INODE_SIZE;\n const afterSize = this.handle.getSize() - afterInodeOffset;\n const afterBuf = new Uint8Array(afterSize);\n this.handle.read(afterBuf, { at: afterInodeOffset });\n\n // Grow file\n this.handle.truncate(this.handle.getSize() + growth);\n\n // Write back shifted content\n this.handle.write(afterBuf, { at: afterInodeOffset + growth });\n\n // Zero out new inode entries\n const zeroes = new Uint8Array(growth);\n this.handle.write(zeroes, { at: afterInodeOffset });\n\n // Update offsets\n this.pathTableOffset += growth;\n this.bitmapOffset += growth;\n this.dataOffset += growth;\n this.inodeCount = newCount;\n\n this.superblockDirty = true;\n\n return oldCount; // First new free inode\n }\n\n // ========== Data I/O ==========\n\n private readData(firstBlock: number, blockCount: number, size: number): Uint8Array {\n const buf = new Uint8Array(size);\n const offset = this.dataOffset + firstBlock * this.blockSize;\n this.handle.read(buf, { at: offset });\n return buf;\n }\n\n private writeData(firstBlock: number, data: Uint8Array): void {\n const offset = this.dataOffset + firstBlock * this.blockSize;\n this.handle.write(data, { at: offset });\n }\n\n // ========== Path resolution ==========\n\n private resolvePath(path: string, depth: number = 0): number | undefined {\n if (depth > MAX_SYMLINK_DEPTH) return undefined; // ELOOP\n\n const idx = this.pathIndex.get(path);\n if (idx === undefined) {\n // Path not found directly — try component resolution (handles intermediate symlinks)\n return this.resolvePathComponents(path, true, depth);\n }\n\n const inode = this.readInode(idx);\n if (inode.type === INODE_TYPE.SYMLINK) {\n // Follow symlink\n const target = decoder.decode(this.readData(inode.firstBlock, inode.blockCount, inode.size));\n const resolved = target.startsWith('/') ? target : this.resolveRelative(path, target);\n return this.resolvePath(resolved, depth + 1);\n }\n\n return idx;\n }\n\n /** Resolve symlinks in intermediate path components */\n private resolvePathComponents(path: string, followLast: boolean = true, depth: number = 0): number | undefined {\n const result = this.resolvePathFull(path, followLast, depth);\n return result?.idx;\n }\n\n /**\n * Resolve a path following symlinks, returning both the inode index AND the\n * fully resolved path. This is needed by readdir: when listing a symlinked\n * directory, we must search for children under the resolved target path\n * (where files actually exist in pathIndex), not under the symlink path.\n */\n private resolvePathFull(path: string, followLast: boolean = true, depth: number = 0): { idx: number; resolvedPath: string } | undefined {\n if (depth > MAX_SYMLINK_DEPTH) return undefined; // ELOOP\n\n const parts = path.split('/').filter(Boolean);\n let current = '/';\n\n for (let i = 0; i < parts.length; i++) {\n const isLast = i === parts.length - 1;\n current = current === '/' ? '/' + parts[i] : current + '/' + parts[i];\n\n const idx = this.pathIndex.get(current);\n if (idx === undefined) return undefined;\n\n const inode = this.readInode(idx);\n if (inode.type === INODE_TYPE.SYMLINK && (!isLast || followLast)) {\n const target = decoder.decode(this.readData(inode.firstBlock, inode.blockCount, inode.size));\n const resolved = target.startsWith('/') ? target : this.resolveRelative(current, target);\n\n if (isLast) {\n // Use resolvePathFull (not resolvePath) so intermediate symlinks\n // in the resolved target path are also followed\n return this.resolvePathFull(resolved, true, depth + 1);\n }\n\n // Reconstruct remaining path with resolved symlink\n const remaining = parts.slice(i + 1).join('/');\n const newPath = resolved + (remaining ? '/' + remaining : '');\n return this.resolvePathFull(newPath, followLast, depth + 1);\n }\n }\n\n const finalIdx = this.pathIndex.get(current);\n if (finalIdx === undefined) return undefined;\n return { idx: finalIdx, resolvedPath: current };\n }\n\n private resolveRelative(from: string, target: string): string {\n const dir = from.substring(0, from.lastIndexOf('/')) || '/';\n const parts = (dir + '/' + target).split('/').filter(Boolean);\n const resolved: string[] = [];\n for (const p of parts) {\n if (p === '.') continue;\n if (p === '..') { resolved.pop(); continue; }\n resolved.push(p);\n }\n return '/' + resolved.join('/');\n }\n\n // ========== Core inode creation helper ==========\n\n private createInode(path: string, type: number, mode: number, size: number, data?: Uint8Array): number {\n const idx = this.findFreeInode();\n const { offset: pathOff, length: pathLen } = this.appendPath(path);\n const now = Date.now();\n\n let firstBlock = 0;\n let blockCount = 0;\n\n if (data && data.byteLength > 0) {\n blockCount = Math.ceil(data.byteLength / this.blockSize);\n firstBlock = this.allocateBlocks(blockCount);\n this.writeData(firstBlock, data);\n }\n\n const inode: Inode = {\n type,\n pathOffset: pathOff,\n pathLength: pathLen,\n nlink: type === INODE_TYPE.DIRECTORY ? 2 : 1,\n mode,\n size,\n firstBlock,\n blockCount,\n mtime: now,\n ctime: now,\n atime: now,\n uid: this.processUid,\n gid: this.processGid,\n };\n\n this.writeInode(idx, inode);\n this.setPathIndex(path, idx);\n this.pathIndexGen++;\n\n return idx;\n }\n\n // ========== Public API — called by server worker dispatch ==========\n\n /** Normalize a path: ensure leading /, resolve . and .. */\n normalizePath(p: string): string {\n if (p.charCodeAt(0) !== 47) p = '/' + p; // 47 = '/'\n // Fast path: already normalized (no '.', '..', '//', trailing '/')\n if (p.length === 1) return p; // \"/\"\n if (p.indexOf('/.') === -1 && p.indexOf('//') === -1 && p.charCodeAt(p.length - 1) !== 47) {\n return p;\n }\n // Slow path: full normalize\n const parts = p.split('/').filter(Boolean);\n const resolved: string[] = [];\n for (const part of parts) {\n if (part === '.') continue;\n if (part === '..') { resolved.pop(); continue; }\n resolved.push(part);\n }\n return '/' + resolved.join('/');\n }\n\n // ---- READ ----\n read(path: string): { status: number; data: Uint8Array | null } {\n const t0 = this.debug ? performance.now() : 0;\n path = this.normalizePath(path);\n\n // Fast path: direct index lookup (skips component-by-component walk)\n let idx = this.pathIndex.get(path);\n if (idx !== undefined) {\n const inode = this.inodeCache.get(idx);\n if (inode) {\n // Symlink? Fall through to full resolve\n if (inode.type === INODE_TYPE.SYMLINK) {\n idx = this.resolvePathComponents(path, true);\n } else if (inode.type === INODE_TYPE.DIRECTORY) {\n return { status: CODE_TO_STATUS.EISDIR, data: null };\n } else {\n // Hot path: cached inode, no symlinks\n const data = inode.size > 0\n ? this.readData(inode.firstBlock, inode.blockCount, inode.size)\n : new Uint8Array(0);\n if (this.debug) {\n const t1 = performance.now();\n console.log(`[VFS read] path=${path} size=${inode.size} TOTAL=${(t1-t0).toFixed(3)}ms (fast)`);\n }\n return { status: 0, data };\n }\n }\n }\n\n // Slow path: full component resolution (handles symlinks, uncached inodes)\n if (idx === undefined) idx = this.resolvePathComponents(path, true);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT, data: null };\n\n const inode = this.readInode(idx);\n if (inode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EISDIR, data: null };\n\n const data = inode.size > 0\n ? this.readData(inode.firstBlock, inode.blockCount, inode.size)\n : new Uint8Array(0);\n\n if (this.debug) {\n const t1 = performance.now();\n console.log(`[VFS read] path=${path} size=${inode.size} TOTAL=${(t1-t0).toFixed(3)}ms (slow path)`);\n }\n\n return { status: 0, data };\n }\n\n // ---- WRITE ----\n write(path: string, data: Uint8Array, flags: number = 0): { status: number } {\n const t0 = this.debug ? performance.now() : 0;\n path = this.normalizePath(path);\n const t1 = this.debug ? performance.now() : 0;\n\n // Ensure parent directory exists\n const parentStatus = this.ensureParent(path);\n if (parentStatus !== 0) return { status: parentStatus };\n const t2 = this.debug ? performance.now() : 0;\n\n const existingIdx = this.resolvePathComponents(path, true);\n const t3 = this.debug ? performance.now() : 0;\n\n let tAlloc = t3, tData = t3, tInode = t3;\n\n if (existingIdx !== undefined) {\n // Update existing file\n const inode = this.readInode(existingIdx);\n if (inode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EISDIR };\n\n const neededBlocks = Math.ceil(data.byteLength / this.blockSize);\n\n if (neededBlocks <= inode.blockCount) {\n // Fits in current blocks\n tAlloc = this.debug ? performance.now() : 0;\n this.writeData(inode.firstBlock, data);\n tData = this.debug ? performance.now() : 0;\n if (neededBlocks < inode.blockCount) {\n this.freeBlockRange(inode.firstBlock + neededBlocks, inode.blockCount - neededBlocks);\n }\n } else {\n // Need more blocks — free old, allocate new\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n const newFirst = this.allocateBlocks(neededBlocks);\n tAlloc = this.debug ? performance.now() : 0;\n this.writeData(newFirst, data);\n tData = this.debug ? performance.now() : 0;\n inode.firstBlock = newFirst;\n }\n\n inode.size = data.byteLength;\n inode.blockCount = neededBlocks;\n inode.mtime = Date.now();\n this.writeInode(existingIdx, inode);\n tInode = this.debug ? performance.now() : 0;\n } else {\n // Refuse to create a regular file at a path that is an implicit\n // directory (children exist beneath it but no inode for the path\n // itself). Without this guard we'd register a FILE inode at `path`\n // while its descendants stay in pathIndex — the resulting \"file with\n // children\" state breaks every subsequent read of `path` and its\n // subtree.\n if (this.isImplicitDirectory(path)) return { status: CODE_TO_STATUS.EISDIR };\n // Create new file\n const mode = DEFAULT_FILE_MODE & ~(this.umask & 0o777);\n this.createInode(path, INODE_TYPE.FILE, mode, data.byteLength, data);\n tAlloc = this.debug ? performance.now() : 0;\n tData = tAlloc;\n tInode = tAlloc;\n }\n\n // Always commit pending superblock/bitmap changes (matches unlink, mkdir, etc.)\n // Without this, PATH_USED won't be persisted for newly created files,\n // causing \"path out of bounds\" corruption on reload.\n this.commitPending();\n if (flags & 1) {\n this.handle.flush();\n }\n const tFlush = this.debug ? performance.now() : 0;\n\n if (this.debug) {\n const existing = existingIdx !== undefined;\n console.log(`[VFS write] path=${path} size=${data.byteLength} ${existing ? 'UPDATE' : 'CREATE'} normalize=${(t1-t0).toFixed(3)}ms parent=${(t2-t1).toFixed(3)}ms resolve=${(t3-t2).toFixed(3)}ms alloc=${(tAlloc-t3).toFixed(3)}ms data=${(tData-tAlloc).toFixed(3)}ms inode=${(tInode-tData).toFixed(3)}ms flush=${(tFlush-tInode).toFixed(3)}ms TOTAL=${(tFlush-t0).toFixed(3)}ms`);\n }\n\n return { status: 0 };\n }\n\n // ---- APPEND ----\n append(path: string, data: Uint8Array): { status: number } {\n path = this.normalizePath(path);\n const existingIdx = this.resolvePathComponents(path, true);\n\n if (existingIdx === undefined) {\n // Create new file with the data\n return this.write(path, data);\n }\n\n const inode = this.readInode(existingIdx);\n if (inode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EISDIR };\n\n // Avoid materializing the whole (existing + data) file in a single\n // Uint8Array — that blew up with \"Array buffer allocation failed\" on\n // large appends (e.g. appending a few MB to a multi-hundred-MB file).\n //\n // Strategy: allocate a new block run sized to the total, copy the\n // existing contents over in bounded chunks, then write the caller's\n // `data` at the end. Peak allocation stays at 4 MB regardless of\n // file size.\n const combinedSize = inode.size + data.byteLength;\n const neededBlocks = Math.ceil(combinedSize / this.blockSize);\n const newFirst = this.allocateBlocks(neededBlocks);\n const newBase = this.dataOffset + newFirst * this.blockSize;\n if (inode.size > 0) {\n const oldBase = this.dataOffset + inode.firstBlock * this.blockSize;\n const CHUNK = 4 * 1024 * 1024; // 4 MB\n const scratch = new Uint8Array(Math.min(CHUNK, inode.size));\n let copied = 0;\n while (copied < inode.size) {\n const n = Math.min(CHUNK, inode.size - copied);\n const slice = n < scratch.length ? scratch.subarray(0, n) : scratch;\n this.handle.read(slice, { at: oldBase + copied });\n this.handle.write(slice, { at: newBase + copied });\n copied += n;\n }\n }\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n this.handle.write(data, { at: newBase + inode.size });\n\n inode.firstBlock = newFirst;\n inode.blockCount = neededBlocks;\n inode.size = combinedSize;\n inode.mtime = Date.now();\n this.writeInode(existingIdx, inode);\n\n this.commitPending();\n return { status: 0 };\n }\n\n // ---- UNLINK ----\n unlink(path: string): { status: number } {\n path = this.normalizePath(path);\n const idx = this.pathIndex.get(path);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n const inode = this.readInode(idx);\n if (inode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EISDIR };\n\n // Decrement nlink; only free data when it reaches 0\n inode.nlink = Math.max(0, inode.nlink - 1);\n\n // Free data blocks\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n\n // Mark inode as free\n inode.type = INODE_TYPE.FREE;\n this.writeInode(idx, inode);\n\n // Remove from index\n this.deletePathIndex(path);\n this.pathIndexGen++;\n // Reset free inode hint\n if (idx < this.freeInodeHint) this.freeInodeHint = idx;\n\n this.commitPending();\n return { status: 0 };\n }\n\n // ---- STAT ----\n stat(path: string): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) {\n // Check for implicit directory (exists because files exist under it)\n if (this.isImplicitDirectory(path)) {\n return this.encodeImplicitDirStatResponse(path);\n }\n return { status: CODE_TO_STATUS.ENOENT, data: null };\n }\n\n return this.encodeStatResponse(idx);\n }\n\n // ---- LSTAT (no symlink follow for the FINAL component) ----\n lstat(path: string): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n // Use resolvePathComponents with followLast=false — follows intermediate\n // symlinks but returns the symlink inode itself for the last component.\n // Direct pathIndex.get(path) fails for paths through symlinked directories\n // because children are stored under the symlink target path in pathIndex.\n let idx = this.resolvePathComponents(path, false);\n if (idx === undefined) {\n // Fallback: followLast=false can fail for paths through symlink chains\n // when pathIndex stores files under their resolved (real) path.\n // Try with followLast=true — if it resolves, use the result regardless\n // of whether the final component is a symlink or not. lstat on an\n // existing symlink should return the symlink's own stats, not ENOENT.\n idx = this.resolvePathComponents(path, true);\n if (idx === undefined) {\n // Check for implicit directory\n if (this.isImplicitDirectory(path)) {\n return this.encodeImplicitDirStatResponse(path);\n }\n return { status: CODE_TO_STATUS.ENOENT, data: null };\n }\n }\n\n return this.encodeStatResponse(idx);\n }\n\n private encodeStatResponse(idx: number): { status: number; data: Uint8Array } {\n const inode = this.readInode(idx);\n\n // Compute nlink for directories: 2 + number of child subdirectories\n // (including implicit subdirectories so nlink stays consistent with\n // what readdir reports).\n let nlink = inode.nlink;\n if (inode.type === INODE_TYPE.DIRECTORY) {\n const path = this.readPath(inode.pathOffset, inode.pathLength);\n const children = this.getDirectChildrenWithImplicit(path);\n let subdirCount = 0;\n for (const child of children) {\n if (child.type === 'implicit') {\n subdirCount++;\n } else {\n const childIdx = this.pathIndex.get(child.path);\n if (childIdx !== undefined) {\n const childInode = this.readInode(childIdx);\n if (childInode.type === INODE_TYPE.DIRECTORY) subdirCount++;\n }\n }\n }\n nlink = 2 + subdirCount;\n }\n\n // Encode stat into binary: type(1) + mode(4) + size(8) + mtime(8) + ctime(8) + atime(8) + uid(4) + gid(4) + ino(4) + nlink(4) = 53 bytes\n const buf = new Uint8Array(53);\n const view = new DataView(buf.buffer);\n view.setUint8(0, inode.type);\n view.setUint32(1, inode.mode, true);\n view.setFloat64(5, inode.size, true);\n view.setFloat64(13, inode.mtime, true);\n view.setFloat64(21, inode.ctime, true);\n view.setFloat64(29, inode.atime, true);\n view.setUint32(37, inode.uid, true);\n view.setUint32(41, inode.gid, true);\n view.setUint32(45, idx, true); // ino = inode index\n view.setUint32(49, nlink, true);\n\n return { status: 0, data: buf };\n }\n\n // ---- MKDIR ----\n mkdir(path: string, flags: number = 0): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n const recursive = (flags & 1) !== 0;\n\n if (recursive) {\n return this.mkdirRecursive(path);\n }\n\n // Check if already exists (explicit or implicit)\n if (this.pathIndex.has(path) || this.isImplicitDirectory(path)) {\n return { status: CODE_TO_STATUS.EEXIST, data: null };\n }\n\n // Ensure parent exists\n const parentStatus = this.ensureParent(path);\n if (parentStatus !== 0) return { status: parentStatus, data: null };\n\n const mode = DEFAULT_DIR_MODE & ~(this.umask & 0o777);\n this.createInode(path, INODE_TYPE.DIRECTORY, mode, 0);\n\n this.commitPending();\n // Non-recursive mkdir returns undefined (null data) per Node.js spec\n return { status: 0, data: null };\n }\n\n private mkdirRecursive(path: string): { status: number; data: Uint8Array | null } {\n const parts = path.split('/').filter(Boolean);\n let current = '';\n let firstCreated: string | null = null;\n\n for (const part of parts) {\n current += '/' + part;\n\n if (this.pathIndex.has(current)) {\n const idx = this.pathIndex.get(current)!;\n const inode = this.readInode(idx);\n if (inode.type !== INODE_TYPE.DIRECTORY) {\n return { status: CODE_TO_STATUS.ENOTDIR, data: null };\n }\n continue;\n }\n\n const mode = DEFAULT_DIR_MODE & ~(this.umask & 0o777);\n this.createInode(current, INODE_TYPE.DIRECTORY, mode, 0);\n if (!firstCreated) firstCreated = current;\n }\n\n this.commitPending();\n const result = firstCreated ? encoder.encode(firstCreated) : undefined;\n return { status: 0, data: result ?? null };\n }\n\n // ---- RMDIR ----\n rmdir(path: string, flags: number = 0): { status: number } {\n path = this.normalizePath(path);\n const recursive = (flags & 1) !== 0;\n const idx = this.pathIndex.get(path);\n if (idx === undefined) {\n // Check for implicit directory — a dir that exists because files\n // exist under it but no explicit inode was created.\n if (this.isImplicitDirectory(path)) {\n const children = this.getDirectChildrenWithImplicit(path);\n if (children.length > 0) {\n if (!recursive) return { status: CODE_TO_STATUS.ENOTEMPTY };\n // Recursive: delete all real descendants; the implicit dir\n // disappears automatically when its children are gone.\n for (const desc of this.getAllDescendants(path)) {\n const descIdx = this.pathIndex.get(desc)!;\n const descInode = this.readInode(descIdx);\n this.freeBlockRange(descInode.firstBlock, descInode.blockCount);\n descInode.type = INODE_TYPE.FREE;\n this.writeInode(descIdx, descInode);\n this.deletePathIndex(desc);\n }\n this.pathIndexGen++;\n this.commitPending();\n }\n // Empty implicit dir or just-emptied: no-op — it vanishes on its own.\n return { status: 0 };\n }\n return { status: CODE_TO_STATUS.ENOENT };\n }\n\n const inode = this.readInode(idx);\n if (inode.type !== INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.ENOTDIR };\n\n // Check for children\n const children = this.getDirectChildren(path);\n\n if (children.length > 0) {\n if (!recursive) return { status: CODE_TO_STATUS.ENOTEMPTY };\n\n // Recursive delete\n for (const child of this.getAllDescendants(path)) {\n const childIdx = this.pathIndex.get(child)!;\n const childInode = this.readInode(childIdx);\n this.freeBlockRange(childInode.firstBlock, childInode.blockCount);\n childInode.type = INODE_TYPE.FREE;\n this.writeInode(childIdx, childInode);\n this.deletePathIndex(child);\n }\n }\n\n // Remove the directory itself\n inode.type = INODE_TYPE.FREE;\n this.writeInode(idx, inode);\n this.deletePathIndex(path);\n this.pathIndexGen++;\n if (idx < this.freeInodeHint) this.freeInodeHint = idx;\n\n this.commitPending();\n return { status: 0 };\n }\n\n // ---- READDIR ----\n readdir(path: string, flags: number = 0): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n const resolved = this.resolvePathFull(path, true);\n\n // Determine the effective directory path for child lookup\n let effectiveDirPath: string;\n\n if (resolved) {\n const inode = this.readInode(resolved.idx);\n if (inode.type !== INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.ENOTDIR, data: null };\n // Use the resolved path for child lookup — when path is a symlink,\n // the actual children are stored under the target path in pathIndex.\n effectiveDirPath = resolved.resolvedPath;\n } else if (this.isImplicitDirectory(path)) {\n effectiveDirPath = path;\n } else {\n return { status: CODE_TO_STATUS.ENOENT, data: null };\n }\n\n const withFileTypes = (flags & 1) !== 0;\n // Use getDirectChildrenWithImplicit to discover both real and implicit children\n const children = this.getDirectChildrenWithImplicit(effectiveDirPath);\n\n if (withFileTypes) {\n // Encode as: count(u32) + entries[name_len(u16) + name(bytes) + type(u8)]\n let totalSize = 4;\n const entries: { name: Uint8Array; type: number }[] = [];\n\n for (const child of children) {\n const name = child.path.substring(child.path.lastIndexOf('/') + 1);\n const nameBytes = encoder.encode(name);\n let type: number;\n if (child.type === 'implicit') {\n type = INODE_TYPE.DIRECTORY;\n } else {\n const childIdx = this.pathIndex.get(child.path)!;\n const childInode = this.readInode(childIdx);\n type = childInode.type;\n }\n entries.push({ name: nameBytes, type });\n totalSize += 2 + nameBytes.byteLength + 1; // nameLen + name + type\n }\n\n const buf = new Uint8Array(totalSize);\n const view = new DataView(buf.buffer);\n view.setUint32(0, entries.length, true);\n let offset = 4;\n\n for (const entry of entries) {\n view.setUint16(offset, entry.name.byteLength, true);\n offset += 2;\n buf.set(entry.name, offset);\n offset += entry.name.byteLength;\n buf[offset++] = entry.type;\n }\n\n return { status: 0, data: buf };\n }\n\n // Simple name list: count(u32) + entries[name_len(u16) + name(bytes)]\n let totalSize = 4;\n const nameEntries: Uint8Array[] = [];\n\n for (const child of children) {\n const name = child.path.substring(child.path.lastIndexOf('/') + 1);\n const nameBytes = encoder.encode(name);\n nameEntries.push(nameBytes);\n totalSize += 2 + nameBytes.byteLength;\n }\n\n const buf = new Uint8Array(totalSize);\n const view = new DataView(buf.buffer);\n view.setUint32(0, nameEntries.length, true);\n let offset = 4;\n\n for (const nameBytes of nameEntries) {\n view.setUint16(offset, nameBytes.byteLength, true);\n offset += 2;\n buf.set(nameBytes, offset);\n offset += nameBytes.byteLength;\n }\n\n return { status: 0, data: buf };\n }\n\n // ---- RENAME ----\n rename(oldPath: string, newPath: string): { status: number } {\n oldPath = this.normalizePath(oldPath);\n newPath = this.normalizePath(newPath);\n\n const idx = this.pathIndex.get(oldPath);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n // Same path → no-op (matches Node.js semantics)\n if (oldPath === newPath) return { status: 0 };\n\n // Ensure parent of new path exists\n const parentStatus = this.ensureParent(newPath);\n if (parentStatus !== 0) return { status: parentStatus };\n\n // If target exists, remove it. For directory targets we MUST recursively\n // free every descendant inode and drop every descendant pathIndex entry —\n // otherwise the source's children get added on top, leaving a mix of\n // source children + leftover target children pointing at zombie inodes\n // (the target's old children still appear in pathIndex, while their\n // inodes are not freed so blocks are leaked too).\n //\n // Concrete consequence of the old behavior: Vite's deps optimization\n // commit (`.vite/deps_temp_<hash>` → `.vite/deps`) on the second run\n // returned success but produced a corrupt deps directory — subsequent\n // requests for `vue.js`, `@unhead/vue`, etc. resolved to stale chunks\n // from the previous round (or 404'd entirely).\n //\n // The target may also be an *implicit* directory (no inode of its own,\n // but children exist under it — the state produced by bulk OPFS import).\n // In that case there's no inode to free, but the descendants must still\n // be cleaned up for the same reason.\n const existingIdx = this.pathIndex.get(newPath);\n const targetIsImplicitDir =\n existingIdx === undefined && this.isImplicitDirectory(newPath);\n\n if (existingIdx !== undefined || targetIsImplicitDir) {\n let cleanDescendants = targetIsImplicitDir;\n\n if (existingIdx !== undefined) {\n const existingInode = this.readInode(existingIdx);\n cleanDescendants = existingInode.type === INODE_TYPE.DIRECTORY;\n this.freeBlockRange(existingInode.firstBlock, existingInode.blockCount);\n existingInode.type = INODE_TYPE.FREE;\n this.writeInode(existingIdx, existingInode);\n this.deletePathIndex(newPath);\n if (existingIdx < this.freeInodeHint) this.freeInodeHint = existingIdx;\n }\n\n if (cleanDescendants) {\n // Free every descendant inode and remove its pathIndex entry.\n // Use getAllDescendants for the deepest-first ordering (matches\n // rmdir's recursive path) — though for a flat free pass order\n // doesn't affect correctness here.\n for (const desc of this.getAllDescendants(newPath)) {\n const descIdx = this.pathIndex.get(desc)!;\n const descInode = this.readInode(descIdx);\n this.freeBlockRange(descInode.firstBlock, descInode.blockCount);\n descInode.type = INODE_TYPE.FREE;\n this.writeInode(descIdx, descInode);\n this.deletePathIndex(desc);\n if (descIdx < this.freeInodeHint) this.freeInodeHint = descIdx;\n }\n }\n }\n\n // Update inode with new path\n const inode = this.readInode(idx);\n const { offset: pathOff, length: pathLen } = this.appendPath(newPath);\n inode.pathOffset = pathOff;\n inode.pathLength = pathLen;\n inode.mtime = Date.now();\n this.writeInode(idx, inode);\n\n // Update index\n this.deletePathIndex(oldPath);\n this.setPathIndex(newPath, idx);\n this.pathIndexGen++;\n\n // If it's a directory, rename all descendants\n if (inode.type === INODE_TYPE.DIRECTORY) {\n const prefix = oldPath === '/' ? '/' : oldPath + '/';\n const toRename: [string, number][] = [];\n\n for (const [p, i] of this.pathIndex) {\n if (p.startsWith(prefix)) {\n toRename.push([p, i]);\n }\n }\n\n for (const [p, i] of toRename) {\n const suffix = p.substring(oldPath.length);\n const childNewPath = newPath + suffix;\n const childInode = this.readInode(i);\n const { offset: cpo, length: cpl } = this.appendPath(childNewPath);\n childInode.pathOffset = cpo;\n childInode.pathLength = cpl;\n this.writeInode(i, childInode);\n this.deletePathIndex(p);\n this.setPathIndex(childNewPath, i);\n }\n }\n\n this.commitPending();\n return { status: 0 };\n }\n\n // ---- EXISTS ----\n exists(path: string): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n const buf = new Uint8Array(1);\n buf[0] = (idx !== undefined || this.isImplicitDirectory(path)) ? 1 : 0;\n return { status: 0, data: buf };\n }\n\n // ---- TRUNCATE ----\n truncate(path: string, len: number = 0): { status: number } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n const inode = this.readInode(idx);\n if (inode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EISDIR };\n\n if (len === 0) {\n // Free all blocks\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n inode.firstBlock = 0;\n inode.blockCount = 0;\n inode.size = 0;\n } else if (len < inode.size) {\n // Shrink\n const neededBlocks = Math.ceil(len / this.blockSize);\n if (neededBlocks < inode.blockCount) {\n this.freeBlockRange(inode.firstBlock + neededBlocks, inode.blockCount - neededBlocks);\n }\n inode.blockCount = neededBlocks;\n inode.size = len;\n } else if (len > inode.size) {\n // Grow with POSIX zero-fill semantics. Old code staged the entire\n // new file as a single `new Uint8Array(len)` — OOMs for large\n // truncates and allocates way more than necessary. Instead, copy\n // old contents in bounded chunks and zero-fill the extension\n // directly on disk.\n const neededBlocks = Math.ceil(len / this.blockSize);\n if (neededBlocks > inode.blockCount) {\n // Allocate-then-copy-then-free so the old range is guaranteed\n // not to overlap the new one. See `fwrite` for the same pattern.\n const newFirst = this.allocateBlocks(neededBlocks);\n const newBase = this.dataOffset + newFirst * this.blockSize;\n if (inode.size > 0) {\n const oldBase = this.dataOffset + inode.firstBlock * this.blockSize;\n const CHUNK = 4 * 1024 * 1024; // 4 MB\n const scratch = new Uint8Array(Math.min(CHUNK, inode.size));\n let copied = 0;\n while (copied < inode.size) {\n const n = Math.min(CHUNK, inode.size - copied);\n const slice = n < scratch.length ? scratch.subarray(0, n) : scratch;\n this.handle.read(slice, { at: oldBase + copied });\n this.handle.write(slice, { at: newBase + copied });\n copied += n;\n }\n }\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n this.zeroFileRange(newBase + inode.size, len - inode.size);\n inode.firstBlock = newFirst;\n } else {\n // Same block count, just growing `size`. The tail of the last\n // existing block still contains whatever stale data was there\n // before — zero it so the extended region reads as zeros.\n this.zeroFileRange(\n this.dataOffset + inode.firstBlock * this.blockSize + inode.size,\n len - inode.size,\n );\n }\n inode.blockCount = neededBlocks;\n inode.size = len;\n }\n\n inode.mtime = Date.now();\n this.writeInode(idx, inode);\n\n this.commitPending();\n return { status: 0 };\n }\n\n // ---- COPY ----\n copy(srcPath: string, destPath: string, flags: number = 0): { status: number } {\n srcPath = this.normalizePath(srcPath);\n destPath = this.normalizePath(destPath);\n\n const srcIdx = this.resolvePathComponents(srcPath, true);\n if (srcIdx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n const srcInode = this.readInode(srcIdx);\n if (srcInode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EISDIR };\n\n // COPYFILE_EXCL check\n if ((flags & 1) && (this.pathIndex.has(destPath) || this.isImplicitDirectory(destPath))) {\n return { status: CODE_TO_STATUS.EEXIST };\n }\n\n // Self-copy — no-op.\n if (srcPath === destPath) return { status: 0 };\n\n const srcSize = srcInode.size;\n const srcFirstBlock = srcInode.firstBlock;\n\n // Stage 1: create the destination as an empty file. This goes through\n // the normal `write` path which handles parent-directory creation,\n // freeing any pre-existing blocks at `destPath`, and registering the\n // inode in `pathIndex`. Doing this first also means any side effects\n // (e.g. a `growPathTable` shift of the data region) happen BEFORE we\n // start allocating destination blocks, so the relative block indices\n // we capture below stay valid.\n const emptyStatus = this.write(destPath, new Uint8Array(0));\n if (emptyStatus.status !== 0) return emptyStatus;\n\n if (srcSize === 0) return { status: 0 };\n\n // Stage 2: allocate a destination block run sized to the source, then\n // copy the bytes directly between block ranges via the file handle in\n // bounded chunks. No full-file buffer is ever allocated — peak scratch\n // stays at 4 MB regardless of how big the source file is.\n const destIdx = this.resolvePathComponents(destPath, true);\n if (destIdx === undefined) return { status: CODE_TO_STATUS.EIO };\n const destInode = this.readInode(destIdx);\n\n const neededBlocks = Math.ceil(srcSize / this.blockSize);\n const newFirst = this.allocateBlocks(neededBlocks);\n const newBase = this.dataOffset + newFirst * this.blockSize;\n const srcBase = this.dataOffset + srcFirstBlock * this.blockSize;\n\n const CHUNK = 4 * 1024 * 1024; // 4 MB\n const scratch = new Uint8Array(Math.min(CHUNK, srcSize));\n let copied = 0;\n while (copied < srcSize) {\n const n = Math.min(CHUNK, srcSize - copied);\n const slice = n < scratch.length ? scratch.subarray(0, n) : scratch;\n this.handle.read(slice, { at: srcBase + copied });\n this.handle.write(slice, { at: newBase + copied });\n copied += n;\n }\n\n destInode.firstBlock = newFirst;\n destInode.blockCount = neededBlocks;\n destInode.size = srcSize;\n destInode.mtime = Date.now();\n this.writeInode(destIdx, destInode);\n this.commitPending();\n return { status: 0 };\n }\n\n // ---- ACCESS ----\n access(path: string, mode: number = 0): { status: number } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) {\n // Check for implicit directory\n if (this.isImplicitDirectory(path)) return { status: 0 };\n return { status: CODE_TO_STATUS.ENOENT };\n }\n\n if (mode === 0) return { status: 0 }; // F_OK — just check existence\n\n if (!this.strictPermissions) return { status: 0 }; // Relaxed mode\n\n const inode = this.readInode(idx);\n // Check permission bits against process identity\n const filePerm = this.getEffectivePermission(inode);\n\n if ((mode & 4) && !(filePerm & 4)) return { status: CODE_TO_STATUS.EACCES }; // R_OK\n if ((mode & 2) && !(filePerm & 2)) return { status: CODE_TO_STATUS.EACCES }; // W_OK\n if ((mode & 1) && !(filePerm & 1)) return { status: CODE_TO_STATUS.EACCES }; // X_OK\n\n return { status: 0 };\n }\n\n private getEffectivePermission(inode: Inode): number {\n const modeBits = inode.mode & 0o777;\n if (this.processUid === inode.uid) return (modeBits >>> 6) & 7;\n if (this.processGid === inode.gid) return (modeBits >>> 3) & 7;\n return modeBits & 7;\n }\n\n // ---- REALPATH ----\n realpath(path: string): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) {\n // Check for implicit directory\n if (this.isImplicitDirectory(path)) {\n return { status: 0, data: encoder.encode(path) };\n }\n return { status: CODE_TO_STATUS.ENOENT, data: null };\n }\n\n // Find the resolved path for this inode\n const inode = this.readInode(idx);\n const resolvedPath = this.readPath(inode.pathOffset, inode.pathLength);\n return { status: 0, data: encoder.encode(resolvedPath) };\n }\n\n // ---- CHMOD ----\n chmod(path: string, mode: number): { status: number } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n const inode = this.readInode(idx);\n // Preserve file type bits, update permission bits\n inode.mode = (inode.mode & S_IFMT) | (mode & 0o7777);\n inode.ctime = Date.now();\n this.writeInode(idx, inode);\n\n return { status: 0 };\n }\n\n // ---- CHOWN ----\n chown(path: string, uid: number, gid: number): { status: number } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n const inode = this.readInode(idx);\n inode.uid = uid;\n inode.gid = gid;\n inode.ctime = Date.now();\n this.writeInode(idx, inode);\n\n return { status: 0 };\n }\n\n // ---- UTIMES ----\n utimes(path: string, atime: number, mtime: number): { status: number } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n const inode = this.readInode(idx);\n inode.atime = atime;\n inode.mtime = mtime;\n inode.ctime = Date.now();\n this.writeInode(idx, inode);\n\n return { status: 0 };\n }\n\n // ---- SYMLINK ----\n symlink(target: string, linkPath: string): { status: number } {\n linkPath = this.normalizePath(linkPath);\n if (this.pathIndex.has(linkPath) || this.isImplicitDirectory(linkPath)) {\n return { status: CODE_TO_STATUS.EEXIST };\n }\n\n const parentStatus = this.ensureParent(linkPath);\n if (parentStatus !== 0) return { status: parentStatus };\n\n const targetBytes = encoder.encode(target);\n this.createInode(linkPath, INODE_TYPE.SYMLINK, DEFAULT_SYMLINK_MODE, targetBytes.byteLength, targetBytes);\n\n this.commitPending();\n return { status: 0 };\n }\n\n // ---- READLINK ----\n readlink(path: string): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n const idx = this.pathIndex.get(path);\n if (idx === undefined) return { status: CODE_TO_STATUS.ENOENT, data: null };\n\n const inode = this.readInode(idx);\n if (inode.type !== INODE_TYPE.SYMLINK) return { status: CODE_TO_STATUS.EINVAL, data: null };\n\n const target = this.readData(inode.firstBlock, inode.blockCount, inode.size);\n return { status: 0, data: target };\n }\n\n // ---- LINK (hard link — copies the file data, tracks nlink) ----\n link(existingPath: string, newPath: string): { status: number } {\n existingPath = this.normalizePath(existingPath);\n newPath = this.normalizePath(newPath);\n\n const srcIdx = this.resolvePathComponents(existingPath, true);\n if (srcIdx === undefined) return { status: CODE_TO_STATUS.ENOENT };\n\n const srcInode = this.readInode(srcIdx);\n if (srcInode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EPERM };\n\n if (this.pathIndex.has(newPath) || this.isImplicitDirectory(newPath)) {\n return { status: CODE_TO_STATUS.EEXIST };\n }\n\n // Copy file data to new inode\n const result = this.copy(existingPath, newPath);\n if (result.status !== 0) return result;\n\n // Increment nlink on source\n srcInode.nlink++;\n this.writeInode(srcIdx, srcInode);\n\n // Set nlink on destination to match source\n const destIdx = this.pathIndex.get(newPath);\n if (destIdx !== undefined) {\n const destInode = this.readInode(destIdx);\n destInode.nlink = srcInode.nlink;\n this.writeInode(destIdx, destInode);\n }\n\n return { status: 0 };\n }\n\n // ---- OPEN (file descriptor) ----\n open(path: string, flags: number, tabId: string): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n\n const hasCreate = (flags & 64) !== 0; // O_CREAT\n const hasTrunc = (flags & 512) !== 0; // O_TRUNC\n const hasExcl = (flags & 128) !== 0; // O_EXCL\n\n let idx = this.resolvePathComponents(path, true);\n\n if (idx === undefined) {\n if (!hasCreate) return { status: CODE_TO_STATUS.ENOENT, data: null };\n // Create file\n const mode = DEFAULT_FILE_MODE & ~(this.umask & 0o777);\n idx = this.createInode(path, INODE_TYPE.FILE, mode, 0);\n } else if (hasExcl && hasCreate) {\n return { status: CODE_TO_STATUS.EEXIST, data: null };\n }\n\n if (hasTrunc) {\n this.truncate(path, 0);\n }\n\n const fd = this.nextFd++;\n this.fdTable.set(fd, { tabId, inodeIdx: idx, position: 0, flags });\n\n const buf = new Uint8Array(4);\n new DataView(buf.buffer).setUint32(0, fd, true);\n return { status: 0, data: buf };\n }\n\n // ---- CLOSE ----\n close(fd: number): { status: number } {\n if (!this.fdTable.has(fd)) return { status: CODE_TO_STATUS.EBADF };\n this.fdTable.delete(fd);\n return { status: 0 };\n }\n\n // ---- FREAD ----\n fread(fd: number, length: number, position: number | null): { status: number; data: Uint8Array | null } {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: CODE_TO_STATUS.EBADF, data: null };\n\n const inode = this.readInode(entry.inodeIdx);\n const pos = position ?? entry.position;\n const readLen = Math.min(length, inode.size - pos);\n\n if (readLen <= 0) return { status: 0, data: new Uint8Array(0) };\n\n // Read from specific offset within the file's data blocks\n const dataOffset = this.dataOffset + inode.firstBlock * this.blockSize + pos;\n const buf = new Uint8Array(readLen);\n this.handle.read(buf, { at: dataOffset });\n\n // Update position\n if (position === null) {\n entry.position += readLen;\n }\n\n return { status: 0, data: buf };\n }\n\n // ---- FWRITE ----\n fwrite(fd: number, data: Uint8Array, position: number | null): { status: number; data: Uint8Array | null } {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: CODE_TO_STATUS.EBADF, data: null };\n\n const inode = this.readInode(entry.inodeIdx);\n const isAppend = (entry.flags & 1024) !== 0; // O_APPEND\n const pos = isAppend ? inode.size : (position ?? entry.position);\n const endPos = pos + data.byteLength;\n\n // Check if we need to grow\n if (endPos > inode.size) {\n const neededBlocks = Math.ceil(endPos / this.blockSize);\n if (neededBlocks > inode.blockCount) {\n // Grow by relocating to a larger block run. We used to stage the\n // entire new file contents in a single `new Uint8Array(endPos)`\n // and then call `writeData` once — that blew up with\n // \"Array buffer allocation failed\" on multi-hundred-MB writes\n // because Chrome refuses contiguous allocations near ~2 GB even\n // with plenty of OS RAM. Instead, allocate new blocks, copy the\n // old contents forward in chunks via the underlying file handle\n // (which is O(N) bytes but with a bounded scratch buffer), then\n // free the old blocks and write just the caller's `data` at its\n // offset inside the new region.\n const newFirst = this.allocateBlocks(neededBlocks);\n const newBase = this.dataOffset + newFirst * this.blockSize;\n const oldBase = this.dataOffset + inode.firstBlock * this.blockSize;\n // Copy oldData from old block run to new block run in chunks.\n if (inode.size > 0) {\n const CHUNK = 4 * 1024 * 1024; // 4 MB\n const scratch = new Uint8Array(Math.min(CHUNK, inode.size));\n let copied = 0;\n while (copied < inode.size) {\n const n = Math.min(CHUNK, inode.size - copied);\n const slice = n < scratch.length ? scratch.subarray(0, n) : scratch;\n this.handle.read(slice, { at: oldBase + copied });\n this.handle.write(slice, { at: newBase + copied });\n copied += n;\n }\n }\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n // POSIX \"hole\" — if the caller is writing past the current EOF\n // with a gap in between, those bytes must read back as zeros\n // rather than whatever stale data lives in the freshly allocated\n // blocks. `allocateBlocks` only flips bitmap bits, it never\n // zeroes the underlying storage.\n if (pos > inode.size) {\n this.zeroFileRange(newBase + inode.size, pos - inode.size);\n }\n // Write the caller's new data at its offset inside the new region.\n this.handle.write(data, { at: newBase + pos });\n inode.firstBlock = newFirst;\n inode.blockCount = neededBlocks;\n } else {\n // Fits within existing blocks. Same hole semantics as above —\n // stale bytes in the tail of the last allocated block (past the\n // old file size) must be zeroed before the caller's write lands.\n if (pos > inode.size) {\n this.zeroFileRange(\n this.dataOffset + inode.firstBlock * this.blockSize + inode.size,\n pos - inode.size,\n );\n }\n const dataOffset = this.dataOffset + inode.firstBlock * this.blockSize + pos;\n this.handle.write(data, { at: dataOffset });\n }\n inode.size = endPos;\n } else {\n // Write within existing bounds\n const dataOffset = this.dataOffset + inode.firstBlock * this.blockSize + pos;\n this.handle.write(data, { at: dataOffset });\n }\n\n inode.mtime = Date.now();\n this.writeInode(entry.inodeIdx, inode);\n\n // Update position\n if (position === null) {\n entry.position = endPos;\n }\n\n this.commitPending();\n const buf = new Uint8Array(4);\n new DataView(buf.buffer).setUint32(0, data.byteLength, true);\n return { status: 0, data: buf };\n }\n\n // ---- FSTAT ----\n fstat(fd: number): { status: number; data: Uint8Array | null } {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: CODE_TO_STATUS.EBADF, data: null };\n if (entry.implicitPath) return this.encodeImplicitDirStatResponse(entry.implicitPath);\n return this.encodeStatResponse(entry.inodeIdx);\n }\n\n // ---- FTRUNCATE ----\n ftruncate(fd: number, len: number = 0): { status: number } {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: CODE_TO_STATUS.EBADF };\n\n const inode = this.readInode(entry.inodeIdx);\n const path = this.readPath(inode.pathOffset, inode.pathLength);\n return this.truncate(path, len);\n }\n\n // ---- FSYNC ----\n fsync(): { status: number } {\n this.commitPending();\n this.handle.flush();\n return { status: 0 };\n }\n\n // ---- FCHMOD ----\n // fd-based chmod: look up the inode directly from the fd table and mutate\n // its mode bits. Native Node does the same thing at the libuv layer.\n fchmod(fd: number, mode: number): { status: number } {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: CODE_TO_STATUS.EBADF };\n if (entry.implicitPath) return { status: 0 }; // no-op for implicit dirs\n const inode = this.readInode(entry.inodeIdx);\n inode.mode = (inode.mode & S_IFMT) | (mode & 0o7777);\n inode.ctime = Date.now();\n this.writeInode(entry.inodeIdx, inode);\n return { status: 0 };\n }\n\n // ---- FCHOWN ----\n fchown(fd: number, uid: number, gid: number): { status: number } {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: CODE_TO_STATUS.EBADF };\n if (entry.implicitPath) return { status: 0 }; // no-op for implicit dirs\n const inode = this.readInode(entry.inodeIdx);\n inode.uid = uid;\n inode.gid = gid;\n inode.ctime = Date.now();\n this.writeInode(entry.inodeIdx, inode);\n return { status: 0 };\n }\n\n // ---- FUTIMES ----\n futimes(fd: number, atime: number, mtime: number): { status: number } {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: CODE_TO_STATUS.EBADF };\n if (entry.implicitPath) return { status: 0 }; // no-op for implicit dirs\n const inode = this.readInode(entry.inodeIdx);\n inode.atime = atime;\n inode.mtime = mtime;\n inode.ctime = Date.now();\n this.writeInode(entry.inodeIdx, inode);\n return { status: 0 };\n }\n\n // ---- OPENDIR ----\n opendir(path: string, tabId: string): { status: number; data: Uint8Array | null } {\n path = this.normalizePath(path);\n const idx = this.resolvePathComponents(path, true);\n if (idx === undefined) {\n // Check for implicit directory\n if (this.isImplicitDirectory(path)) {\n // Create fd with synthetic inode index -1 and the path stored so\n // fd-based operations (fstat, fchmod, etc.) can handle it.\n const fd = this.nextFd++;\n this.fdTable.set(fd, { tabId, inodeIdx: -1, position: 0, flags: 0, implicitPath: path });\n const buf = new Uint8Array(4);\n new DataView(buf.buffer).setUint32(0, fd, true);\n return { status: 0, data: buf };\n }\n return { status: CODE_TO_STATUS.ENOENT, data: null };\n }\n\n const inode = this.readInode(idx);\n if (inode.type !== INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.ENOTDIR, data: null };\n\n // Use fd table for dir handles too\n const fd = this.nextFd++;\n this.fdTable.set(fd, { tabId, inodeIdx: idx, position: 0, flags: 0 });\n\n const buf = new Uint8Array(4);\n new DataView(buf.buffer).setUint32(0, fd, true);\n return { status: 0, data: buf };\n }\n\n // ---- MKDTEMP ----\n mkdtemp(prefix: string): { status: number; data: Uint8Array | null } {\n const suffix = Math.random().toString(36).substring(2, 8);\n const path = this.normalizePath(prefix + suffix);\n\n // Ensure parent directories exist\n const parentStatus = this.ensureParent(path);\n if (parentStatus !== 0) {\n // Auto-create parent directories for mkdtemp\n const parentPath = path.substring(0, path.lastIndexOf('/'));\n if (parentPath) {\n this.mkdirRecursive(parentPath);\n }\n }\n\n const mode = DEFAULT_DIR_MODE & ~(this.umask & 0o777);\n this.createInode(path, INODE_TYPE.DIRECTORY, mode, 0);\n\n this.commitPending();\n return { status: 0, data: encoder.encode(path) };\n }\n\n // ========== Helpers ==========\n\n private getDirectChildren(dirPath: string): string[] {\n const prefix = dirPath === '/' ? '/' : dirPath + '/';\n const children: string[] = [];\n\n for (const path of this.pathIndex.keys()) {\n if (path === dirPath) continue;\n if (!path.startsWith(prefix)) continue;\n // Direct child: no more slashes after prefix\n const rest = path.substring(prefix.length);\n if (!rest.includes('/')) {\n children.push(path);\n }\n }\n\n return children.sort();\n }\n\n /**\n * Rebuild the set of all implicit directory paths.\n * An implicit directory is any ancestor path of a file/symlink in pathIndex\n * that doesn't itself have an explicit inode entry.\n * Only rebuilt when pathIndex has changed (tracked via generation counter).\n */\n private rebuildImplicitDirs(): void {\n if (this.implicitDirsGen === this.pathIndexGen) return;\n\n const now = Date.now();\n const prev = this.implicitDirs;\n this.implicitDirs = new Map<string, number>();\n for (const filePath of this.pathIndex.keys()) {\n // Walk up from each path, adding all ancestor dirs that aren't explicit\n let pos = filePath.length;\n while (true) {\n pos = filePath.lastIndexOf('/', pos - 1);\n if (pos <= 0) break; // reached root\n const ancestor = filePath.substring(0, pos);\n if (this.implicitDirs.has(ancestor)) break; // already tracked all ancestors from here up\n if (!this.pathIndex.has(ancestor)) {\n // Preserve timestamp if this implicit dir was already known,\n // otherwise stamp it with \"now\" so stat() stays stable.\n this.implicitDirs.set(ancestor, prev.get(ancestor) ?? now);\n }\n }\n }\n\n this.implicitDirsGen = this.pathIndexGen;\n }\n\n /**\n * Check if a path is an implicit directory (exists because files exist under it,\n * but no explicit directory inode was created for it).\n *\n * O(1) via the incrementally maintained `descCount` map (an implicit dir\n * is exactly !pathIndex.has(P) && descCount[P] > 0). If `pathIndex` was\n * mutated directly without going through the helpers (test scaffolding),\n * descCount is stale and we rebuild it from scratch — once — to resync.\n */\n private isImplicitDirectory(path: string): boolean {\n if (path === '/') return false; // root always has an explicit inode\n if (this.pathIndex.has(path)) return false;\n if (this.descCountGen < this.pathIndexGen) this.rebuildDescCount();\n return (this.descCount.get(path) ?? 0) > 0;\n }\n\n /**\n * Recompute `descCount` from scratch by walking every pathIndex entry's\n * ancestor chain. O(N×depth). Only triggered when something bypassed the\n * setPathIndex/deletePathIndex helpers — in production code that's\n * never; the tests exercise this path.\n */\n private rebuildDescCount(): void {\n this.descCount.clear();\n for (const path of this.pathIndex.keys()) {\n this.bumpDescCount(path);\n }\n this.descCountGen = this.pathIndexGen;\n }\n\n // ---- pathIndex helpers — keep `descCount` in sync ----\n // Every pathIndex.set/delete in the engine MUST go through these so the\n // `descCount` map (used by `isImplicitDirectory`) stays correct. We\n // anticipate the caller's `pathIndexGen++` by setting `descCountGen` to\n // `pathIndexGen + 1`; idempotent across multiple helper calls within a\n // single logical op (e.g. rmdir doing N deletes then one bump). Test\n // code that mutates `pathIndex` directly leaves descCountGen behind,\n // which is what triggers the rebuild path in `isImplicitDirectory`.\n\n private setPathIndex(path: string, idx: number): void {\n const had = this.pathIndex.has(path);\n this.pathIndex.set(path, idx);\n if (!had) this.bumpDescCount(path);\n this.descCountGen = this.pathIndexGen + 1;\n }\n\n private deletePathIndex(path: string): boolean {\n const had = this.pathIndex.delete(path);\n if (had) this.decDescCount(path);\n this.descCountGen = this.pathIndexGen + 1;\n return had;\n }\n\n private bumpDescCount(path: string): void {\n let pos = path.length;\n while (true) {\n pos = path.lastIndexOf('/', pos - 1);\n if (pos <= 0) break; // reached root, which has no descCount entry\n const ancestor = path.substring(0, pos);\n this.descCount.set(ancestor, (this.descCount.get(ancestor) ?? 0) + 1);\n }\n }\n\n private decDescCount(path: string): void {\n let pos = path.length;\n while (true) {\n pos = path.lastIndexOf('/', pos - 1);\n if (pos <= 0) break;\n const ancestor = path.substring(0, pos);\n const cur = this.descCount.get(ancestor);\n if (cur === undefined) break;\n if (cur <= 1) this.descCount.delete(ancestor);\n else this.descCount.set(ancestor, cur - 1);\n }\n }\n\n /**\n * Get direct children of a directory path, including implicit subdirectories.\n * Returns unique child full paths. Each entry is tagged with whether it's a\n * real inode or an implicit directory.\n */\n private getDirectChildrenWithImplicit(dirPath: string): { path: string; type: 'real' | 'implicit' }[] {\n const prefix = dirPath === '/' ? '/' : dirPath + '/';\n const childNames = new Map<string, 'real' | 'implicit'>();\n\n for (const path of this.pathIndex.keys()) {\n if (path === dirPath) continue;\n if (!path.startsWith(prefix)) continue;\n const rest = path.substring(prefix.length);\n const slashPos = rest.indexOf('/');\n if (slashPos === -1) {\n // Direct child file/dir — it's a real inode\n childNames.set(rest, 'real');\n } else {\n // Deeper descendant — the first segment is an implicit subdirectory\n const childName = rest.substring(0, slashPos);\n if (!childNames.has(childName)) {\n // Only mark as implicit if there's no real inode for it\n const childFullPath = prefix + childName;\n childNames.set(childName, this.pathIndex.has(childFullPath) ? 'real' : 'implicit');\n }\n }\n }\n\n const result: { path: string; type: 'real' | 'implicit' }[] = [];\n for (const [name, type] of childNames) {\n result.push({ path: prefix + name, type });\n }\n result.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);\n return result;\n }\n\n /**\n * Encode a synthetic stat response for an implicit directory.\n * Returns directory stats with default mode, zero size, current timestamps.\n */\n private encodeImplicitDirStatResponse(path: string): { status: number; data: Uint8Array } {\n // Use the stable timestamp assigned when this implicit dir was first\n // discovered, so repeated stat() calls return the same mtime/ctime/atime.\n this.rebuildImplicitDirs();\n const ts = this.implicitDirs.get(path) ?? Date.now();\n const mode = DEFAULT_DIR_MODE & ~(this.umask & 0o777);\n\n // Count implicit subdirectories for nlink\n const children = this.getDirectChildrenWithImplicit(path);\n let subdirCount = 0;\n for (const child of children) {\n if (child.type === 'implicit') {\n subdirCount++;\n } else {\n const childIdx = this.pathIndex.get(child.path);\n if (childIdx !== undefined) {\n const childInode = this.readInode(childIdx);\n if (childInode.type === INODE_TYPE.DIRECTORY) subdirCount++;\n }\n }\n }\n const nlink = 2 + subdirCount;\n\n // Encode stat: type(1) + mode(4) + size(8) + mtime(8) + ctime(8) + atime(8) + uid(4) + gid(4) + ino(4) + nlink(4) = 53 bytes\n const buf = new Uint8Array(53);\n const view = new DataView(buf.buffer);\n view.setUint8(0, INODE_TYPE.DIRECTORY);\n view.setUint32(1, mode, true);\n view.setFloat64(5, 0, true); // size = 0\n view.setFloat64(13, ts, true); // mtime\n view.setFloat64(21, ts, true); // ctime\n view.setFloat64(29, ts, true); // atime\n view.setUint32(37, this.processUid, true);\n view.setUint32(41, this.processGid, true);\n view.setUint32(45, 0, true); // ino = 0 (synthetic)\n view.setUint32(49, nlink, true);\n\n return { status: 0, data: buf };\n }\n\n private getAllDescendants(dirPath: string): string[] {\n const prefix = dirPath === '/' ? '/' : dirPath + '/';\n const descendants: string[] = [];\n\n for (const path of this.pathIndex.keys()) {\n if (path.startsWith(prefix)) descendants.push(path);\n }\n\n // Sort by depth (deepest first) for safe deletion\n return descendants.sort((a, b) => {\n const da = a.split('/').length;\n const db = b.split('/').length;\n return db - da;\n });\n }\n\n private ensureParent(path: string): number {\n const lastSlash = path.lastIndexOf('/');\n if (lastSlash <= 0) return 0; // Parent is root, always exists\n\n const parentPath = path.substring(0, lastSlash);\n const parentIdx = this.pathIndex.get(parentPath);\n if (parentIdx === undefined) {\n // Check for implicit directory\n if (this.isImplicitDirectory(parentPath)) return 0;\n return CODE_TO_STATUS.ENOENT;\n }\n\n const parentInode = this.readInode(parentIdx);\n if (parentInode.type !== INODE_TYPE.DIRECTORY) return CODE_TO_STATUS.ENOTDIR;\n\n return 0;\n }\n\n /** Clean up all fds owned by a tab */\n cleanupTab(tabId: string): void {\n for (const [fd, entry] of this.fdTable) {\n if (entry.tabId === tabId) {\n this.fdTable.delete(fd);\n }\n }\n }\n\n /** Get all file paths and their data for OPFS sync */\n getAllFiles(): { path: string; idx: number }[] {\n const files: { path: string; idx: number }[] = [];\n for (const [path, idx] of this.pathIndex) {\n files.push({ path, idx });\n }\n return files;\n }\n\n /** Get file path for a file descriptor (used by OPFS sync for FD-based ops) */\n getPathForFd(fd: number): string | null {\n const entry = this.fdTable.get(fd);\n if (!entry) return null;\n const inode = this.readInode(entry.inodeIdx);\n return this.readPath(inode.pathOffset, inode.pathLength);\n }\n\n /** Get file data by inode index */\n getInodeData(idx: number): { type: number; data: Uint8Array; mtime: number } {\n const inode = this.readInode(idx);\n const data = inode.size > 0\n ? this.readData(inode.firstBlock, inode.blockCount, inode.size)\n : new Uint8Array(0);\n return { type: inode.type, data, mtime: inode.mtime };\n }\n\n /** Export all files/dirs/symlinks from the VFS */\n exportAll(): Array<{ path: string; type: number; data: Uint8Array | null; mode: number; mtime: number }> {\n const result: Array<{ path: string; type: number; data: Uint8Array | null; mode: number; mtime: number }> = [];\n for (const [path, idx] of this.pathIndex) {\n const inode = this.readInode(idx);\n let data: Uint8Array | null = null;\n if (inode.type === INODE_TYPE.FILE || inode.type === INODE_TYPE.SYMLINK) {\n data = inode.size > 0\n ? this.readData(inode.firstBlock, inode.blockCount, inode.size)\n : new Uint8Array(0);\n }\n result.push({ path, type: inode.type, data, mode: inode.mode, mtime: inode.mtime });\n }\n // Sort directories first so parents are created before children\n result.sort((a, b) => {\n if (a.type === INODE_TYPE.DIRECTORY && b.type !== INODE_TYPE.DIRECTORY) return -1;\n if (a.type !== INODE_TYPE.DIRECTORY && b.type === INODE_TYPE.DIRECTORY) return 1;\n return a.path.localeCompare(b.path);\n });\n return result;\n }\n\n flush(): void {\n this.handle.flush();\n }\n}\n","/**\n * OPFS Engine — operates directly on real OPFS files.\n *\n * Drop-in async replacement for VFSEngine. Used when mode='opfs' or as\n * fallback when VFS binary corruption is detected in hybrid mode.\n *\n * All methods are async because OPFS directory operations require async APIs.\n * File content operations use createSyncAccessHandle for speed.\n *\n * Limitations compared to VFSEngine:\n * - No symlinks (OPFS doesn't support them)\n * - No permissions/ownership (OPFS doesn't support them)\n * - Slower directory operations (async OPFS API calls)\n */\n\nconst encoder = new TextEncoder();\n\n// Match VFS inode types for stat encoding\nconst TYPE_FILE = 1;\nconst TYPE_DIRECTORY = 2;\n\n// Match binary protocol status codes from errors.ts\nconst OK = 0;\nconst ENOENT = 1;\nconst EEXIST = 2;\nconst EISDIR = 3;\nconst ENOTDIR = 4;\nconst ENOTEMPTY = 5;\nconst EINVAL = 7;\nconst EBADF = 8;\n\ninterface OPFSResult {\n status: number;\n data?: Uint8Array | null;\n}\n\ninterface FdEntry {\n handle: FileSystemSyncAccessHandle;\n path: string;\n position: number;\n flags: number;\n}\n\nexport class OPFSEngine {\n private rootDir!: FileSystemDirectoryHandle;\n private fdTable = new Map<number, FdEntry>();\n private nextFd = 3;\n private nextIno = 1;\n private processUid = 0;\n private processGid = 0;\n\n async init(\n rootDir: FileSystemDirectoryHandle,\n opts?: { uid?: number; gid?: number },\n ): Promise<void> {\n this.rootDir = rootDir;\n this.processUid = opts?.uid ?? 0;\n this.processGid = opts?.gid ?? 0;\n }\n\n cleanupTab(_tabId: string): void {\n for (const [fd, entry] of this.fdTable) {\n try { entry.handle.close(); } catch {}\n this.fdTable.delete(fd);\n }\n }\n\n getPathForFd(fd: number): string | null {\n return this.fdTable.get(fd)?.path ?? null;\n }\n\n // ========== Path helpers ==========\n\n private normalizePath(path: string): string {\n if (!path.startsWith('/')) path = '/' + path;\n while (path.length > 1 && path.endsWith('/')) path = path.slice(0, -1);\n const parts = path.split('/');\n const resolved: string[] = [];\n for (const part of parts) {\n if (part === '' || part === '.') continue;\n if (part === '..') { resolved.pop(); continue; }\n resolved.push(part);\n }\n return '/' + resolved.join('/');\n }\n\n /** Navigate to the parent directory of a path, returning the parent handle and child name. */\n private async navigateToParent(\n path: string,\n ): Promise<{ dir: FileSystemDirectoryHandle; name: string } | null> {\n const parts = path.split('/').filter(Boolean);\n if (parts.length === 0) return null;\n const name = parts.pop()!;\n let dir = this.rootDir;\n for (const part of parts) {\n try {\n dir = await dir.getDirectoryHandle(part);\n } catch {\n return null;\n }\n }\n return { dir, name };\n }\n\n /** Navigate to a directory by path. */\n private async navigateToDir(path: string): Promise<FileSystemDirectoryHandle | null> {\n if (path === '/') return this.rootDir;\n const parts = path.split('/').filter(Boolean);\n let dir = this.rootDir;\n for (const part of parts) {\n try {\n dir = await dir.getDirectoryHandle(part);\n } catch {\n return null;\n }\n }\n return dir;\n }\n\n /** Get a file or directory handle for a path. */\n private async getEntry(\n path: string,\n ): Promise<{ handle: FileSystemFileHandle | FileSystemDirectoryHandle; kind: 'file' | 'directory' } | null> {\n if (path === '/') return { handle: this.rootDir, kind: 'directory' };\n const nav = await this.navigateToParent(path);\n if (!nav) return null;\n try {\n return { handle: await nav.dir.getFileHandle(nav.name), kind: 'file' };\n } catch {\n try {\n return { handle: await nav.dir.getDirectoryHandle(nav.name), kind: 'directory' };\n } catch {\n return null;\n }\n }\n }\n\n /** Ensure all parent directories exist (recursive mkdir for parents). */\n private async ensureParent(path: string): Promise<FileSystemDirectoryHandle | null> {\n const parts = path.split('/').filter(Boolean);\n parts.pop(); // remove the leaf\n let dir = this.rootDir;\n for (const part of parts) {\n try {\n dir = await dir.getDirectoryHandle(part, { create: true });\n } catch {\n return null;\n }\n }\n return dir;\n }\n\n private encodeStat(\n kind: 'file' | 'directory',\n size: number,\n mtime: number,\n ino: number,\n ): Uint8Array {\n const buf = new Uint8Array(53);\n const view = new DataView(buf.buffer);\n view.setUint8(0, kind === 'file' ? TYPE_FILE : TYPE_DIRECTORY);\n view.setUint32(1, kind === 'file' ? 0o100644 : 0o040755, true);\n view.setFloat64(5, size, true);\n view.setFloat64(13, mtime, true);\n view.setFloat64(21, mtime, true);\n view.setFloat64(29, mtime, true);\n view.setUint32(37, this.processUid, true);\n view.setUint32(41, this.processGid, true);\n view.setUint32(45, ino, true);\n view.setUint32(49, kind === 'directory' ? 2 : 1, true); // nlink\n return buf;\n }\n\n // ========== FS Operations ==========\n\n async read(path: string): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const nav = await this.navigateToParent(path);\n if (!nav) return { status: ENOENT, data: null };\n try {\n const fh = await nav.dir.getFileHandle(nav.name);\n const file = await fh.getFile();\n return { status: OK, data: new Uint8Array(await file.arrayBuffer()) };\n } catch {\n return { status: ENOENT, data: null };\n }\n }\n\n async write(path: string, data: Uint8Array, _flags?: number): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const parentDir = await this.ensureParent(path);\n if (!parentDir) return { status: ENOENT, data: null };\n const name = path.split('/').filter(Boolean).pop()!;\n try {\n const fh = await parentDir.getFileHandle(name, { create: true });\n const sh = await (fh as any).createSyncAccessHandle();\n try {\n sh.truncate(0);\n if (data.byteLength > 0) sh.write(data, { at: 0 });\n sh.flush();\n } finally {\n sh.close();\n }\n return { status: OK, data: null };\n } catch {\n return { status: ENOENT, data: null };\n }\n }\n\n async append(path: string, data: Uint8Array): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const parentDir = await this.ensureParent(path);\n if (!parentDir) return { status: ENOENT, data: null };\n const name = path.split('/').filter(Boolean).pop()!;\n try {\n const fh = await parentDir.getFileHandle(name, { create: true });\n const sh = await (fh as any).createSyncAccessHandle();\n try {\n const size: number = sh.getSize();\n sh.write(data, { at: size });\n sh.flush();\n } finally {\n sh.close();\n }\n return { status: OK, data: null };\n } catch {\n return { status: ENOENT, data: null };\n }\n }\n\n async unlink(path: string): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const nav = await this.navigateToParent(path);\n if (!nav) return { status: ENOENT, data: null };\n try {\n // Verify it exists and is a file\n await nav.dir.getFileHandle(nav.name);\n await nav.dir.removeEntry(nav.name);\n return { status: OK, data: null };\n } catch {\n return { status: ENOENT, data: null };\n }\n }\n\n async stat(path: string): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const entry = await this.getEntry(path);\n if (!entry) return { status: ENOENT, data: null };\n if (entry.kind === 'file') {\n const file = await (entry.handle as FileSystemFileHandle).getFile();\n return { status: OK, data: this.encodeStat('file', file.size, file.lastModified, this.nextIno++) };\n }\n return { status: OK, data: this.encodeStat('directory', 0, Date.now(), this.nextIno++) };\n }\n\n async lstat(path: string): Promise<OPFSResult> {\n return this.stat(path);\n }\n\n async mkdir(path: string, flags: number = 0): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const recursive = (flags & 1) !== 0;\n\n if (recursive) {\n const parts = path.split('/').filter(Boolean);\n let dir = this.rootDir;\n let firstCreated: string | null = null;\n let current = '';\n for (const part of parts) {\n current += '/' + part;\n let existed = true;\n try {\n dir = await dir.getDirectoryHandle(part);\n } catch {\n existed = false;\n dir = await dir.getDirectoryHandle(part, { create: true });\n }\n if (!existed && !firstCreated) firstCreated = current;\n }\n return { status: OK, data: firstCreated ? encoder.encode(firstCreated) : null };\n }\n\n const nav = await this.navigateToParent(path);\n if (!nav) return { status: ENOENT, data: null };\n try {\n // Check if already exists\n try {\n await nav.dir.getDirectoryHandle(nav.name);\n return { status: EEXIST, data: null };\n } catch {\n // doesn't exist — create it\n }\n await nav.dir.getDirectoryHandle(nav.name, { create: true });\n // Non-recursive mkdir returns undefined (null data) per Node.js spec\n return { status: OK, data: null };\n } catch {\n return { status: ENOENT, data: null };\n }\n }\n\n async rmdir(path: string, flags: number = 0): Promise<OPFSResult> {\n path = this.normalizePath(path);\n if (path === '/') return { status: EINVAL, data: null };\n const recursive = (flags & 1) !== 0;\n const nav = await this.navigateToParent(path);\n if (!nav) return { status: ENOENT, data: null };\n try {\n // Verify it's a directory\n await nav.dir.getDirectoryHandle(nav.name);\n await nav.dir.removeEntry(nav.name, { recursive });\n return { status: OK, data: null };\n } catch (err: any) {\n if (err.name === 'InvalidModificationError') return { status: ENOTEMPTY, data: null };\n return { status: ENOENT, data: null };\n }\n }\n\n async readdir(path: string, flags: number = 0): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const dir = await this.navigateToDir(path);\n if (!dir) return { status: ENOENT, data: null };\n\n // Verify it's a directory (navigateToDir already guarantees this)\n const withFileTypes = (flags & 1) !== 0;\n const entries: { name: string; kind: string }[] = [];\n\n for await (const [name, handle] of (dir as any).entries()) {\n entries.push({ name, kind: handle.kind });\n }\n\n if (withFileTypes) {\n let totalSize = 4;\n const encoded: { nameBytes: Uint8Array; type: number }[] = [];\n for (const e of entries) {\n const nameBytes = encoder.encode(e.name);\n encoded.push({ nameBytes, type: e.kind === 'file' ? TYPE_FILE : TYPE_DIRECTORY });\n totalSize += 2 + nameBytes.byteLength + 1;\n }\n\n const buf = new Uint8Array(totalSize);\n const view = new DataView(buf.buffer);\n view.setUint32(0, encoded.length, true);\n let offset = 4;\n for (const e of encoded) {\n view.setUint16(offset, e.nameBytes.byteLength, true);\n offset += 2;\n buf.set(e.nameBytes, offset);\n offset += e.nameBytes.byteLength;\n buf[offset++] = e.type;\n }\n return { status: OK, data: buf };\n }\n\n // Simple name list\n let totalSize = 4;\n const nameEntries: Uint8Array[] = [];\n for (const e of entries) {\n const nameBytes = encoder.encode(e.name);\n nameEntries.push(nameBytes);\n totalSize += 2 + nameBytes.byteLength;\n }\n\n const buf = new Uint8Array(totalSize);\n const view = new DataView(buf.buffer);\n view.setUint32(0, nameEntries.length, true);\n let offset = 4;\n for (const nameBytes of nameEntries) {\n view.setUint16(offset, nameBytes.byteLength, true);\n offset += 2;\n buf.set(nameBytes, offset);\n offset += nameBytes.byteLength;\n }\n return { status: OK, data: buf };\n }\n\n async rename(oldPath: string, newPath: string): Promise<OPFSResult> {\n oldPath = this.normalizePath(oldPath);\n newPath = this.normalizePath(newPath);\n\n const entry = await this.getEntry(oldPath);\n if (!entry) return { status: ENOENT, data: null };\n\n if (entry.kind === 'file') {\n // File rename: read → write new → delete old\n const fh = entry.handle as FileSystemFileHandle;\n const file = await fh.getFile();\n const data = new Uint8Array(await file.arrayBuffer());\n const writeResult = await this.write(newPath, data);\n if (writeResult.status !== OK) return writeResult;\n await this.unlink(oldPath);\n } else {\n // Directory rename: recursive copy → delete old\n await this.mkdir(newPath, 1);\n await this.copyDirectoryContents(oldPath, newPath);\n await this.rmdir(oldPath, 1);\n }\n return { status: OK, data: null };\n }\n\n private async copyDirectoryContents(srcPath: string, dstPath: string): Promise<void> {\n const srcDir = await this.navigateToDir(srcPath);\n if (!srcDir) return;\n\n for await (const [name, handle] of (srcDir as any).entries()) {\n const srcChild = srcPath === '/' ? `/${name}` : `${srcPath}/${name}`;\n const dstChild = dstPath === '/' ? `/${name}` : `${dstPath}/${name}`;\n\n if (handle.kind === 'directory') {\n await this.mkdir(dstChild, 1);\n await this.copyDirectoryContents(srcChild, dstChild);\n } else {\n const file = await (handle as FileSystemFileHandle).getFile();\n const data = new Uint8Array(await file.arrayBuffer());\n await this.write(dstChild, data);\n }\n }\n }\n\n async exists(path: string): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const entry = await this.getEntry(path);\n return { status: OK, data: new Uint8Array([entry ? 1 : 0]) };\n }\n\n async truncate(path: string, len: number): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const nav = await this.navigateToParent(path);\n if (!nav) return { status: ENOENT, data: null };\n try {\n const fh = await nav.dir.getFileHandle(nav.name);\n const sh = await (fh as any).createSyncAccessHandle();\n try {\n sh.truncate(len);\n sh.flush();\n } finally {\n sh.close();\n }\n return { status: OK, data: null };\n } catch {\n return { status: ENOENT, data: null };\n }\n }\n\n async copy(src: string, dest: string, _flags?: number): Promise<OPFSResult> {\n src = this.normalizePath(src);\n dest = this.normalizePath(dest);\n const readResult = await this.read(src);\n if (readResult.status !== OK) return readResult;\n return this.write(dest, readResult.data ?? new Uint8Array(0));\n }\n\n async access(path: string, _mode?: number): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const entry = await this.getEntry(path);\n if (!entry) return { status: ENOENT, data: null };\n return { status: OK, data: null };\n }\n\n async realpath(path: string): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const entry = await this.getEntry(path);\n if (!entry) return { status: ENOENT, data: null };\n return { status: OK, data: encoder.encode(path) };\n }\n\n // OPFS doesn't support permissions/ownership/timestamps — these succeed as\n // no-ops when the target exists, mirroring the VFS engine's behavior so\n // callers can write code that works in both modes.\n\n async chmod(path: string, _mode: number): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const entry = await this.getEntry(path);\n if (!entry) return { status: ENOENT, data: null };\n return { status: OK, data: null };\n }\n\n async chown(path: string, _uid: number, _gid: number): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const entry = await this.getEntry(path);\n if (!entry) return { status: ENOENT, data: null };\n return { status: OK, data: null };\n }\n\n async utimes(path: string, _atime: number, _mtime: number): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const entry = await this.getEntry(path);\n if (!entry) return { status: ENOENT, data: null };\n return { status: OK, data: null };\n }\n\n // fd-based variants: validate the fd and succeed. There's nowhere to store\n // mode/uid/gid/timestamps in OPFS, so they're accepted and discarded.\n async fchmod(fd: number, _mode: number): Promise<OPFSResult> {\n return this.fdTable.has(fd) ? { status: OK, data: null } : { status: EBADF, data: null };\n }\n\n async fchown(fd: number, _uid: number, _gid: number): Promise<OPFSResult> {\n return this.fdTable.has(fd) ? { status: OK, data: null } : { status: EBADF, data: null };\n }\n\n async futimes(fd: number, _atime: number, _mtime: number): Promise<OPFSResult> {\n return this.fdTable.has(fd) ? { status: OK, data: null } : { status: EBADF, data: null };\n }\n\n // OPFS has no symlinks or hard links\n\n async symlink(_target: string, _linkPath: string): Promise<OPFSResult> {\n return { status: EINVAL, data: null };\n }\n\n async readlink(_path: string): Promise<OPFSResult> {\n return { status: EINVAL, data: null };\n }\n\n async link(existingPath: string, newPath: string): Promise<OPFSResult> {\n return this.copy(existingPath, newPath);\n }\n\n // ========== File descriptor operations ==========\n\n async open(path: string, flags: number, _tabId: string): Promise<OPFSResult> {\n path = this.normalizePath(path);\n const hasCreate = (flags & 64) !== 0; // O_CREAT\n const hasTrunc = (flags & 512) !== 0; // O_TRUNC\n const hasExcl = (flags & 128) !== 0; // O_EXCL\n\n const parentDir = await this.ensureParent(path);\n if (!parentDir) return { status: ENOENT, data: null };\n const name = path.split('/').filter(Boolean).pop()!;\n\n try {\n // Check existence\n let exists = true;\n try {\n await parentDir.getFileHandle(name);\n } catch {\n exists = false;\n }\n\n if (!exists && !hasCreate) return { status: ENOENT, data: null };\n if (exists && hasExcl && hasCreate) return { status: EEXIST, data: null };\n\n const fh = await parentDir.getFileHandle(name, { create: hasCreate });\n const sh = await (fh as any).createSyncAccessHandle();\n\n if (hasTrunc) {\n sh.truncate(0);\n sh.flush();\n }\n\n const fd = this.nextFd++;\n this.fdTable.set(fd, { handle: sh, path, position: 0, flags });\n\n const buf = new Uint8Array(4);\n new DataView(buf.buffer).setUint32(0, fd, true);\n return { status: OK, data: buf };\n } catch {\n return { status: ENOENT, data: null };\n }\n }\n\n async close(fd: number): Promise<OPFSResult> {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: EBADF, data: null };\n try { entry.handle.close(); } catch {}\n this.fdTable.delete(fd);\n return { status: OK, data: null };\n }\n\n async fread(fd: number, length: number, position: number | null): Promise<OPFSResult> {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: EBADF, data: null };\n\n const pos = position ?? entry.position;\n const size: number = entry.handle.getSize();\n const readLen = Math.min(length, size - pos);\n if (readLen <= 0) return { status: OK, data: new Uint8Array(0) };\n\n const buf = new Uint8Array(readLen);\n entry.handle.read(buf, { at: pos });\n\n if (position === null) {\n entry.position += readLen;\n }\n return { status: OK, data: buf };\n }\n\n async fwrite(fd: number, data: Uint8Array, position: number | null): Promise<OPFSResult> {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: EBADF, data: null };\n\n const isAppend = (entry.flags & 1024) !== 0; // O_APPEND\n const pos = isAppend ? entry.handle.getSize() : (position ?? entry.position);\n\n entry.handle.write(data, { at: pos });\n\n if (position === null) {\n entry.position = pos + data.byteLength;\n }\n\n const buf = new Uint8Array(4);\n new DataView(buf.buffer).setUint32(0, data.byteLength, true);\n return { status: OK, data: buf };\n }\n\n async fstat(fd: number): Promise<OPFSResult> {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: EBADF, data: null };\n\n const size: number = entry.handle.getSize();\n return { status: OK, data: this.encodeStat('file', size, Date.now(), fd) };\n }\n\n async ftruncate(fd: number, len: number = 0): Promise<OPFSResult> {\n const entry = this.fdTable.get(fd);\n if (!entry) return { status: EBADF, data: null };\n entry.handle.truncate(len);\n entry.handle.flush();\n return { status: OK, data: null };\n }\n\n async fsync(): Promise<OPFSResult> {\n for (const [, entry] of this.fdTable) {\n try { entry.handle.flush(); } catch {}\n }\n return { status: OK, data: null };\n }\n\n async opendir(path: string, _tabId: string): Promise<OPFSResult> {\n return this.readdir(path, 1);\n }\n\n async mkdtemp(prefix: string): Promise<OPFSResult> {\n const random = Math.random().toString(36).substring(2, 8);\n const path = this.normalizePath(prefix + random);\n return this.mkdir(path, 1);\n }\n}\n","/**\n * Binary protocol operation codes and header encoding/decoding.\n * All inter-worker messages use this minimal binary protocol — no JSON, no strings.\n */\n\n// Operation codes\nexport const OP = {\n READ: 1,\n WRITE: 2,\n UNLINK: 3,\n STAT: 4,\n LSTAT: 5,\n MKDIR: 6,\n RMDIR: 7,\n READDIR: 8,\n RENAME: 9,\n EXISTS: 10,\n TRUNCATE: 11,\n APPEND: 12,\n COPY: 13,\n ACCESS: 14,\n REALPATH: 15,\n CHMOD: 16,\n CHOWN: 17,\n UTIMES: 18,\n SYMLINK: 19,\n READLINK: 20,\n LINK: 21,\n OPEN: 22,\n CLOSE: 23,\n FREAD: 24,\n FWRITE: 25,\n FSTAT: 26,\n FTRUNCATE: 27,\n FSYNC: 28,\n OPENDIR: 29,\n MKDTEMP: 30,\n FCHMOD: 31,\n FCHOWN: 32,\n FUTIMES: 33,\n} as const;\n\nexport type OpCode = (typeof OP)[keyof typeof OP];\n\n// Response status codes\nexport const STATUS = {\n OK: 0,\n ENOENT: 1,\n EEXIST: 2,\n EISDIR: 3,\n ENOTDIR: 4,\n ENOTEMPTY: 5,\n EACCES: 6,\n EINVAL: 7,\n EBADF: 8,\n ELOOP: 9,\n ENOSPC: 10,\n} as const;\n\n// SAB layout offsets\nexport const SAB_OFFSETS = {\n CONTROL: 0, // Int32 - signal (0=idle, 1=request, 2=response, 3=chunk, 4=ack)\n OPCODE: 4, // Int32 - operation code\n STATUS: 8, // Int32 - response status / error\n CHUNK_LEN: 12, // Int32 - bytes in this chunk\n TOTAL_LEN: 16, // BigUint64 - full data size across all chunks\n CHUNK_IDX: 24, // Int32 - 0-based chunk index\n HEARTBEAT: 28, // Int32 - liveness counter; the relay worker bumps this ~1×/s\n // while its event loop is alive (incl. mid-await of a\n // long op) so a spin-waiting main thread can tell\n // \"slow\" from \"dead\". Never written by the main thread.\n HEADER_SIZE: 32, // Data payload starts here\n} as const;\n\n// SAB control signals\nexport const SIGNAL = {\n IDLE: 0,\n REQUEST: 1,\n RESPONSE: 2,\n CHUNK: 3,\n CHUNK_ACK: 4,\n} as const;\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/**\n * Encode a request into an ArrayBuffer for MessageChannel transfer.\n *\n * Request format (16-byte header + path + data):\n * bytes 0-3: operation (uint32)\n * bytes 4-7: flags (uint32)\n * bytes 8-11: pathLen (uint32)\n * bytes 12-15: dataLen (uint32)\n * bytes 16+: path (UTF-8)\n * bytes 16+pathLen: data payload\n */\nexport function encodeRequest(\n op: number,\n path: string,\n flags: number = 0,\n data?: Uint8Array\n): ArrayBuffer {\n const pathBytes = encoder.encode(path);\n const dataLen = data ? data.byteLength : 0;\n const totalLen = 16 + pathBytes.byteLength + dataLen;\n const buf = new ArrayBuffer(totalLen);\n const view = new DataView(buf);\n\n view.setUint32(0, op, true);\n view.setUint32(4, flags, true);\n view.setUint32(8, pathBytes.byteLength, true);\n view.setUint32(12, dataLen, true);\n\n const bytes = new Uint8Array(buf);\n bytes.set(pathBytes, 16);\n if (data) {\n bytes.set(data, 16 + pathBytes.byteLength);\n }\n\n return buf;\n}\n\n/**\n * Decode a request ArrayBuffer.\n */\nexport function decodeRequest(buf: ArrayBuffer): {\n op: number;\n flags: number;\n path: string;\n data: Uint8Array | null;\n} {\n // Minimum header: 16 bytes (op + flags + pathLen + dataLen)\n if (buf.byteLength < 16) {\n throw new Error(`Request buffer too small: ${buf.byteLength} < 16 bytes (possible SAB race)`);\n }\n\n const view = new DataView(buf);\n const op = view.getUint32(0, true);\n const flags = view.getUint32(4, true);\n const pathLen = view.getUint32(8, true);\n const dataLen = view.getUint32(12, true);\n\n // Validate payload fits in buffer\n const expectedMin = 16 + pathLen + dataLen;\n if (buf.byteLength < expectedMin) {\n throw new Error(`Request buffer truncated: ${buf.byteLength} < ${expectedMin} bytes (op=${op}, pathLen=${pathLen}, dataLen=${dataLen})`);\n }\n\n const bytes = new Uint8Array(buf);\n const path = decoder.decode(bytes.subarray(16, 16 + pathLen));\n const data = dataLen > 0\n ? bytes.subarray(16 + pathLen, 16 + pathLen + dataLen)\n : null;\n\n return { op, flags, path, data };\n}\n\n/**\n * Encode a response into an ArrayBuffer.\n *\n * Response format (8-byte header + data):\n * bytes 0-3: status (uint32)\n * bytes 4-7: dataLen (uint32)\n * bytes 8+: data payload\n */\nexport function encodeResponse(status: number, data?: Uint8Array): ArrayBuffer {\n const dataLen = data ? data.byteLength : 0;\n const buf = new ArrayBuffer(8 + dataLen);\n const view = new DataView(buf);\n\n view.setUint32(0, status, true);\n view.setUint32(4, dataLen, true);\n\n if (data) {\n new Uint8Array(buf).set(data, 8);\n }\n\n return buf;\n}\n\n/**\n * Decode a response ArrayBuffer.\n */\nexport function decodeResponse(buf: ArrayBuffer): {\n status: number;\n data: Uint8Array | null;\n} {\n const view = new DataView(buf);\n const status = view.getUint32(0, true);\n const dataLen = view.getUint32(4, true);\n\n const data = dataLen > 0\n ? new Uint8Array(buf, 8, dataLen)\n : null;\n\n return { status, data };\n}\n\n/**\n * Encode a two-path request (rename, copy, symlink, link).\n * Data payload contains: [pathLen2:u32] [path2 bytes]\n */\nexport function encodeTwoPathRequest(\n op: number,\n path1: string,\n path2: string,\n flags: number = 0\n): ArrayBuffer {\n const path2Bytes = encoder.encode(path2);\n const payload = new Uint8Array(4 + path2Bytes.byteLength);\n const pv = new DataView(payload.buffer);\n pv.setUint32(0, path2Bytes.byteLength, true);\n payload.set(path2Bytes, 4);\n\n return encodeRequest(op, path1, flags, payload);\n}\n\n/**\n * Decode the second path from a two-path request's data payload.\n */\nexport function decodeSecondPath(data: Uint8Array): string {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const pathLen = view.getUint32(0, true);\n return decoder.decode(data.subarray(4, 4 + pathLen));\n}\n","/**\n * Sync Relay Worker — the VFS engine owner and primary request processor.\n *\n * Operates in one of two modes:\n *\n * LEADER MODE (primary tab):\n * - Owns the VFS engine and OPFS sync access handle\n * - Processes own tab's sync requests via syncSAB (fastest path, no hops)\n * - Processes own tab's async requests via asyncSAB (no MessagePort hop)\n * - Accepts MessagePort connections from secondary tabs\n * - Yields periodically to process port messages when clients are connected\n * - When no clients: pure blocking loop — zero overhead\n *\n * FOLLOWER MODE (secondary tabs):\n * - Does NOT own VFS engine\n * - Connects to leader's sync-relay via MessagePort (through service worker)\n * - Relays own tab's sync + async SAB requests via MessagePort to leader\n * - Same SAB protocol with own main thread, but forwards to leader for processing\n *\n * Priority order: syncSAB > asyncSAB > client port messages\n */\n\nimport { VFSEngine } from '../vfs/engine.js';\nimport { OPFSEngine } from '../opfs-engine.js';\nimport { SAB_OFFSETS, SIGNAL, OP, decodeRequest, decodeSecondPath, encodeResponse } from '../protocol/opcodes.js';\nimport { VFS_MAGIC, VFS_VERSION, SUPERBLOCK, INODE_SIZE } from '../vfs/layout.js';\n\nconst engine = new VFSEngine();\nlet opfsEngine: OPFSEngine | null = null;\nlet opfsMode = false;\n\n// Guards: prevent duplicate init and double-ready\nlet leaderInitialized = false;\nlet readySent = false;\nlet debug = false;\nlet leaderLoopRunning = false;\n\n// OPFS Sync Worker (leader mode only — mirrors VFS to real OPFS files)\nlet opfsSyncPort: MessagePort | null = null;\nlet opfsSyncEnabled = false;\nconst suppressPaths = new Set<string>(); // break external→engine→notify loop\n\n// Watch broadcast (leader mode only — fires on every VFS mutation)\nlet watchBc: BroadcastChannel | null = null;\n\n// Own tab's sync SAB\nlet sab: SharedArrayBuffer;\nlet ctrl: Int32Array;\nlet readySab: SharedArrayBuffer;\nlet readySignal: Int32Array;\n\n// Own tab's async SAB (shared with async-relay worker)\nlet asyncSab: SharedArrayBuffer | null = null;\nlet asyncCtrl: Int32Array | null = null;\n\n// Tab identity\nlet tabId: string = '';\n\nconst HEADER_SIZE = SAB_OFFSETS.HEADER_SIZE;\nconst HEARTBEAT_INDEX = SAB_OFFSETS.HEARTBEAT >> 2;\nconst HEARTBEAT_INTERVAL_MS = 1000;\n\n// Liveness heartbeat: the main thread can't Atomics.wait(), so it spin-waits and\n// needs a way to tell \"this relay worker is slow\" from \"…is dead\". This timer\n// bumps a counter in the control SAB whenever our event loop is alive — crucially\n// it still fires while we're parked on an `await` inside a long OPFS op (rename of\n// a huge tree, etc.), so a genuinely-progressing op never trips the main thread's\n// stall detector. It only goes quiet if the worker thread is wedged or gone.\nlet heartbeatTimer: ReturnType<typeof setInterval> | null = null;\nfunction startHeartbeat(): void {\n if (heartbeatTimer !== null || !ctrl) return;\n heartbeatTimer = setInterval(() => {\n Atomics.add(ctrl, HEARTBEAT_INDEX, 1);\n }, HEARTBEAT_INTERVAL_MS);\n}\n\n// ========== Leader mode: client port management ==========\n\nconst clientPorts = new Map<string, MessagePort>();\nconst portQueue: Array<{ port: MessagePort; tabId: string; id: string; buffer: ArrayBuffer }> = [];\n\n// Fast macrotask yield via MessageChannel self-post (~0.1ms)\nconst yieldChannel = new MessageChannel();\nyieldChannel.port2.start();\n\nfunction yieldToEventLoop(): Promise<void> {\n return new Promise(resolve => {\n yieldChannel.port2.onmessage = () => resolve();\n yieldChannel.port1.postMessage(null);\n });\n}\n\nfunction registerClientPort(clientTabId: string, port: MessagePort): void {\n port.onmessage = async (e: MessageEvent) => {\n if (e.data.buffer instanceof ArrayBuffer) {\n if (leaderLoopRunning) {\n // Leader loop will drain the queue\n portQueue.push({\n port,\n tabId: clientTabId,\n id: e.data.id,\n buffer: e.data.buffer,\n });\n } else {\n // No leader loop (no-SAB mode): handle directly\n const result = opfsMode\n ? await handleRequestOPFS(clientTabId, e.data.buffer)\n : handleRequest(clientTabId, e.data.buffer);\n const response = encodeResponse(result.status, result.data);\n port.postMessage({ id: e.data.id, buffer: response }, [response]);\n if (!opfsMode && result._op !== undefined) notifyOPFSSync(result._op, result._path!, result._newPath);\n }\n }\n };\n port.start();\n clientPorts.set(clientTabId, port);\n}\n\nfunction removeClientPort(clientTabId: string): void {\n const port = clientPorts.get(clientTabId);\n if (port) {\n port.close();\n clientPorts.delete(clientTabId);\n }\n if (opfsMode) {\n opfsEngine?.cleanupTab(clientTabId);\n } else {\n engine.cleanupTab(clientTabId);\n }\n}\n\nfunction drainPortQueue(): void {\n while (portQueue.length > 0) {\n const msg = portQueue.shift()!;\n const result = handleRequest(msg.tabId, msg.buffer);\n const response = encodeResponse(result.status, result.data);\n msg.port.postMessage({ id: msg.id, buffer: response }, [response]);\n if (result._op !== undefined) notifyOPFSSync(result._op, result._path!, result._newPath);\n }\n}\n\nasync function drainPortQueueAsync(): Promise<void> {\n while (portQueue.length > 0) {\n const msg = portQueue.shift()!;\n const result = await handleRequestOPFS(msg.tabId, msg.buffer);\n const response = encodeResponse(result.status, result.data);\n msg.port.postMessage({ id: msg.id, buffer: response }, [response]);\n }\n}\n\n// ========== Follower mode: leader port ==========\n\nlet leaderPort: MessagePort | null = null;\nlet pendingResolve: ((buf: ArrayBuffer) => void) | null = null;\n\n// No-SAB mode: async-relay port (for forwarding in follower mode)\nlet asyncRelayPort: MessagePort | null = null;\n\nfunction forwardToLeader(payload: Uint8Array): Promise<ArrayBuffer> {\n return new Promise(resolve => {\n pendingResolve = resolve;\n const buf = payload.buffer.byteLength === payload.byteLength\n ? payload.buffer\n : payload.slice().buffer;\n leaderPort!.postMessage(\n { id: tabId, tabId, buffer: buf },\n [buf]\n );\n });\n}\n\nfunction onLeaderMessage(e: MessageEvent): void {\n if (e.data.buffer instanceof ArrayBuffer) {\n if (pendingResolve) {\n // SAB follower: resolve sync relay promise\n const resolve = pendingResolve;\n pendingResolve = null;\n resolve(e.data.buffer);\n } else if (asyncRelayPort) {\n // No-SAB follower: forward response back to async-relay\n asyncRelayPort.postMessage({ id: e.data.id, buffer: e.data.buffer }, [e.data.buffer]);\n }\n }\n}\n\n// ========== Request dispatch (leader mode) ==========\n\nconst OP_NAMES: Record<number, string> = {\n 1: 'READ', 2: 'WRITE', 3: 'UNLINK', 4: 'STAT', 5: 'LSTAT', 6: 'MKDIR',\n 7: 'RMDIR', 8: 'READDIR', 9: 'RENAME', 10: 'EXISTS', 11: 'TRUNCATE',\n 12: 'APPEND', 13: 'COPY', 14: 'ACCESS', 15: 'REALPATH', 16: 'CHMOD',\n 17: 'CHOWN', 18: 'UTIMES', 19: 'SYMLINK', 20: 'READLINK', 21: 'LINK',\n 22: 'OPEN', 23: 'CLOSE', 24: 'FREAD', 25: 'FWRITE', 26: 'FSTAT',\n 27: 'FTRUNCATE', 28: 'FSYNC', 29: 'OPENDIR', 30: 'MKDTEMP',\n};\n\nfunction handleRequest(reqTabId: string, buffer: ArrayBuffer): { status: number; data?: Uint8Array; _op?: number; _path?: string; _newPath?: string } {\n const t0 = debug ? performance.now() : 0;\n let op: number, flags: number, path: string, data: Uint8Array | null;\n try {\n ({ op, flags, path, data } = decodeRequest(buffer));\n } catch (err: any) {\n console.error(`[sync-relay] decodeRequest failed (bufLen=${buffer.byteLength}): ${err.message}`);\n return { status: -1 };\n }\n const t1 = debug ? performance.now() : 0;\n\n let result: { status: number; data?: Uint8Array | null };\n let syncOp: number | undefined;\n let syncPath: string | undefined;\n let syncNewPath: string | undefined;\n\n switch (op) {\n case OP.READ:\n result = engine.read(path);\n break;\n\n case OP.WRITE:\n result = engine.write(path, data ?? new Uint8Array(0), flags);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n\n case OP.APPEND:\n result = engine.append(path, data ?? new Uint8Array(0));\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n\n case OP.UNLINK:\n result = engine.unlink(path);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n\n case OP.STAT:\n result = engine.stat(path);\n break;\n\n case OP.LSTAT:\n result = engine.lstat(path);\n break;\n\n case OP.MKDIR:\n result = engine.mkdir(path, flags);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n\n case OP.RMDIR:\n result = engine.rmdir(path, flags);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n\n case OP.READDIR:\n result = engine.readdir(path, flags);\n break;\n\n case OP.RENAME: {\n const newPath = data ? decodeSecondPath(data) : '';\n result = engine.rename(path, newPath);\n if (result.status === 0) { syncOp = op; syncPath = path; syncNewPath = newPath; }\n break;\n }\n\n case OP.EXISTS:\n result = engine.exists(path);\n break;\n\n case OP.TRUNCATE: {\n const len = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getFloat64(0, true) : 0;\n result = engine.truncate(path, len);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n }\n\n case OP.COPY: {\n const destPath = data ? decodeSecondPath(data) : '';\n result = engine.copy(path, destPath, flags);\n if (result.status === 0) { syncOp = op; syncPath = destPath; }\n break;\n }\n\n case OP.ACCESS:\n result = engine.access(path, flags);\n break;\n\n case OP.REALPATH:\n result = engine.realpath(path);\n break;\n\n case OP.CHMOD: {\n const chmodMode = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) : 0;\n result = engine.chmod(path, chmodMode);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n }\n\n case OP.CHOWN: {\n if (!data || data.byteLength < 8) {\n result = { status: 7 }; // EINVAL\n break;\n }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const uid = dv.getUint32(0, true);\n const gid = dv.getUint32(4, true);\n result = engine.chown(path, uid, gid);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n }\n\n case OP.UTIMES: {\n if (!data || data.byteLength < 16) {\n result = { status: 7 }; // EINVAL\n break;\n }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const atime = dv.getFloat64(0, true);\n const mtime = dv.getFloat64(8, true);\n result = engine.utimes(path, atime, mtime);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n }\n\n case OP.SYMLINK: {\n const target = data ? new TextDecoder().decode(data) : '';\n result = engine.symlink(target, path);\n if (result.status === 0) { syncOp = op; syncPath = path; }\n break;\n }\n\n case OP.READLINK:\n result = engine.readlink(path);\n break;\n\n case OP.LINK: {\n const newPath = data ? decodeSecondPath(data) : '';\n result = engine.link(path, newPath);\n if (result.status === 0) { syncOp = op; syncPath = newPath; }\n break;\n }\n\n case OP.OPEN:\n result = engine.open(path, flags, reqTabId);\n break;\n\n case OP.CLOSE: {\n const fd = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) : 0;\n result = engine.close(fd);\n break;\n }\n\n case OP.FREAD: {\n if (!data || data.byteLength < 16) {\n result = { status: 7 };\n break;\n }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const fd = dv.getUint32(0, true);\n const length = dv.getUint32(4, true);\n const pos = dv.getFloat64(8, true);\n result = engine.fread(fd, length, pos === -1 ? null : pos);\n break;\n }\n\n case OP.FWRITE: {\n if (!data || data.byteLength < 12) {\n result = { status: 7 };\n break;\n }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const fd = dv.getUint32(0, true);\n const pos = dv.getFloat64(4, true);\n const writeData = data.subarray(12);\n result = engine.fwrite(fd, writeData, pos === -1 ? null : pos);\n if (result.status === 0) { syncOp = op; syncPath = engine.getPathForFd(fd) ?? undefined; }\n break;\n }\n\n case OP.FSTAT: {\n const fd = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) : 0;\n result = engine.fstat(fd);\n break;\n }\n\n case OP.FTRUNCATE: {\n if (!data || data.byteLength < 12) {\n result = { status: 7 };\n break;\n }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const fd = dv.getUint32(0, true);\n const len = dv.getFloat64(4, true);\n result = engine.ftruncate(fd, len);\n if (result.status === 0) { syncOp = op; syncPath = engine.getPathForFd(fd) ?? undefined; }\n break;\n }\n\n case OP.FSYNC:\n result = engine.fsync();\n break;\n\n case OP.OPENDIR:\n result = engine.opendir(path, reqTabId);\n break;\n\n case OP.MKDTEMP:\n result = engine.mkdtemp(path);\n if (result.status === 0 && result.data) {\n syncOp = op;\n syncPath = new TextDecoder().decode(result.data instanceof Uint8Array ? result.data : new Uint8Array(0));\n }\n break;\n\n case OP.FCHMOD: {\n // Payload: [fd: u32][mode: u32]\n if (!data || data.byteLength < 8) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const fd = dv.getUint32(0, true);\n const mode = dv.getUint32(4, true);\n result = engine.fchmod(fd, mode);\n if (result.status === 0) {\n syncOp = OP.CHMOD;\n syncPath = engine.getPathForFd(fd) ?? undefined;\n }\n break;\n }\n\n case OP.FCHOWN: {\n // Payload: [fd: u32][uid: u32][gid: u32]\n if (!data || data.byteLength < 12) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const fd = dv.getUint32(0, true);\n const uid = dv.getUint32(4, true);\n const gid = dv.getUint32(8, true);\n result = engine.fchown(fd, uid, gid);\n if (result.status === 0) {\n syncOp = OP.CHOWN;\n syncPath = engine.getPathForFd(fd) ?? undefined;\n }\n break;\n }\n\n case OP.FUTIMES: {\n // Payload: [fd: u32][pad: u32][atime: f64][mtime: f64]\n if (!data || data.byteLength < 24) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const fd = dv.getUint32(0, true);\n const atime = dv.getFloat64(8, true);\n const mtime = dv.getFloat64(16, true);\n result = engine.futimes(fd, atime, mtime);\n if (result.status === 0) {\n syncOp = OP.UTIMES;\n syncPath = engine.getPathForFd(fd) ?? undefined;\n }\n break;\n }\n\n default:\n result = { status: 7 }; // EINVAL — unknown op\n }\n\n if (debug) {\n const t2 = performance.now();\n console.log(`[sync-relay] op=${OP_NAMES[op] ?? op} path=${path} decode=${(t1-t0).toFixed(3)}ms engine=${(t2-t1).toFixed(3)}ms TOTAL=${(t2-t0).toFixed(3)}ms`);\n }\n\n const ret: { status: number; data?: Uint8Array; _op?: number; _path?: string; _newPath?: string } = {\n status: result.status,\n data: result.data instanceof Uint8Array ? result.data : undefined,\n };\n if (syncOp !== undefined && syncPath) {\n // OPFS sync metadata (only used when opfsSyncEnabled, but callers guard via notifyOPFSSync)\n ret._op = syncOp;\n ret._path = syncPath;\n ret._newPath = syncNewPath;\n // Watch broadcast (always, for all tabs)\n broadcastWatch(syncOp, syncPath, syncNewPath);\n }\n return ret;\n}\n\n// ========== OPFS mode: async request handler ==========\n\nasync function handleRequestOPFS(reqTabId: string, buffer: ArrayBuffer): Promise<{ status: number; data?: Uint8Array; _op?: number; _path?: string; _newPath?: string }> {\n const oe = opfsEngine!;\n let op: number, flags: number, path: string, data: Uint8Array | null;\n try {\n ({ op, flags, path, data } = decodeRequest(buffer));\n } catch (err: any) {\n console.error(`[sync-relay] decodeRequest failed in OPFS handler (bufLen=${buffer.byteLength}): ${err.message}`);\n return { status: -1 };\n }\n\n let result: { status: number; data?: Uint8Array | null };\n let syncPath: string | undefined;\n let syncNewPath: string | undefined;\n\n switch (op) {\n case OP.READ:\n result = await oe.read(path);\n break;\n case OP.WRITE:\n result = await oe.write(path, data ?? new Uint8Array(0), flags);\n syncPath = path;\n break;\n case OP.APPEND:\n result = await oe.append(path, data ?? new Uint8Array(0));\n syncPath = path;\n break;\n case OP.UNLINK:\n result = await oe.unlink(path);\n syncPath = path;\n break;\n case OP.STAT:\n result = await oe.stat(path);\n break;\n case OP.LSTAT:\n result = await oe.lstat(path);\n break;\n case OP.MKDIR:\n result = await oe.mkdir(path, flags);\n syncPath = path;\n break;\n case OP.RMDIR:\n result = await oe.rmdir(path, flags);\n syncPath = path;\n break;\n case OP.READDIR:\n result = await oe.readdir(path, flags);\n break;\n case OP.RENAME: {\n const newPath = data ? decodeSecondPath(data) : '';\n result = await oe.rename(path, newPath);\n syncPath = path; syncNewPath = newPath;\n break;\n }\n case OP.EXISTS:\n result = await oe.exists(path);\n break;\n case OP.TRUNCATE: {\n const len = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getFloat64(0, true) : 0;\n result = await oe.truncate(path, len);\n syncPath = path;\n break;\n }\n case OP.COPY: {\n const destPath = data ? decodeSecondPath(data) : '';\n result = await oe.copy(path, destPath, flags);\n syncPath = destPath;\n break;\n }\n case OP.ACCESS:\n result = await oe.access(path, flags);\n break;\n case OP.REALPATH:\n result = await oe.realpath(path);\n break;\n case OP.CHMOD: {\n const chmodMode = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) : 0;\n result = await oe.chmod(path, chmodMode);\n break;\n }\n case OP.CHOWN: {\n if (!data || data.byteLength < 8) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n result = await oe.chown(path, dv.getUint32(0, true), dv.getUint32(4, true));\n break;\n }\n case OP.UTIMES: {\n if (!data || data.byteLength < 16) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n result = await oe.utimes(path, dv.getFloat64(0, true), dv.getFloat64(8, true));\n break;\n }\n case OP.SYMLINK: {\n const target = data ? new TextDecoder().decode(data) : '';\n result = await oe.symlink(target, path);\n break;\n }\n case OP.READLINK:\n result = await oe.readlink(path);\n break;\n case OP.LINK: {\n const newPath = data ? decodeSecondPath(data) : '';\n result = await oe.link(path, newPath);\n syncPath = newPath;\n break;\n }\n case OP.OPEN:\n result = await oe.open(path, flags, reqTabId);\n break;\n case OP.CLOSE: {\n const fd = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) : 0;\n result = await oe.close(fd);\n break;\n }\n case OP.FREAD: {\n if (!data || data.byteLength < 16) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const pos = dv.getFloat64(8, true);\n result = await oe.fread(dv.getUint32(0, true), dv.getUint32(4, true), pos === -1 ? null : pos);\n break;\n }\n case OP.FWRITE: {\n if (!data || data.byteLength < 12) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const fd = dv.getUint32(0, true);\n const pos = dv.getFloat64(4, true);\n result = await oe.fwrite(fd, data.subarray(12), pos === -1 ? null : pos);\n syncPath = oe.getPathForFd(fd) ?? undefined;\n break;\n }\n case OP.FSTAT: {\n const fd = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) : 0;\n result = await oe.fstat(fd);\n break;\n }\n case OP.FTRUNCATE: {\n if (!data || data.byteLength < 12) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n result = await oe.ftruncate(dv.getUint32(0, true), dv.getFloat64(4, true));\n syncPath = oe.getPathForFd(dv.getUint32(0, true)) ?? undefined;\n break;\n }\n case OP.FSYNC:\n result = await oe.fsync();\n break;\n case OP.OPENDIR:\n result = await oe.opendir(path, reqTabId);\n break;\n case OP.MKDTEMP:\n result = await oe.mkdtemp(path);\n if (result.status === 0 && result.data) {\n syncPath = new TextDecoder().decode(result.data instanceof Uint8Array ? result.data : new Uint8Array(0));\n }\n break;\n case OP.FCHMOD: {\n if (!data || data.byteLength < 8) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n result = await oe.fchmod(dv.getUint32(0, true), dv.getUint32(4, true));\n break;\n }\n case OP.FCHOWN: {\n if (!data || data.byteLength < 12) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n result = await oe.fchown(dv.getUint32(0, true), dv.getUint32(4, true), dv.getUint32(8, true));\n break;\n }\n case OP.FUTIMES: {\n if (!data || data.byteLength < 24) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n result = await oe.futimes(dv.getUint32(0, true), dv.getFloat64(8, true), dv.getFloat64(16, true));\n break;\n }\n default:\n result = { status: 7 };\n }\n\n // Fallback to VfsEngine for read-only operations that failed in OPFS.\n // OPFS doesn't support symlinks, so paths through pnpm symlinks resolve in\n // VfsEngine (which has the symlink→target mapping) but not in OPFSEngine.\n // This handles: readdir, stat, lstat, read, exists, access, realpath, readlink\n //\n // For most ops, OPFS returns ENOENT (status=1) when path not found.\n // But EXISTS is special: it returns OK (status=0) with data=[0] for non-existent paths.\n // So we also trigger fallback for EXISTS when the result indicates \"not found\".\n const ENOENT_STATUS = 1; // CODE_TO_STATUS.ENOENT\n const READ_OPS: number[] = [OP.READ, OP.STAT, OP.LSTAT, OP.READDIR, OP.EXISTS, OP.ACCESS, OP.REALPATH, OP.READLINK];\n const isExistsNotFound = op === OP.EXISTS && result.status === 0 && result.data instanceof Uint8Array && result.data[0] === 0;\n if ((result.status === ENOENT_STATUS || isExistsNotFound) && READ_OPS.includes(op)) {\n const vfsResult = (() => {\n switch (op) {\n case OP.READ: return engine.read(path);\n case OP.STAT: return engine.stat(path);\n case OP.LSTAT: return engine.lstat(path);\n case OP.READDIR: return engine.readdir(path, flags);\n case OP.EXISTS: return engine.exists(path);\n case OP.ACCESS: return engine.access(path, flags);\n case OP.REALPATH: return engine.realpath(path);\n case OP.READLINK: return engine.readlink(path);\n default: return null;\n }\n })();\n if (vfsResult && vfsResult.status !== ENOENT_STATUS) {\n result = vfsResult;\n }\n }\n\n const ret: { status: number; data?: Uint8Array; _op?: number; _path?: string; _newPath?: string } = {\n status: result.status,\n data: result.data instanceof Uint8Array ? result.data : undefined,\n };\n if (result.status === 0 && syncPath) {\n // Watch broadcast (OPFS mode doesn't need OPFS sync since it IS OPFS)\n broadcastWatch(op, syncPath, syncNewPath);\n }\n return ret;\n}\n\n// ========== SAB I/O helpers ==========\n\n/**\n * Read the full request/response payload from a SAB. Handles multi-chunk assembly.\n * Returns an owned Uint8Array (not a view into the SAB).\n */\nfunction readPayload(targetSab: SharedArrayBuffer, targetCtrl: Int32Array): Uint8Array {\n const totalLenView = new BigUint64Array(targetSab, SAB_OFFSETS.TOTAL_LEN, 1);\n const maxChunk = targetSab.byteLength - HEADER_SIZE;\n\n const chunkLen = Atomics.load(targetCtrl, 3);\n const totalLen = Number(Atomics.load(totalLenView, 0));\n\n // Guard against zero/negative chunk lengths (SAB race or stale data)\n if (chunkLen <= 0 || chunkLen > maxChunk) {\n console.error(`[sync-relay] readPayload: invalid chunkLen=${chunkLen} (maxChunk=${maxChunk}, totalLen=${totalLen})`);\n return new Uint8Array(0);\n }\n\n if (totalLen <= maxChunk) {\n // Fast path: single chunk\n return new Uint8Array(targetSab, HEADER_SIZE, chunkLen).slice();\n }\n\n // Guard against corrupt TOTAL_LEN causing OOM\n if (totalLen > activeLimits.maxPayload || totalLen <= 0) {\n console.error(`[sync-relay] readPayload: totalLen=${totalLen} exceeds limit (${activeLimits.maxPayload}) or invalid`);\n return new Uint8Array(0);\n }\n\n // Multi-chunk: assemble full buffer\n const fullBuffer = new Uint8Array(totalLen);\n let offset = 0;\n\n // Read first chunk (already in SAB)\n fullBuffer.set(new Uint8Array(targetSab, HEADER_SIZE, chunkLen), offset);\n offset += chunkLen;\n\n // Ack and wait for more chunks\n while (offset < totalLen) {\n Atomics.store(targetCtrl, 0, SIGNAL.CHUNK_ACK);\n Atomics.notify(targetCtrl, 0);\n Atomics.wait(targetCtrl, 0, SIGNAL.CHUNK_ACK); // Wait for next chunk\n const nextLen = Atomics.load(targetCtrl, 3);\n if (nextLen <= 0 || nextLen > maxChunk) {\n console.error(`[sync-relay] readPayload: invalid nextLen=${nextLen} at offset=${offset}`);\n return fullBuffer.slice(0, offset); // return what we have so far\n }\n fullBuffer.set(new Uint8Array(targetSab, HEADER_SIZE, nextLen), offset);\n offset += nextLen;\n }\n\n return fullBuffer;\n}\n\n/**\n * Write status + data directly into a SAB (no intermediate encodeResponse buffer).\n * Saves one full copy of the data compared to encodeResponse + writeResponse.\n */\nfunction writeDirectResponse(\n targetSab: SharedArrayBuffer,\n targetCtrl: Int32Array,\n status: number,\n data?: Uint8Array\n): void {\n const dataLen = data ? data.byteLength : 0;\n const totalLen = 8 + dataLen;\n const maxChunk = targetSab.byteLength - HEADER_SIZE;\n\n if (totalLen <= maxChunk) {\n // Fast path: write 8-byte header + data directly into SAB\n const hdr = new DataView(targetSab, HEADER_SIZE, 8);\n hdr.setUint32(0, status, true);\n hdr.setUint32(4, dataLen, true);\n if (data && dataLen > 0) {\n new Uint8Array(targetSab, HEADER_SIZE + 8, dataLen).set(data);\n }\n Atomics.store(targetCtrl, 3, totalLen);\n const totalView = new BigUint64Array(targetSab, SAB_OFFSETS.TOTAL_LEN, 1);\n Atomics.store(totalView, 0, BigInt(totalLen));\n Atomics.store(targetCtrl, 0, SIGNAL.RESPONSE);\n Atomics.notify(targetCtrl, 0);\n } else {\n // Multi-chunk: fall back to encoded buffer + chunked write\n const response = encodeResponse(status, data);\n writeResponse(targetSab, targetCtrl, new Uint8Array(response));\n }\n}\n\n/**\n * Write a response payload to a SAB and signal RESPONSE. Handles multi-chunk.\n */\nfunction writeResponse(targetSab: SharedArrayBuffer, targetCtrl: Int32Array, responseData: Uint8Array): void {\n const maxChunk = targetSab.byteLength - HEADER_SIZE;\n\n if (responseData.byteLength <= maxChunk) {\n // Fast path: single chunk\n new Uint8Array(targetSab, HEADER_SIZE, responseData.byteLength).set(responseData);\n Atomics.store(targetCtrl, 3, responseData.byteLength);\n const totalView = new BigUint64Array(targetSab, SAB_OFFSETS.TOTAL_LEN, 1);\n Atomics.store(totalView, 0, BigInt(responseData.byteLength));\n Atomics.store(targetCtrl, 0, SIGNAL.RESPONSE);\n Atomics.notify(targetCtrl, 0);\n } else {\n // Multi-chunk response\n const totalView = new BigUint64Array(targetSab, SAB_OFFSETS.TOTAL_LEN, 1);\n Atomics.store(totalView, 0, BigInt(responseData.byteLength));\n let sent = 0;\n while (sent < responseData.byteLength) {\n const chunkSize = Math.min(maxChunk, responseData.byteLength - sent);\n new Uint8Array(targetSab, HEADER_SIZE, chunkSize).set(\n responseData.subarray(sent, sent + chunkSize)\n );\n Atomics.store(targetCtrl, 3, chunkSize);\n Atomics.store(targetCtrl, 6, Math.floor(sent / maxChunk));\n\n const isLast = sent + chunkSize >= responseData.byteLength;\n Atomics.store(targetCtrl, 0, isLast ? SIGNAL.RESPONSE : SIGNAL.CHUNK);\n Atomics.notify(targetCtrl, 0);\n\n if (!isLast) {\n Atomics.wait(targetCtrl, 0, SIGNAL.CHUNK); // Wait for reader ack\n }\n sent += chunkSize;\n }\n }\n}\n\n// ========== Leader mode: main loop ==========\n\nasync function leaderLoop(): Promise<void> {\n leaderLoopRunning = true;\n while (true) {\n // === Inner tight loop: process all pending work without yielding ===\n let processed = true;\n let tightOps = 0;\n while (processed) {\n processed = false;\n\n // Periodic yield: during sustained load the inner loop never exits,\n // starving MessagePort handlers (external OPFS changes, client ports).\n // Yield every 100 ops to let the event loop process pending messages.\n if (++tightOps >= 100) {\n tightOps = 0;\n await yieldToEventLoop();\n }\n\n // Priority 1: own tab's sync requests (fastest path)\n if (Atomics.load(ctrl, 0) === SIGNAL.REQUEST) {\n const lt0 = debug ? performance.now() : 0;\n const payload = readPayload(sab, ctrl);\n const lt1 = debug ? performance.now() : 0;\n const reqResult = handleRequest(tabId, payload.buffer as ArrayBuffer);\n const lt2 = debug ? performance.now() : 0;\n writeDirectResponse(sab, ctrl, reqResult.status, reqResult.data);\n if (reqResult._op !== undefined) notifyOPFSSync(reqResult._op, reqResult._path!, reqResult._newPath);\n const lt3 = debug ? performance.now() : 0;\n if (debug) {\n console.log(`[leaderLoop] readPayload=${(lt1-lt0).toFixed(3)}ms handleRequest=${(lt2-lt1).toFixed(3)}ms writeResponse=${(lt3-lt2).toFixed(3)}ms TOTAL=${(lt3-lt0).toFixed(3)}ms`);\n }\n // Wait for main thread to consume response (10ms safety timeout).\n // Main thread sets IDLE without notify — worker stays asleep until the\n // NEXT request's notify wakes it. This gives ONE wake per operation.\n const waitResult = Atomics.wait(ctrl, 0, SIGNAL.RESPONSE, 100);\n if (waitResult === 'timed-out') {\n Atomics.store(ctrl, 0, SIGNAL.IDLE);\n }\n processed = true;\n continue;\n }\n\n // Priority 2: own tab's async requests\n if (asyncCtrl && Atomics.load(asyncCtrl, 0) === SIGNAL.REQUEST) {\n const payload = readPayload(asyncSab!, asyncCtrl);\n const asyncResult = handleRequest(tabId, payload.buffer as ArrayBuffer);\n writeDirectResponse(asyncSab!, asyncCtrl, asyncResult.status, asyncResult.data);\n if (asyncResult._op !== undefined) notifyOPFSSync(asyncResult._op, asyncResult._path!, asyncResult._newPath);\n // Wait for async-relay to consume response and reset to IDLE.\n // writeResponse handles multi-chunk handshake internally; when it\n // returns the async-relay has all data but may need one more tick\n // to set IDLE. Use Atomics.wait with a reasonable timeout.\n if (Atomics.load(asyncCtrl, 0) !== SIGNAL.IDLE) {\n Atomics.wait(asyncCtrl, 0, SIGNAL.RESPONSE, 5000);\n }\n processed = true;\n continue;\n }\n\n // Priority 3: client requests already queued from previous yields\n if (portQueue.length > 0) {\n drainPortQueue();\n processed = true;\n continue;\n }\n }\n\n // === All queues empty — yield to process MessagePort events ===\n // Always yield: external OPFS changes arrive via opfsSyncPort.onmessage,\n // client registrations via self.onmessage — both need the event loop.\n await yieldToEventLoop();\n\n // If no clients and no new SAB work, block briefly for next request\n if (clientPorts.size === 0 && !opfsSyncEnabled) {\n const currentSignal = Atomics.load(ctrl, 0);\n if (currentSignal !== SIGNAL.REQUEST) {\n Atomics.wait(ctrl, 0, currentSignal, 50);\n }\n }\n }\n}\n\n// ========== OPFS mode: leader loop (async handleRequest) ==========\n\nasync function leaderLoopOPFS(): Promise<void> {\n leaderLoopRunning = true;\n while (true) {\n let processed = true;\n let tightOps = 0;\n while (processed) {\n processed = false;\n\n if (++tightOps >= 100) {\n tightOps = 0;\n await yieldToEventLoop();\n }\n\n // Priority 1: own tab's sync requests\n if (Atomics.load(ctrl, 0) === SIGNAL.REQUEST) {\n const payload = readPayload(sab, ctrl);\n const reqResult = await handleRequestOPFS(tabId, payload.buffer as ArrayBuffer);\n writeDirectResponse(sab, ctrl, reqResult.status, reqResult.data);\n const waitResult = Atomics.wait(ctrl, 0, SIGNAL.RESPONSE, 100);\n if (waitResult === 'timed-out') {\n Atomics.store(ctrl, 0, SIGNAL.IDLE);\n }\n processed = true;\n continue;\n }\n\n // Priority 2: own tab's async requests\n if (asyncCtrl && Atomics.load(asyncCtrl, 0) === SIGNAL.REQUEST) {\n const payload = readPayload(asyncSab!, asyncCtrl);\n const asyncResult = await handleRequestOPFS(tabId, payload.buffer as ArrayBuffer);\n writeDirectResponse(asyncSab!, asyncCtrl, asyncResult.status, asyncResult.data);\n const waitResult = Atomics.wait(asyncCtrl, 0, SIGNAL.RESPONSE, 100);\n if (waitResult === 'timed-out') {\n Atomics.store(asyncCtrl, 0, SIGNAL.IDLE);\n }\n processed = true;\n continue;\n }\n\n // Priority 3: client requests\n if (portQueue.length > 0) {\n await drainPortQueueAsync();\n processed = true;\n continue;\n }\n }\n\n await yieldToEventLoop();\n\n if (clientPorts.size === 0) {\n const currentSignal = Atomics.load(ctrl, 0);\n if (currentSignal !== SIGNAL.REQUEST) {\n Atomics.wait(ctrl, 0, currentSignal, 50);\n }\n }\n }\n}\n\n// ========== Follower mode: relay loop ==========\n\nasync function followerLoop(): Promise<void> {\n while (true) {\n // Check own sync SAB\n if (Atomics.load(ctrl, 0) === SIGNAL.REQUEST) {\n const payload = readPayload(sab, ctrl);\n const response = await forwardToLeader(payload);\n writeResponse(sab, ctrl, new Uint8Array(response));\n // Wait for main thread to consume response (safety timeout to prevent deadlock —\n // main thread stores IDLE without notify)\n const result = Atomics.wait(ctrl, 0, SIGNAL.RESPONSE, 100);\n if (result === 'timed-out') {\n Atomics.store(ctrl, 0, SIGNAL.IDLE);\n }\n continue;\n }\n\n // Check own async SAB\n if (asyncCtrl && Atomics.load(asyncCtrl, 0) === SIGNAL.REQUEST) {\n const payload = readPayload(asyncSab!, asyncCtrl);\n const response = await forwardToLeader(payload);\n writeResponse(asyncSab!, asyncCtrl, new Uint8Array(response));\n const result = Atomics.wait(asyncCtrl, 0, SIGNAL.RESPONSE, 100);\n if (result === 'timed-out') {\n Atomics.store(asyncCtrl, 0, SIGNAL.IDLE);\n }\n continue;\n }\n\n // Wait for SAB notification or timeout; yield on idle to process onmessage\n // (e.g. leader-port reconnection). Requests wake via Atomics.notify on ctrl.\n const waitResult = Atomics.wait(ctrl, 0, SIGNAL.IDLE, 50);\n if (waitResult === 'timed-out') {\n await yieldToEventLoop();\n }\n }\n}\n\n// ========== OPFS + VFS engine initialization (leader only) ==========\n\n// ========== OPFS directory scanning (for auto-populate on fresh VFS) ==========\n\nconst OPFS_SKIP = new Set(['.vfs.bin', '.vfs.bin.tmp']);\n\n// Chunk size for streamed population of fresh VFS from existing OPFS.\n// Caps peak memory during init at this size per file instead of\n// materializing every OPFS file into the heap simultaneously.\nconst OPFS_POPULATE_CHUNK = 2 * 1024 * 1024;\n\n// Populate a fresh VFS from an existing OPFS tree, streaming one file at\n// a time through the engine. Directories are created before their files,\n// files are written via truncate + chunked append so peak memory is\n// bounded by OPFS_POPULATE_CHUNK rather than the sum of all file sizes.\nasync function populateVFSFromOPFS(\n dir: FileSystemDirectoryHandle,\n prefix: string,\n): Promise<void> {\n const subdirs: Array<{ name: string; handle: FileSystemDirectoryHandle }> = [];\n const files: Array<{ name: string; handle: FileSystemFileHandle }> = [];\n for await (const [name, handle] of (dir as any).entries()) {\n if (prefix === '' && OPFS_SKIP.has(name)) continue;\n if (handle.kind === 'directory') {\n subdirs.push({ name, handle: handle as FileSystemDirectoryHandle });\n } else {\n files.push({ name, handle: handle as FileSystemFileHandle });\n }\n }\n\n // Create directories at this level first so file writes below (and\n // recursive calls) can rely on their parents existing.\n for (const { name } of subdirs) {\n const fullPath = prefix ? `${prefix}/${name}` : `/${name}`;\n engine.mkdir(fullPath, 0o040755);\n }\n\n // Stream each file through a single reusable chunk buffer.\n for (const { name, handle } of files) {\n const fullPath = prefix ? `${prefix}/${name}` : `/${name}`;\n let access: FileSystemSyncAccessHandle | null = null;\n try {\n access = await (handle as unknown as { createSyncAccessHandle: () => Promise<FileSystemSyncAccessHandle> }).createSyncAccessHandle();\n const size = access.getSize();\n // Create as empty, then append in chunks. engine.write(fullPath, empty)\n // establishes the inode; engine.append grows it without reallocation.\n engine.write(fullPath, new Uint8Array(0));\n if (size > 0) {\n const chunk = new Uint8Array(Math.min(size, OPFS_POPULATE_CHUNK));\n let offset = 0;\n while (offset < size) {\n const len = Math.min(chunk.length, size - offset);\n const view = len === chunk.length ? chunk : chunk.subarray(0, len);\n access.read(view, { at: offset });\n engine.append(fullPath, view);\n offset += len;\n }\n }\n } finally {\n if (access) { try { access.close(); } catch { /* ignore */ } }\n }\n }\n\n // Recurse into subdirectories.\n for (const { name, handle } of subdirs) {\n const fullPath = prefix ? `${prefix}/${name}` : `/${name}`;\n await populateVFSFromOPFS(handle, fullPath);\n }\n}\n\n/**\n * Quick superblock validation — reads only 64 bytes to detect corruption\n * BEFORE engine.init() runs. Prevents hangs from corrupt values causing\n * huge allocations or blocking Atomics loops.\n * Returns null if valid, or an error description string if corrupt.\n */\ninterface ResolvedLimits {\n maxInodes: number;\n maxBlocks: number;\n maxPathTable: number;\n maxVFSSize: number;\n maxPayload: number;\n}\n\nconst DEFAULT_LIMITS: ResolvedLimits = {\n maxInodes: 4_000_000,\n maxBlocks: 4_000_000,\n maxPathTable: 256 * 1024 * 1024,\n maxVFSSize: 100 * 1024 * 1024 * 1024,\n maxPayload: 2 * 1024 * 1024 * 1024,\n};\n\nfunction resolveLimits(input?: Partial<ResolvedLimits>): ResolvedLimits {\n return { ...DEFAULT_LIMITS, ...input };\n}\n\n// Active limits for this worker instance\nlet activeLimits: ResolvedLimits = { ...DEFAULT_LIMITS };\n\nfunction quickValidateVFS(handle: FileSystemSyncAccessHandle, fileSize: number, limits: ResolvedLimits): string | null {\n if (fileSize < SUPERBLOCK.SIZE) return `file too small (${fileSize} bytes)`;\n\n const buf = new Uint8Array(SUPERBLOCK.SIZE);\n handle.read(buf, { at: 0 });\n const v = new DataView(buf.buffer);\n\n const magic = v.getUint32(SUPERBLOCK.MAGIC, true);\n if (magic !== VFS_MAGIC) return `bad magic 0x${magic.toString(16)}`;\n const version = v.getUint32(SUPERBLOCK.VERSION, true);\n if (version !== VFS_VERSION) return `unsupported version ${version}`;\n\n const inodeCount = v.getUint32(SUPERBLOCK.INODE_COUNT, true);\n const blockSize = v.getUint32(SUPERBLOCK.BLOCK_SIZE, true);\n const totalBlocks = v.getUint32(SUPERBLOCK.TOTAL_BLOCKS, true);\n const freeBlocks = v.getUint32(SUPERBLOCK.FREE_BLOCKS, true);\n const inodeTableOffset = v.getFloat64(SUPERBLOCK.INODE_OFFSET, true);\n const pathTableOffset = v.getFloat64(SUPERBLOCK.PATH_OFFSET, true);\n const dataOffset = v.getFloat64(SUPERBLOCK.DATA_OFFSET, true);\n const bitmapOffset = v.getFloat64(SUPERBLOCK.BITMAP_OFFSET, true);\n const pathUsed = v.getUint32(SUPERBLOCK.PATH_USED, true);\n\n // Basic field sanity\n if (blockSize === 0 || (blockSize & (blockSize - 1)) !== 0) return `invalid block size ${blockSize}`;\n if (inodeCount === 0) return 'inode count is 0';\n if (inodeCount > limits.maxInodes) return `inode count ${inodeCount} exceeds maximum ${limits.maxInodes}`;\n if (totalBlocks > limits.maxBlocks) return `total blocks ${totalBlocks} exceeds maximum ${limits.maxBlocks}`;\n if (freeBlocks > totalBlocks) return `free blocks (${freeBlocks}) exceeds total (${totalBlocks})`;\n\n // Offsets must be finite positive numbers\n if (!Number.isFinite(inodeTableOffset) || inodeTableOffset < 0 ||\n !Number.isFinite(pathTableOffset) || pathTableOffset < 0 ||\n !Number.isFinite(bitmapOffset) || bitmapOffset < 0 ||\n !Number.isFinite(dataOffset) || dataOffset < 0) return 'non-finite or negative section offset';\n\n // Section ordering\n if (inodeTableOffset !== SUPERBLOCK.SIZE) return `inode table offset ${inodeTableOffset} (expected ${SUPERBLOCK.SIZE})`;\n const expectedPathOffset = inodeTableOffset + inodeCount * INODE_SIZE;\n if (pathTableOffset !== expectedPathOffset) return `path table offset ${pathTableOffset} (expected ${expectedPathOffset})`;\n if (bitmapOffset <= pathTableOffset) return 'bitmap offset must be after path table';\n if (dataOffset <= bitmapOffset) return 'data offset must be after bitmap';\n\n // Path table bounds\n const pathTableSize = bitmapOffset - pathTableOffset;\n if (pathUsed > pathTableSize) return `path used (${pathUsed}) exceeds path table size (${pathTableSize})`;\n if (pathTableSize > limits.maxPathTable) return `path table size ${pathTableSize} exceeds maximum ${limits.maxPathTable}`;\n\n // File size vs declared layout\n const expectedMinSize = dataOffset + totalBlocks * blockSize;\n if (expectedMinSize > limits.maxVFSSize) return `computed layout size ${expectedMinSize} exceeds maximum ${limits.maxVFSSize}`;\n if (fileSize < expectedMinSize) return `file size ${fileSize} too small for layout (need ${expectedMinSize})`;\n\n return null;\n}\n\nasync function initEngine(config: {\n root: string;\n ns: string;\n opfsSync: boolean;\n opfsSyncRoot?: string;\n uid: number;\n gid: number;\n umask: number;\n strictPermissions: boolean;\n debug?: boolean;\n limits?: Partial<ResolvedLimits>;\n}): Promise<void> {\n debug = config.debug ?? false;\n activeLimits = resolveLimits(config.limits);\n\n // Navigate to configured OPFS root\n let rootDir = await navigator.storage.getDirectory();\n\n if (config.root && config.root !== '/') {\n const segments = config.root.split('/').filter(Boolean);\n for (const segment of segments) {\n rootDir = await rootDir.getDirectoryHandle(segment, { create: true });\n }\n }\n\n // Open VFS binary file with exclusive sync access\n const vfsFileHandle = await rootDir.getFileHandle('.vfs.bin', { create: true });\n const vfsHandle = await vfsFileHandle.createSyncAccessHandle();\n\n // Pre-validate vfs.bin BEFORE engine.init() to prevent hangs from corrupt data\n // causing huge allocations or blocking Atomics loops. Throws early so the caller\n // can offer repair instead of silently losing data.\n const vfsSize = vfsHandle.getSize();\n if (vfsSize > 0) {\n const validationError = quickValidateVFS(vfsHandle, vfsSize, activeLimits);\n if (validationError) {\n try { vfsHandle.close(); } catch (_) {}\n throw new Error(`Corrupt VFS: ${validationError}`);\n }\n }\n\n const wasFresh = vfsSize === 0;\n\n // Initialize VFS engine — release handle on corruption/failure\n try {\n engine.init(vfsHandle, {\n uid: config.uid,\n gid: config.gid,\n umask: config.umask,\n strictPermissions: config.strictPermissions,\n debug: config.debug,\n limits: activeLimits,\n });\n } catch (err) {\n // Release the exclusive sync handle so it can be re-acquired\n try { vfsHandle.close(); } catch (_) {}\n throw err;\n }\n\n // Auto-populate fresh VFS from existing OPFS files (streamed one file\n // at a time — see populateVFSFromOPFS for why).\n if (wasFresh) {\n await populateVFSFromOPFS(rootDir, '');\n engine.flush();\n }\n\n // Spawn OPFS sync worker (mirrors VFS mutations to real OPFS files)\n if (config.opfsSync) {\n opfsSyncEnabled = true;\n const mc = new MessageChannel();\n opfsSyncPort = mc.port1;\n opfsSyncPort.onmessage = (e) => handleExternalChange(e.data);\n opfsSyncPort.start();\n\n const workerUrl = new URL('./opfs-sync.worker.js', import.meta.url);\n const syncWorker = new Worker(workerUrl, { type: 'module' });\n syncWorker.postMessage(\n { type: 'init', root: config.opfsSyncRoot ?? config.root },\n [mc.port2],\n );\n }\n\n // Watch broadcast channel — fires on every VFS mutation for fs.watch() support\n watchBc = new BroadcastChannel(`${config.ns}-watch`);\n}\n\n/** Initialize OPFS-direct mode engine (no VFS binary) */\nasync function initOPFSEngine(config: {\n root: string;\n ns: string;\n uid: number;\n gid: number;\n debug?: boolean;\n}): Promise<void> {\n debug = config.debug ?? false;\n opfsMode = true;\n\n // Navigate to configured OPFS root\n let rootDir = await navigator.storage.getDirectory();\n if (config.root && config.root !== '/') {\n const segments = config.root.split('/').filter(Boolean);\n for (const segment of segments) {\n rootDir = await rootDir.getDirectoryHandle(segment, { create: true });\n }\n }\n\n opfsEngine = new OPFSEngine();\n await opfsEngine.init(rootDir, {\n uid: config.uid,\n gid: config.gid,\n });\n\n // Watch broadcast channel for fs.watch() support\n watchBc = new BroadcastChannel(`${config.ns}-watch`);\n}\n\n// ========== Watch broadcast (fire-and-forget, after SAB response) ==========\n\nfunction broadcastWatch(op: number, path: string, newPath?: string): void {\n if (!watchBc) return;\n\n // Mirror Node/libuv semantics:\n // 'change' — contents or metadata of an existing entry changed\n // 'rename' — an entry was created, removed, or moved in its parent\n let eventType: 'change' | 'rename';\n switch (op) {\n case OP.WRITE:\n case OP.APPEND:\n case OP.TRUNCATE:\n case OP.FWRITE:\n case OP.FTRUNCATE:\n case OP.CHMOD:\n case OP.CHOWN:\n case OP.UTIMES:\n case OP.COPY: // target file's contents were overwritten → 'change'\n eventType = 'change';\n break;\n case OP.UNLINK:\n case OP.RMDIR:\n case OP.RENAME:\n case OP.MKDIR:\n case OP.MKDTEMP:\n case OP.SYMLINK:\n case OP.LINK:\n eventType = 'rename';\n break;\n default:\n return;\n }\n\n watchBc.postMessage({ eventType, path });\n if (op === OP.RENAME && newPath) {\n watchBc.postMessage({ eventType: 'rename', path: newPath });\n }\n}\n\n// ========== OPFS sync notification (fire-and-forget, after SAB response) ==========\n//\n// Per-path debounce coalescer. Without this, every FWRITE/WRITE/FTRUNCATE\n// triggers a full-file `engine.read(path)` here — which allocates a\n// `new Uint8Array(inode.size)` on every call. For a file grown chunk-by-\n// chunk (e.g. formidable writing a 100 MB upload via a 64 KB stream),\n// that's ~1500 full-file reads totalling many GB of allocations, and the\n// largest allocation (the final full file size) eventually fails with\n// \"Array buffer allocation failed\" under memory pressure.\n//\n// Instead, coalesce bursts: any write-op schedules a sync 50 ms later,\n// and subsequent write-ops to the same path reset the timer. At most\n// ONE full-file read per burst, reading the file once at its final size.\nconst pendingPathSyncs = new Map<string, ReturnType<typeof setTimeout>>();\nconst SYNC_DEBOUNCE_MS = 50;\n\nfunction flushPathSync(path: string): void {\n pendingPathSyncs.delete(path);\n if (!opfsSyncPort) return;\n try {\n const result = engine.read(path);\n if (result.status !== 0) return;\n const ts = Date.now();\n if (result.data && result.data.byteLength > 0) {\n const buf = result.data.buffer.byteLength === result.data.byteLength\n ? result.data.buffer\n : result.data.slice().buffer;\n opfsSyncPort.postMessage({ op: 'write', path, data: buf, ts } as const, [buf as ArrayBuffer]);\n } else {\n opfsSyncPort.postMessage({ op: 'write', path, data: new ArrayBuffer(0), ts });\n }\n } catch { /* best effort — don't crash the relay on sync failures */ }\n}\n\nfunction schedulePathSync(path: string): void {\n const prev = pendingPathSyncs.get(path);\n if (prev) clearTimeout(prev);\n pendingPathSyncs.set(path, setTimeout(() => flushPathSync(path), SYNC_DEBOUNCE_MS));\n}\n\nfunction notifyOPFSSync(op: number, path: string, newPath?: string): void {\n if (!opfsSyncPort) return;\n if (suppressPaths.has(path)) {\n suppressPaths.delete(path);\n return;\n }\n\n const ts = Date.now();\n\n switch (op) {\n case OP.WRITE:\n case OP.APPEND:\n case OP.TRUNCATE:\n case OP.FWRITE:\n case OP.FTRUNCATE:\n case OP.COPY:\n case OP.LINK: {\n // Coalesce bursts of writes to the same path — flush once after a\n // short idle period so large chunked writes don't cause N\n // full-file reads that exhaust the worker's heap.\n schedulePathSync(path);\n break;\n }\n case OP.SYMLINK: {\n // OPFS has no symlinks — mirror as regular file with the target's\n // content. Route through the same debounced flusher so this also\n // benefits from coalescing if the symlink target is being actively\n // written in the same burst.\n schedulePathSync(path);\n break;\n }\n case OP.UNLINK:\n case OP.RMDIR: {\n // Cancel any pending debounced sync for this path — the file no\n // longer exists, we'd just fail the read.\n const pending = pendingPathSyncs.get(path);\n if (pending) { clearTimeout(pending); pendingPathSyncs.delete(path); }\n opfsSyncPort.postMessage({ op: 'delete', path, ts });\n break;\n }\n case OP.MKDIR:\n case OP.MKDTEMP:\n opfsSyncPort.postMessage({ op: 'mkdir', path, ts });\n break;\n case OP.RENAME:\n if (newPath) {\n // Reroute any pending sync on the old path to the new path so\n // the content ends up at the final location after the burst.\n const pending = pendingPathSyncs.get(path);\n if (pending) {\n clearTimeout(pending);\n pendingPathSyncs.delete(path);\n schedulePathSync(newPath);\n }\n opfsSyncPort.postMessage({ op: 'rename', path, newPath, ts });\n }\n break;\n }\n}\n\nfunction handleExternalChange(msg: { op: string; path: string; newPath?: string; data?: ArrayBuffer }): void {\n switch (msg.op) {\n case 'external-write': {\n suppressPaths.add(msg.path);\n const result = engine.write(msg.path, new Uint8Array(msg.data!), 0);\n if (result.status === 0) broadcastWatch(OP.WRITE, msg.path);\n console.log('[sync-relay] external-write:', msg.path, `${msg.data?.byteLength ?? 0}B`, `status=${result.status}`);\n break;\n }\n case 'external-delete': {\n suppressPaths.add(msg.path);\n const result = engine.unlink(msg.path);\n if (result.status !== 0) {\n const rmdirResult = engine.rmdir(msg.path, 1);\n if (rmdirResult.status === 0) broadcastWatch(OP.RMDIR, msg.path);\n console.log('[sync-relay] external-delete (rmdir):', msg.path, `status=${rmdirResult.status}`);\n } else {\n broadcastWatch(OP.UNLINK, msg.path);\n console.log('[sync-relay] external-delete:', msg.path, `status=${result.status}`);\n }\n break;\n }\n case 'external-rename':\n suppressPaths.add(msg.path);\n if (msg.newPath) {\n suppressPaths.add(msg.newPath);\n const result = engine.rename(msg.path, msg.newPath);\n if (result.status === 0) broadcastWatch(OP.RENAME, msg.path, msg.newPath);\n console.log('[sync-relay] external-rename:', msg.path, '→', msg.newPath, `status=${result.status}`);\n }\n break;\n }\n}\n\n// ========== Message handling ==========\n\nself.onmessage = async (e: MessageEvent) => {\n const msg = e.data;\n\n // --- Async port registration (no-SAB mode: async-relay connects via MessagePort) ---\n if (msg.type === 'async-port') {\n const port = msg.port ?? e.ports[0];\n if (port) {\n asyncRelayPort = port;\n port.onmessage = async (ev: MessageEvent) => {\n if (ev.data.buffer instanceof ArrayBuffer) {\n if (leaderInitialized) {\n // Leader mode: handle locally (engine available)\n const result = opfsMode\n ? await handleRequestOPFS(tabId || 'nosab', ev.data.buffer)\n : handleRequest(tabId || 'nosab', ev.data.buffer);\n const response = encodeResponse(result.status, result.data);\n port.postMessage({ id: ev.data.id, buffer: response }, [response]);\n if (!opfsMode && result._op !== undefined) notifyOPFSSync(result._op, result._path!, result._newPath);\n } else if (leaderPort) {\n // Follower mode: forward to leader via leader port\n const buf = ev.data.buffer;\n leaderPort.postMessage({ id: ev.data.id, tabId, buffer: buf }, [buf]);\n }\n }\n };\n port.start();\n }\n return;\n }\n\n // --- Leader mode init ---\n if (msg.type === 'init-leader') {\n if (leaderInitialized) return; // Prevent duplicate init during async gap\n leaderInitialized = true;\n\n tabId = msg.tabId;\n const hasSAB = msg.sab != null;\n\n if (hasSAB) {\n sab = msg.sab;\n readySab = msg.readySab;\n ctrl = new Int32Array(sab, 0, 8);\n readySignal = new Int32Array(readySab, 0, 1);\n startHeartbeat(); // begin pulsing before init work so a slow init isn't mistaken for a dead worker\n }\n\n if (msg.asyncSab) {\n asyncSab = msg.asyncSab;\n asyncCtrl = new Int32Array(msg.asyncSab, 0, 8);\n }\n\n try {\n await initEngine(msg.config);\n } catch (err) {\n // OPFS handle unavailable — tell main thread to fall back\n leaderInitialized = false; // Allow retry\n (self as unknown as Worker).postMessage({\n type: 'init-failed',\n error: (err as Error).message,\n });\n return;\n }\n\n // Signal ready to main thread\n if (!readySent) {\n readySent = true;\n if (hasSAB) {\n Atomics.store(readySignal, 0, 1);\n Atomics.notify(readySignal, 0);\n }\n (self as unknown as Worker).postMessage({ type: 'ready' });\n }\n\n // Start leader loop only when SABs are available (it uses Atomics.wait)\n if (hasSAB) {\n leaderLoop();\n }\n // When no SAB, requests arrive only via MessagePorts (async-port handler above)\n return;\n }\n\n // --- OPFS-direct mode init ---\n if (msg.type === 'init-opfs') {\n // Reset guards for re-init (corruption fallback or mode=opfs)\n leaderInitialized = true;\n readySent = false;\n\n tabId = msg.tabId;\n const hasSAB = msg.sab != null;\n\n if (hasSAB) {\n sab = msg.sab;\n readySab = msg.readySab;\n ctrl = new Int32Array(sab, 0, 8);\n readySignal = new Int32Array(readySab, 0, 1);\n startHeartbeat(); // begin pulsing before init work so a slow init isn't mistaken for a dead worker\n }\n\n if (msg.asyncSab) {\n asyncSab = msg.asyncSab;\n asyncCtrl = new Int32Array(msg.asyncSab, 0, 8);\n }\n\n try {\n await initOPFSEngine(msg.config);\n } catch (err) {\n leaderInitialized = false;\n (self as unknown as Worker).postMessage({\n type: 'init-failed',\n error: (err as Error).message,\n });\n return;\n }\n\n // Signal ready\n if (!readySent) {\n readySent = true;\n if (hasSAB) {\n Atomics.store(readySignal, 0, 1);\n Atomics.notify(readySignal, 0);\n }\n (self as unknown as Worker).postMessage({ type: 'ready', mode: 'opfs' });\n }\n\n if (hasSAB) {\n leaderLoopOPFS();\n }\n return;\n }\n\n // --- Follower mode init ---\n if (msg.type === 'init-follower') {\n tabId = msg.tabId;\n const hasSAB = msg.sab != null;\n\n if (hasSAB) {\n sab = msg.sab;\n readySab = msg.readySab;\n ctrl = new Int32Array(sab, 0, 8);\n readySignal = new Int32Array(readySab, 0, 1);\n startHeartbeat(); // begin pulsing before init work so a slow init isn't mistaken for a dead worker\n }\n\n if (msg.asyncSab) {\n asyncSab = msg.asyncSab;\n asyncCtrl = new Int32Array(msg.asyncSab, 0, 8);\n }\n\n // Leader port will be sent separately\n return;\n }\n\n // --- Leader port (follower mode / reconnection) ---\n if (msg.type === 'leader-port') {\n // If already running as leader, ignore stale follower port\n if (leaderInitialized) return;\n\n const newPort = msg.port ?? e.ports[0];\n if (!newPort) return;\n\n // Reconnection: close old port and unblock any pending forwardToLeader()\n if (leaderPort) {\n leaderPort.close();\n if (pendingResolve) {\n // Resolve with EIO error response to unblock followerLoop\n const errorBuf = encodeResponse(5); // EIO\n pendingResolve(errorBuf);\n pendingResolve = null;\n }\n }\n\n leaderPort = newPort;\n newPort.onmessage = onLeaderMessage;\n newPort.start();\n\n if (!readySent) {\n // First time: signal ready and start follower loop\n readySent = true;\n if (readySignal) {\n Atomics.store(readySignal, 0, 1);\n Atomics.notify(readySignal, 0);\n }\n (self as unknown as Worker).postMessage({ type: 'ready' });\n if (ctrl) {\n followerLoop();\n }\n // When no SAB (no crossOriginIsolated), follower can't relay sync requests.\n // Only promises work — async-relay uses MessagePort to leader's sync-relay.\n }\n // If followerLoop is already running, it will pick up the new port on next iteration\n return;\n }\n\n // --- Client port registration (leader mode, during yields) ---\n if (msg.type === 'client-port') {\n registerClientPort(msg.tabId, msg.port ?? e.ports[0]);\n return;\n }\n\n // --- Client disconnection (leader mode) ---\n if (msg.type === 'client-lost') {\n removeClientPort(msg.tabId);\n return;\n }\n};\n"],"mappings":"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","names":["inode","data","children","totalSize","buf","view","offset","tabId","fd","encoder","encoder","totalSize","buf","view","offset","encoder","decoder","decoder","decoder"]}
|