@componentor/fs 3.0.12 → 3.0.14
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/README.md +11 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/workers/repair.worker.js +11 -7
- package/dist/workers/repair.worker.js.map +1 -1
- package/dist/workers/server.worker.js +1 -1
- package/dist/workers/server.worker.js.map +1 -1
- package/dist/workers/sync-relay.worker.js +1 -1
- package/dist/workers/sync-relay.worker.js.map +1 -1
- package/package.json +3 -3
|
@@ -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 = 10000;\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 RESERVED_10: 10, // uint16\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}\n\ninterface FdEntry {\n tabId: string;\n inodeIdx: number;\n position: number;\n flags: number;\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 init(\n handle: FileSystemSyncAccessHandle,\n opts?: { uid?: number; gid?: number; umask?: number; strictPermissions?: boolean; debug?: boolean }\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\n const size = handle.getSize();\n\n if (size === 0) {\n this.format();\n } else {\n this.mount();\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 // 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\n // Validate file is large enough for the declared layout\n const expectedMinSize = dataOffset + totalBlocks * blockSize;\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 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 }\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 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.RESERVED_10, 0, 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 // Need to shift bitmap and data region forward\n // Use in-memory bitmap (no read needed)\n\n // Read existing data region\n const dataSize = this.totalBlocks * this.blockSize;\n const dataBuf = new Uint8Array(dataSize);\n this.handle.read(dataBuf, { at: this.dataOffset });\n\n // Grow file\n const newTotalSize = this.handle.getSize() + growth;\n this.handle.truncate(newTotalSize);\n\n // Write data back at new offset\n const newBitmapOffset = this.bitmapOffset + growth;\n const newDataOffset = this.dataOffset + growth;\n this.handle.write(dataBuf, { at: newDataOffset });\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 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 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 resolvePathComponents (not resolvePath) so intermediate symlinks\n // in the resolved target path are also followed\n return this.resolvePathComponents(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.resolvePathComponents(newPath, followLast, depth + 1);\n }\n }\n\n return this.pathIndex.get(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 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\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 // 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 if (flags & 1) {\n this.commitPending();\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 // Read existing data\n const existing = inode.size > 0\n ? this.readData(inode.firstBlock, inode.blockCount, inode.size)\n : new Uint8Array(0);\n\n // Concat\n const combined = new Uint8Array(existing.byteLength + data.byteLength);\n combined.set(existing);\n combined.set(data, existing.byteLength);\n\n // Rewrite\n const neededBlocks = Math.ceil(combined.byteLength / this.blockSize);\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n const newFirst = this.allocateBlocks(neededBlocks);\n this.writeData(newFirst, combined);\n\n inode.firstBlock = newFirst;\n inode.blockCount = neededBlocks;\n inode.size = combined.byteLength;\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 // 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 // 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) return { status: CODE_TO_STATUS.ENOENT, data: null };\n\n return this.encodeStatResponse(idx);\n }\n\n // ---- LSTAT (no symlink follow) ----\n lstat(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 return this.encodeStatResponse(idx);\n }\n\n private encodeStatResponse(idx: number): { status: number; data: Uint8Array } {\n const inode = this.readInode(idx);\n // Encode stat into binary: type(1) + mode(4) + size(8) + mtime(8) + ctime(8) + atime(8) + uid(4) + gid(4) + ino(4) = 49 bytes\n const buf = new Uint8Array(49);\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\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\n if (this.pathIndex.has(path)) return { status: CODE_TO_STATUS.EEXIST, data: null };\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 // Return created path as data\n const pathBytes = encoder.encode(path);\n return { status: 0, data: pathBytes };\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) 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.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 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 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.ENOTDIR, data: null };\n\n const withFileTypes = (flags & 1) !== 0;\n const children = this.getDirectChildren(path);\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 childPath of children) {\n const name = childPath.substring(childPath.lastIndexOf('/') + 1);\n const nameBytes = encoder.encode(name);\n const childIdx = this.pathIndex.get(childPath)!;\n const childInode = this.readInode(childIdx);\n entries.push({ name: nameBytes, type: childInode.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 childPath of children) {\n const name = childPath.substring(childPath.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 // 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\n const existingIdx = this.pathIndex.get(newPath);\n if (existingIdx !== undefined) {\n const existingInode = this.readInode(existingIdx);\n this.freeBlockRange(existingInode.firstBlock, existingInode.blockCount);\n existingInode.type = INODE_TYPE.FREE;\n this.writeInode(existingIdx, existingInode);\n this.pathIndex.delete(newPath);\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\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 ? 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 (zero-fill)\n const neededBlocks = Math.ceil(len / this.blockSize);\n if (neededBlocks > inode.blockCount) {\n // Need more blocks\n const oldData = this.readData(inode.firstBlock, inode.blockCount, inode.size);\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n const newFirst = this.allocateBlocks(neededBlocks);\n const newData = new Uint8Array(len);\n newData.set(oldData);\n // Rest is already zero-filled\n this.writeData(newFirst, newData);\n inode.firstBlock = newFirst;\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)) {\n return { status: CODE_TO_STATUS.EEXIST };\n }\n\n // Read source data\n const data = srcInode.size > 0\n ? this.readData(srcInode.firstBlock, srcInode.blockCount, srcInode.size)\n : new Uint8Array(0);\n\n return this.write(destPath, data);\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) return { status: CODE_TO_STATUS.ENOENT };\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) return { status: CODE_TO_STATUS.ENOENT, data: null };\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)) return { status: CODE_TO_STATUS.EEXIST };\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) ----\n link(existingPath: string, newPath: string): { status: number } {\n return this.copy(existingPath, newPath);\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 — read old data, reallocate, write back\n const oldData = inode.size > 0\n ? this.readData(inode.firstBlock, inode.blockCount, inode.size)\n : new Uint8Array(0);\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n const newFirst = this.allocateBlocks(neededBlocks);\n const newBuf = new Uint8Array(endPos);\n newBuf.set(oldData);\n newBuf.set(data, pos);\n this.writeData(newFirst, newBuf);\n inode.firstBlock = newFirst;\n inode.blockCount = neededBlocks;\n } else {\n // Fits, write at position\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 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 // ---- 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) 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.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 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) return CODE_TO_STATUS.ENOENT;\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(49);\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 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 for (const part of parts) {\n dir = await dir.getDirectoryHandle(part, { create: true });\n }\n return { status: OK, data: encoder.encode(path) };\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 return { status: OK, data: encoder.encode(path) };\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 — these are no-ops\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 // 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} 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 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 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';\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 const { op, flags, path, data } = decodeRequest(buffer);\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).getUint32(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 < 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 length = dv.getUint32(4, true);\n const pos = dv.getInt32(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 < 8) {\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.getInt32(4, true);\n const writeData = data.subarray(8);\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 < 8) {\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.getUint32(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 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 const { op, flags, path, data } = decodeRequest(buffer);\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).getUint32(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 < 12) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n result = await oe.fread(dv.getUint32(0, true), dv.getUint32(4, true), dv.getInt32(8, true) === -1 ? null : dv.getInt32(8, true));\n break;\n }\n case OP.FWRITE: {\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 pos = dv.getInt32(4, true);\n result = await oe.fwrite(fd, data.subarray(8), 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 < 8) { 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.getUint32(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 default:\n result = { status: 7 };\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 if (totalLen <= maxChunk) {\n // Fast path: single chunk\n return new Uint8Array(targetSab, HEADER_SIZE, chunkLen).slice();\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 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 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, 10);\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 const waitResult = Atomics.wait(asyncCtrl, 0, SIGNAL.RESPONSE, 10);\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 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, 10);\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, 10);\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, 10);\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, 10);\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\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}): Promise<void> {\n debug = config.debug ?? false;\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 // 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 });\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 // 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 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 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 case OP.COPY:\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\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 const result = engine.read(path);\n if (result.status === 0) {\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 // Empty file (e.g. .gitkeep) — send with empty ArrayBuffer\n opfsSyncPort.postMessage({ op: 'write', path, data: new ArrayBuffer(0), ts });\n }\n }\n break;\n }\n case OP.SYMLINK: {\n // OPFS has no symlinks — mirror as regular file with target's content\n const result = engine.read(path); // follows symlink to target\n if (result.status === 0) {\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 }\n // If target doesn't exist yet (dangling symlink), skip — will be synced\n // when the target is written and read through the symlink succeeds\n break;\n }\n case OP.UNLINK:\n case OP.RMDIR:\n opfsSyncPort.postMessage({ op: 'delete', path, ts });\n break;\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 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","totalSize","buf","view","offset","tabId","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 = 10000;\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 RESERVED_10: 10, // uint16\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}\n\ninterface FdEntry {\n tabId: string;\n inodeIdx: number;\n position: number;\n flags: number;\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 init(\n handle: FileSystemSyncAccessHandle,\n opts?: { uid?: number; gid?: number; umask?: number; strictPermissions?: boolean; debug?: boolean }\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\n const size = handle.getSize();\n\n if (size === 0) {\n this.format();\n } else {\n this.mount();\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 // 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\n // Validate file is large enough for the declared layout\n const expectedMinSize = dataOffset + totalBlocks * blockSize;\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 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 }\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 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.RESERVED_10, 0, 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 // Need to shift bitmap and data region forward\n // Use in-memory bitmap (no read needed)\n\n // Read existing data region\n const dataSize = this.totalBlocks * this.blockSize;\n const dataBuf = new Uint8Array(dataSize);\n this.handle.read(dataBuf, { at: this.dataOffset });\n\n // Grow file\n const newTotalSize = this.handle.getSize() + growth;\n this.handle.truncate(newTotalSize);\n\n // Write data back at new offset\n const newBitmapOffset = this.bitmapOffset + growth;\n const newDataOffset = this.dataOffset + growth;\n this.handle.write(dataBuf, { at: newDataOffset });\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 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 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 resolvePathComponents (not resolvePath) so intermediate symlinks\n // in the resolved target path are also followed\n return this.resolvePathComponents(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.resolvePathComponents(newPath, followLast, depth + 1);\n }\n }\n\n return this.pathIndex.get(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 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\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 // 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 // Read existing data\n const existing = inode.size > 0\n ? this.readData(inode.firstBlock, inode.blockCount, inode.size)\n : new Uint8Array(0);\n\n // Concat\n const combined = new Uint8Array(existing.byteLength + data.byteLength);\n combined.set(existing);\n combined.set(data, existing.byteLength);\n\n // Rewrite\n const neededBlocks = Math.ceil(combined.byteLength / this.blockSize);\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n const newFirst = this.allocateBlocks(neededBlocks);\n this.writeData(newFirst, combined);\n\n inode.firstBlock = newFirst;\n inode.blockCount = neededBlocks;\n inode.size = combined.byteLength;\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 // 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 // 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) return { status: CODE_TO_STATUS.ENOENT, data: null };\n\n return this.encodeStatResponse(idx);\n }\n\n // ---- LSTAT (no symlink follow) ----\n lstat(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 return this.encodeStatResponse(idx);\n }\n\n private encodeStatResponse(idx: number): { status: number; data: Uint8Array } {\n const inode = this.readInode(idx);\n // Encode stat into binary: type(1) + mode(4) + size(8) + mtime(8) + ctime(8) + atime(8) + uid(4) + gid(4) + ino(4) = 49 bytes\n const buf = new Uint8Array(49);\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\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\n if (this.pathIndex.has(path)) return { status: CODE_TO_STATUS.EEXIST, data: null };\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 // Return created path as data\n const pathBytes = encoder.encode(path);\n return { status: 0, data: pathBytes };\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) 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.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 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 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.ENOTDIR, data: null };\n\n const withFileTypes = (flags & 1) !== 0;\n const children = this.getDirectChildren(path);\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 childPath of children) {\n const name = childPath.substring(childPath.lastIndexOf('/') + 1);\n const nameBytes = encoder.encode(name);\n const childIdx = this.pathIndex.get(childPath)!;\n const childInode = this.readInode(childIdx);\n entries.push({ name: nameBytes, type: childInode.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 childPath of children) {\n const name = childPath.substring(childPath.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 // 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\n const existingIdx = this.pathIndex.get(newPath);\n if (existingIdx !== undefined) {\n const existingInode = this.readInode(existingIdx);\n this.freeBlockRange(existingInode.firstBlock, existingInode.blockCount);\n existingInode.type = INODE_TYPE.FREE;\n this.writeInode(existingIdx, existingInode);\n this.pathIndex.delete(newPath);\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\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 ? 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 (zero-fill)\n const neededBlocks = Math.ceil(len / this.blockSize);\n if (neededBlocks > inode.blockCount) {\n // Need more blocks\n const oldData = this.readData(inode.firstBlock, inode.blockCount, inode.size);\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n const newFirst = this.allocateBlocks(neededBlocks);\n const newData = new Uint8Array(len);\n newData.set(oldData);\n // Rest is already zero-filled\n this.writeData(newFirst, newData);\n inode.firstBlock = newFirst;\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)) {\n return { status: CODE_TO_STATUS.EEXIST };\n }\n\n // Read source data\n const data = srcInode.size > 0\n ? this.readData(srcInode.firstBlock, srcInode.blockCount, srcInode.size)\n : new Uint8Array(0);\n\n return this.write(destPath, data);\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) return { status: CODE_TO_STATUS.ENOENT };\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) return { status: CODE_TO_STATUS.ENOENT, data: null };\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)) return { status: CODE_TO_STATUS.EEXIST };\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) ----\n link(existingPath: string, newPath: string): { status: number } {\n return this.copy(existingPath, newPath);\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 — read old data, reallocate, write back\n const oldData = inode.size > 0\n ? this.readData(inode.firstBlock, inode.blockCount, inode.size)\n : new Uint8Array(0);\n this.freeBlockRange(inode.firstBlock, inode.blockCount);\n const newFirst = this.allocateBlocks(neededBlocks);\n const newBuf = new Uint8Array(endPos);\n newBuf.set(oldData);\n newBuf.set(data, pos);\n this.writeData(newFirst, newBuf);\n inode.firstBlock = newFirst;\n inode.blockCount = neededBlocks;\n } else {\n // Fits, write at position\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 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 // ---- 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) 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.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 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) return CODE_TO_STATUS.ENOENT;\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(49);\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 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 for (const part of parts) {\n dir = await dir.getDirectoryHandle(part, { create: true });\n }\n return { status: OK, data: encoder.encode(path) };\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 return { status: OK, data: encoder.encode(path) };\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 — these are no-ops\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 // 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} 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 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 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';\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 const { op, flags, path, data } = decodeRequest(buffer);\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).getUint32(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 < 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 length = dv.getUint32(4, true);\n const pos = dv.getInt32(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 < 8) {\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.getInt32(4, true);\n const writeData = data.subarray(8);\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 < 8) {\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.getUint32(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 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 const { op, flags, path, data } = decodeRequest(buffer);\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).getUint32(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 < 12) { result = { status: 7 }; break; }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n result = await oe.fread(dv.getUint32(0, true), dv.getUint32(4, true), dv.getInt32(8, true) === -1 ? null : dv.getInt32(8, true));\n break;\n }\n case OP.FWRITE: {\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 pos = dv.getInt32(4, true);\n result = await oe.fwrite(fd, data.subarray(8), 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 < 8) { 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.getUint32(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 default:\n result = { status: 7 };\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 if (totalLen <= maxChunk) {\n // Fast path: single chunk\n return new Uint8Array(targetSab, HEADER_SIZE, chunkLen).slice();\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 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 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, 10);\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 const waitResult = Atomics.wait(asyncCtrl, 0, SIGNAL.RESPONSE, 10);\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 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, 10);\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, 10);\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, 10);\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, 10);\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\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}): Promise<void> {\n debug = config.debug ?? false;\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 // 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 });\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 // 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 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 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 case OP.COPY:\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\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 const result = engine.read(path);\n if (result.status === 0) {\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 // Empty file (e.g. .gitkeep) — send with empty ArrayBuffer\n opfsSyncPort.postMessage({ op: 'write', path, data: new ArrayBuffer(0), ts });\n }\n }\n break;\n }\n case OP.SYMLINK: {\n // OPFS has no symlinks — mirror as regular file with target's content\n const result = engine.read(path); // follows symlink to target\n if (result.status === 0) {\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 }\n // If target doesn't exist yet (dangling symlink), skip — will be synced\n // when the target is written and read through the symlink succeeds\n break;\n }\n case OP.UNLINK:\n case OP.RMDIR:\n opfsSyncPort.postMessage({ op: 'delete', path, ts });\n break;\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 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","totalSize","buf","view","offset","tabId","encoder","encoder","totalSize","buf","view","offset","encoder","decoder","decoder","decoder"]}
|