@zenfs/dom 0.0.6 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/FileSystemAccess.d.ts +55 -0
- package/dist/FileSystemAccess.js +216 -0
- package/dist/IndexedDB.d.ts +56 -0
- package/dist/IndexedDB.js +201 -0
- package/dist/Storage.d.ts +29 -0
- package/dist/Storage.js +68 -0
- package/dist/browser.min.js +1 -3
- package/dist/browser.min.js.map +4 -4
- package/dist/index.d.ts +3 -5
- package/dist/index.js +3 -5
- package/package.json +7 -7
- package/readme.md +12 -20
- package/dist/backends/FileSystemAccess.d.ts +0 -44
- package/dist/backends/FileSystemAccess.js +0 -208
- package/dist/backends/HTTPRequest.d.ts +0 -85
- package/dist/backends/HTTPRequest.js +0 -202
- package/dist/backends/IndexedDB.d.ts +0 -63
- package/dist/backends/IndexedDB.js +0 -221
- package/dist/backends/Storage.d.ts +0 -39
- package/dist/backends/Storage.js +0 -75
- package/dist/backends/Worker.d.ts +0 -78
- package/dist/backends/Worker.js +0 -163
- package/dist/fetch.d.ts +0 -16
- package/dist/fetch.js +0 -37
package/dist/browser.min.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../node_modules/@zenfs/core/dist/emulation/path.js", "../node_modules/@zenfs/core/dist/
|
|
4
|
-
"sourcesContent": ["export * from './backends/FileSystemAccess.js';\nexport * from './backends/HTTPRequest.js';\nexport * from './backends/IndexedDB.js';\nexport * from './backends/Storage.js';\nexport * from './backends/Worker.js';\n", "/*\nCopyright Joyent, Inc. and other Node contributors.\n\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to permit\npersons to whom the Software is furnished to do so, subject to the\nfollowing conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\nNO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\nDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\nUSE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\nexport const cwd = '/';\nexport const sep = '/';\nfunction validateString(str, name) {\n if (typeof str != 'string') {\n throw new TypeError(`\"${name}\" is not a string`);\n }\n}\nfunction validateObject(str, name) {\n if (typeof str != 'object') {\n throw new TypeError(`\"${name}\" is not an object`);\n }\n}\n// Resolves . and .. elements in a path with directory names\nexport function normalizeString(path, allowAboveRoot) {\n let res = '';\n let lastSegmentLength = 0;\n let lastSlash = -1;\n let dots = 0;\n let char = '\\x00';\n for (let i = 0; i <= path.length; ++i) {\n if (i < path.length) {\n char = path[i];\n }\n else if (char == '/') {\n break;\n }\n else {\n char = '/';\n }\n if (char == '/') {\n if (lastSlash === i - 1 || dots === 1) {\n // NOOP\n }\n else if (dots === 2) {\n if (res.length < 2 || lastSegmentLength !== 2 || res.at(-1) !== '.' || res.at(-2) !== '.') {\n if (res.length > 2) {\n const lastSlashIndex = res.lastIndexOf('/');\n if (lastSlashIndex === -1) {\n res = '';\n lastSegmentLength = 0;\n }\n else {\n res = res.slice(0, lastSlashIndex);\n lastSegmentLength = res.length - 1 - res.lastIndexOf('/');\n }\n lastSlash = i;\n dots = 0;\n continue;\n }\n else if (res.length !== 0) {\n res = '';\n lastSegmentLength = 0;\n lastSlash = i;\n dots = 0;\n continue;\n }\n }\n if (allowAboveRoot) {\n res += res.length > 0 ? '/..' : '..';\n lastSegmentLength = 2;\n }\n }\n else {\n if (res.length > 0)\n res += '/' + path.slice(lastSlash + 1, i);\n else\n res = path.slice(lastSlash + 1, i);\n lastSegmentLength = i - lastSlash - 1;\n }\n lastSlash = i;\n dots = 0;\n }\n else if (char === '.' && dots !== -1) {\n ++dots;\n }\n else {\n dots = -1;\n }\n }\n return res;\n}\nexport function formatExt(ext) {\n return ext ? `${ext[0] === '.' ? '' : '.'}${ext}` : '';\n}\nexport function resolve(...args) {\n let resolvedPath = '';\n let resolvedAbsolute = false;\n for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {\n const path = i >= 0 ? args[i] : cwd;\n validateString(path, `paths[${i}]`);\n // Skip empty entries\n if (path.length === 0) {\n continue;\n }\n resolvedPath = `${path}/${resolvedPath}`;\n resolvedAbsolute = path[0] === '/';\n }\n // At this point the path should be resolved to a full absolute path, but\n // handle relative paths to be safe (might happen when process.cwd() fails)\n // Normalize the path\n resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);\n if (resolvedAbsolute) {\n return `/${resolvedPath}`;\n }\n return resolvedPath.length > 0 ? resolvedPath : '.';\n}\nexport function normalize(path) {\n validateString(path, 'path');\n if (path.length === 0)\n return '.';\n const isAbsolute = path[0] === '/';\n const trailingSeparator = path.at(-1) === '/';\n // Normalize the path\n path = normalizeString(path, !isAbsolute);\n if (path.length === 0) {\n if (isAbsolute)\n return '/';\n return trailingSeparator ? './' : '.';\n }\n if (trailingSeparator)\n path += '/';\n return isAbsolute ? `/${path}` : path;\n}\nexport function isAbsolute(path) {\n validateString(path, 'path');\n return path.length > 0 && path[0] === '/';\n}\nexport function join(...args) {\n if (args.length === 0)\n return '.';\n let joined;\n for (let i = 0; i < args.length; ++i) {\n const arg = args[i];\n validateString(arg, 'path');\n if (arg.length > 0) {\n if (joined === undefined)\n joined = arg;\n else\n joined += `/${arg}`;\n }\n }\n if (joined === undefined)\n return '.';\n return normalize(joined);\n}\nexport function relative(from, to) {\n validateString(from, 'from');\n validateString(to, 'to');\n if (from === to)\n return '';\n // Trim leading forward slashes.\n from = resolve(from);\n to = resolve(to);\n if (from === to)\n return '';\n const fromStart = 1;\n const fromEnd = from.length;\n const fromLen = fromEnd - fromStart;\n const toStart = 1;\n const toLen = to.length - toStart;\n // Compare paths to find the longest common path from root\n const length = fromLen < toLen ? fromLen : toLen;\n let lastCommonSep = -1;\n let i = 0;\n for (; i < length; i++) {\n const fromCode = from[fromStart + i];\n if (fromCode !== to[toStart + i])\n break;\n else if (fromCode === '/')\n lastCommonSep = i;\n }\n if (i === length) {\n if (toLen > length) {\n if (to[toStart + i] === '/') {\n // We get here if `from` is the exact base path for `to`.\n // For example: from='/foo/bar'; to='/foo/bar/baz'\n return to.slice(toStart + i + 1);\n }\n if (i === 0) {\n // We get here if `from` is the root\n // For example: from='/'; to='/foo'\n return to.slice(toStart + i);\n }\n }\n else if (fromLen > length) {\n if (from[fromStart + i] === '/') {\n // We get here if `to` is the exact base path for `from`.\n // For example: from='/foo/bar/baz'; to='/foo/bar'\n lastCommonSep = i;\n }\n else if (i === 0) {\n // We get here if `to` is the root.\n // For example: from='/foo/bar'; to='/'\n lastCommonSep = 0;\n }\n }\n }\n let out = '';\n // Generate the relative path based on the path difference between `to`\n // and `from`.\n for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {\n if (i === fromEnd || from[i] === '/') {\n out += out.length === 0 ? '..' : '/..';\n }\n }\n // Lastly, append the rest of the destination (`to`) path that comes after\n // the common path parts.\n return `${out}${to.slice(toStart + lastCommonSep)}`;\n}\nexport function dirname(path) {\n validateString(path, 'path');\n if (path.length === 0)\n return '.';\n const hasRoot = path[0] === '/';\n let end = -1;\n let matchedSlash = true;\n for (let i = path.length - 1; i >= 1; --i) {\n if (path[i] === '/') {\n if (!matchedSlash) {\n end = i;\n break;\n }\n }\n else {\n // We saw the first non-path separator\n matchedSlash = false;\n }\n }\n if (end === -1)\n return hasRoot ? '/' : '.';\n if (hasRoot && end === 1)\n return '//';\n return path.slice(0, end);\n}\nexport function basename(path, suffix) {\n if (suffix !== undefined)\n validateString(suffix, 'ext');\n validateString(path, 'path');\n let start = 0;\n let end = -1;\n let matchedSlash = true;\n if (suffix !== undefined && suffix.length > 0 && suffix.length <= path.length) {\n if (suffix === path)\n return '';\n let extIdx = suffix.length - 1;\n let firstNonSlashEnd = -1;\n for (let i = path.length - 1; i >= 0; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n start = i + 1;\n break;\n }\n }\n else {\n if (firstNonSlashEnd === -1) {\n // We saw the first non-path separator, remember this index in case\n // we need it if the extension ends up not matching\n matchedSlash = false;\n firstNonSlashEnd = i + 1;\n }\n if (extIdx >= 0) {\n // Try to match the explicit extension\n if (path[i] === suffix[extIdx]) {\n if (--extIdx === -1) {\n // We matched the extension, so mark this as the end of our path\n // component\n end = i;\n }\n }\n else {\n // Extension does not match, so our result is the entire path\n // component\n extIdx = -1;\n end = firstNonSlashEnd;\n }\n }\n }\n }\n if (start === end)\n end = firstNonSlashEnd;\n else if (end === -1)\n end = path.length;\n return path.slice(start, end);\n }\n for (let i = path.length - 1; i >= 0; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n start = i + 1;\n break;\n }\n }\n else if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // path component\n matchedSlash = false;\n end = i + 1;\n }\n }\n if (end === -1)\n return '';\n return path.slice(start, end);\n}\nexport function extname(path) {\n validateString(path, 'path');\n let startDot = -1;\n let startPart = 0;\n let end = -1;\n let matchedSlash = true;\n // Track the state of characters (if any) we see before our first dot and\n // after any path separator we find\n let preDotState = 0;\n for (let i = path.length - 1; i >= 0; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n startPart = i + 1;\n break;\n }\n continue;\n }\n if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // extension\n matchedSlash = false;\n end = i + 1;\n }\n if (path[i] === '.') {\n // If this is our first dot, mark it as the start of our extension\n if (startDot === -1)\n startDot = i;\n else if (preDotState !== 1)\n preDotState = 1;\n }\n else if (startDot !== -1) {\n // We saw a non-dot and non-path separator before our dot, so we should\n // have a good chance at having a non-empty extension\n preDotState = -1;\n }\n }\n if (startDot === -1 ||\n end === -1 ||\n // We saw a non-dot character immediately before the dot\n preDotState === 0 ||\n // The (right-most) trimmed path component is exactly '..'\n (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)) {\n return '';\n }\n return path.slice(startDot, end);\n}\nexport function format(pathObject) {\n validateObject(pathObject, 'pathObject');\n const dir = pathObject.dir || pathObject.root;\n const base = pathObject.base || `${pathObject.name || ''}${formatExt(pathObject.ext)}`;\n if (!dir) {\n return base;\n }\n return dir === pathObject.root ? `${dir}${base}` : `${dir}/${base}`;\n}\nexport function parse(path) {\n validateString(path, 'path');\n const isAbsolute = path[0] === '/';\n const ret = { root: isAbsolute ? '/' : '', dir: '', base: '', ext: '', name: '' };\n if (path.length === 0)\n return ret;\n const start = isAbsolute ? 1 : 0;\n let startDot = -1;\n let startPart = 0;\n let end = -1;\n let matchedSlash = true;\n let i = path.length - 1;\n // Track the state of characters (if any) we see before our first dot and\n // after any path separator we find\n let preDotState = 0;\n // Get non-dir info\n for (; i >= start; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n startPart = i + 1;\n break;\n }\n continue;\n }\n if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // extension\n matchedSlash = false;\n end = i + 1;\n }\n if (path[i] === '.') {\n // If this is our first dot, mark it as the start of our extension\n if (startDot === -1)\n startDot = i;\n else if (preDotState !== 1)\n preDotState = 1;\n }\n else if (startDot !== -1) {\n // We saw a non-dot and non-path separator before our dot, so we should\n // have a good chance at having a non-empty extension\n preDotState = -1;\n }\n }\n if (end !== -1) {\n const start = startPart === 0 && isAbsolute ? 1 : startPart;\n if (startDot === -1 ||\n // We saw a non-dot character immediately before the dot\n preDotState === 0 ||\n // The (right-most) trimmed path component is exactly '..'\n (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)) {\n ret.base = ret.name = path.slice(start, end);\n }\n else {\n ret.name = path.slice(start, startDot);\n ret.base = path.slice(start, end);\n ret.ext = path.slice(startDot, end);\n }\n }\n if (startPart > 0)\n ret.dir = path.slice(0, startPart - 1);\n else if (isAbsolute)\n ret.dir = '/';\n return ret;\n}\n", "import { ErrorCode, ApiError } from './ApiError.js';\nimport * as path from './emulation/path.js';\n/**\n * Synchronous recursive makedir.\n * @internal\n */\nexport function mkdirpSync(p, mode, cred, fs) {\n if (!fs.existsSync(p, cred)) {\n mkdirpSync(path.dirname(p), mode, cred, fs);\n fs.mkdirSync(p, mode, cred);\n }\n}\n/*\n * Levenshtein distance, from the `js-levenshtein` NPM module.\n * Copied here to avoid complexity of adding another CommonJS module dependency.\n */\nfunction _min(d0, d1, d2, bx, ay) {\n return Math.min(d0 + 1, d1 + 1, d2 + 1, bx === ay ? d1 : d1 + 1);\n}\n/**\n * Calculates levenshtein distance.\n * @param a\n * @param b\n */\nfunction levenshtein(a, b) {\n if (a === b) {\n return 0;\n }\n if (a.length > b.length) {\n [a, b] = [b, a]; // Swap a and b\n }\n let la = a.length;\n let lb = b.length;\n // Trim common suffix\n while (la > 0 && a.charCodeAt(la - 1) === b.charCodeAt(lb - 1)) {\n la--;\n lb--;\n }\n let offset = 0;\n // Trim common prefix\n while (offset < la && a.charCodeAt(offset) === b.charCodeAt(offset)) {\n offset++;\n }\n la -= offset;\n lb -= offset;\n if (la === 0 || lb === 1) {\n return lb;\n }\n const vector = new Array(la << 1);\n for (let y = 0; y < la;) {\n vector[la + y] = a.charCodeAt(offset + y);\n vector[y] = ++y;\n }\n let x;\n let d0;\n let d1;\n let d2;\n let d3;\n for (x = 0; x + 3 < lb;) {\n const bx0 = b.charCodeAt(offset + (d0 = x));\n const bx1 = b.charCodeAt(offset + (d1 = x + 1));\n const bx2 = b.charCodeAt(offset + (d2 = x + 2));\n const bx3 = b.charCodeAt(offset + (d3 = x + 3));\n let dd = (x += 4);\n for (let y = 0; y < la;) {\n const ay = vector[la + y];\n const dy = vector[y];\n d0 = _min(dy, d0, d1, bx0, ay);\n d1 = _min(d0, d1, d2, bx1, ay);\n d2 = _min(d1, d2, d3, bx2, ay);\n dd = _min(d2, d3, dd, bx3, ay);\n vector[y++] = dd;\n d3 = d2;\n d2 = d1;\n d1 = d0;\n d0 = dy;\n }\n }\n let dd = 0;\n for (; x < lb;) {\n const bx0 = b.charCodeAt(offset + (d0 = x));\n dd = ++x;\n for (let y = 0; y < la; y++) {\n const dy = vector[y];\n vector[y] = dd = dy < d0 || dd < d0 ? (dy > dd ? dd + 1 : dy + 1) : bx0 === vector[la + y] ? d0 : d0 + 1;\n d0 = dy;\n }\n }\n return dd;\n}\n/**\n * Checks that the given options object is valid for the file system options.\n * @internal\n */\nexport async function checkOptions(backend, opts) {\n const optsInfo = backend.Options;\n const fsName = backend.Name;\n let pendingValidators = 0;\n let callbackCalled = false;\n let loopEnded = false;\n // Check for required options.\n for (const optName in optsInfo) {\n if (Object.prototype.hasOwnProperty.call(optsInfo, optName)) {\n const opt = optsInfo[optName];\n const providedValue = opts && opts[optName];\n if (providedValue === undefined || providedValue === null) {\n if (!opt.optional) {\n // Required option, not provided.\n // Any incorrect options provided? Which ones are close to the provided one?\n // (edit distance 5 === close)\n const incorrectOptions = Object.keys(opts)\n .filter(o => !(o in optsInfo))\n .map((a) => {\n return { str: a, distance: levenshtein(optName, a) };\n })\n .filter(o => o.distance < 5)\n .sort((a, b) => a.distance - b.distance);\n // Validators may be synchronous.\n if (callbackCalled) {\n return;\n }\n callbackCalled = true;\n throw new ApiError(ErrorCode.EINVAL, `[${fsName}] Required option '${optName}' not provided.${incorrectOptions.length > 0 ? ` You provided unrecognized option '${incorrectOptions[0].str}'; perhaps you meant to type '${optName}'.` : ''}\\nOption description: ${opt.description}`);\n }\n // Else: Optional option, not provided. That is OK.\n }\n else {\n // Option provided! Check type.\n let typeMatches = false;\n if (Array.isArray(opt.type)) {\n typeMatches = opt.type.indexOf(typeof providedValue) !== -1;\n }\n else {\n typeMatches = typeof providedValue === opt.type;\n }\n if (!typeMatches) {\n // Validators may be synchronous.\n if (callbackCalled) {\n return;\n }\n callbackCalled = true;\n throw new ApiError(ErrorCode.EINVAL, `[${fsName}] Value provided for option ${optName} is not the proper type. Expected ${Array.isArray(opt.type) ? `one of {${opt.type.join(', ')}}` : opt.type}, but received ${typeof providedValue}\\nOption description: ${opt.description}`);\n }\n else if (opt.validator) {\n pendingValidators++;\n try {\n await opt.validator(providedValue);\n }\n catch (e) {\n if (!callbackCalled) {\n if (e) {\n callbackCalled = true;\n throw e;\n }\n pendingValidators--;\n if (pendingValidators === 0 && loopEnded) {\n return;\n }\n }\n }\n }\n // Otherwise: All good!\n }\n }\n }\n loopEnded = true;\n if (pendingValidators === 0 && !callbackCalled) {\n return;\n }\n}\n/** Waits n ms. */\nexport function wait(ms) {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n/**\n * Converts a callback into a promise. Assumes last parameter is the callback\n * @todo Look at changing resolve value from cbArgs[0] to include other callback arguments?\n */\nexport function toPromise(fn) {\n return function (...args) {\n return new Promise((resolve, reject) => {\n args.push((e, ...cbArgs) => {\n if (e) {\n reject(e);\n }\n else {\n resolve(cbArgs[0]);\n }\n });\n fn(...args);\n });\n };\n}\n/**\n * @internal\n */\nexport const setImmediate = typeof globalThis.setImmediate == 'function' ? globalThis.setImmediate : cb => setTimeout(cb, 0);\n/**\n * @internal\n */\nexport const ROOT_NODE_ID = '/';\n/**\n * @internal\n * Used for caching text decoders\n */\nconst decoderCache = new Map();\nconst textEncoder = new globalThis.TextEncoder();\nexport function encode(input, encoding = 'utf8') {\n return textEncoder.encode(input);\n}\nexport function decode(input, encoding = 'utf8') {\n if (!decoderCache.has(encoding)) {\n const textDecoder = new globalThis.TextDecoder(encoding);\n decoderCache.set(encoding, textDecoder.decode.bind(textDecoder));\n }\n return decoderCache.get(encoding)(input);\n}\n/**\n * Generates a random ID.\n * @internal\n */\nexport function randomUUID() {\n // From http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n", "import { decode, encode } from './utils.js';\n/**\n * Standard libc error codes. More will be added to this enum and ErrorStrings as they are\n * needed.\n * @url http://www.gnu.org/software/libc/manual/html_node/Error-Codes.html\n */\nexport var ErrorCode;\n(function (ErrorCode) {\n ErrorCode[ErrorCode[\"EPERM\"] = 1] = \"EPERM\";\n ErrorCode[ErrorCode[\"ENOENT\"] = 2] = \"ENOENT\";\n ErrorCode[ErrorCode[\"EIO\"] = 5] = \"EIO\";\n ErrorCode[ErrorCode[\"EBADF\"] = 9] = \"EBADF\";\n ErrorCode[ErrorCode[\"EACCES\"] = 13] = \"EACCES\";\n ErrorCode[ErrorCode[\"EBUSY\"] = 16] = \"EBUSY\";\n ErrorCode[ErrorCode[\"EEXIST\"] = 17] = \"EEXIST\";\n ErrorCode[ErrorCode[\"ENOTDIR\"] = 20] = \"ENOTDIR\";\n ErrorCode[ErrorCode[\"EISDIR\"] = 21] = \"EISDIR\";\n ErrorCode[ErrorCode[\"EINVAL\"] = 22] = \"EINVAL\";\n ErrorCode[ErrorCode[\"EFBIG\"] = 27] = \"EFBIG\";\n ErrorCode[ErrorCode[\"ENOSPC\"] = 28] = \"ENOSPC\";\n ErrorCode[ErrorCode[\"EROFS\"] = 30] = \"EROFS\";\n ErrorCode[ErrorCode[\"ENOTEMPTY\"] = 39] = \"ENOTEMPTY\";\n ErrorCode[ErrorCode[\"ENOTSUP\"] = 95] = \"ENOTSUP\";\n})(ErrorCode = ErrorCode || (ErrorCode = {}));\n/**\n * Strings associated with each error code.\n * @internal\n */\nexport const ErrorStrings = {\n [ErrorCode.EPERM]: 'Operation not permitted.',\n [ErrorCode.ENOENT]: 'No such file or directory.',\n [ErrorCode.EIO]: 'Input/output error.',\n [ErrorCode.EBADF]: 'Bad file descriptor.',\n [ErrorCode.EACCES]: 'Permission denied.',\n [ErrorCode.EBUSY]: 'Resource busy or locked.',\n [ErrorCode.EEXIST]: 'File exists.',\n [ErrorCode.ENOTDIR]: 'File is not a directory.',\n [ErrorCode.EISDIR]: 'File is a directory.',\n [ErrorCode.EINVAL]: 'Invalid argument.',\n [ErrorCode.EFBIG]: 'File is too big.',\n [ErrorCode.ENOSPC]: 'No space left on disk.',\n [ErrorCode.EROFS]: 'Cannot modify a read-only file system.',\n [ErrorCode.ENOTEMPTY]: 'Directory is not empty.',\n [ErrorCode.ENOTSUP]: 'Operation is not supported.',\n};\n/**\n * Represents a BrowserFS error. Passed back to applications after a failed\n * call to the BrowserFS API.\n */\nexport class ApiError extends Error {\n static fromJSON(json) {\n const err = new ApiError(json.errno, json.message, json.path);\n err.code = json.code;\n err.stack = json.stack;\n return err;\n }\n /**\n * Creates an ApiError object from a buffer.\n */\n static Derserialize(data, i = 0) {\n const view = new DataView('buffer' in data ? data.buffer : data);\n const dataText = decode(view.buffer.slice(i + 4, i + 4 + view.getUint32(i, true)));\n return ApiError.fromJSON(JSON.parse(dataText));\n }\n static FileError(code, p) {\n return new ApiError(code, ErrorStrings[code], p);\n }\n static EACCES(path) {\n return this.FileError(ErrorCode.EACCES, path);\n }\n static ENOENT(path) {\n return this.FileError(ErrorCode.ENOENT, path);\n }\n static EEXIST(path) {\n return this.FileError(ErrorCode.EEXIST, path);\n }\n static EISDIR(path) {\n return this.FileError(ErrorCode.EISDIR, path);\n }\n static ENOTDIR(path) {\n return this.FileError(ErrorCode.ENOTDIR, path);\n }\n static EPERM(path) {\n return this.FileError(ErrorCode.EPERM, path);\n }\n static ENOTEMPTY(path) {\n return this.FileError(ErrorCode.ENOTEMPTY, path);\n }\n /**\n * Represents a BrowserFS error. Passed back to applications after a failed\n * call to the BrowserFS API.\n *\n * Error codes mirror those returned by regular Unix file operations, which is\n * what Node returns.\n * @constructor ApiError\n * @param type The type of the error.\n * @param [message] A descriptive error message.\n */\n constructor(type, message = ErrorStrings[type], path) {\n super(message);\n // Unsupported.\n this.syscall = '';\n this.errno = type;\n this.code = ErrorCode[type];\n this.path = path;\n this.message = `Error: ${this.code}: ${message}${this.path ? `, '${this.path}'` : ''}`;\n }\n /**\n * @return A friendly error message.\n */\n toString() {\n return this.message;\n }\n toJSON() {\n return {\n errno: this.errno,\n code: this.code,\n path: this.path,\n stack: this.stack,\n message: this.message,\n };\n }\n /**\n * Writes the API error into a buffer.\n */\n serialize(data = new Uint8Array(this.bufferSize()), i = 0) {\n const view = new DataView('buffer' in data ? data.buffer : data), buffer = new Uint8Array(view.buffer);\n const newData = encode(JSON.stringify(this.toJSON()));\n buffer.set(newData);\n view.setUint32(i, newData.byteLength, true);\n return buffer;\n }\n /**\n * The size of the API error in buffer-form in bytes.\n */\n bufferSize() {\n // 4 bytes for string length.\n return 4 + JSON.stringify(this.toJSON()).length;\n }\n}\n", "/**\n * Credentials used for FS ops.\n * Similar to Linux's cred struct. See https://github.com/torvalds/linux/blob/master/include/linux/cred.h\n */\nexport class Cred {\n constructor(uid, gid, suid, sgid, euid, egid) {\n this.uid = uid;\n this.gid = gid;\n this.suid = suid;\n this.sgid = sgid;\n this.euid = euid;\n this.egid = egid;\n }\n}\nCred.Root = new Cred(0, 0, 0, 0, 0, 0);\n", "import { Cred } from './cred.js';\nimport { S_IFDIR, S_IFLNK, S_IFMT, S_IFREG } from './emulation/constants.js';\n/**\n * Indicates the type of the given file. Applied to 'mode'.\n */\nexport var FileType;\n(function (FileType) {\n FileType[FileType[\"FILE\"] = S_IFREG] = \"FILE\";\n FileType[FileType[\"DIRECTORY\"] = S_IFDIR] = \"DIRECTORY\";\n FileType[FileType[\"SYMLINK\"] = S_IFLNK] = \"SYMLINK\";\n})(FileType = FileType || (FileType = {}));\n/**\n * Common code used by both Stats and BigIntStats\n */\nexport class StatsCommon {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n static Deserialize(data) {\n throw new ReferenceError('Called static abstract method: StatsCommon.Deserialize()');\n }\n get _typename() {\n return this._isBigint ? 'bigint' : 'number';\n }\n get _typename_inverse() {\n return this._isBigint ? 'number' : 'bigint';\n }\n _convert(arg) {\n return (this._isBigint ? BigInt(arg) : Number(arg));\n }\n get atime() {\n return new Date(Number(this.atimeMs));\n }\n get mtime() {\n return new Date(Number(this.mtimeMs));\n }\n get ctime() {\n return new Date(Number(this.ctimeMs));\n }\n get birthtime() {\n return new Date(Number(this.birthtimeMs));\n }\n /**\n * Provides information about a particular entry in the file system.\n * @param itemType Type of the item (FILE, DIRECTORY, SYMLINK, or SOCKET)\n * @param size Size of the item in bytes. For directories/symlinks,\n * this is normally the size of the struct that represents the item.\n * @param mode Unix-style file mode (e.g. 0o644)\n * @param atimeMs time of last access, in milliseconds since epoch\n * @param mtimeMs time of last modification, in milliseconds since epoch\n * @param ctimeMs time of last time file status was changed, in milliseconds since epoch\n * @param uid the id of the user that owns the file\n * @param gid the id of the group that owns the file\n * @param birthtimeMs time of file creation, in milliseconds since epoch\n */\n constructor(itemType = FileType.FILE, size = -1, mode, atimeMs, mtimeMs, ctimeMs, uid, gid, birthtimeMs) {\n /**\n * ID of device containing file\n */\n this.dev = this._convert(0);\n /**\n * inode number\n */\n this.ino = this._convert(0);\n /**\n * device ID (if special file)\n */\n this.rdev = this._convert(0);\n /**\n * number of hard links\n */\n this.nlink = this._convert(1);\n /**\n * blocksize for file system I/O\n */\n this.blksize = this._convert(4096);\n /**\n * user ID of owner\n */\n this.uid = this._convert(0);\n /**\n * group ID of owner\n */\n this.gid = this._convert(0);\n /**\n * Some file systems stash data on stats objects.\n */\n this.fileData = null;\n const currentTime = Date.now();\n const resolveT = (v, def) => (typeof v == this._typename ? v : this._convert(typeof v == this._typename_inverse ? v : def));\n this.atimeMs = resolveT(atimeMs, currentTime);\n this.mtimeMs = resolveT(mtimeMs, currentTime);\n this.ctimeMs = resolveT(ctimeMs, currentTime);\n this.birthtimeMs = resolveT(birthtimeMs, currentTime);\n this.uid = resolveT(uid, 0);\n this.gid = resolveT(gid, 0);\n this.size = this._convert(size);\n if (mode) {\n this.mode = this._convert(mode);\n }\n else {\n switch (itemType) {\n case FileType.FILE:\n this.mode = this._convert(0o644);\n break;\n case FileType.DIRECTORY:\n default:\n this.mode = this._convert(0o777);\n }\n }\n // number of 512B blocks allocated\n this.blocks = this._convert(Math.ceil(Number(size) / 512));\n // Check if mode also includes top-most bits, which indicate the file's\n // type.\n if ((this.mode & S_IFMT) == 0) {\n this.mode = (this.mode | this._convert(itemType));\n }\n }\n /**\n * @return [Boolean] True if this item is a file.\n */\n isFile() {\n return (this.mode & S_IFMT) === S_IFREG;\n }\n /**\n * @return [Boolean] True if this item is a directory.\n */\n isDirectory() {\n return (this.mode & S_IFMT) === S_IFDIR;\n }\n /**\n * @return [Boolean] True if this item is a symbolic link (only valid through lstat)\n */\n isSymbolicLink() {\n return (this.mode & S_IFMT) === S_IFLNK;\n }\n /**\n * Checks if a given user/group has access to this item\n * @param mode The request access as 4 bits (unused, read, write, execute)\n * @param uid The requesting UID\n * @param gid The requesting GID\n * @returns [Boolean] True if the request has access, false if the request does not\n */\n hasAccess(mode, cred) {\n if (cred.euid === 0 || cred.egid === 0) {\n //Running as root\n return true;\n }\n const perms = this.mode & ~S_IFMT;\n let uMode = 0xf, gMode = 0xf, wMode = 0xf;\n if (cred.euid == this.uid) {\n const uPerms = (0xf00 & perms) >> 8;\n uMode = (mode ^ uPerms) & mode;\n }\n if (cred.egid == this.gid) {\n const gPerms = (0xf0 & perms) >> 4;\n gMode = (mode ^ gPerms) & mode;\n }\n const wPerms = 0xf & perms;\n wMode = (mode ^ wPerms) & mode;\n /*\n Result = 0b0xxx (read, write, execute)\n If any bits are set that means the request does not have that permission.\n */\n const result = uMode & gMode & wMode;\n return !result;\n }\n /**\n * Convert the current stats object into a cred object\n */\n getCred(uid = Number(this.uid), gid = Number(this.gid)) {\n return new Cred(uid, gid, Number(this.uid), Number(this.gid), uid, gid);\n }\n /**\n * Change the mode of the file. We use this helper function to prevent messing\n * up the type of the file, which is encoded in mode.\n */\n chmod(mode) {\n this.mode = this._convert((this.mode & S_IFMT) | mode);\n }\n /**\n * Change the owner user/group of the file.\n * This function makes sure it is a valid UID/GID (that is, a 32 unsigned int)\n */\n chown(uid, gid) {\n uid = Number(uid);\n gid = Number(gid);\n if (!isNaN(uid) && 0 <= uid && uid < 2 ** 32) {\n this.uid = this._convert(uid);\n }\n if (!isNaN(gid) && 0 <= gid && gid < 2 ** 32) {\n this.gid = this._convert(gid);\n }\n }\n // We don't support the following types of files.\n isSocket() {\n return false;\n }\n isBlockDevice() {\n return false;\n }\n isCharacterDevice() {\n return false;\n }\n isFIFO() {\n return false;\n }\n}\n/**\n * Implementation of Node's `Stats`.\n *\n * Attribute descriptions are from `man 2 stat'\n * @see http://nodejs.org/api/fs.html#fs_class_fs_stats\n * @see http://man7.org/linux/man-pages/man2/stat.2.html\n */\nexport class Stats extends StatsCommon {\n constructor() {\n super(...arguments);\n this._isBigint = false;\n }\n /**\n * Clones the stats object.\n */\n static clone(s) {\n return new Stats(s.mode & S_IFMT, s.size, s.mode & ~S_IFMT, s.atimeMs, s.mtimeMs, s.ctimeMs, s.uid, s.gid, s.birthtimeMs);\n }\n static Deserialize(data) {\n const view = new DataView('buffer' in data ? data.buffer : data);\n const size = view.getUint32(0, true), mode = view.getUint32(4, true), atime = view.getFloat64(8, true), mtime = view.getFloat64(16, true), ctime = view.getFloat64(24, true), uid = view.getUint32(32, true), gid = view.getUint32(36, true);\n return new Stats(mode & S_IFMT, size, mode & ~S_IFMT, atime, mtime, ctime, uid, gid);\n }\n serialize() {\n const data = new Uint8Array(32), view = new DataView(data.buffer);\n view.setUint32(0, this.size, true);\n view.setUint32(4, this.mode, true);\n view.setFloat64(8, this.atime.getTime(), true);\n view.setFloat64(16, this.mtime.getTime(), true);\n view.setFloat64(24, this.ctime.getTime(), true);\n view.setUint32(32, this.uid, true);\n view.setUint32(36, this.gid, true);\n return data;\n }\n}\nStats;\n/**\n * Stats with bigint\n * @todo Implement with bigint instead of wrapping Stats\n */\nexport class BigIntStats extends StatsCommon {\n constructor() {\n super(...arguments);\n this._isBigint = true;\n }\n /**\n * Clone a stats object.\n */\n static clone(s) {\n return new BigIntStats(Number(s.mode) & S_IFMT, BigInt(s.size), BigInt(s.mode) & BigInt(~S_IFMT), BigInt(s.atimeMs), BigInt(s.mtimeMs), BigInt(s.ctimeMs), BigInt(s.uid), BigInt(s.gid), BigInt(s.birthtimeMs));\n }\n static Deserialize(data) {\n const view = new DataView('buffer' in data ? data.buffer : data);\n const size = view.getBigUint64(0, true), mode = view.getBigUint64(4, true), atime = view.getFloat64(8, true), mtime = view.getFloat64(16, true), ctime = view.getFloat64(24, true), uid = view.getBigUint64(32, true), gid = view.getBigUint64(36, true);\n return new Stats(Number(mode) & S_IFMT, size, mode & BigInt(~S_IFMT), atime, mtime, ctime, uid, gid);\n }\n serialize() {\n const data = new Uint8Array(32), view = new DataView(data.buffer);\n view.setBigUint64(0, this.size, true);\n view.setBigUint64(4, this.mode, true);\n view.setFloat64(8, this.atime.getTime(), true);\n view.setFloat64(16, this.mtime.getTime(), true);\n view.setFloat64(24, this.ctime.getTime(), true);\n view.setBigUint64(32, this.uid, true);\n view.setBigUint64(36, this.gid, true);\n return data;\n }\n}\nBigIntStats;\n", "/* eslint-disable @typescript-eslint/no-unused-vars */\n// disable no-unused-vars since BaseFileSystem uses them a lot\nvar _a;\nimport { ApiError, ErrorCode } from './ApiError.js';\nimport { FileFlag, ActionType } from './file.js';\nimport * as path from './emulation/path.js';\nimport { encode } from './utils.js';\n/**\n * Structure for a filesystem. **All** BrowserFS FileSystems must implement\n * this.\n *\n * ### Argument Assumptions\n *\n * You can assume the following about arguments passed to each API method:\n *\n * - Every path is an absolute path. `.`, `..`, and other items\n * are resolved into an absolute form.\n * - All arguments are present. Any optional arguments at the Node API level\n * have been passed in with their default values.\n */\nexport class FileSystem {\n constructor(options) {\n // unused\n }\n}\n/**\n * Basic filesystem class. Most filesystems should extend this class, as it\n * provides default implementations for a handful of methods.\n */\nexport class BaseFileSystem extends FileSystem {\n constructor(options) {\n super();\n this._ready = Promise.resolve(this);\n }\n get metadata() {\n return {\n name: this.constructor.name,\n readonly: false,\n synchronous: false,\n supportsProperties: false,\n supportsLinks: false,\n totalSpace: 0,\n freeSpace: 0,\n };\n }\n whenReady() {\n return this._ready;\n }\n /**\n * Opens the file at path p with the given flag. The file must exist.\n * @param p The path to open.\n * @param flag The flag to use when opening the file.\n */\n async openFile(p, flag, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n /**\n * Create the file at path p with the given mode. Then, open it with the given\n * flag.\n */\n async createFile(p, flag, mode, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async open(p, flag, mode, cred) {\n try {\n const stats = await this.stat(p, cred);\n switch (flag.pathExistsAction()) {\n case ActionType.THROW_EXCEPTION:\n throw ApiError.EEXIST(p);\n case ActionType.TRUNCATE_FILE:\n // NOTE: In a previous implementation, we deleted the file and\n // re-created it. However, this created a race condition if another\n // asynchronous request was trying to read the file, as the file\n // would not exist for a small period of time.\n const fd = await this.openFile(p, flag, cred);\n if (!fd)\n throw new Error('BFS has reached an impossible code path; please file a bug.');\n await fd.truncate(0);\n await fd.sync();\n return fd;\n case ActionType.NOP:\n return this.openFile(p, flag, cred);\n default:\n throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');\n }\n // File exists.\n }\n catch (e) {\n // File does not exist.\n switch (flag.pathNotExistsAction()) {\n case ActionType.CREATE_FILE:\n // Ensure parent exists.\n const parentStats = await this.stat(path.dirname(p), cred);\n if (parentStats && !parentStats.isDirectory()) {\n throw ApiError.ENOTDIR(path.dirname(p));\n }\n return this.createFile(p, flag, mode, cred);\n case ActionType.THROW_EXCEPTION:\n throw ApiError.ENOENT(p);\n default:\n throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');\n }\n }\n }\n async access(p, mode, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n accessSync(p, mode, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async rename(oldPath, newPath, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n renameSync(oldPath, newPath, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async stat(p, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n statSync(p, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n /**\n * Opens the file at path p with the given flag. The file must exist.\n * @param p The path to open.\n * @param flag The flag to use when opening the file.\n * @return A File object corresponding to the opened file.\n */\n openFileSync(p, flag, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n /**\n * Create the file at path p with the given mode. Then, open it with the given\n * flag.\n */\n createFileSync(p, flag, mode, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n openSync(p, flag, mode, cred) {\n // Check if the path exists, and is a file.\n let stats;\n try {\n stats = this.statSync(p, cred);\n }\n catch (e) {\n // File does not exist.\n switch (flag.pathNotExistsAction()) {\n case ActionType.CREATE_FILE:\n // Ensure parent exists.\n const parentStats = this.statSync(path.dirname(p), cred);\n if (!parentStats.isDirectory()) {\n throw ApiError.ENOTDIR(path.dirname(p));\n }\n return this.createFileSync(p, flag, mode, cred);\n case ActionType.THROW_EXCEPTION:\n throw ApiError.ENOENT(p);\n default:\n throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');\n }\n }\n if (!stats.hasAccess(mode, cred)) {\n throw ApiError.EACCES(p);\n }\n // File exists.\n switch (flag.pathExistsAction()) {\n case ActionType.THROW_EXCEPTION:\n throw ApiError.EEXIST(p);\n case ActionType.TRUNCATE_FILE:\n // Delete file.\n this.unlinkSync(p, cred);\n // Create file. Use the same mode as the old file.\n // Node itself modifies the ctime when this occurs, so this action\n // will preserve that behavior if the underlying file system\n // supports those properties.\n return this.createFileSync(p, flag, stats.mode, cred);\n case ActionType.NOP:\n return this.openFileSync(p, flag, cred);\n default:\n throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');\n }\n }\n async unlink(p, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n unlinkSync(p, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async rmdir(p, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n rmdirSync(p, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async mkdir(p, mode, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n mkdirSync(p, mode, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async readdir(p, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n readdirSync(p, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async exists(p, cred) {\n try {\n await this.stat(p, cred);\n return true;\n }\n catch (e) {\n return false;\n }\n }\n existsSync(p, cred) {\n try {\n this.statSync(p, cred);\n return true;\n }\n catch (e) {\n return false;\n }\n }\n async realpath(p, cred) {\n if (this.metadata.supportsLinks) {\n // The path could contain symlinks. Split up the path,\n // resolve any symlinks, return the resolved string.\n const splitPath = p.split(path.sep);\n // TODO: Simpler to just pass through file, find sep and such.\n for (let i = 0; i < splitPath.length; i++) {\n const addPaths = splitPath.slice(0, i + 1);\n splitPath[i] = path.join(...addPaths);\n }\n return splitPath.join(path.sep);\n }\n else {\n // No symlinks. We just need to verify that it exists.\n if (!(await this.exists(p, cred))) {\n throw ApiError.ENOENT(p);\n }\n return p;\n }\n }\n realpathSync(p, cred) {\n if (this.metadata.supportsLinks) {\n // The path could contain symlinks. Split up the path,\n // resolve any symlinks, return the resolved string.\n const splitPath = p.split(path.sep);\n // TODO: Simpler to just pass through file, find sep and such.\n for (let i = 0; i < splitPath.length; i++) {\n const addPaths = splitPath.slice(0, i + 1);\n splitPath[i] = path.join(...addPaths);\n }\n return splitPath.join(path.sep);\n }\n else {\n // No symlinks. We just need to verify that it exists.\n if (this.existsSync(p, cred)) {\n return p;\n }\n else {\n throw ApiError.ENOENT(p);\n }\n }\n }\n async truncate(p, len, cred) {\n const fd = await this.open(p, FileFlag.getFileFlag('r+'), 0o644, cred);\n try {\n await fd.truncate(len);\n }\n finally {\n await fd.close();\n }\n }\n truncateSync(p, len, cred) {\n const fd = this.openSync(p, FileFlag.getFileFlag('r+'), 0o644, cred);\n // Need to safely close FD, regardless of whether or not truncate succeeds.\n try {\n fd.truncateSync(len);\n }\n finally {\n fd.closeSync();\n }\n }\n async readFile(fname, flag, cred) {\n // Get file.\n const fd = await this.open(fname, flag, 0o644, cred);\n try {\n const stat = await fd.stat();\n // Allocate buffer.\n const buf = new Uint8Array(stat.size);\n await fd.read(buf, 0, stat.size, 0);\n await fd.close();\n return buf;\n }\n finally {\n await fd.close();\n }\n }\n readFileSync(fname, flag, cred) {\n // Get file.\n const fd = this.openSync(fname, flag, 0o644, cred);\n try {\n const stat = fd.statSync();\n // Allocate buffer.\n const buf = new Uint8Array(stat.size);\n fd.readSync(buf, 0, stat.size, 0);\n fd.closeSync();\n return buf;\n }\n finally {\n fd.closeSync();\n }\n }\n async writeFile(fname, data, flag, mode, cred) {\n // Get file.\n const fd = await this.open(fname, flag, mode, cred);\n try {\n if (typeof data === 'string') {\n data = encode(data);\n }\n // Write into file.\n await fd.write(data, 0, data.length, 0);\n }\n finally {\n await fd.close();\n }\n }\n writeFileSync(fname, data, flag, mode, cred) {\n // Get file.\n const fd = this.openSync(fname, flag, mode, cred);\n try {\n if (typeof data === 'string') {\n data = encode(data);\n }\n // Write into file.\n fd.writeSync(data, 0, data.length, 0);\n }\n finally {\n fd.closeSync();\n }\n }\n async appendFile(fname, data, flag, mode, cred) {\n const fd = await this.open(fname, flag, mode, cred);\n try {\n if (typeof data === 'string') {\n data = encode(data);\n }\n await fd.write(data, 0, data.length, null);\n }\n finally {\n await fd.close();\n }\n }\n appendFileSync(fname, data, flag, mode, cred) {\n const fd = this.openSync(fname, flag, mode, cred);\n try {\n if (typeof data === 'string') {\n data = encode(data);\n }\n fd.writeSync(data, 0, data.length, null);\n }\n finally {\n fd.closeSync();\n }\n }\n async chmod(p, mode, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n chmodSync(p, mode, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async chown(p, new_uid, new_gid, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n chownSync(p, new_uid, new_gid, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async utimes(p, atime, mtime, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n utimesSync(p, atime, mtime, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async link(srcpath, dstpath, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n linkSync(srcpath, dstpath, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async symlink(srcpath, dstpath, type, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n symlinkSync(srcpath, dstpath, type, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async readlink(p, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n readlinkSync(p, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n}\n_a = BaseFileSystem;\nBaseFileSystem.Name = _a.name;\n/**\n * Implements the asynchronous API in terms of the synchronous API.\n */\nexport class SynchronousFileSystem extends BaseFileSystem {\n get metadata() {\n return { ...super.metadata, synchronous: true };\n }\n async access(p, mode, cred) {\n return this.accessSync(p, mode, cred);\n }\n async rename(oldPath, newPath, cred) {\n return this.renameSync(oldPath, newPath, cred);\n }\n async stat(p, cred) {\n return this.statSync(p, cred);\n }\n async open(p, flags, mode, cred) {\n return this.openSync(p, flags, mode, cred);\n }\n async unlink(p, cred) {\n return this.unlinkSync(p, cred);\n }\n async rmdir(p, cred) {\n return this.rmdirSync(p, cred);\n }\n async mkdir(p, mode, cred) {\n return this.mkdirSync(p, mode, cred);\n }\n async readdir(p, cred) {\n return this.readdirSync(p, cred);\n }\n async chmod(p, mode, cred) {\n return this.chmodSync(p, mode, cred);\n }\n async chown(p, new_uid, new_gid, cred) {\n return this.chownSync(p, new_uid, new_gid, cred);\n }\n async utimes(p, atime, mtime, cred) {\n return this.utimesSync(p, atime, mtime, cred);\n }\n async link(srcpath, dstpath, cred) {\n return this.linkSync(srcpath, dstpath, cred);\n }\n async symlink(srcpath, dstpath, type, cred) {\n return this.symlinkSync(srcpath, dstpath, type, cred);\n }\n async readlink(p, cred) {\n return this.readlinkSync(p, cred);\n }\n}\n", "import { Stats, FileType } from './stats.js';\nimport { decode, encode } from './utils.js';\n/**\n * Generic inode definition that can easily be serialized.\n */\nexport default class Inode {\n /**\n * Converts the buffer into an Inode.\n */\n static Deserialize(data) {\n const view = new DataView('buffer' in data ? data.buffer : data);\n return new Inode(decode(view.buffer.slice(38)), view.getUint32(0, true), view.getUint16(4, true), view.getFloat64(6, true), view.getFloat64(14, true), view.getFloat64(22, true), view.getUint32(30, true), view.getUint32(34, true));\n }\n constructor(id, size, mode, atime, mtime, ctime, uid, gid) {\n this.id = id;\n this.size = size;\n this.mode = mode;\n this.atime = atime;\n this.mtime = mtime;\n this.ctime = ctime;\n this.uid = uid;\n this.gid = gid;\n }\n /**\n * Handy function that converts the Inode to a Node Stats object.\n */\n toStats() {\n return new Stats((this.mode & 0xf000) === FileType.DIRECTORY ? FileType.DIRECTORY : FileType.FILE, this.size, this.mode, this.atime, this.mtime, this.ctime, this.uid, this.gid);\n }\n /**\n * Get the size of this Inode, in bytes.\n */\n getSize() {\n // ASSUMPTION: ID is 1 byte per char.\n return 38 + this.id.length;\n }\n /**\n * Writes the inode into the start of the buffer.\n */\n serialize(data = new Uint8Array(this.getSize())) {\n const view = new DataView('buffer' in data ? data.buffer : data);\n view.setUint32(0, this.size, true);\n view.setUint16(4, this.mode, true);\n view.setFloat64(6, this.atime, true);\n view.setFloat64(14, this.mtime, true);\n view.setFloat64(22, this.ctime, true);\n view.setUint32(30, this.uid, true);\n view.setUint32(34, this.gid, true);\n const buffer = new Uint8Array(view.buffer);\n buffer.set(encode(this.id), 38);\n return buffer;\n }\n /**\n * Updates the Inode using information from the stats object. Used by file\n * systems at sync time, e.g.:\n * - Program opens file and gets a File object.\n * - Program mutates file. File object is responsible for maintaining\n * metadata changes locally -- typically in a Stats object.\n * - Program closes file. File object's metadata changes are synced with the\n * file system.\n * @return True if any changes have occurred.\n */\n update(stats) {\n let hasChanged = false;\n if (this.size !== stats.size) {\n this.size = stats.size;\n hasChanged = true;\n }\n if (this.mode !== stats.mode) {\n this.mode = stats.mode;\n hasChanged = true;\n }\n const atimeMs = stats.atime.getTime();\n if (this.atime !== atimeMs) {\n this.atime = atimeMs;\n hasChanged = true;\n }\n const mtimeMs = stats.mtime.getTime();\n if (this.mtime !== mtimeMs) {\n this.mtime = mtimeMs;\n hasChanged = true;\n }\n const ctimeMs = stats.ctime.getTime();\n if (this.ctime !== ctimeMs) {\n this.ctime = ctimeMs;\n hasChanged = true;\n }\n if (this.uid !== stats.uid) {\n this.uid = stats.uid;\n hasChanged = true;\n }\n if (this.uid !== stats.uid) {\n this.uid = stats.uid;\n hasChanged = true;\n }\n return hasChanged;\n }\n // XXX: Copied from Stats. Should reconcile these two into something more\n // compact.\n /**\n * @return [Boolean] True if this item is a file.\n */\n isFile() {\n return (this.mode & 0xf000) === FileType.FILE;\n }\n /**\n * @return [Boolean] True if this item is a directory.\n */\n isDirectory() {\n return (this.mode & 0xf000) === FileType.DIRECTORY;\n }\n}\n", "import { dirname, basename, join, resolve, sep } from '../emulation/path.js';\nimport { ApiError, ErrorCode } from '../ApiError.js';\nimport { W_OK, R_OK } from '../emulation/constants.js';\nimport { FileFlag, PreloadFile } from '../file.js';\nimport { SynchronousFileSystem } from '../filesystem.js';\nimport Inode from '../inode.js';\nimport { FileType } from '../stats.js';\nimport { decode, encode, randomUUID, ROOT_NODE_ID } from '../utils.js';\n/**\n * A simple RW transaction for simple synchronous key-value stores.\n */\nexport class SimpleSyncRWTransaction {\n constructor(store) {\n this.store = store;\n /**\n * Stores data in the keys we modify prior to modifying them.\n * Allows us to roll back commits.\n */\n this.originalData = {};\n /**\n * List of keys modified in this transaction, if any.\n */\n this.modifiedKeys = [];\n }\n get(key) {\n const val = this.store.get(key);\n this.stashOldValue(key, val);\n return val;\n }\n put(key, data, overwrite) {\n this.markModified(key);\n return this.store.put(key, data, overwrite);\n }\n del(key) {\n this.markModified(key);\n this.store.del(key);\n }\n commit() {\n /* NOP */\n }\n abort() {\n // Rollback old values.\n for (const key of this.modifiedKeys) {\n const value = this.originalData[key];\n if (!value) {\n // Key didn't exist.\n this.store.del(key);\n }\n else {\n // Key existed. Store old value.\n this.store.put(key, value, true);\n }\n }\n }\n _has(key) {\n return Object.prototype.hasOwnProperty.call(this.originalData, key);\n }\n /**\n * Stashes given key value pair into `originalData` if it doesn't already\n * exist. Allows us to stash values the program is requesting anyway to\n * prevent needless `get` requests if the program modifies the data later\n * on during the transaction.\n */\n stashOldValue(key, value) {\n // Keep only the earliest value in the transaction.\n if (!this._has(key)) {\n this.originalData[key] = value;\n }\n }\n /**\n * Marks the given key as modified, and stashes its value if it has not been\n * stashed already.\n */\n markModified(key) {\n if (this.modifiedKeys.indexOf(key) === -1) {\n this.modifiedKeys.push(key);\n if (!this._has(key)) {\n this.originalData[key] = this.store.get(key);\n }\n }\n }\n}\nexport class SyncKeyValueFile extends PreloadFile {\n constructor(_fs, _path, _flag, _stat, contents) {\n super(_fs, _path, _flag, _stat, contents);\n }\n syncSync() {\n if (this.isDirty()) {\n this._fs._syncSync(this.getPath(), this.getBuffer(), this.getStats());\n this.resetDirty();\n }\n }\n closeSync() {\n this.syncSync();\n }\n}\n/**\n * A \"Synchronous key-value file system\". Stores data to/retrieves data from an\n * underlying key-value store.\n *\n * We use a unique ID for each node in the file system. The root node has a\n * fixed ID.\n * @todo Introduce Node ID caching.\n * @todo Check modes.\n */\nexport class SyncKeyValueFileSystem extends SynchronousFileSystem {\n static isAvailable() {\n return true;\n }\n constructor(options) {\n super();\n this.store = options.store;\n // INVARIANT: Ensure that the root exists.\n this.makeRootDirectory();\n }\n getName() {\n return this.store.name();\n }\n isReadOnly() {\n return false;\n }\n supportsSymlinks() {\n return false;\n }\n supportsProps() {\n return true;\n }\n supportsSynch() {\n return true;\n }\n /**\n * Delete all contents stored in the file system.\n */\n empty() {\n this.store.clear();\n // INVARIANT: Root always exists.\n this.makeRootDirectory();\n }\n accessSync(p, mode, cred) {\n const tx = this.store.beginTransaction('readonly'), node = this.findINode(tx, p);\n if (!node.toStats().hasAccess(mode, cred)) {\n throw ApiError.EACCES(p);\n }\n }\n renameSync(oldPath, newPath, cred) {\n const tx = this.store.beginTransaction('readwrite'), oldParent = dirname(oldPath), oldName = basename(oldPath), newParent = dirname(newPath), newName = basename(newPath), \n // Remove oldPath from parent's directory listing.\n oldDirNode = this.findINode(tx, oldParent), oldDirList = this.getDirListing(tx, oldParent, oldDirNode);\n if (!oldDirNode.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(oldPath);\n }\n if (!oldDirList[oldName]) {\n throw ApiError.ENOENT(oldPath);\n }\n const nodeId = oldDirList[oldName];\n delete oldDirList[oldName];\n // Invariant: Can't move a folder inside itself.\n // This funny little hack ensures that the check passes only if oldPath\n // is a subpath of newParent. We append '/' to avoid matching folders that\n // are a substring of the bottom-most folder in the path.\n if ((newParent + '/').indexOf(oldPath + '/') === 0) {\n throw new ApiError(ErrorCode.EBUSY, oldParent);\n }\n // Add newPath to parent's directory listing.\n let newDirNode, newDirList;\n if (newParent === oldParent) {\n // Prevent us from re-grabbing the same directory listing, which still\n // contains oldName.\n newDirNode = oldDirNode;\n newDirList = oldDirList;\n }\n else {\n newDirNode = this.findINode(tx, newParent);\n newDirList = this.getDirListing(tx, newParent, newDirNode);\n }\n if (newDirList[newName]) {\n // If it's a file, delete it.\n const newNameNode = this.getINode(tx, newPath, newDirList[newName]);\n if (newNameNode.isFile()) {\n try {\n tx.del(newNameNode.id);\n tx.del(newDirList[newName]);\n }\n catch (e) {\n tx.abort();\n throw e;\n }\n }\n else {\n // If it's a directory, throw a permissions error.\n throw ApiError.EPERM(newPath);\n }\n }\n newDirList[newName] = nodeId;\n // Commit the two changed directory listings.\n try {\n tx.put(oldDirNode.id, encode(JSON.stringify(oldDirList)), true);\n tx.put(newDirNode.id, encode(JSON.stringify(newDirList)), true);\n }\n catch (e) {\n tx.abort();\n throw e;\n }\n tx.commit();\n }\n statSync(p, cred) {\n // Get the inode to the item, convert it into a Stats object.\n const stats = this.findINode(this.store.beginTransaction('readonly'), p).toStats();\n if (!stats.hasAccess(R_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n return stats;\n }\n createFileSync(p, flag, mode, cred) {\n const tx = this.store.beginTransaction('readwrite'), data = new Uint8Array(0), newFile = this.commitNewFile(tx, p, FileType.FILE, mode, cred, data);\n // Open the file.\n return new SyncKeyValueFile(this, p, flag, newFile.toStats(), data);\n }\n openFileSync(p, flag, cred) {\n const tx = this.store.beginTransaction('readonly'), node = this.findINode(tx, p), data = tx.get(node.id);\n if (!node.toStats().hasAccess(flag.getMode(), cred)) {\n throw ApiError.EACCES(p);\n }\n if (data === undefined) {\n throw ApiError.ENOENT(p);\n }\n return new SyncKeyValueFile(this, p, flag, node.toStats(), data);\n }\n unlinkSync(p, cred) {\n this.removeEntry(p, false, cred);\n }\n rmdirSync(p, cred) {\n // Check first if directory is empty.\n if (this.readdirSync(p, cred).length > 0) {\n throw ApiError.ENOTEMPTY(p);\n }\n else {\n this.removeEntry(p, true, cred);\n }\n }\n mkdirSync(p, mode, cred) {\n const tx = this.store.beginTransaction('readwrite'), data = encode('{}');\n this.commitNewFile(tx, p, FileType.DIRECTORY, mode, cred, data);\n }\n readdirSync(p, cred) {\n const tx = this.store.beginTransaction('readonly');\n const node = this.findINode(tx, p);\n if (!node.toStats().hasAccess(R_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n return Object.keys(this.getDirListing(tx, p, node));\n }\n chmodSync(p, mode, cred) {\n const fd = this.openFileSync(p, FileFlag.getFileFlag('r+'), cred);\n fd.chmodSync(mode);\n }\n chownSync(p, new_uid, new_gid, cred) {\n const fd = this.openFileSync(p, FileFlag.getFileFlag('r+'), cred);\n fd.chownSync(new_uid, new_gid);\n }\n _syncSync(p, data, stats) {\n // @todo Ensure mtime updates properly, and use that to determine if a data\n // update is required.\n const tx = this.store.beginTransaction('readwrite'), \n // We use the _findInode helper because we actually need the INode id.\n fileInodeId = this._findINode(tx, dirname(p), basename(p)), fileInode = this.getINode(tx, p, fileInodeId), inodeChanged = fileInode.update(stats);\n try {\n // Sync data.\n tx.put(fileInode.id, data, true);\n // Sync metadata.\n if (inodeChanged) {\n tx.put(fileInodeId, fileInode.serialize(), true);\n }\n }\n catch (e) {\n tx.abort();\n throw e;\n }\n tx.commit();\n }\n /**\n * Checks if the root directory exists. Creates it if it doesn't.\n */\n makeRootDirectory() {\n const tx = this.store.beginTransaction('readwrite');\n if (tx.get(ROOT_NODE_ID) === undefined) {\n // Create new inode.\n const currTime = new Date().getTime(), \n // Mode 0666, owned by root:root\n dirInode = new Inode(randomUUID(), 4096, 511 | FileType.DIRECTORY, currTime, currTime, currTime, 0, 0);\n // If the root doesn't exist, the first random ID shouldn't exist,\n // either.\n tx.put(dirInode.id, encode('{}'), false);\n tx.put(ROOT_NODE_ID, dirInode.serialize(), false);\n tx.commit();\n }\n }\n /**\n * Helper function for findINode.\n * @param parent The parent directory of the file we are attempting to find.\n * @param filename The filename of the inode we are attempting to find, minus\n * the parent.\n * @return string The ID of the file's inode in the file system.\n */\n _findINode(tx, parent, filename, visited = new Set()) {\n const currentPath = join(parent, filename);\n if (visited.has(currentPath)) {\n throw new ApiError(ErrorCode.EIO, 'Infinite loop detected while finding inode', currentPath);\n }\n visited.add(currentPath);\n const readDirectory = (inode) => {\n // Get the root's directory listing.\n const dirList = this.getDirListing(tx, parent, inode);\n // Get the file's ID.\n if (dirList[filename]) {\n return dirList[filename];\n }\n else {\n throw ApiError.ENOENT(resolve(parent, filename));\n }\n };\n if (parent === '/') {\n if (filename === '') {\n // Return the root's ID.\n return ROOT_NODE_ID;\n }\n else {\n // Find the item in the root node.\n return readDirectory(this.getINode(tx, parent, ROOT_NODE_ID));\n }\n }\n else {\n return readDirectory(this.getINode(tx, parent + sep + filename, this._findINode(tx, dirname(parent), basename(parent), visited)));\n }\n }\n /**\n * Finds the Inode of the given path.\n * @param p The path to look up.\n * @return The Inode of the path p.\n * @todo memoize/cache\n */\n findINode(tx, p) {\n return this.getINode(tx, p, this._findINode(tx, dirname(p), basename(p)));\n }\n /**\n * Given the ID of a node, retrieves the corresponding Inode.\n * @param tx The transaction to use.\n * @param p The corresponding path to the file (used for error messages).\n * @param id The ID to look up.\n */\n getINode(tx, p, id) {\n const inode = tx.get(id);\n if (inode === undefined) {\n throw ApiError.ENOENT(p);\n }\n return Inode.Deserialize(inode);\n }\n /**\n * Given the Inode of a directory, retrieves the corresponding directory\n * listing.\n */\n getDirListing(tx, p, inode) {\n if (!inode.isDirectory()) {\n throw ApiError.ENOTDIR(p);\n }\n const data = tx.get(inode.id);\n if (data === undefined) {\n throw ApiError.ENOENT(p);\n }\n return JSON.parse(decode(data));\n }\n /**\n * Creates a new node under a random ID. Retries 5 times before giving up in\n * the exceedingly unlikely chance that we try to reuse a random GUID.\n * @return The GUID that the data was stored under.\n */\n addNewNode(tx, data) {\n const retries = 0;\n let currId;\n while (retries < 5) {\n try {\n currId = randomUUID();\n tx.put(currId, data, false);\n return currId;\n }\n catch (e) {\n // Ignore and reroll.\n }\n }\n throw new ApiError(ErrorCode.EIO, 'Unable to commit data to key-value store.');\n }\n /**\n * Commits a new file (well, a FILE or a DIRECTORY) to the file system with\n * the given mode.\n * Note: This will commit the transaction.\n * @param p The path to the new file.\n * @param type The type of the new file.\n * @param mode The mode to create the new file with.\n * @param data The data to store at the file's data node.\n * @return The Inode for the new file.\n */\n commitNewFile(tx, p, type, mode, cred, data) {\n const parentDir = dirname(p), fname = basename(p), parentNode = this.findINode(tx, parentDir), dirListing = this.getDirListing(tx, parentDir, parentNode), currTime = new Date().getTime();\n //Check that the creater has correct access\n if (!parentNode.toStats().hasAccess(0b0100 /* Write */, cred)) {\n throw ApiError.EACCES(p);\n }\n // Invariant: The root always exists.\n // If we don't check this prior to taking steps below, we will create a\n // file with name '' in root should p == '/'.\n if (p === '/') {\n throw ApiError.EEXIST(p);\n }\n // Check if file already exists.\n if (dirListing[fname]) {\n throw ApiError.EEXIST(p);\n }\n let fileNode;\n try {\n // Commit data.\n const dataId = this.addNewNode(tx, data);\n fileNode = new Inode(dataId, data.length, mode | type, currTime, currTime, currTime, cred.uid, cred.gid);\n // Commit file node.\n const fileNodeId = this.addNewNode(tx, fileNode.serialize());\n // Update and commit parent directory listing.\n dirListing[fname] = fileNodeId;\n tx.put(parentNode.id, encode(JSON.stringify(dirListing)), true);\n }\n catch (e) {\n tx.abort();\n throw e;\n }\n tx.commit();\n return fileNode;\n }\n /**\n * Remove all traces of the given path from the file system.\n * @param p The path to remove from the file system.\n * @param isDir Does the path belong to a directory, or a file?\n * @todo Update mtime.\n */\n removeEntry(p, isDir, cred) {\n const tx = this.store.beginTransaction('readwrite'), parent = dirname(p), parentNode = this.findINode(tx, parent), parentListing = this.getDirListing(tx, parent, parentNode), fileName = basename(p);\n if (!parentListing[fileName]) {\n throw ApiError.ENOENT(p);\n }\n const fileNodeId = parentListing[fileName];\n // Get file inode.\n const fileNode = this.getINode(tx, p, fileNodeId);\n if (!fileNode.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n // Remove from directory listing of parent.\n delete parentListing[fileName];\n if (!isDir && fileNode.isDirectory()) {\n throw ApiError.EISDIR(p);\n }\n else if (isDir && !fileNode.isDirectory()) {\n throw ApiError.ENOTDIR(p);\n }\n try {\n // Delete data.\n tx.del(fileNode.id);\n // Delete node.\n tx.del(fileNodeId);\n // Update directory listing.\n tx.put(parentNode.id, encode(JSON.stringify(parentListing)), true);\n }\n catch (e) {\n tx.abort();\n throw e;\n }\n // Success.\n tx.commit();\n }\n}\n", "import { checkOptions } from '../utils.js';\nexport function CreateBackend(options, cb) {\n cb = typeof options === 'function' ? options : cb;\n checkOptions(this, options);\n const fs = new this(typeof options === 'function' ? {} : options);\n // Promise\n if (typeof cb != 'function') {\n return fs.whenReady();\n }\n // Callback\n fs.whenReady()\n .then(fs => cb(null, fs))\n .catch(err => cb(err));\n}\n", "var _a;\nimport { SimpleSyncRWTransaction, SyncKeyValueFileSystem } from './SyncStore.js';\nimport { CreateBackend } from './backend.js';\n/**\n * A simple in-memory key-value store backed by a JavaScript object.\n */\nexport class InMemoryStore {\n constructor() {\n this.store = new Map();\n }\n name() {\n return InMemoryFileSystem.Name;\n }\n clear() {\n this.store.clear();\n }\n beginTransaction(type) {\n return new SimpleSyncRWTransaction(this);\n }\n get(key) {\n return this.store.get(key);\n }\n put(key, data, overwrite) {\n if (!overwrite && this.store.has(key)) {\n return false;\n }\n this.store.set(key, data);\n return true;\n }\n del(key) {\n this.store.delete(key);\n }\n}\n/**\n * A simple in-memory file system backed by an InMemoryStore.\n * Files are not persisted across page loads.\n */\nexport class InMemoryFileSystem extends SyncKeyValueFileSystem {\n constructor() {\n super({ store: new InMemoryStore() });\n }\n}\n_a = InMemoryFileSystem;\nInMemoryFileSystem.Name = 'InMemory';\nInMemoryFileSystem.Create = CreateBackend.bind(_a);\nInMemoryFileSystem.Options = {};\n", "// Utilities and shared data\nimport { resolve } from './path.js';\nimport { ApiError, ErrorCode } from '../ApiError.js';\nimport { Cred } from '../cred.js';\nimport { InMemoryFileSystem } from '../backends/InMemory.js';\n/**\n * converts Date or number to a fractional UNIX timestamp\n * Grabbed from NodeJS sources (lib/fs.js)\n */\nexport function _toUnixTimestamp(time) {\n if (typeof time === 'number') {\n return time;\n }\n else if (time instanceof Date) {\n return time.getTime() / 1000;\n }\n throw new Error('Cannot parse time: ' + time);\n}\nexport function normalizeMode(mode, def) {\n switch (typeof mode) {\n case 'number':\n // (path, flag, mode, cb?)\n return mode;\n case 'string':\n // (path, flag, modeString, cb?)\n const trueMode = parseInt(mode, 8);\n if (!isNaN(trueMode)) {\n return trueMode;\n }\n // Invalid string.\n return def;\n default:\n return def;\n }\n}\nexport function normalizeTime(time) {\n if (time instanceof Date) {\n return time;\n }\n if (typeof time === 'number') {\n return new Date(time * 1000);\n }\n throw new ApiError(ErrorCode.EINVAL, `Invalid time.`);\n}\nexport function normalizePath(p) {\n // Node doesn't allow null characters in paths.\n if (p.indexOf('\\u0000') >= 0) {\n throw new ApiError(ErrorCode.EINVAL, 'Path must be a string without null bytes.');\n }\n if (p === '') {\n throw new ApiError(ErrorCode.EINVAL, 'Path must not be empty.');\n }\n p = p.replaceAll(/\\/+/g, '/');\n return resolve(p);\n}\nexport function normalizeOptions(options, defEnc, defFlag, defMode) {\n // typeof null === 'object' so special-case handing is needed.\n switch (options === null ? 'null' : typeof options) {\n case 'object':\n return {\n encoding: typeof options['encoding'] !== 'undefined' ? options['encoding'] : defEnc,\n flag: typeof options['flag'] !== 'undefined' ? options['flag'] : defFlag,\n mode: normalizeMode(options['mode'], defMode),\n };\n case 'string':\n return {\n encoding: options,\n flag: defFlag,\n mode: defMode,\n };\n case 'null':\n case 'undefined':\n case 'function':\n return {\n encoding: defEnc,\n flag: defFlag,\n mode: defMode,\n };\n default:\n throw new TypeError(`\"options\" must be a string or an object, got ${typeof options} instead.`);\n }\n}\nexport function nop() {\n // do nothing\n}\n// credentials\nexport let cred = Cred.Root;\nexport function setCred(val) {\n cred = val;\n}\n// descriptors\nexport const fdMap = new Map();\nlet nextFd = 100;\nexport function getFdForFile(file) {\n const fd = nextFd++;\n fdMap.set(fd, file);\n return fd;\n}\nexport function fd2file(fd) {\n if (!fdMap.has(fd)) {\n throw new ApiError(ErrorCode.EBADF, 'Invalid file descriptor.');\n }\n return fdMap.get(fd);\n}\nexport const mounts = new Map();\n/*\nSet a default root.\nThere is a very small but not 0 change that initialize() will try to unmount the default before it is mounted.\nThis can be fixed by using a top-level await, which is not done to maintain ES6 compatibility.\n*/\nInMemoryFileSystem.Create().then(fs => mount('/', fs));\n/**\n * Gets the file system mounted at `mountPoint`\n */\nexport function getMount(mountPoint) {\n return mounts.get(mountPoint);\n}\n/**\n * Gets an object of mount points (keys) and filesystems (values)\n */\nexport function getMounts() {\n return Object.fromEntries(mounts.entries());\n}\n/**\n * Mounts the file system at the given mount point.\n */\nexport function mount(mountPoint, fs) {\n if (mountPoint[0] !== '/') {\n mountPoint = '/' + mountPoint;\n }\n mountPoint = resolve(mountPoint);\n if (mounts.has(mountPoint)) {\n throw new ApiError(ErrorCode.EINVAL, 'Mount point ' + mountPoint + ' is already in use.');\n }\n mounts.set(mountPoint, fs);\n}\n/**\n * Unmounts the file system at the given mount point.\n */\nexport function umount(mountPoint) {\n if (mountPoint[0] !== '/') {\n mountPoint = `/${mountPoint}`;\n }\n mountPoint = resolve(mountPoint);\n if (!mounts.has(mountPoint)) {\n throw new ApiError(ErrorCode.EINVAL, 'Mount point ' + mountPoint + ' is already unmounted.');\n }\n mounts.delete(mountPoint);\n}\n/**\n * Gets the internal FileSystem for the path, then returns it along with the path relative to the FS' root\n */\nexport function resolveFS(path) {\n const sortedMounts = [...mounts].sort((a, b) => (a[0].length > b[0].length ? -1 : 1)); // decending order of the string length\n for (const [mountPoint, fs] of sortedMounts) {\n // We know path is normalized, so it would be a substring of the mount point.\n if (mountPoint.length <= path.length && path.startsWith(mountPoint)) {\n path = path.slice(mountPoint.length > 1 ? mountPoint.length : 0); // Resolve the path relative to the mount point\n if (path === '') {\n path = '/';\n }\n return { fs, path, mountPoint };\n }\n }\n throw new ApiError(ErrorCode.EIO, 'BrowserFS not initialized with a file system');\n}\n/**\n * Reverse maps the paths in text from the mounted FileSystem to the global path\n */\nexport function fixPaths(text, paths) {\n for (const [from, to] of Object.entries(paths)) {\n text = text?.replaceAll(from, to);\n }\n return text;\n}\nexport function fixError(e, paths) {\n if (typeof e.stack == 'string') {\n e.stack = fixPaths(e.stack, paths);\n }\n e.message = fixPaths(e.message, paths);\n return e;\n}\nexport function initialize(mountMapping) {\n if (mountMapping['/']) {\n umount('/');\n }\n for (const [point, fs] of Object.entries(mountMapping)) {\n const FS = fs.constructor;\n if (!FS.isAvailable()) {\n throw new ApiError(ErrorCode.EINVAL, `Can not mount \"${point}\" since the filesystem is unavailable.`);\n }\n mount(point, fs);\n }\n}\n", "import { ApiError, ErrorCode } from './ApiError.js';\nimport { Stats } from './stats.js';\nimport { getMount } from './emulation/shared.js';\nimport { O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_TRUNC, O_APPEND, O_SYNC } from './emulation/constants.js';\nexport var ActionType;\n(function (ActionType) {\n // Indicates that the code should not do anything.\n ActionType[ActionType[\"NOP\"] = 0] = \"NOP\";\n // Indicates that the code should throw an exception.\n ActionType[ActionType[\"THROW_EXCEPTION\"] = 1] = \"THROW_EXCEPTION\";\n // Indicates that the code should truncate the file, but only if it is a file.\n ActionType[ActionType[\"TRUNCATE_FILE\"] = 2] = \"TRUNCATE_FILE\";\n // Indicates that the code should create the file.\n ActionType[ActionType[\"CREATE_FILE\"] = 3] = \"CREATE_FILE\";\n})(ActionType = ActionType || (ActionType = {}));\n/**\n * Represents one of the following file flags. A convenience object.\n *\n * * `'r'` - Open file for reading. An exception occurs if the file does not exist.\n * * `'r+'` - Open file for reading and writing. An exception occurs if the file does not exist.\n * * `'rs'` - Open file for reading in synchronous mode. Instructs the filesystem to not cache writes.\n * * `'rs+'` - Open file for reading and writing, and opens the file in synchronous mode.\n * * `'w'` - Open file for writing. The file is created (if it does not exist) or truncated (if it exists).\n * * `'wx'` - Like 'w' but opens the file in exclusive mode.\n * * `'w+'` - Open file for reading and writing. The file is created (if it does not exist) or truncated (if it exists).\n * * `'wx+'` - Like 'w+' but opens the file in exclusive mode.\n * * `'a'` - Open file for appending. The file is created if it does not exist.\n * * `'ax'` - Like 'a' but opens the file in exclusive mode.\n * * `'a+'` - Open file for reading and appending. The file is created if it does not exist.\n * * `'ax+'` - Like 'a+' but opens the file in exclusive mode.\n *\n * Exclusive mode ensures that the file path is newly created.\n */\nexport class FileFlag {\n /**\n * Get an object representing the given file flag.\n * @param flag The string or number representing the flag\n * @return The FileFlag object representing the flag\n * @throw when the flag string is invalid\n */\n static getFileFlag(flag) {\n // Check cache first.\n if (!FileFlag.flagCache.has(flag)) {\n FileFlag.flagCache.set(flag, new FileFlag(flag));\n }\n return FileFlag.flagCache.get(flag);\n }\n /**\n * This should never be called directly.\n * @param flag The string or number representing the flag\n * @throw when the flag is invalid\n */\n constructor(flag) {\n if (typeof flag === 'number') {\n flag = FileFlag.StringFromNumber(flag);\n }\n if (FileFlag.validFlagStrs.indexOf(flag) < 0) {\n throw new ApiError(ErrorCode.EINVAL, 'Invalid flag string: ' + flag);\n }\n this.flagStr = flag;\n }\n /**\n * @param flag The number representing the flag\n * @return The string representing the flag\n * @throw when the flag number is invalid\n */\n static StringFromNumber(flag) {\n // based on https://github.com/nodejs/node/blob/abbdc3efaa455e6c907ebef5409ac8b0f222f969/lib/internal/fs/utils.js#L619\n switch (flag) {\n case O_RDONLY:\n return 'r';\n case O_RDONLY | O_SYNC:\n return 'rs';\n case O_RDWR:\n return 'r+';\n case O_RDWR | O_SYNC:\n return 'rs+';\n case O_TRUNC | O_CREAT | O_WRONLY:\n return 'w';\n case O_TRUNC | O_CREAT | O_WRONLY | O_EXCL:\n return 'wx';\n case O_TRUNC | O_CREAT | O_RDWR:\n return 'w+';\n case O_TRUNC | O_CREAT | O_RDWR | O_EXCL:\n return 'wx+';\n case O_APPEND | O_CREAT | O_WRONLY:\n return 'a';\n case O_APPEND | O_CREAT | O_WRONLY | O_EXCL:\n return 'ax';\n case O_APPEND | O_CREAT | O_RDWR:\n return 'a+';\n case O_APPEND | O_CREAT | O_RDWR | O_EXCL:\n return 'ax+';\n default:\n throw new ApiError(ErrorCode.EINVAL, 'Invalid flag number: ' + flag);\n }\n }\n /**\n * Get the underlying flag string for this flag.\n */\n getFlagString() {\n return this.flagStr;\n }\n /**\n * Get the equivalent mode (0b0xxx: read, write, execute)\n * Note: Execute will always be 0\n */\n getMode() {\n let mode = 0;\n mode <<= 1;\n mode += +this.isReadable();\n mode <<= 1;\n mode += +this.isWriteable();\n mode <<= 1;\n return mode;\n }\n /**\n * Returns true if the file is readable.\n */\n isReadable() {\n return this.flagStr.indexOf('r') !== -1 || this.flagStr.indexOf('+') !== -1;\n }\n /**\n * Returns true if the file is writeable.\n */\n isWriteable() {\n return this.flagStr.indexOf('w') !== -1 || this.flagStr.indexOf('a') !== -1 || this.flagStr.indexOf('+') !== -1;\n }\n /**\n * Returns true if the file mode should truncate.\n */\n isTruncating() {\n return this.flagStr.indexOf('w') !== -1;\n }\n /**\n * Returns true if the file is appendable.\n */\n isAppendable() {\n return this.flagStr.indexOf('a') !== -1;\n }\n /**\n * Returns true if the file is open in synchronous mode.\n */\n isSynchronous() {\n return this.flagStr.indexOf('s') !== -1;\n }\n /**\n * Returns true if the file is open in exclusive mode.\n */\n isExclusive() {\n return this.flagStr.indexOf('x') !== -1;\n }\n /**\n * Returns one of the static fields on this object that indicates the\n * appropriate response to the path existing.\n */\n pathExistsAction() {\n if (this.isExclusive()) {\n return ActionType.THROW_EXCEPTION;\n }\n else if (this.isTruncating()) {\n return ActionType.TRUNCATE_FILE;\n }\n else {\n return ActionType.NOP;\n }\n }\n /**\n * Returns one of the static fields on this object that indicates the\n * appropriate response to the path not existing.\n */\n pathNotExistsAction() {\n if ((this.isWriteable() || this.isAppendable()) && this.flagStr !== 'r+') {\n return ActionType.CREATE_FILE;\n }\n else {\n return ActionType.THROW_EXCEPTION;\n }\n }\n}\n// Contains cached FileMode instances.\nFileFlag.flagCache = new Map();\n// Array of valid mode strings.\nFileFlag.validFlagStrs = ['r', 'r+', 'rs', 'rs+', 'w', 'wx', 'w+', 'wx+', 'a', 'ax', 'a+', 'ax+'];\n/**\n * Base class that contains shared implementations of functions for the file\n * object.\n */\nexport class BaseFile {\n async sync() {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n syncSync() {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async datasync() {\n return this.sync();\n }\n datasyncSync() {\n return this.syncSync();\n }\n async chown(uid, gid) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n chownSync(uid, gid) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async chmod(mode) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n chmodSync(mode) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async utimes(atime, mtime) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n utimesSync(atime, mtime) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n}\n/**\n * An implementation of the File interface that operates on a file that is\n * completely in-memory. PreloadFiles are backed by a Uint8Array.\n *\n * This is also an abstract class, as it lacks an implementation of 'sync' and\n * 'close'. Each filesystem that wishes to use this file representation must\n * extend this class and implement those two methods.\n * @todo 'close' lever that disables functionality once closed.\n */\nexport class PreloadFile extends BaseFile {\n /**\n * Creates a file with the given path and, optionally, the given contents. Note\n * that, if contents is specified, it will be mutated by the file!\n * @param _fs The file system that created the file.\n * @param _path\n * @param _mode The mode that the file was opened using.\n * Dictates permissions and where the file pointer starts.\n * @param _stat The stats object for the given file.\n * PreloadFile will mutate this object. Note that this object must contain\n * the appropriate mode that the file was opened as.\n * @param contents A buffer containing the entire\n * contents of the file. PreloadFile will mutate this buffer. If not\n * specified, we assume it is a new file.\n */\n constructor(_fs, _path, _flag, _stat, contents) {\n super();\n this._pos = 0;\n this._dirty = false;\n this._fs = _fs;\n this._path = _path;\n this._flag = _flag;\n this._stat = _stat;\n this._buffer = contents ? contents : new Uint8Array(0);\n // Note: This invariant is *not* maintained once the file starts getting\n // modified.\n // Note: Only actually matters if file is readable, as writeable modes may\n // truncate/append to file.\n if (this._stat.size !== this._buffer.length && this._flag.isReadable()) {\n throw new Error(`Invalid buffer: Uint8Array is ${this._buffer.length} long, yet Stats object specifies that file is ${this._stat.size} long.`);\n }\n }\n /**\n * NONSTANDARD: Get the underlying buffer for this file. !!DO NOT MUTATE!! Will mess up dirty tracking.\n */\n getBuffer() {\n return this._buffer;\n }\n /**\n * NONSTANDARD: Get underlying stats for this file. !!DO NOT MUTATE!!\n */\n getStats() {\n return this._stat;\n }\n getFlag() {\n return this._flag;\n }\n /**\n * Get the path to this file.\n * @return [String] The path to the file.\n */\n getPath() {\n return this._path;\n }\n /**\n * Get the current file position.\n *\n * We emulate the following bug mentioned in the Node documentation:\n * > On Linux, positional writes don't work when the file is opened in append\n * mode. The kernel ignores the position argument and always appends the data\n * to the end of the file.\n * @return [Number] The current file position.\n */\n getPos() {\n if (this._flag.isAppendable()) {\n return this._stat.size;\n }\n return this._pos;\n }\n /**\n * Advance the current file position by the indicated number of positions.\n * @param [Number] delta\n */\n advancePos(delta) {\n return (this._pos += delta);\n }\n /**\n * Set the file position.\n * @param [Number] newPos\n */\n setPos(newPos) {\n return (this._pos = newPos);\n }\n /**\n * **Core**: Asynchronous sync. Must be implemented by subclasses of this\n * class.\n * @param [Function(BrowserFS.ApiError)] cb\n */\n async sync() {\n this.syncSync();\n }\n /**\n * **Core**: Synchronous sync.\n */\n syncSync() {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n /**\n * **Core**: Asynchronous close. Must be implemented by subclasses of this\n * class.\n * @param [Function(BrowserFS.ApiError)] cb\n */\n async close() {\n this.closeSync();\n }\n /**\n * **Core**: Synchronous close.\n */\n closeSync() {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n /**\n * Asynchronous `stat`.\n * @param [Function(BrowserFS.ApiError, BrowserFS.node.fs.Stats)] cb\n */\n async stat() {\n return Stats.clone(this._stat);\n }\n /**\n * Synchronous `stat`.\n */\n statSync() {\n return Stats.clone(this._stat);\n }\n /**\n * Asynchronous truncate.\n * @param [Number] len\n * @param [Function(BrowserFS.ApiError)] cb\n */\n truncate(len) {\n this.truncateSync(len);\n if (this._flag.isSynchronous() && !getMount('/').metadata.synchronous) {\n return this.sync();\n }\n }\n /**\n * Synchronous truncate.\n * @param [Number] len\n */\n truncateSync(len) {\n this._dirty = true;\n if (!this._flag.isWriteable()) {\n throw new ApiError(ErrorCode.EPERM, 'File not opened with a writeable mode.');\n }\n this._stat.mtimeMs = Date.now();\n if (len > this._buffer.length) {\n const buf = new Uint8Array(len - this._buffer.length);\n // Write will set @_stat.size for us.\n this.writeSync(buf, 0, buf.length, this._buffer.length);\n if (this._flag.isSynchronous() && getMount('/').metadata.synchronous) {\n this.syncSync();\n }\n return;\n }\n this._stat.size = len;\n // Truncate buffer to 'len'.\n this._buffer = this._buffer.subarray(0, len);\n if (this._flag.isSynchronous() && getMount('/').metadata.synchronous) {\n this.syncSync();\n }\n }\n /**\n * Write buffer to the file.\n * Note that it is unsafe to use fs.write multiple times on the same file\n * without waiting for the callback.\n * @param [BrowserFS.node.Uint8Array] buffer Uint8Array containing the data to write to\n * the file.\n * @param [Number] offset Offset in the buffer to start reading data from.\n * @param [Number] length The amount of bytes to write to the file.\n * @param [Number] position Offset from the beginning of the file where this\n * data should be written. If position is null, the data will be written at\n * the current position.\n * @param [Function(BrowserFS.ApiError, Number, BrowserFS.node.Uint8Array)]\n * cb The number specifies the number of bytes written into the file.\n */\n async write(buffer, offset, length, position) {\n return this.writeSync(buffer, offset, length, position);\n }\n /**\n * Write buffer to the file.\n * Note that it is unsafe to use fs.writeSync multiple times on the same file\n * without waiting for the callback.\n * @param [BrowserFS.node.Uint8Array] buffer Uint8Array containing the data to write to\n * the file.\n * @param [Number] offset Offset in the buffer to start reading data from.\n * @param [Number] length The amount of bytes to write to the file.\n * @param [Number] position Offset from the beginning of the file where this\n * data should be written. If position is null, the data will be written at\n * the current position.\n * @return [Number]\n */\n writeSync(buffer, offset, length, position) {\n this._dirty = true;\n if (position === undefined || position === null) {\n position = this.getPos();\n }\n if (!this._flag.isWriteable()) {\n throw new ApiError(ErrorCode.EPERM, 'File not opened with a writeable mode.');\n }\n const endFp = position + length;\n if (endFp > this._stat.size) {\n this._stat.size = endFp;\n if (endFp > this._buffer.length) {\n // Extend the buffer!\n const newBuffer = new Uint8Array(endFp);\n newBuffer.set(this._buffer);\n this._buffer = newBuffer;\n }\n }\n this._buffer.set(buffer.slice(offset, offset + length), position);\n const len = this._buffer.length;\n this._stat.mtimeMs = Date.now();\n if (this._flag.isSynchronous()) {\n this.syncSync();\n return len;\n }\n this.setPos(position + len);\n return len;\n }\n /**\n * Read data from the file.\n * @param [BrowserFS.node.Uint8Array] buffer The buffer that the data will be\n * written to.\n * @param [Number] offset The offset within the buffer where writing will\n * start.\n * @param [Number] length An integer specifying the number of bytes to read.\n * @param [Number] position An integer specifying where to begin reading from\n * in the file. If position is null, data will be read from the current file\n * position.\n * @param [Function(BrowserFS.ApiError, Number, BrowserFS.node.Uint8Array)] cb The\n * number is the number of bytes read\n */\n async read(buffer, offset, length, position) {\n return { bytesRead: this.readSync(buffer, offset, length, position), buffer };\n }\n /**\n * Read data from the file.\n * @param [BrowserFS.node.Uint8Array] buffer The buffer that the data will be\n * written to.\n * @param [Number] offset The offset within the buffer where writing will\n * start.\n * @param [Number] length An integer specifying the number of bytes to read.\n * @param [Number] position An integer specifying where to begin reading from\n * in the file. If position is null, data will be read from the current file\n * position.\n * @return [Number]\n */\n readSync(buffer, offset, length, position) {\n if (!this._flag.isReadable()) {\n throw new ApiError(ErrorCode.EPERM, 'File not opened with a readable mode.');\n }\n if (position === undefined || position === null) {\n position = this.getPos();\n }\n const endRead = position + length;\n if (endRead > this._stat.size) {\n length = this._stat.size - position;\n }\n this._buffer.set(buffer.slice(offset, offset + length), position);\n this._stat.atimeMs = Date.now();\n this._pos = position + length;\n return this._buffer.length;\n }\n /**\n * Asynchronous `fchmod`.\n * @param [Number|String] mode\n */\n async chmod(mode) {\n this.chmodSync(mode);\n }\n /**\n * Synchronous `fchmod`.\n * @param [Number] mode\n */\n chmodSync(mode) {\n if (!this._fs.metadata.supportsProperties) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n this._dirty = true;\n this._stat.chmod(mode);\n this.syncSync();\n }\n /**\n * Asynchronous `fchown`.\n * @param [Number] uid\n * @param [Number] gid\n */\n async chown(uid, gid) {\n this.chownSync(uid, gid);\n }\n /**\n * Synchronous `fchown`.\n * @param [Number] uid\n * @param [Number] gid\n */\n chownSync(uid, gid) {\n if (!this._fs.metadata.supportsProperties) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n this._dirty = true;\n this._stat.chown(uid, gid);\n this.syncSync();\n }\n isDirty() {\n return this._dirty;\n }\n /**\n * Resets the dirty bit. Should only be called after a sync has completed successfully.\n */\n resetDirty() {\n this._dirty = false;\n }\n}\n/**\n * File class for the InMemory and XHR file systems.\n * Doesn't sync to anything, so it works nicely for memory-only files.\n */\nexport class NoSyncFile extends PreloadFile {\n constructor(_fs, _path, _flag, _stat, contents) {\n super(_fs, _path, _flag, _stat, contents);\n }\n /**\n * Asynchronous sync. Doesn't do anything, simply calls the cb.\n * @param [Function(BrowserFS.ApiError)] cb\n */\n async sync() {\n return;\n }\n /**\n * Synchronous sync. Doesn't do anything.\n */\n syncSync() {\n // NOP.\n }\n /**\n * Asynchronous close. Doesn't do anything, simply calls the cb.\n * @param [Function(BrowserFS.ApiError)] cb\n */\n async close() {\n return;\n }\n /**\n * Synchronous close. Doesn't do anything.\n */\n closeSync() {\n // NOP.\n }\n}\n", "import { basename, dirname, join } from '@zenfs/core/emulation/path.js';\nimport { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';\nimport { Cred } from '@zenfs/core/cred.js';\nimport { FileFlag, PreloadFile } from '@zenfs/core/file.js';\nimport { BaseFileSystem, FileSystemMetadata } from '@zenfs/core/filesystem.js';\nimport { Stats, FileType } from '@zenfs/core/stats.js';\nimport { CreateBackend, type BackendOptions } from '@zenfs/core/backends/backend.js';\n\ndeclare global {\n\tinterface FileSystemDirectoryHandle {\n\t\t[Symbol.iterator](): IterableIterator<[string, FileSystemHandle]>;\n\t\tentries(): IterableIterator<[string, FileSystemHandle]>;\n\t\tkeys(): IterableIterator<string>;\n\t\tvalues(): IterableIterator<FileSystemHandle>;\n\t}\n}\n\ninterface FileSystemAccessFileSystemOptions {\n\thandle: FileSystemDirectoryHandle;\n}\n\nconst handleError = (path = '', error: Error) => {\n\tif (error.name === 'NotFoundError') {\n\t\tthrow ApiError.ENOENT(path);\n\t}\n\n\tthrow error as ApiError;\n};\n\nexport class FileSystemAccessFile extends PreloadFile<FileSystemAccessFileSystem> {\n\tconstructor(_fs: FileSystemAccessFileSystem, _path: string, _flag: FileFlag, _stat: Stats, contents?: Uint8Array) {\n\t\tsuper(_fs, _path, _flag, _stat, contents);\n\t}\n\n\tpublic async sync(): Promise<void> {\n\t\tif (this.isDirty()) {\n\t\t\tawait this._fs._sync(this.getPath(), this.getBuffer(), this.getStats(), Cred.Root);\n\t\t\tthis.resetDirty();\n\t\t}\n\t}\n\n\tpublic async close(): Promise<void> {\n\t\tawait this.sync();\n\t}\n}\n\nexport class FileSystemAccessFileSystem extends BaseFileSystem {\n\tpublic static readonly Name = 'FileSystemAccess';\n\n\tpublic static Create = CreateBackend.bind(this);\n\n\tpublic static readonly Options: BackendOptions = {};\n\n\tpublic static isAvailable(): boolean {\n\t\treturn typeof FileSystemHandle === 'function';\n\t}\n\n\tprivate _handles: Map<string, FileSystemHandle> = new Map();\n\n\tpublic constructor({ handle }: FileSystemAccessFileSystemOptions) {\n\t\tsuper();\n\t\tthis._handles.set('/', handle);\n\t}\n\n\tpublic get metadata(): FileSystemMetadata {\n\t\treturn {\n\t\t\t...super.metadata,\n\t\t\tname: FileSystemAccessFileSystem.Name,\n\t\t};\n\t}\n\n\tpublic async _sync(p: string, data: Uint8Array, stats: Stats, cred: Cred): Promise<void> {\n\t\tconst currentStats = await this.stat(p, cred);\n\t\tif (stats.mtime !== currentStats!.mtime) {\n\t\t\tawait this.writeFile(p, data, FileFlag.getFileFlag('w'), currentStats!.mode, cred);\n\t\t}\n\t}\n\n\tpublic async rename(oldPath: string, newPath: string, cred: Cred): Promise<void> {\n\t\ttry {\n\t\t\tconst handle = await this.getHandle(oldPath);\n\t\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\t\tconst files = await this.readdir(oldPath, cred);\n\n\t\t\t\tawait this.mkdir(newPath, 'wx', cred);\n\t\t\t\tif (files.length === 0) {\n\t\t\t\t\tawait this.unlink(oldPath, cred);\n\t\t\t\t} else {\n\t\t\t\t\tfor (const file of files) {\n\t\t\t\t\t\tawait this.rename(join(oldPath, file), join(newPath, file), cred);\n\t\t\t\t\t\tawait this.unlink(oldPath, cred);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (handle instanceof FileSystemFileHandle) {\n\t\t\t\tconst oldFile = await handle.getFile(),\n\t\t\t\t\tdestFolder = await this.getHandle(dirname(newPath));\n\t\t\t\tif (destFolder instanceof FileSystemDirectoryHandle) {\n\t\t\t\t\tconst newFile = await destFolder.getFileHandle(basename(newPath), { create: true });\n\t\t\t\t\tconst writable = await newFile.createWritable();\n\t\t\t\t\tconst buffer = await oldFile.arrayBuffer();\n\t\t\t\t\tawait writable.write(buffer);\n\n\t\t\t\t\twritable.close();\n\t\t\t\t\tawait this.unlink(oldPath, cred);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err) {\n\t\t\thandleError(oldPath, err);\n\t\t}\n\t}\n\n\tpublic async writeFile(fname: string, data: Uint8Array, flag: FileFlag, mode: number, cred: Cred, createFile?: boolean): Promise<void> {\n\t\tconst handle = await this.getHandle(dirname(fname));\n\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\tconst file = await handle.getFileHandle(basename(fname), { create: true });\n\t\t\tconst writable = await file.createWritable();\n\t\t\tawait writable.write(data);\n\t\t\tawait writable.close();\n\t\t\t//return createFile ? this.newFile(fname, flag, data) : undefined;\n\t\t}\n\t}\n\n\tpublic async createFile(p: string, flag: FileFlag, mode: number, cred: Cred): Promise<FileSystemAccessFile> {\n\t\tawait this.writeFile(p, new Uint8Array(), flag, mode, cred, true);\n\t\treturn this.openFile(p, flag, cred);\n\t}\n\n\tpublic async stat(path: string, cred: Cred): Promise<Stats> {\n\t\tconst handle = await this.getHandle(path);\n\t\tif (!handle) {\n\t\t\tthrow ApiError.FileError(ErrorCode.EINVAL, path);\n\t\t}\n\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\treturn new Stats(FileType.DIRECTORY, 4096);\n\t\t}\n\t\tif (handle instanceof FileSystemFileHandle) {\n\t\t\tconst { lastModified, size } = await handle.getFile();\n\t\t\treturn new Stats(FileType.FILE, size, undefined, undefined, lastModified);\n\t\t}\n\t}\n\n\tpublic async exists(p: string, cred: Cred): Promise<boolean> {\n\t\ttry {\n\t\t\tawait this.getHandle(p);\n\t\t\treturn true;\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic async openFile(path: string, flags: FileFlag, cred: Cred): Promise<FileSystemAccessFile> {\n\t\tconst handle = await this.getHandle(path);\n\t\tif (handle instanceof FileSystemFileHandle) {\n\t\t\tconst file = await handle.getFile();\n\t\t\tconst buffer = await file.arrayBuffer();\n\t\t\treturn this.newFile(path, flags, buffer, file.size, file.lastModified);\n\t\t}\n\t}\n\n\tpublic async unlink(path: string, cred: Cred): Promise<void> {\n\t\tconst handle = await this.getHandle(dirname(path));\n\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\ttry {\n\t\t\t\tawait handle.removeEntry(basename(path), { recursive: true });\n\t\t\t} catch (e) {\n\t\t\t\thandleError(path, e);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic async rmdir(path: string, cred: Cred): Promise<void> {\n\t\treturn this.unlink(path, cred);\n\t}\n\n\tpublic async mkdir(p: string, mode: any, cred: Cred): Promise<void> {\n\t\tconst overwrite = mode && mode.flag && mode.flag.includes('w') && !mode.flag.includes('x');\n\n\t\tconst existingHandle = await this.getHandle(p);\n\t\tif (existingHandle && !overwrite) {\n\t\t\tthrow ApiError.EEXIST(p);\n\t\t}\n\n\t\tconst handle = await this.getHandle(dirname(p));\n\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\tawait handle.getDirectoryHandle(basename(p), { create: true });\n\t\t}\n\t}\n\n\tpublic async readdir(path: string, cred: Cred): Promise<string[]> {\n\t\tconst handle = await this.getHandle(path);\n\t\tif (!(handle instanceof FileSystemDirectoryHandle)) {\n\t\t\tthrow ApiError.ENOTDIR(path);\n\t\t}\n\t\tconst _keys: string[] = [];\n\t\tfor await (const key of handle.keys()) {\n\t\t\t_keys.push(join(path, key));\n\t\t}\n\t\treturn _keys;\n\t}\n\n\tprivate newFile(path: string, flag: FileFlag, data: ArrayBuffer, size?: number, lastModified?: number): FileSystemAccessFile {\n\t\treturn new FileSystemAccessFile(this, path, flag, new Stats(FileType.FILE, size || 0, undefined, undefined, lastModified || new Date().getTime()), new Uint8Array(data));\n\t}\n\n\tprivate async getHandle(path: string): Promise<FileSystemHandle> {\n\t\tif (this._handles.has(path)) {\n\t\t\treturn this._handles.get(path);\n\t\t}\n\n\t\tlet walkedPath = '/';\n\t\tconst [, ...pathParts] = path.split('/');\n\t\tconst getHandleParts = async ([pathPart, ...remainingPathParts]: string[]) => {\n\t\t\tconst walkingPath = join(walkedPath, pathPart);\n\t\t\tconst continueWalk = (handle: FileSystemHandle) => {\n\t\t\t\twalkedPath = walkingPath;\n\t\t\t\tthis._handles.set(walkedPath, handle);\n\n\t\t\t\tif (remainingPathParts.length === 0) {\n\t\t\t\t\treturn this._handles.get(path);\n\t\t\t\t}\n\n\t\t\t\tgetHandleParts(remainingPathParts);\n\t\t\t};\n\t\t\tconst handle = this._handles.get(walkedPath) as FileSystemDirectoryHandle;\n\n\t\t\ttry {\n\t\t\t\treturn await continueWalk(await handle.getDirectoryHandle(pathPart));\n\t\t\t} catch (error) {\n\t\t\t\tif (error.name === 'TypeMismatchError') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn await continueWalk(await handle.getFileHandle(pathPart));\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\thandleError(walkingPath, err);\n\t\t\t\t\t}\n\t\t\t\t} else if (error.message === 'Name is not allowed.') {\n\t\t\t\t\tthrow new ApiError(ErrorCode.ENOENT, error.message, walkingPath);\n\t\t\t\t} else {\n\t\t\t\t\thandleError(walkingPath, error);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tawait getHandleParts(pathParts);\n\t}\n}\n", "/**\n * Contains utility methods for network I/O (using fetch)\n */\nimport { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';\n\nexport const fetchIsAvailable = typeof fetch !== 'undefined' && fetch !== null;\n\n/**\n * @hidden\n */\nfunction convertError(e): never {\n\tthrow new ApiError(ErrorCode.EIO, e.message);\n}\n\n/**\n * Asynchronously download a file as a buffer or a JSON object.\n * Note that the third function signature with a non-specialized type is\n * invalid, but TypeScript requires it when you specialize string arguments to\n * constants.\n * @hidden\n */\nexport async function fetchFile(p: string, type: 'buffer'): Promise<Uint8Array>;\nexport async function fetchFile(p: string, type: 'json'): Promise<any>;\nexport async function fetchFile(p: string, type: 'buffer' | 'json'): Promise<any>;\nexport async function fetchFile(p: string, type: 'buffer' | 'json'): Promise<any> {\n\tconst response = await fetch(p).catch(convertError);\n\tif (!response.ok) {\n\t\tthrow new ApiError(ErrorCode.EIO, `fetch error: response returned code ${response.status}`);\n\t}\n\tswitch (type) {\n\t\tcase 'buffer':\n\t\t\tconst arrayBuffer = await response.arrayBuffer().catch(convertError);\n\t\t\treturn new Uint8Array(arrayBuffer);\n\t\tcase 'json':\n\t\t\treturn response.json().catch(convertError);\n\t\tdefault:\n\t\t\tthrow new ApiError(ErrorCode.EINVAL, 'Invalid download type: ' + type);\n\t}\n}\n\n/**\n * Asynchronously retrieves the size of the given file in bytes.\n * @hidden\n */\nexport async function fetchFileSize(p: string): Promise<number> {\n\tconst response = await fetch(p, { method: 'HEAD' }).catch(convertError);\n\tif (!response.ok) {\n\t\tthrow new ApiError(ErrorCode.EIO, `fetch HEAD error: response returned code ${response.status}`);\n\t}\n\treturn parseInt(response.headers.get('Content-Length') || '-1', 10);\n}\n", "import { Stats, FileType } from './stats.js';\nimport * as path from './emulation/path.js';\n/**\n * A simple class for storing a filesystem index. Assumes that all paths passed\n * to it are *absolute* paths.\n *\n * Can be used as a partial or a full index, although care must be taken if used\n * for the former purpose, especially when directories are concerned.\n */\nexport class FileIndex {\n /**\n * Static method for constructing indices from a JSON listing.\n * @param listing Directory listing generated by tools/XHRIndexer.coffee\n * @return A new FileIndex object.\n */\n static fromListing(listing) {\n const idx = new FileIndex();\n // Add a root DirNode.\n const rootInode = new IndexDirInode();\n idx._index['/'] = rootInode;\n const queue = [['', listing, rootInode]];\n while (queue.length > 0) {\n let inode;\n const next = queue.pop();\n const pwd = next[0];\n const tree = next[1];\n const parent = next[2];\n for (const node in tree) {\n if (Object.prototype.hasOwnProperty.call(tree, node)) {\n const children = tree[node];\n const name = `${pwd}/${node}`;\n if (children) {\n idx._index[name] = inode = new IndexDirInode();\n queue.push([name, children, inode]);\n }\n else {\n // This inode doesn't have correct size information, noted with -1.\n inode = new IndexFileInode(new Stats(FileType.FILE, -1, 0x16d));\n }\n if (parent) {\n parent._ls[node] = inode;\n }\n }\n }\n }\n return idx;\n }\n /**\n * Constructs a new FileIndex.\n */\n constructor() {\n // _index is a single-level key,value store that maps *directory* paths to\n // DirInodes. File information is only contained in DirInodes themselves.\n this._index = {};\n // Create the root directory.\n this.addPath('/', new IndexDirInode());\n }\n /**\n * Runs the given function over all files in the index.\n */\n fileIterator(cb) {\n for (const path in this._index) {\n if (Object.prototype.hasOwnProperty.call(this._index, path)) {\n const dir = this._index[path];\n const files = dir.getListing();\n for (const file of files) {\n const item = dir.getItem(file);\n if (isIndexFileInode(item)) {\n cb(item.getData());\n }\n }\n }\n }\n }\n /**\n * Adds the given absolute path to the index if it is not already in the index.\n * Creates any needed parent directories.\n * @param path The path to add to the index.\n * @param inode The inode for the\n * path to add.\n * @return 'True' if it was added or already exists, 'false' if there\n * was an issue adding it (e.g. item in path is a file, item exists but is\n * different).\n * @todo If adding fails and implicitly creates directories, we do not clean up\n * the new empty directories.\n */\n addPath(path, inode) {\n if (!inode) {\n throw new Error('Inode must be specified');\n }\n if (path[0] !== '/') {\n throw new Error('Path must be absolute, got: ' + path);\n }\n // Check if it already exists.\n if (Object.prototype.hasOwnProperty.call(this._index, path)) {\n return this._index[path] === inode;\n }\n const splitPath = this._split_path(path);\n const dirpath = splitPath[0];\n const itemname = splitPath[1];\n // Try to add to its parent directory first.\n let parent = this._index[dirpath];\n if (parent === undefined && path !== '/') {\n // Create parent.\n parent = new IndexDirInode();\n if (!this.addPath(dirpath, parent)) {\n return false;\n }\n }\n // Add myself to my parent.\n if (path !== '/') {\n if (!parent.addItem(itemname, inode)) {\n return false;\n }\n }\n // If I'm a directory, add myself to the index.\n if (isIndexDirInode(inode)) {\n this._index[path] = inode;\n }\n return true;\n }\n /**\n * Adds the given absolute path to the index if it is not already in the index.\n * The path is added without special treatment (no joining of adjacent separators, etc).\n * Creates any needed parent directories.\n * @param path The path to add to the index.\n * @param inode The inode for the\n * path to add.\n * @return 'True' if it was added or already exists, 'false' if there\n * was an issue adding it (e.g. item in path is a file, item exists but is\n * different).\n * @todo If adding fails and implicitly creates directories, we do not clean up\n * the new empty directories.\n */\n addPathFast(path, inode) {\n const itemNameMark = path.lastIndexOf('/');\n const parentPath = itemNameMark === 0 ? '/' : path.substring(0, itemNameMark);\n const itemName = path.substring(itemNameMark + 1);\n // Try to add to its parent directory first.\n let parent = this._index[parentPath];\n if (parent === undefined) {\n // Create parent.\n parent = new IndexDirInode();\n this.addPathFast(parentPath, parent);\n }\n if (!parent.addItem(itemName, inode)) {\n return false;\n }\n // If adding a directory, add to the index as well.\n if (inode.isDir()) {\n this._index[path] = inode;\n }\n return true;\n }\n /**\n * Removes the given path. Can be a file or a directory.\n * @return The removed item,\n * or null if it did not exist.\n */\n removePath(path) {\n const splitPath = this._split_path(path);\n const dirpath = splitPath[0];\n const itemname = splitPath[1];\n // Try to remove it from its parent directory first.\n const parent = this._index[dirpath];\n if (parent === undefined) {\n return null;\n }\n // Remove myself from my parent.\n const inode = parent.remItem(itemname);\n if (inode === null) {\n return null;\n }\n // If I'm a directory, remove myself from the index, and remove my children.\n if (isIndexDirInode(inode)) {\n const children = inode.getListing();\n for (const child of children) {\n this.removePath(path + '/' + child);\n }\n // Remove the directory from the index, unless it's the root.\n if (path !== '/') {\n delete this._index[path];\n }\n }\n return inode;\n }\n /**\n * Retrieves the directory listing of the given path.\n * @return An array of files in the given path, or 'null' if it does not exist.\n */\n ls(path) {\n const item = this._index[path];\n if (item === undefined) {\n return null;\n }\n return item.getListing();\n }\n /**\n * Returns the inode of the given item.\n * @return Returns null if the item does not exist.\n */\n getInode(path) {\n const splitPath = this._split_path(path);\n const dirpath = splitPath[0];\n const itemname = splitPath[1];\n // Retrieve from its parent directory.\n const parent = this._index[dirpath];\n if (parent === undefined) {\n return null;\n }\n // Root case\n if (dirpath === path) {\n return parent;\n }\n return parent.getItem(itemname);\n }\n /**\n * Split into a (directory path, item name) pair\n */\n _split_path(p) {\n const dirpath = path.dirname(p);\n const itemname = p.slice(dirpath.length + (dirpath === '/' ? 0 : 1));\n return [dirpath, itemname];\n }\n}\n/**\n * Inode for a file. Stores an arbitrary (filesystem-specific) data payload.\n */\nexport class IndexFileInode {\n constructor(data) {\n this.data = data;\n }\n isFile() {\n return true;\n }\n isDir() {\n return false;\n }\n getData() {\n return this.data;\n }\n setData(data) {\n this.data = data;\n }\n toStats() {\n return new Stats(FileType.FILE, 4096, 0o666);\n }\n}\n/**\n * Inode for a directory. Currently only contains the directory listing.\n */\nexport class IndexDirInode {\n /**\n * Constructs an inode for a directory.\n */\n constructor(data = null) {\n this.data = data;\n this._ls = {};\n }\n isFile() {\n return false;\n }\n isDir() {\n return true;\n }\n getData() {\n return this.data;\n }\n /**\n * Return a Stats object for this inode.\n * @todo Should probably remove this at some point. This isn't the\n * responsibility of the FileIndex.\n */\n getStats() {\n return new Stats(FileType.DIRECTORY, 4096, 0o555);\n }\n /**\n * Alias of getStats()\n * @todo Remove this at some point. This isn't the\n * responsibility of the FileIndex.\n */\n toStats() {\n return this.getStats();\n }\n /**\n * Returns the directory listing for this directory. Paths in the directory are\n * relative to the directory's path.\n * @return The directory listing for this directory.\n */\n getListing() {\n return Object.keys(this._ls);\n }\n /**\n * Returns the inode for the indicated item, or null if it does not exist.\n * @param p Name of item in this directory.\n */\n getItem(p) {\n const item = this._ls[p];\n return item ? item : null;\n }\n /**\n * Add the given item to the directory listing. Note that the given inode is\n * not copied, and will be mutated by the DirInode if it is a DirInode.\n * @param p Item name to add to the directory listing.\n * @param inode The inode for the\n * item to add to the directory inode.\n * @return True if it was added, false if it already existed.\n */\n addItem(p, inode) {\n if (p in this._ls) {\n return false;\n }\n this._ls[p] = inode;\n return true;\n }\n /**\n * Removes the given item from the directory listing.\n * @param p Name of item to remove from the directory listing.\n * @return Returns the item\n * removed, or null if the item did not exist.\n */\n remItem(p) {\n const item = this._ls[p];\n if (item === undefined) {\n return null;\n }\n delete this._ls[p];\n return item;\n }\n}\n/**\n * @hidden\n */\nexport function isIndexFileInode(inode) {\n return !!inode && inode.isFile();\n}\n/**\n * @hidden\n */\nexport function isIndexDirInode(inode) {\n return !!inode && inode.isDir();\n}\n", "import { BaseFileSystem, FileSystemMetadata } from '@zenfs/core/filesystem.js';\nimport { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';\nimport { FileFlag, ActionType, NoSyncFile } from '@zenfs/core/file.js';\nimport { Stats } from '@zenfs/core/stats.js';\nimport { fetchIsAvailable, fetchFile, fetchFileSize } from '../fetch.js';\nimport { FileIndex, isIndexFileInode, isIndexDirInode } from '@zenfs/core/FileIndex.js';\nimport { Cred } from '@zenfs/core/cred.js';\nimport { CreateBackend, type BackendOptions } from '@zenfs/core/backends/backend.js';\nimport { R_OK } from '@zenfs/core/emulation/constants.js';\n\nexport interface HTTPRequestIndex {\n\t[key: string]: string;\n}\n\nexport namespace HTTPRequest {\n\t/**\n\t * Configuration options for a HTTPRequest file system.\n\t */\n\texport interface Options {\n\t\t/**\n\t\t * URL to a file index as a JSON file or the file index object itself, generated with the make_http_index script.\n\t\t * Defaults to `index.json`.\n\t\t */\n\t\tindex?: string | HTTPRequestIndex;\n\n\t\t/** Used as the URL prefix for fetched files.\n\t\t * Default: Fetch files relative to the index.\n\t\t */\n\t\tbaseUrl?: string;\n\t}\n}\n\n/**\n * A simple filesystem backed by HTTP downloads. You must create a directory listing using the\n * `make_http_index` tool provided by ZenFS.\n *\n * If you install ZenFS globally with `npm i -g zenfs`, you can generate a listing by\n * running `make_http_index` in your terminal in the directory you would like to index:\n *\n * ```\n * make_http_index > index.json\n * ```\n *\n * Listings objects look like the following:\n *\n * ```json\n * {\n * \"home\": {\n * \"jvilk\": {\n * \"someFile.txt\": null,\n * \"someDir\": {\n * // Empty directory\n * }\n * }\n * }\n * }\n * ```\n *\n * *This example has the folder `/home/jvilk` with subfile `someFile.txt` and subfolder `someDir`.*\n */\nexport class HTTPRequest extends BaseFileSystem {\n\tpublic static readonly Name = 'HTTPRequest';\n\n\tpublic static Create = CreateBackend.bind(this);\n\n\tpublic static readonly Options: BackendOptions = {\n\t\tindex: {\n\t\t\ttype: ['string', 'object'],\n\t\t\toptional: true,\n\t\t\tdescription: 'URL to a file index as a JSON file or the file index object itself, generated with the make_http_index script. Defaults to `index.json`.',\n\t\t},\n\t\tbaseUrl: {\n\t\t\ttype: 'string',\n\t\t\toptional: true,\n\t\t\tdescription: 'Used as the URL prefix for fetched files. Default: Fetch files relative to the index.',\n\t\t},\n\t};\n\n\tpublic static isAvailable(): boolean {\n\t\treturn fetchIsAvailable;\n\t}\n\n\tpublic readonly prefixUrl: string;\n\tprivate _index: FileIndex<{}>;\n\n\tconstructor({ index, baseUrl = '' }: HTTPRequest.Options) {\n\t\tsuper();\n\t\tif (!index) {\n\t\t\tindex = 'index.json';\n\t\t}\n\n\t\tconst indexRequest = typeof index == 'string' ? fetchFile(index, 'json') : Promise.resolve(index);\n\t\tthis._ready = indexRequest.then(data => {\n\t\t\tthis._index = FileIndex.fromListing(data);\n\t\t\treturn this;\n\t\t});\n\n\t\t// prefix_url must end in a directory separator.\n\t\tif (baseUrl.length > 0 && baseUrl.charAt(baseUrl.length - 1) !== '/') {\n\t\t\tbaseUrl = baseUrl + '/';\n\t\t}\n\t\tthis.prefixUrl = baseUrl;\n\t}\n\n\tpublic get metadata(): FileSystemMetadata {\n\t\treturn {\n\t\t\t...super.metadata,\n\t\t\tname: HTTPRequest.Name,\n\t\t\treadonly: true,\n\t\t};\n\t}\n\n\tpublic empty(): void {\n\t\tthis._index.fileIterator(function (file: Stats) {\n\t\t\tfile.fileData = null;\n\t\t});\n\t}\n\n\t/**\n\t * Special HTTPFS function: Preload the given file into the index.\n\t * @param path\n\t * @param buffer\n\t */\n\tpublic preloadFile(path: string, buffer: Uint8Array): void {\n\t\tconst inode = this._index.getInode(path);\n\t\tif (isIndexFileInode<Stats>(inode)) {\n\t\t\tif (inode === null) {\n\t\t\t\tthrow ApiError.ENOENT(path);\n\t\t\t}\n\t\t\tconst stats = inode.getData();\n\t\t\tstats.size = buffer.length;\n\t\t\tstats.fileData = buffer;\n\t\t} else {\n\t\t\tthrow ApiError.EISDIR(path);\n\t\t}\n\t}\n\n\tpublic async stat(path: string, cred: Cred): Promise<Stats> {\n\t\tconst inode = this._index.getInode(path);\n\t\tif (inode === null) {\n\t\t\tthrow ApiError.ENOENT(path);\n\t\t}\n\t\tif (!inode.toStats().hasAccess(R_OK, cred)) {\n\t\t\tthrow ApiError.EACCES(path);\n\t\t}\n\t\tlet stats: Stats;\n\t\tif (isIndexFileInode<Stats>(inode)) {\n\t\t\tstats = inode.getData();\n\t\t\t// At this point, a non-opened file will still have default stats from the listing.\n\t\t\tif (stats.size < 0) {\n\t\t\t\tstats.size = await this._requestFileSize(path);\n\t\t\t}\n\t\t} else if (isIndexDirInode(inode)) {\n\t\t\tstats = inode.getStats();\n\t\t} else {\n\t\t\tthrow ApiError.FileError(ErrorCode.EINVAL, path);\n\t\t}\n\t\treturn stats;\n\t}\n\n\tpublic async open(path: string, flags: FileFlag, mode: number, cred: Cred): Promise<NoSyncFile<this>> {\n\t\t// INVARIANT: You can't write to files on this file system.\n\t\tif (flags.isWriteable()) {\n\t\t\tthrow new ApiError(ErrorCode.EPERM, path);\n\t\t}\n\t\t// Check if the path exists, and is a file.\n\t\tconst inode = this._index.getInode(path);\n\t\tif (inode === null) {\n\t\t\tthrow ApiError.ENOENT(path);\n\t\t}\n\t\tif (!inode.toStats().hasAccess(flags.getMode(), cred)) {\n\t\t\tthrow ApiError.EACCES(path);\n\t\t}\n\t\tif (isIndexFileInode<Stats>(inode) || isIndexDirInode<Stats>(inode)) {\n\t\t\tswitch (flags.pathExistsAction()) {\n\t\t\t\tcase ActionType.THROW_EXCEPTION:\n\t\t\t\tcase ActionType.TRUNCATE_FILE:\n\t\t\t\t\tthrow ApiError.EEXIST(path);\n\t\t\t\tcase ActionType.NOP:\n\t\t\t\t\tif (isIndexDirInode<Stats>(inode)) {\n\t\t\t\t\t\tconst stats = inode.getStats();\n\t\t\t\t\t\treturn new NoSyncFile(this, path, flags, stats, stats.fileData || undefined);\n\t\t\t\t\t}\n\t\t\t\t\tconst stats = inode.getData();\n\t\t\t\t\t// Use existing file contents.\n\t\t\t\t\t// XXX: Uh, this maintains the previously-used flag.\n\t\t\t\t\tif (stats.fileData) {\n\t\t\t\t\t\treturn new NoSyncFile(this, path, flags, Stats.clone(stats), stats.fileData);\n\t\t\t\t\t}\n\t\t\t\t\t// @todo be lazier about actually requesting the file\n\t\t\t\t\tconst buffer = await this._requestFile(path, 'buffer');\n\t\t\t\t\t// we don't initially have file sizes\n\t\t\t\t\tstats.size = buffer.length;\n\t\t\t\t\tstats.fileData = buffer;\n\t\t\t\t\treturn new NoSyncFile(this, path, flags, Stats.clone(stats), buffer);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ApiError(ErrorCode.EINVAL, 'Invalid FileMode object.');\n\t\t\t}\n\t\t} else {\n\t\t\tthrow ApiError.EPERM(path);\n\t\t}\n\t}\n\n\tpublic async readdir(path: string, cred: Cred): Promise<string[]> {\n\t\treturn this.readdirSync(path, cred);\n\t}\n\n\t/**\n\t * We have the entire file as a buffer; optimize readFile.\n\t */\n\tpublic async readFile(fname: string, flag: FileFlag, cred: Cred): Promise<Uint8Array> {\n\t\t// Get file.\n\t\tconst fd: NoSyncFile<HTTPRequest> = await this.open(fname, flag, 0o644, cred);\n\t\ttry {\n\t\t\treturn fd.getBuffer();\n\t\t} finally {\n\t\t\tawait fd.close();\n\t\t}\n\t}\n\n\tprivate _getHTTPPath(filePath: string): string {\n\t\tif (filePath.charAt(0) === '/') {\n\t\t\tfilePath = filePath.slice(1);\n\t\t}\n\t\treturn this.prefixUrl + filePath;\n\t}\n\n\t/**\n\t * Asynchronously download the given file.\n\t */\n\tprivate _requestFile(p: string, type: 'buffer'): Promise<Uint8Array>;\n\tprivate _requestFile(p: string, type: 'json'): Promise<any>;\n\tprivate _requestFile(p: string, type: 'buffer' | 'json'): Promise<any>;\n\tprivate _requestFile(p: string, type: 'buffer' | 'json'): Promise<any> {\n\t\treturn fetchFile(this._getHTTPPath(p), type);\n\t}\n\n\t/**\n\t * Only requests the HEAD content, for the file size.\n\t */\n\tprivate _requestFileSize(path: string): Promise<number> {\n\t\treturn fetchFileSize(this._getHTTPPath(path));\n\t}\n}\n", "import { dirname, basename, join, resolve } from '../emulation/path.js';\nimport { ApiError, ErrorCode } from '../ApiError.js';\nimport { W_OK, R_OK } from '../emulation/constants.js';\nimport { PreloadFile, FileFlag } from '../file.js';\nimport { BaseFileSystem } from '../filesystem.js';\nimport Inode from '../inode.js';\nimport { FileType } from '../stats.js';\nimport { ROOT_NODE_ID, randomUUID, encode, decode } from '../utils.js';\nclass LRUNode {\n constructor(key, value) {\n this.key = key;\n this.value = value;\n this.prev = null;\n this.next = null;\n }\n}\n// Adapted from https://chrisrng.svbtle.com/lru-cache-in-javascript\nclass LRUCache {\n constructor(limit) {\n this.limit = limit;\n this.size = 0;\n this.map = {};\n this.head = null;\n this.tail = null;\n }\n /**\n * Change or add a new value in the cache\n * We overwrite the entry if it already exists\n */\n set(key, value) {\n const node = new LRUNode(key, value);\n if (this.map[key]) {\n this.map[key].value = node.value;\n this.remove(node.key);\n }\n else {\n if (this.size >= this.limit) {\n delete this.map[this.tail.key];\n this.size--;\n this.tail = this.tail.prev;\n this.tail.next = null;\n }\n }\n this.setHead(node);\n }\n /* Retrieve a single entry from the cache */\n get(key) {\n if (this.map[key]) {\n const value = this.map[key].value;\n const node = new LRUNode(key, value);\n this.remove(key);\n this.setHead(node);\n return value;\n }\n else {\n return null;\n }\n }\n /* Remove a single entry from the cache */\n remove(key) {\n const node = this.map[key];\n if (!node) {\n return;\n }\n if (node.prev !== null) {\n node.prev.next = node.next;\n }\n else {\n this.head = node.next;\n }\n if (node.next !== null) {\n node.next.prev = node.prev;\n }\n else {\n this.tail = node.prev;\n }\n delete this.map[key];\n this.size--;\n }\n /* Resets the entire cache - Argument limit is optional to be reset */\n removeAll() {\n this.size = 0;\n this.map = {};\n this.head = null;\n this.tail = null;\n }\n setHead(node) {\n node.next = this.head;\n node.prev = null;\n if (this.head !== null) {\n this.head.prev = node;\n }\n this.head = node;\n if (this.tail === null) {\n this.tail = node;\n }\n this.size++;\n this.map[node.key] = node;\n }\n}\nexport class AsyncKeyValueFile extends PreloadFile {\n constructor(_fs, _path, _flag, _stat, contents) {\n super(_fs, _path, _flag, _stat, contents);\n }\n async sync() {\n if (!this.isDirty()) {\n return;\n }\n await this._fs._sync(this.getPath(), this.getBuffer(), this.getStats());\n this.resetDirty();\n }\n async close() {\n this.sync();\n }\n}\n/**\n * An \"Asynchronous key-value file system\". Stores data to/retrieves data from\n * an underlying asynchronous key-value store.\n */\nexport class AsyncKeyValueFileSystem extends BaseFileSystem {\n static isAvailable() {\n return true;\n }\n constructor(cacheSize) {\n super();\n this._cache = null;\n if (cacheSize > 0) {\n this._cache = new LRUCache(cacheSize);\n }\n }\n /**\n * Initializes the file system. Typically called by subclasses' async\n * constructors.\n */\n async init(store) {\n this.store = store;\n // INVARIANT: Ensure that the root exists.\n await this.makeRootDirectory();\n }\n getName() {\n return this.store.name();\n }\n isReadOnly() {\n return false;\n }\n supportsSymlinks() {\n return false;\n }\n supportsProps() {\n return true;\n }\n supportsSynch() {\n return false;\n }\n /**\n * Delete all contents stored in the file system.\n */\n async empty() {\n if (this._cache) {\n this._cache.removeAll();\n }\n await this.store.clear();\n // INVARIANT: Root always exists.\n await this.makeRootDirectory();\n }\n async access(p, mode, cred) {\n const tx = this.store.beginTransaction('readonly');\n const inode = await this.findINode(tx, p);\n if (!inode) {\n throw ApiError.ENOENT(p);\n }\n if (!inode.toStats().hasAccess(mode, cred)) {\n throw ApiError.EACCES(p);\n }\n }\n /**\n * @todo Make rename compatible with the cache.\n */\n async rename(oldPath, newPath, cred) {\n const c = this._cache;\n if (this._cache) {\n // Clear and disable cache during renaming process.\n this._cache = null;\n c.removeAll();\n }\n try {\n const tx = this.store.beginTransaction('readwrite'), oldParent = dirname(oldPath), oldName = basename(oldPath), newParent = dirname(newPath), newName = basename(newPath), \n // Remove oldPath from parent's directory listing.\n oldDirNode = await this.findINode(tx, oldParent), oldDirList = await this.getDirListing(tx, oldParent, oldDirNode);\n if (!oldDirNode.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(oldPath);\n }\n if (!oldDirList[oldName]) {\n throw ApiError.ENOENT(oldPath);\n }\n const nodeId = oldDirList[oldName];\n delete oldDirList[oldName];\n // Invariant: Can't move a folder inside itself.\n // This funny little hack ensures that the check passes only if oldPath\n // is a subpath of newParent. We append '/' to avoid matching folders that\n // are a substring of the bottom-most folder in the path.\n if ((newParent + '/').indexOf(oldPath + '/') === 0) {\n throw new ApiError(ErrorCode.EBUSY, oldParent);\n }\n // Add newPath to parent's directory listing.\n let newDirNode, newDirList;\n if (newParent === oldParent) {\n // Prevent us from re-grabbing the same directory listing, which still\n // contains oldName.\n newDirNode = oldDirNode;\n newDirList = oldDirList;\n }\n else {\n newDirNode = await this.findINode(tx, newParent);\n newDirList = await this.getDirListing(tx, newParent, newDirNode);\n }\n if (newDirList[newName]) {\n // If it's a file, delete it.\n const newNameNode = await this.getINode(tx, newPath, newDirList[newName]);\n if (newNameNode.isFile()) {\n try {\n await tx.del(newNameNode.id);\n await tx.del(newDirList[newName]);\n }\n catch (e) {\n await tx.abort();\n throw e;\n }\n }\n else {\n // If it's a directory, throw a permissions error.\n throw ApiError.EPERM(newPath);\n }\n }\n newDirList[newName] = nodeId;\n // Commit the two changed directory listings.\n try {\n await tx.put(oldDirNode.id, encode(JSON.stringify(oldDirList)), true);\n await tx.put(newDirNode.id, encode(JSON.stringify(newDirList)), true);\n }\n catch (e) {\n await tx.abort();\n throw e;\n }\n await tx.commit();\n }\n finally {\n if (c) {\n this._cache = c;\n }\n }\n }\n async stat(p, cred) {\n const tx = this.store.beginTransaction('readonly');\n const inode = await this.findINode(tx, p);\n const stats = inode.toStats();\n if (!stats.hasAccess(R_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n return stats;\n }\n async createFile(p, flag, mode, cred) {\n const tx = this.store.beginTransaction('readwrite'), data = new Uint8Array(0), newFile = await this.commitNewFile(tx, p, FileType.FILE, mode, cred, data);\n // Open the file.\n return new AsyncKeyValueFile(this, p, flag, newFile.toStats(), data);\n }\n async openFile(p, flag, cred) {\n const tx = this.store.beginTransaction('readonly'), node = await this.findINode(tx, p), data = await tx.get(node.id);\n if (!node.toStats().hasAccess(flag.getMode(), cred)) {\n throw ApiError.EACCES(p);\n }\n if (data === undefined) {\n throw ApiError.ENOENT(p);\n }\n return new AsyncKeyValueFile(this, p, flag, node.toStats(), data);\n }\n async unlink(p, cred) {\n return this.removeEntry(p, false, cred);\n }\n async rmdir(p, cred) {\n // Check first if directory is empty.\n const list = await this.readdir(p, cred);\n if (list.length > 0) {\n throw ApiError.ENOTEMPTY(p);\n }\n await this.removeEntry(p, true, cred);\n }\n async mkdir(p, mode, cred) {\n const tx = this.store.beginTransaction('readwrite'), data = encode('{}');\n await this.commitNewFile(tx, p, FileType.DIRECTORY, mode, cred, data);\n }\n async readdir(p, cred) {\n const tx = this.store.beginTransaction('readonly');\n const node = await this.findINode(tx, p);\n if (!node.toStats().hasAccess(R_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n return Object.keys(await this.getDirListing(tx, p, node));\n }\n async chmod(p, mode, cred) {\n const fd = await this.openFile(p, FileFlag.getFileFlag('r+'), cred);\n await fd.chmod(mode);\n }\n async chown(p, new_uid, new_gid, cred) {\n const fd = await this.openFile(p, FileFlag.getFileFlag('r+'), cred);\n await fd.chown(new_uid, new_gid);\n }\n async _sync(p, data, stats) {\n // @todo Ensure mtime updates properly, and use that to determine if a data\n // update is required.\n const tx = this.store.beginTransaction('readwrite'), \n // We use the _findInode helper because we actually need the INode id.\n fileInodeId = await this._findINode(tx, dirname(p), basename(p)), fileInode = await this.getINode(tx, p, fileInodeId), inodeChanged = fileInode.update(stats);\n try {\n // Sync data.\n await tx.put(fileInode.id, data, true);\n // Sync metadata.\n if (inodeChanged) {\n await tx.put(fileInodeId, fileInode.serialize(), true);\n }\n }\n catch (e) {\n await tx.abort();\n throw e;\n }\n await tx.commit();\n }\n /**\n * Checks if the root directory exists. Creates it if it doesn't.\n */\n async makeRootDirectory() {\n const tx = this.store.beginTransaction('readwrite');\n if ((await tx.get(ROOT_NODE_ID)) === undefined) {\n // Create new inode.\n const currTime = new Date().getTime(), \n // Mode 0666, owned by root:root\n dirInode = new Inode(randomUUID(), 4096, 511 | FileType.DIRECTORY, currTime, currTime, currTime, 0, 0);\n // If the root doesn't exist, the first random ID shouldn't exist,\n // either.\n await tx.put(dirInode.id, encode('{}'), false);\n await tx.put(ROOT_NODE_ID, dirInode.serialize(), false);\n await tx.commit();\n }\n }\n /**\n * Helper function for findINode.\n * @param parent The parent directory of the file we are attempting to find.\n * @param filename The filename of the inode we are attempting to find, minus\n * the parent.\n */\n async _findINode(tx, parent, filename, visited = new Set()) {\n const currentPath = join(parent, filename);\n if (visited.has(currentPath)) {\n throw new ApiError(ErrorCode.EIO, 'Infinite loop detected while finding inode', currentPath);\n }\n visited.add(currentPath);\n if (this._cache) {\n const id = this._cache.get(currentPath);\n if (id) {\n return id;\n }\n }\n if (parent === '/') {\n if (filename === '') {\n // BASE CASE #1: Return the root's ID.\n if (this._cache) {\n this._cache.set(currentPath, ROOT_NODE_ID);\n }\n return ROOT_NODE_ID;\n }\n else {\n // BASE CASE #2: Find the item in the root node.\n const inode = await this.getINode(tx, parent, ROOT_NODE_ID);\n const dirList = await this.getDirListing(tx, parent, inode);\n if (dirList[filename]) {\n const id = dirList[filename];\n if (this._cache) {\n this._cache.set(currentPath, id);\n }\n return id;\n }\n else {\n throw ApiError.ENOENT(resolve(parent, filename));\n }\n }\n }\n else {\n // Get the parent directory's INode, and find the file in its directory\n // listing.\n const inode = await this.findINode(tx, parent, visited);\n const dirList = await this.getDirListing(tx, parent, inode);\n if (dirList[filename]) {\n const id = dirList[filename];\n if (this._cache) {\n this._cache.set(currentPath, id);\n }\n return id;\n }\n else {\n throw ApiError.ENOENT(resolve(parent, filename));\n }\n }\n }\n /**\n * Finds the Inode of the given path.\n * @param p The path to look up.\n * @todo memoize/cache\n */\n async findINode(tx, p, visited = new Set()) {\n const id = await this._findINode(tx, dirname(p), basename(p), visited);\n return this.getINode(tx, p, id);\n }\n /**\n * Given the ID of a node, retrieves the corresponding Inode.\n * @param tx The transaction to use.\n * @param p The corresponding path to the file (used for error messages).\n * @param id The ID to look up.\n */\n async getINode(tx, p, id) {\n const data = await tx.get(id);\n if (!data) {\n throw ApiError.ENOENT(p);\n }\n return Inode.Deserialize(data);\n }\n /**\n * Given the Inode of a directory, retrieves the corresponding directory\n * listing.\n */\n async getDirListing(tx, p, inode) {\n if (!inode.isDirectory()) {\n throw ApiError.ENOTDIR(p);\n }\n const data = await tx.get(inode.id);\n try {\n return JSON.parse(decode(data));\n }\n catch (e) {\n // Occurs when data is undefined, or corresponds to something other\n // than a directory listing. The latter should never occur unless\n // the file system is corrupted.\n throw ApiError.ENOENT(p);\n }\n }\n /**\n * Adds a new node under a random ID. Retries 5 times before giving up in\n * the exceedingly unlikely chance that we try to reuse a random GUID.\n */\n async addNewNode(tx, data) {\n let retries = 0;\n const reroll = async () => {\n if (++retries === 5) {\n // Max retries hit. Return with an error.\n throw new ApiError(ErrorCode.EIO, 'Unable to commit data to key-value store.');\n }\n else {\n // Try again.\n const currId = randomUUID();\n const committed = await tx.put(currId, data, false);\n if (!committed) {\n return reroll();\n }\n else {\n return currId;\n }\n }\n };\n return reroll();\n }\n /**\n * Commits a new file (well, a FILE or a DIRECTORY) to the file system with\n * the given mode.\n * Note: This will commit the transaction.\n * @param p The path to the new file.\n * @param type The type of the new file.\n * @param mode The mode to create the new file with.\n * @param cred The UID/GID to create the file with\n * @param data The data to store at the file's data node.\n */\n async commitNewFile(tx, p, type, mode, cred, data) {\n const parentDir = dirname(p), fname = basename(p), parentNode = await this.findINode(tx, parentDir), dirListing = await this.getDirListing(tx, parentDir, parentNode), currTime = new Date().getTime();\n //Check that the creater has correct access\n if (!parentNode.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n // Invariant: The root always exists.\n // If we don't check this prior to taking steps below, we will create a\n // file with name '' in root should p == '/'.\n if (p === '/') {\n throw ApiError.EEXIST(p);\n }\n // Check if file already exists.\n if (dirListing[fname]) {\n await tx.abort();\n throw ApiError.EEXIST(p);\n }\n try {\n // Commit data.\n const dataId = await this.addNewNode(tx, data);\n const fileNode = new Inode(dataId, data.length, mode | type, currTime, currTime, currTime, cred.uid, cred.gid);\n // Commit file node.\n const fileNodeId = await this.addNewNode(tx, fileNode.serialize());\n // Update and commit parent directory listing.\n dirListing[fname] = fileNodeId;\n await tx.put(parentNode.id, encode(JSON.stringify(dirListing)), true);\n await tx.commit();\n return fileNode;\n }\n catch (e) {\n tx.abort();\n throw e;\n }\n }\n /**\n * Remove all traces of the given path from the file system.\n * @param p The path to remove from the file system.\n * @param isDir Does the path belong to a directory, or a file?\n * @todo Update mtime.\n */\n /**\n * Remove all traces of the given path from the file system.\n * @param p The path to remove from the file system.\n * @param isDir Does the path belong to a directory, or a file?\n * @todo Update mtime.\n */\n async removeEntry(p, isDir, cred) {\n if (this._cache) {\n this._cache.remove(p);\n }\n const tx = this.store.beginTransaction('readwrite'), parent = dirname(p), parentNode = await this.findINode(tx, parent), parentListing = await this.getDirListing(tx, parent, parentNode), fileName = basename(p);\n if (!parentListing[fileName]) {\n throw ApiError.ENOENT(p);\n }\n const fileNodeId = parentListing[fileName];\n // Get file inode.\n const fileNode = await this.getINode(tx, p, fileNodeId);\n if (!fileNode.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n // Remove from directory listing of parent.\n delete parentListing[fileName];\n if (!isDir && fileNode.isDirectory()) {\n throw ApiError.EISDIR(p);\n }\n else if (isDir && !fileNode.isDirectory()) {\n throw ApiError.ENOTDIR(p);\n }\n try {\n // Delete data.\n await tx.del(fileNode.id);\n // Delete node.\n await tx.del(fileNodeId);\n // Update directory listing.\n await tx.put(parentNode.id, encode(JSON.stringify(parentListing)), true);\n }\n catch (e) {\n await tx.abort();\n throw e;\n }\n // Success.\n await tx.commit();\n }\n}\n", "import { AsyncKeyValueROTransaction, AsyncKeyValueRWTransaction, AsyncKeyValueStore, AsyncKeyValueFileSystem } from '@zenfs/core/backends/AsyncStore.js';\nimport { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';\nimport { CreateBackend, type BackendOptions } from '@zenfs/core/backends/backend.js';\n\n/**\n * Converts a DOMException or a DOMError from an IndexedDB event into a\n * standardized ZenFS API error.\n * @hidden\n */\nfunction convertError(e: { name: string }, message: string = e.toString()): ApiError {\n\tswitch (e.name) {\n\t\tcase 'NotFoundError':\n\t\t\treturn new ApiError(ErrorCode.ENOENT, message);\n\t\tcase 'QuotaExceededError':\n\t\t\treturn new ApiError(ErrorCode.ENOSPC, message);\n\t\tdefault:\n\t\t\t// The rest do not seem to map cleanly to standard error codes.\n\t\t\treturn new ApiError(ErrorCode.EIO, message);\n\t}\n}\n\n/**\n * Produces a new onerror handler for IDB. Our errors are always fatal, so we\n * handle them generically: Call the user-supplied callback with a translated\n * version of the error, and let the error bubble up.\n * @hidden\n */\nfunction onErrorHandler(cb: (e: ApiError) => void, code: ErrorCode = ErrorCode.EIO, message: string | null = null): (e?: any) => void {\n\treturn function (e?: any): void {\n\t\t// Prevent the error from canceling the transaction.\n\t\te.preventDefault();\n\t\tcb(new ApiError(code, message !== null ? message : undefined));\n\t};\n}\n\n/**\n * @hidden\n */\nexport class IndexedDBROTransaction implements AsyncKeyValueROTransaction {\n\tconstructor(public tx: IDBTransaction, public store: IDBObjectStore) {}\n\n\tpublic get(key: string): Promise<Uint8Array> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\ttry {\n\t\t\t\tconst r: IDBRequest = this.store.get(key);\n\t\t\t\tr.onerror = onErrorHandler(reject);\n\t\t\t\tr.onsuccess = event => {\n\t\t\t\t\t// IDB returns the value 'undefined' when you try to get keys that\n\t\t\t\t\t// don't exist. The caller expects this behavior.\n\t\t\t\t\tconst result = (<any>event.target).result;\n\t\t\t\t\tif (result === undefined) {\n\t\t\t\t\t\tresolve(result);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// IDB data is stored as an ArrayUint8Array\n\t\t\t\t\t\tresolve(Uint8Array.from(result));\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t} catch (e) {\n\t\t\t\treject(convertError(e));\n\t\t\t}\n\t\t});\n\t}\n}\n\n/**\n * @hidden\n */\nexport class IndexedDBRWTransaction extends IndexedDBROTransaction implements AsyncKeyValueRWTransaction, AsyncKeyValueROTransaction {\n\tconstructor(tx: IDBTransaction, store: IDBObjectStore) {\n\t\tsuper(tx, store);\n\t}\n\n\t/**\n\t * @todo return false when add has a key conflict (no error)\n\t */\n\tpublic put(key: string, data: Uint8Array, overwrite: boolean): Promise<boolean> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\ttry {\n\t\t\t\tconst r: IDBRequest = overwrite ? this.store.put(data, key) : this.store.add(data, key);\n\t\t\t\tr.onerror = onErrorHandler(reject);\n\t\t\t\tr.onsuccess = () => {\n\t\t\t\t\tresolve(true);\n\t\t\t\t};\n\t\t\t} catch (e) {\n\t\t\t\treject(convertError(e));\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic del(key: string): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\ttry {\n\t\t\t\tconst r: IDBRequest = this.store.delete(key);\n\t\t\t\tr.onerror = onErrorHandler(reject);\n\t\t\t\tr.onsuccess = () => {\n\t\t\t\t\tresolve();\n\t\t\t\t};\n\t\t\t} catch (e) {\n\t\t\t\treject(convertError(e));\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic commit(): Promise<void> {\n\t\treturn new Promise(resolve => {\n\t\t\t// Return to the event loop to commit the transaction.\n\t\t\tsetTimeout(resolve, 0);\n\t\t});\n\t}\n\n\tpublic abort(): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\ttry {\n\t\t\t\tthis.tx.abort();\n\t\t\t\tresolve();\n\t\t\t} catch (e) {\n\t\t\t\treject(convertError(e));\n\t\t\t}\n\t\t});\n\t}\n}\n\nexport class IndexedDBStore implements AsyncKeyValueStore {\n\tpublic static Create(storeName: string, indexedDB: IDBFactory): Promise<IndexedDBStore> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst openReq: IDBOpenDBRequest = indexedDB.open(storeName, 1);\n\n\t\t\topenReq.onupgradeneeded = event => {\n\t\t\t\tconst db: IDBDatabase = (<IDBOpenDBRequest>event.target).result;\n\t\t\t\t// Huh. This should never happen; we're at version 1. Why does another\n\t\t\t\t// database exist?\n\t\t\t\tif (db.objectStoreNames.contains(storeName)) {\n\t\t\t\t\tdb.deleteObjectStore(storeName);\n\t\t\t\t}\n\t\t\t\tdb.createObjectStore(storeName);\n\t\t\t};\n\n\t\t\topenReq.onsuccess = event => {\n\t\t\t\tresolve(new IndexedDBStore((<IDBOpenDBRequest>event.target).result, storeName));\n\t\t\t};\n\n\t\t\topenReq.onerror = onErrorHandler(reject, ErrorCode.EACCES);\n\t\t});\n\t}\n\n\tconstructor(private db: IDBDatabase, private storeName: string) {}\n\n\tpublic name(): string {\n\t\treturn IndexedDBFileSystem.Name + ' - ' + this.storeName;\n\t}\n\n\tpublic clear(): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\ttry {\n\t\t\t\tconst tx = this.db.transaction(this.storeName, 'readwrite'),\n\t\t\t\t\tobjectStore = tx.objectStore(this.storeName),\n\t\t\t\t\tr: IDBRequest = objectStore.clear();\n\t\t\t\tr.onsuccess = () => {\n\t\t\t\t\t// Use setTimeout to commit transaction.\n\t\t\t\t\tsetTimeout(resolve, 0);\n\t\t\t\t};\n\t\t\t\tr.onerror = onErrorHandler(reject);\n\t\t\t} catch (e) {\n\t\t\t\treject(convertError(e));\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic beginTransaction(type: 'readonly'): AsyncKeyValueROTransaction;\n\tpublic beginTransaction(type: 'readwrite'): AsyncKeyValueRWTransaction;\n\tpublic beginTransaction(type: 'readonly' | 'readwrite' = 'readonly'): AsyncKeyValueROTransaction {\n\t\tconst tx = this.db.transaction(this.storeName, type),\n\t\t\tobjectStore = tx.objectStore(this.storeName);\n\t\tif (type === 'readwrite') {\n\t\t\treturn new IndexedDBRWTransaction(tx, objectStore);\n\t\t} else if (type === 'readonly') {\n\t\t\treturn new IndexedDBROTransaction(tx, objectStore);\n\t\t} else {\n\t\t\tthrow new ApiError(ErrorCode.EINVAL, 'Invalid transaction type.');\n\t\t}\n\t}\n}\n\nexport namespace IndexedDBFileSystem {\n\t/**\n\t * Configuration options for the IndexedDB file system.\n\t */\n\texport interface Options {\n\t\t/**\n\t\t * The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.\n\t\t */\n\t\tstoreName?: string;\n\n\t\t/**\n\t\t * The size of the inode cache. Defaults to 100. A size of 0 or below disables caching.\n\t\t */\n\t\tcacheSize?: number;\n\n\t\t/**\n\t\t * The IDBFactory to use. Defaults to `globalThis.indexedDB`.\n\t\t */\n\t\tidbFactory?: IDBFactory;\n\t}\n}\n\n/**\n * A file system that uses the IndexedDB key value file system.\n */\nexport class IndexedDBFileSystem extends AsyncKeyValueFileSystem {\n\tpublic static readonly Name = 'IndexedDB';\n\n\tpublic static Create = CreateBackend.bind(this);\n\n\tpublic static readonly Options: BackendOptions = {\n\t\tstoreName: {\n\t\t\ttype: 'string',\n\t\t\toptional: true,\n\t\t\tdescription: 'The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.',\n\t\t},\n\t\tcacheSize: {\n\t\t\ttype: 'number',\n\t\t\toptional: true,\n\t\t\tdescription: 'The size of the inode cache. Defaults to 100. A size of 0 or below disables caching.',\n\t\t},\n\t\tidbFactory: {\n\t\t\ttype: 'object',\n\t\t\toptional: true,\n\t\t\tdescription: 'The IDBFactory to use. Defaults to globalThis.indexedDB.',\n\t\t},\n\t};\n\n\tpublic static isAvailable(idbFactory: IDBFactory = globalThis.indexedDB): boolean {\n\t\ttry {\n\t\t\tif (!(idbFactory instanceof IDBFactory)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst req = idbFactory.open('__zenfs_test__');\n\t\t\tif (!req) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tconstructor({ cacheSize = 100, storeName = 'zenfs', idbFactory = globalThis.indexedDB }: IndexedDBFileSystem.Options) {\n\t\tsuper(cacheSize);\n\t\tthis._ready = IndexedDBStore.Create(storeName, idbFactory).then(store => {\n\t\t\tthis.init(store);\n\t\t\treturn this;\n\t\t});\n\t}\n}\n", "import { SyncKeyValueStore, SimpleSyncStore, SyncKeyValueFileSystem, SimpleSyncRWTransaction, SyncKeyValueRWTransaction } from '@zenfs/core/backends/SyncStore.js';\nimport { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';\nimport { CreateBackend, type BackendOptions } from '@zenfs/core/backends/backend.js';\nimport { decode, encode } from '@zenfs/core/utils.js';\n\n/**\n * A synchronous key-value store backed by Storage.\n */\nexport class StorageStore implements SyncKeyValueStore, SimpleSyncStore {\n\tpublic name(): string {\n\t\treturn StorageFileSystem.Name;\n\t}\n\n\tconstructor(protected _storage: Storage) {}\n\n\tpublic clear(): void {\n\t\tthis._storage.clear();\n\t}\n\n\tpublic beginTransaction(type: string): SyncKeyValueRWTransaction {\n\t\t// No need to differentiate.\n\t\treturn new SimpleSyncRWTransaction(this);\n\t}\n\n\tpublic get(key: string): Uint8Array | undefined {\n\t\tconst data = this._storage.getItem(key);\n\t\tif (typeof data != 'string') {\n\t\t\treturn;\n\t\t}\n\n\t\treturn encode(data);\n\t}\n\n\tpublic put(key: string, data: Uint8Array, overwrite: boolean): boolean {\n\t\ttry {\n\t\t\tif (!overwrite && this._storage.getItem(key) !== null) {\n\t\t\t\t// Don't want to overwrite the key!\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis._storage.setItem(key, decode(data));\n\t\t\treturn true;\n\t\t} catch (e) {\n\t\t\tthrow new ApiError(ErrorCode.ENOSPC, 'Storage is full.');\n\t\t}\n\t}\n\n\tpublic del(key: string): void {\n\t\ttry {\n\t\t\tthis._storage.removeItem(key);\n\t\t} catch (e) {\n\t\t\tthrow new ApiError(ErrorCode.EIO, 'Unable to delete key ' + key + ': ' + e);\n\t\t}\n\t}\n}\n\nexport namespace StorageFileSystem {\n\t/**\n\t * Options to pass to the StorageFileSystem\n\t */\n\texport interface Options {\n\t\t/**\n\t\t * The Storage to use. Defaults to globalThis.localStorage.\n\t\t */\n\t\tstorage: Storage;\n\t}\n}\n\n/**\n * A synchronous file system backed by a `Storage` (e.g. localStorage).\n */\nexport class StorageFileSystem extends SyncKeyValueFileSystem {\n\tpublic static readonly Name = 'Storage';\n\n\tpublic static Create = CreateBackend.bind(this);\n\n\tpublic static readonly Options: BackendOptions = {\n\t\tstorage: {\n\t\t\ttype: 'object',\n\t\t\toptional: true,\n\t\t\tdescription: 'The Storage to use. Defaults to globalThis.localStorage.',\n\t\t},\n\t};\n\n\tpublic static isAvailable(storage: Storage = globalThis.localStorage): boolean {\n\t\treturn storage instanceof Storage;\n\t}\n\t/**\n\t * Creates a new Storage file system using the contents of `Storage`.\n\t */\n\tconstructor({ storage = globalThis.localStorage }: StorageFileSystem.Options) {\n\t\tsuper({ store: new StorageStore(storage) });\n\t}\n}\n", "import { type FileSystem, BaseFileSystem, FileContents, FileSystemMetadata } from '@zenfs/core/filesystem.js';\nimport { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';\nimport { File, FileFlag } from '@zenfs/core/file.js';\nimport { Stats } from '@zenfs/core/stats.js';\nimport { Cred } from '@zenfs/core/cred.js';\nimport { CreateBackend, type BackendOptions } from '@zenfs/core/backends/backend.js';\n\n/**\n * @hidden\n */\ndeclare const importScripts: (...path: string[]) => unknown;\n\n/**\n * An RPC message\n */\ninterface RPCMessage {\n\tisBFS: true;\n\tid: number;\n}\n\ntype _FSAsyncMethods = {\n\t[Method in keyof FileSystem]: Extract<FileSystem[Method], (...args: unknown[]) => Promise<unknown>>;\n};\n\ntype _RPCFSRequests = {\n\t[Method in keyof _FSAsyncMethods]: { method: Method; args: Parameters<_FSAsyncMethods[Method]> };\n};\n\ntype _RPCFSResponses = {\n\t[Method in keyof _FSAsyncMethods]: { method: Method; value: Awaited<ReturnType<_FSAsyncMethods[Method]>> };\n};\n\n/**\n * @see https://stackoverflow.com/a/60920767/17637456\n */\ntype RPCRequest = RPCMessage & (_RPCFSRequests[keyof _FSAsyncMethods] | { method: 'metadata'; args: [] } | { method: 'syncClose'; args: [string, File] });\n\ntype RPCResponse = RPCMessage & (_RPCFSResponses[keyof _FSAsyncMethods] | { method: 'metadata'; value: FileSystemMetadata } | { method: 'syncClose'; value: null });\n\nfunction isRPCMessage(arg: unknown): arg is RPCMessage {\n\treturn typeof arg == 'object' && 'isBFS' in arg && !!arg.isBFS;\n}\n\ntype _executor = Parameters<ConstructorParameters<typeof Promise>[0]>;\ninterface WorkerRequest {\n\tresolve: _executor[0];\n\treject: _executor[1];\n}\n\nexport namespace WorkerFS {\n\texport interface Options {\n\t\t/**\n\t\t * The target worker that you want to connect to, or the current worker if in a worker context.\n\t\t */\n\t\tworker: Worker;\n\t}\n}\n\ntype _RPCExtractReturnValue<T extends RPCResponse['method']> = Promise<Extract<RPCResponse, { method: T }>['value']>;\n\n/**\n * WorkerFS lets you access a ZenFS instance that is running in a different\n * JavaScript context (e.g. access ZenFS in one of your WebWorkers, or\n * access ZenFS running on the main page from a WebWorker).\n *\n * For example, to have a WebWorker access files in the main browser thread,\n * do the following:\n *\n * MAIN BROWSER THREAD:\n *\n * ```javascript\n * // Listen for remote file system requests.\n * ZenFS.Backend.WorkerFS.attachRemoteListener(webWorkerObject);\n * ```\n *\n * WEBWORKER THREAD:\n *\n * ```javascript\n * // Set the remote file system as the root file system.\n * ZenFS.configure({ fs: \"WorkerFS\", options: { worker: self }}, function(e) {\n * // Ready!\n * });\n * ```\n *\n * Note that synchronous operations are not permitted on the WorkerFS, regardless\n * of the configuration option of the remote FS.\n */\nexport class WorkerFS extends BaseFileSystem {\n\tpublic static readonly Name = 'WorkerFS';\n\n\tpublic static Create = CreateBackend.bind(this);\n\n\tpublic static readonly Options: BackendOptions = {\n\t\tworker: {\n\t\t\ttype: 'object',\n\t\t\tdescription: 'The target worker that you want to connect to, or the current worker if in a worker context.',\n\t\t\tvalidator(worker: Worker) {\n\t\t\t\t// Check for a `postMessage` function.\n\t\t\t\tif (typeof worker?.postMessage != 'function') {\n\t\t\t\t\tthrow new ApiError(ErrorCode.EINVAL, 'option must be a Web Worker instance.');\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t};\n\n\tpublic static isAvailable(): boolean {\n\t\treturn typeof importScripts !== 'undefined' || typeof Worker !== 'undefined';\n\t}\n\n\tprivate _worker: Worker;\n\tprivate _currentID: number = 0;\n\tprivate _requests: Map<number, WorkerRequest> = new Map();\n\n\tprivate _isInitialized: boolean = false;\n\tprivate _metadata: FileSystemMetadata;\n\n\t/**\n\t * Constructs a new WorkerFS instance that connects with ZenFS running on\n\t * the specified worker.\n\t */\n\tpublic constructor({ worker }: WorkerFS.Options) {\n\t\tsuper();\n\t\tthis._worker = worker;\n\t\tthis._worker.onmessage = (event: MessageEvent) => {\n\t\t\tif (!isRPCMessage(event.data)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst { id, method, value } = event.data as RPCResponse;\n\n\t\t\tif (method === 'metadata') {\n\t\t\t\tthis._metadata = value;\n\t\t\t\tthis._isInitialized = true;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { resolve, reject } = this._requests.get(id);\n\t\t\tthis._requests.delete(id);\n\t\t\tif (value instanceof Error || value instanceof ApiError) {\n\t\t\t\treject(value);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve(value);\n\t\t};\n\t}\n\n\tpublic get metadata(): FileSystemMetadata {\n\t\treturn {\n\t\t\t...super.metadata,\n\t\t\t...this._metadata,\n\t\t\tname: WorkerFS.Name,\n\t\t\tsynchronous: false,\n\t\t};\n\t}\n\n\tprivate async _rpc<T extends RPCRequest['method']>(method: T, ...args: Extract<RPCRequest, { method: T }>['args']): _RPCExtractReturnValue<T> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst id = this._currentID++;\n\t\t\tthis._requests.set(id, { resolve, reject });\n\t\t\tthis._worker.postMessage({\n\t\t\t\tisBFS: true,\n\t\t\t\tid,\n\t\t\t\tmethod,\n\t\t\t\targs,\n\t\t\t} as RPCRequest);\n\t\t});\n\t}\n\n\tpublic rename(oldPath: string, newPath: string, cred: Cred): Promise<void> {\n\t\treturn this._rpc('rename', oldPath, newPath, cred);\n\t}\n\tpublic stat(p: string, cred: Cred): Promise<Stats> {\n\t\treturn this._rpc('stat', p, cred);\n\t}\n\tpublic open(p: string, flag: FileFlag, mode: number, cred: Cred): Promise<File> {\n\t\treturn this._rpc('open', p, flag, mode, cred);\n\t}\n\tpublic unlink(p: string, cred: Cred): Promise<void> {\n\t\treturn this._rpc('unlink', p, cred);\n\t}\n\tpublic rmdir(p: string, cred: Cred): Promise<void> {\n\t\treturn this._rpc('rmdir', p, cred);\n\t}\n\tpublic mkdir(p: string, mode: number, cred: Cred): Promise<void> {\n\t\treturn this._rpc('mkdir', p, mode, cred);\n\t}\n\tpublic readdir(p: string, cred: Cred): Promise<string[]> {\n\t\treturn this._rpc('readdir', p, cred);\n\t}\n\tpublic exists(p: string, cred: Cred): Promise<boolean> {\n\t\treturn this._rpc('exists', p, cred);\n\t}\n\tpublic realpath(p: string, cred: Cred): Promise<string> {\n\t\treturn this._rpc('realpath', p, cred);\n\t}\n\tpublic truncate(p: string, len: number, cred: Cred): Promise<void> {\n\t\treturn this._rpc('truncate', p, len, cred);\n\t}\n\tpublic readFile(fname: string, flag: FileFlag, cred: Cred): Promise<Uint8Array> {\n\t\treturn this._rpc('readFile', fname, flag, cred);\n\t}\n\tpublic writeFile(fname: string, data: Uint8Array, flag: FileFlag, mode: number, cred: Cred): Promise<void> {\n\t\treturn this._rpc('writeFile', fname, data, flag, mode, cred);\n\t}\n\tpublic appendFile(fname: string, data: Uint8Array, flag: FileFlag, mode: number, cred: Cred): Promise<void> {\n\t\treturn this._rpc('appendFile', fname, data, flag, mode, cred);\n\t}\n\tpublic chmod(p: string, mode: number, cred: Cred): Promise<void> {\n\t\treturn this._rpc('chmod', p, mode, cred);\n\t}\n\tpublic chown(p: string, new_uid: number, new_gid: number, cred: Cred): Promise<void> {\n\t\treturn this._rpc('chown', p, new_uid, new_gid, cred);\n\t}\n\tpublic utimes(p: string, atime: Date, mtime: Date, cred: Cred): Promise<void> {\n\t\treturn this._rpc('utimes', p, atime, mtime, cred);\n\t}\n\tpublic link(srcpath: string, dstpath: string, cred: Cred): Promise<void> {\n\t\treturn this._rpc('link', srcpath, dstpath, cred);\n\t}\n\tpublic symlink(srcpath: string, dstpath: string, type: string, cred: Cred): Promise<void> {\n\t\treturn this._rpc('symlink', srcpath, dstpath, type, cred);\n\t}\n\tpublic readlink(p: string, cred: Cred): Promise<string> {\n\t\treturn this._rpc('readlink', p, cred);\n\t}\n\n\tpublic syncClose(method: string, fd: File): Promise<void> {\n\t\treturn this._rpc('syncClose', method, fd);\n\t}\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["src_exports", "__export", "
|
|
3
|
+
"sources": ["../src/index.ts", "../node_modules/@zenfs/core/dist/emulation/path.js", "../node_modules/@zenfs/core/dist/ApiError.js", "../node_modules/@zenfs/core/dist/cred.js", "../node_modules/@zenfs/core/dist/stats.js", "../node_modules/@zenfs/core/dist/inode.js", "../node_modules/@zenfs/core/dist/file.js", "../node_modules/@zenfs/core/dist/filesystem.js", "../src/FileSystemAccess.ts", "../node_modules/@zenfs/core/dist/utils.js", "../node_modules/@zenfs/core/dist/backends/AsyncStore.js", "../src/IndexedDB.ts", "../node_modules/@zenfs/core/dist/backends/SyncStore.js", "../src/Storage.ts"],
|
|
4
|
+
"sourcesContent": ["export * from './FileSystemAccess.js';\nexport * from './IndexedDB.js';\nexport * from './Storage.js';\n", "/*\nCopyright Joyent, Inc. and other Node contributors.\n\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to permit\npersons to whom the Software is furnished to do so, subject to the\nfollowing conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\nNO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\nDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\nUSE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\nexport const cwd = '/';\nexport const sep = '/';\nfunction validateString(str, name) {\n if (typeof str != 'string') {\n throw new TypeError(`\"${name}\" is not a string`);\n }\n}\nfunction validateObject(str, name) {\n if (typeof str != 'object') {\n throw new TypeError(`\"${name}\" is not an object`);\n }\n}\n// Resolves . and .. elements in a path with directory names\nexport function normalizeString(path, allowAboveRoot) {\n let res = '';\n let lastSegmentLength = 0;\n let lastSlash = -1;\n let dots = 0;\n let char = '\\x00';\n for (let i = 0; i <= path.length; ++i) {\n if (i < path.length) {\n char = path[i];\n }\n else if (char == '/') {\n break;\n }\n else {\n char = '/';\n }\n if (char == '/') {\n if (lastSlash === i - 1 || dots === 1) {\n // NOOP\n }\n else if (dots === 2) {\n if (res.length < 2 || lastSegmentLength !== 2 || res.at(-1) !== '.' || res.at(-2) !== '.') {\n if (res.length > 2) {\n const lastSlashIndex = res.lastIndexOf('/');\n if (lastSlashIndex === -1) {\n res = '';\n lastSegmentLength = 0;\n }\n else {\n res = res.slice(0, lastSlashIndex);\n lastSegmentLength = res.length - 1 - res.lastIndexOf('/');\n }\n lastSlash = i;\n dots = 0;\n continue;\n }\n else if (res.length !== 0) {\n res = '';\n lastSegmentLength = 0;\n lastSlash = i;\n dots = 0;\n continue;\n }\n }\n if (allowAboveRoot) {\n res += res.length > 0 ? '/..' : '..';\n lastSegmentLength = 2;\n }\n }\n else {\n if (res.length > 0)\n res += '/' + path.slice(lastSlash + 1, i);\n else\n res = path.slice(lastSlash + 1, i);\n lastSegmentLength = i - lastSlash - 1;\n }\n lastSlash = i;\n dots = 0;\n }\n else if (char === '.' && dots !== -1) {\n ++dots;\n }\n else {\n dots = -1;\n }\n }\n return res;\n}\nexport function formatExt(ext) {\n return ext ? `${ext[0] === '.' ? '' : '.'}${ext}` : '';\n}\nexport function resolve(...args) {\n let resolvedPath = '';\n let resolvedAbsolute = false;\n for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {\n const path = i >= 0 ? args[i] : cwd;\n validateString(path, `paths[${i}]`);\n // Skip empty entries\n if (path.length === 0) {\n continue;\n }\n resolvedPath = `${path}/${resolvedPath}`;\n resolvedAbsolute = path[0] === '/';\n }\n // At this point the path should be resolved to a full absolute path, but\n // handle relative paths to be safe (might happen when process.cwd() fails)\n // Normalize the path\n resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);\n if (resolvedAbsolute) {\n return `/${resolvedPath}`;\n }\n return resolvedPath.length > 0 ? resolvedPath : '.';\n}\nexport function normalize(path) {\n validateString(path, 'path');\n if (path.length === 0)\n return '.';\n const isAbsolute = path[0] === '/';\n const trailingSeparator = path.at(-1) === '/';\n // Normalize the path\n path = normalizeString(path, !isAbsolute);\n if (path.length === 0) {\n if (isAbsolute)\n return '/';\n return trailingSeparator ? './' : '.';\n }\n if (trailingSeparator)\n path += '/';\n return isAbsolute ? `/${path}` : path;\n}\nexport function isAbsolute(path) {\n validateString(path, 'path');\n return path.length > 0 && path[0] === '/';\n}\nexport function join(...args) {\n if (args.length === 0)\n return '.';\n let joined;\n for (let i = 0; i < args.length; ++i) {\n const arg = args[i];\n validateString(arg, 'path');\n if (arg.length > 0) {\n if (joined === undefined)\n joined = arg;\n else\n joined += `/${arg}`;\n }\n }\n if (joined === undefined)\n return '.';\n return normalize(joined);\n}\nexport function relative(from, to) {\n validateString(from, 'from');\n validateString(to, 'to');\n if (from === to)\n return '';\n // Trim leading forward slashes.\n from = resolve(from);\n to = resolve(to);\n if (from === to)\n return '';\n const fromStart = 1;\n const fromEnd = from.length;\n const fromLen = fromEnd - fromStart;\n const toStart = 1;\n const toLen = to.length - toStart;\n // Compare paths to find the longest common path from root\n const length = fromLen < toLen ? fromLen : toLen;\n let lastCommonSep = -1;\n let i = 0;\n for (; i < length; i++) {\n const fromCode = from[fromStart + i];\n if (fromCode !== to[toStart + i])\n break;\n else if (fromCode === '/')\n lastCommonSep = i;\n }\n if (i === length) {\n if (toLen > length) {\n if (to[toStart + i] === '/') {\n // We get here if `from` is the exact base path for `to`.\n // For example: from='/foo/bar'; to='/foo/bar/baz'\n return to.slice(toStart + i + 1);\n }\n if (i === 0) {\n // We get here if `from` is the root\n // For example: from='/'; to='/foo'\n return to.slice(toStart + i);\n }\n }\n else if (fromLen > length) {\n if (from[fromStart + i] === '/') {\n // We get here if `to` is the exact base path for `from`.\n // For example: from='/foo/bar/baz'; to='/foo/bar'\n lastCommonSep = i;\n }\n else if (i === 0) {\n // We get here if `to` is the root.\n // For example: from='/foo/bar'; to='/'\n lastCommonSep = 0;\n }\n }\n }\n let out = '';\n // Generate the relative path based on the path difference between `to`\n // and `from`.\n for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {\n if (i === fromEnd || from[i] === '/') {\n out += out.length === 0 ? '..' : '/..';\n }\n }\n // Lastly, append the rest of the destination (`to`) path that comes after\n // the common path parts.\n return `${out}${to.slice(toStart + lastCommonSep)}`;\n}\nexport function dirname(path) {\n validateString(path, 'path');\n if (path.length === 0)\n return '.';\n const hasRoot = path[0] === '/';\n let end = -1;\n let matchedSlash = true;\n for (let i = path.length - 1; i >= 1; --i) {\n if (path[i] === '/') {\n if (!matchedSlash) {\n end = i;\n break;\n }\n }\n else {\n // We saw the first non-path separator\n matchedSlash = false;\n }\n }\n if (end === -1)\n return hasRoot ? '/' : '.';\n if (hasRoot && end === 1)\n return '//';\n return path.slice(0, end);\n}\nexport function basename(path, suffix) {\n if (suffix !== undefined)\n validateString(suffix, 'ext');\n validateString(path, 'path');\n let start = 0;\n let end = -1;\n let matchedSlash = true;\n if (suffix !== undefined && suffix.length > 0 && suffix.length <= path.length) {\n if (suffix === path)\n return '';\n let extIdx = suffix.length - 1;\n let firstNonSlashEnd = -1;\n for (let i = path.length - 1; i >= 0; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n start = i + 1;\n break;\n }\n }\n else {\n if (firstNonSlashEnd === -1) {\n // We saw the first non-path separator, remember this index in case\n // we need it if the extension ends up not matching\n matchedSlash = false;\n firstNonSlashEnd = i + 1;\n }\n if (extIdx >= 0) {\n // Try to match the explicit extension\n if (path[i] === suffix[extIdx]) {\n if (--extIdx === -1) {\n // We matched the extension, so mark this as the end of our path\n // component\n end = i;\n }\n }\n else {\n // Extension does not match, so our result is the entire path\n // component\n extIdx = -1;\n end = firstNonSlashEnd;\n }\n }\n }\n }\n if (start === end)\n end = firstNonSlashEnd;\n else if (end === -1)\n end = path.length;\n return path.slice(start, end);\n }\n for (let i = path.length - 1; i >= 0; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n start = i + 1;\n break;\n }\n }\n else if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // path component\n matchedSlash = false;\n end = i + 1;\n }\n }\n if (end === -1)\n return '';\n return path.slice(start, end);\n}\nexport function extname(path) {\n validateString(path, 'path');\n let startDot = -1;\n let startPart = 0;\n let end = -1;\n let matchedSlash = true;\n // Track the state of characters (if any) we see before our first dot and\n // after any path separator we find\n let preDotState = 0;\n for (let i = path.length - 1; i >= 0; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n startPart = i + 1;\n break;\n }\n continue;\n }\n if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // extension\n matchedSlash = false;\n end = i + 1;\n }\n if (path[i] === '.') {\n // If this is our first dot, mark it as the start of our extension\n if (startDot === -1)\n startDot = i;\n else if (preDotState !== 1)\n preDotState = 1;\n }\n else if (startDot !== -1) {\n // We saw a non-dot and non-path separator before our dot, so we should\n // have a good chance at having a non-empty extension\n preDotState = -1;\n }\n }\n if (startDot === -1 ||\n end === -1 ||\n // We saw a non-dot character immediately before the dot\n preDotState === 0 ||\n // The (right-most) trimmed path component is exactly '..'\n (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)) {\n return '';\n }\n return path.slice(startDot, end);\n}\nexport function format(pathObject) {\n validateObject(pathObject, 'pathObject');\n const dir = pathObject.dir || pathObject.root;\n const base = pathObject.base || `${pathObject.name || ''}${formatExt(pathObject.ext)}`;\n if (!dir) {\n return base;\n }\n return dir === pathObject.root ? `${dir}${base}` : `${dir}/${base}`;\n}\nexport function parse(path) {\n validateString(path, 'path');\n const isAbsolute = path[0] === '/';\n const ret = { root: isAbsolute ? '/' : '', dir: '', base: '', ext: '', name: '' };\n if (path.length === 0)\n return ret;\n const start = isAbsolute ? 1 : 0;\n let startDot = -1;\n let startPart = 0;\n let end = -1;\n let matchedSlash = true;\n let i = path.length - 1;\n // Track the state of characters (if any) we see before our first dot and\n // after any path separator we find\n let preDotState = 0;\n // Get non-dir info\n for (; i >= start; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n startPart = i + 1;\n break;\n }\n continue;\n }\n if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // extension\n matchedSlash = false;\n end = i + 1;\n }\n if (path[i] === '.') {\n // If this is our first dot, mark it as the start of our extension\n if (startDot === -1)\n startDot = i;\n else if (preDotState !== 1)\n preDotState = 1;\n }\n else if (startDot !== -1) {\n // We saw a non-dot and non-path separator before our dot, so we should\n // have a good chance at having a non-empty extension\n preDotState = -1;\n }\n }\n if (end !== -1) {\n const start = startPart === 0 && isAbsolute ? 1 : startPart;\n if (startDot === -1 ||\n // We saw a non-dot character immediately before the dot\n preDotState === 0 ||\n // The (right-most) trimmed path component is exactly '..'\n (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)) {\n ret.base = ret.name = path.slice(start, end);\n }\n else {\n ret.name = path.slice(start, startDot);\n ret.base = path.slice(start, end);\n ret.ext = path.slice(startDot, end);\n }\n }\n if (startPart > 0)\n ret.dir = path.slice(0, startPart - 1);\n else if (isAbsolute)\n ret.dir = '/';\n return ret;\n}\n", "/**\n * Standard libc error codes. More will be added to this enum and ErrorStrings as they are\n * needed.\n * @url http://www.gnu.org/software/libc/manual/html_node/Error-Codes.html\n */\nexport var ErrorCode;\n(function (ErrorCode) {\n /**\n * Operation not permitted\n */\n ErrorCode[ErrorCode[\"EPERM\"] = 1] = \"EPERM\";\n /**\n * No such file or directory\n */\n ErrorCode[ErrorCode[\"ENOENT\"] = 2] = \"ENOENT\";\n /**\n * Input/output error\n */\n ErrorCode[ErrorCode[\"EIO\"] = 5] = \"EIO\";\n /**\n * Bad file descriptor\n */\n ErrorCode[ErrorCode[\"EBADF\"] = 9] = \"EBADF\";\n /**\n * Permission denied\n */\n ErrorCode[ErrorCode[\"EACCES\"] = 13] = \"EACCES\";\n /**\n * Resource busy or locked\n */\n ErrorCode[ErrorCode[\"EBUSY\"] = 16] = \"EBUSY\";\n /**\n * File exists\n */\n ErrorCode[ErrorCode[\"EEXIST\"] = 17] = \"EEXIST\";\n /**\n * File is not a directory\n */\n ErrorCode[ErrorCode[\"ENOTDIR\"] = 20] = \"ENOTDIR\";\n /**\n * File is a directory\n */\n ErrorCode[ErrorCode[\"EISDIR\"] = 21] = \"EISDIR\";\n /**\n * Invalid argument\n */\n ErrorCode[ErrorCode[\"EINVAL\"] = 22] = \"EINVAL\";\n /**\n * File is too big\n */\n ErrorCode[ErrorCode[\"EFBIG\"] = 27] = \"EFBIG\";\n /**\n * No space left on disk\n */\n ErrorCode[ErrorCode[\"ENOSPC\"] = 28] = \"ENOSPC\";\n /**\n * Cannot modify a read-only file system\n */\n ErrorCode[ErrorCode[\"EROFS\"] = 30] = \"EROFS\";\n /**\n * Directory is not empty\n */\n ErrorCode[ErrorCode[\"ENOTEMPTY\"] = 39] = \"ENOTEMPTY\";\n /**\n * Operation is not supported\n */\n ErrorCode[ErrorCode[\"ENOTSUP\"] = 95] = \"ENOTSUP\";\n})(ErrorCode = ErrorCode || (ErrorCode = {}));\n/**\n * Strings associated with each error code.\n * @internal\n */\nexport const ErrorStrings = {\n [ErrorCode.EPERM]: 'Operation not permitted.',\n [ErrorCode.ENOENT]: 'No such file or directory.',\n [ErrorCode.EIO]: 'Input/output error.',\n [ErrorCode.EBADF]: 'Bad file descriptor.',\n [ErrorCode.EACCES]: 'Permission denied.',\n [ErrorCode.EBUSY]: 'Resource busy or locked.',\n [ErrorCode.EEXIST]: 'File exists.',\n [ErrorCode.ENOTDIR]: 'File is not a directory.',\n [ErrorCode.EISDIR]: 'File is a directory.',\n [ErrorCode.EINVAL]: 'Invalid argument.',\n [ErrorCode.EFBIG]: 'File is too big.',\n [ErrorCode.ENOSPC]: 'No space left on disk.',\n [ErrorCode.EROFS]: 'Cannot modify a read-only file system.',\n [ErrorCode.ENOTEMPTY]: 'Directory is not empty.',\n [ErrorCode.ENOTSUP]: 'Operation is not supported.',\n};\n/**\n * Represents a BrowserFS error. Passed back to applications after a failed\n * call to the BrowserFS API.\n */\nexport class ApiError extends Error {\n static fromJSON(json) {\n const err = new ApiError(json.errno, json.message, json.path);\n err.code = json.code;\n err.stack = json.stack;\n return err;\n }\n static OnPath(code, path) {\n return new ApiError(code, ErrorStrings[code], path);\n }\n static EACCES(path) {\n return this.OnPath(ErrorCode.EACCES, path);\n }\n static ENOENT(path) {\n return this.OnPath(ErrorCode.ENOENT, path);\n }\n static EEXIST(path) {\n return this.OnPath(ErrorCode.EEXIST, path);\n }\n static EISDIR(path) {\n return this.OnPath(ErrorCode.EISDIR, path);\n }\n static ENOTDIR(path) {\n return this.OnPath(ErrorCode.ENOTDIR, path);\n }\n static EPERM(path) {\n return this.OnPath(ErrorCode.EPERM, path);\n }\n static ENOTEMPTY(path) {\n return this.OnPath(ErrorCode.ENOTEMPTY, path);\n }\n /**\n * Represents a BrowserFS error. Passed back to applications after a failed\n * call to the BrowserFS API.\n *\n * Error codes mirror those returned by regular Unix file operations, which is\n * what Node returns.\n * @constructor ApiError\n * @param type The type of the error.\n * @param message A descriptive error message.\n */\n constructor(errno, message = ErrorStrings[errno], path) {\n super(message);\n this.errno = errno;\n this.path = path;\n // Unsupported.\n this.syscall = '';\n this.code = ErrorCode[errno];\n this.message = `${this.code}: ${message}${this.path ? `, '${this.path}'` : ''}`;\n }\n /**\n * @return A friendly error message.\n */\n toString() {\n return this.message;\n }\n toJSON() {\n return {\n errno: this.errno,\n code: this.code,\n path: this.path,\n stack: this.stack,\n message: this.message,\n };\n }\n /**\n * The size of the API error in buffer-form in bytes.\n */\n bufferSize() {\n // 4 bytes for string length.\n return 4 + JSON.stringify(this.toJSON()).length;\n }\n}\n", "/**\n * Credentials used for various operations.\n * Similar to Linux's cred struct. See https://github.com/torvalds/linux/blob/master/include/linux/cred.h\n */\nexport class Cred {\n constructor(uid, gid, suid, sgid, euid, egid) {\n this.uid = uid;\n this.gid = gid;\n this.suid = suid;\n this.sgid = sgid;\n this.euid = euid;\n this.egid = egid;\n }\n}\nCred.Root = new Cred(0, 0, 0, 0, 0, 0);\n", "import { Cred } from './cred.js';\nimport { S_IFDIR, S_IFLNK, S_IFMT, S_IFREG } from './emulation/constants.js';\n/**\n * Indicates the type of the given file. Applied to 'mode'.\n */\nexport var FileType;\n(function (FileType) {\n FileType[FileType[\"FILE\"] = S_IFREG] = \"FILE\";\n FileType[FileType[\"DIRECTORY\"] = S_IFDIR] = \"DIRECTORY\";\n FileType[FileType[\"SYMLINK\"] = S_IFLNK] = \"SYMLINK\";\n})(FileType = FileType || (FileType = {}));\n/**\n * Provides information about a particular entry in the file system.\n * Common code used by both Stats and BigIntStats.\n */\nexport class StatsCommon {\n get _typename() {\n return this._isBigint ? 'bigint' : 'number';\n }\n get _typename_inverse() {\n return this._isBigint ? 'number' : 'bigint';\n }\n _convert(arg) {\n return (this._isBigint ? BigInt(arg) : Number(arg));\n }\n get atime() {\n return new Date(Number(this.atimeMs));\n }\n set atime(value) {\n this.atimeMs = this._convert(value.getTime());\n }\n get mtime() {\n return new Date(Number(this.mtimeMs));\n }\n set mtime(value) {\n this.mtimeMs = this._convert(value.getTime());\n }\n get ctime() {\n return new Date(Number(this.ctimeMs));\n }\n set ctime(value) {\n this.ctimeMs = this._convert(value.getTime());\n }\n get birthtime() {\n return new Date(Number(this.birthtimeMs));\n }\n set birthtime(value) {\n this.birthtimeMs = this._convert(value.getTime());\n }\n /**\n * Creates a new stats instance from a stats-like object. Can be used to copy stats (note)\n */\n constructor({ atimeMs, mtimeMs, ctimeMs, birthtimeMs, uid, gid, size, mode } = {}) {\n /**\n * ID of device containing file\n */\n this.dev = this._convert(0);\n /**\n * inode number\n */\n this.ino = this._convert(0);\n /**\n * device ID (if special file)\n */\n this.rdev = this._convert(0);\n /**\n * number of hard links\n */\n this.nlink = this._convert(1);\n /**\n * blocksize for file system I/O\n */\n this.blksize = this._convert(4096);\n /**\n * user ID of owner\n */\n this.uid = this._convert(0);\n /**\n * group ID of owner\n */\n this.gid = this._convert(0);\n /**\n * Some file systems stash data on stats objects.\n */\n this.fileData = null;\n const currentTime = Date.now();\n const resolveT = (val, _default) => (typeof val == this._typename ? val : this._convert(typeof val == this._typename_inverse ? val : _default));\n this.atimeMs = resolveT(atimeMs, currentTime);\n this.mtimeMs = resolveT(mtimeMs, currentTime);\n this.ctimeMs = resolveT(ctimeMs, currentTime);\n this.birthtimeMs = resolveT(birthtimeMs, currentTime);\n this.uid = resolveT(uid, 0);\n this.gid = resolveT(gid, 0);\n this.size = this._convert(size);\n const itemType = Number(mode) & S_IFMT || FileType.FILE;\n if (mode) {\n this.mode = this._convert(mode);\n }\n else {\n switch (itemType) {\n case FileType.FILE:\n this.mode = this._convert(0o644);\n break;\n case FileType.DIRECTORY:\n default:\n this.mode = this._convert(0o777);\n }\n }\n // number of 512B blocks allocated\n this.blocks = this._convert(Math.ceil(Number(size) / 512));\n // Check if mode also includes top-most bits, which indicate the file's type.\n if ((this.mode & S_IFMT) == 0) {\n this.mode = (this.mode | this._convert(itemType));\n }\n }\n /**\n * @returns true if this item is a file.\n */\n isFile() {\n return (this.mode & S_IFMT) === S_IFREG;\n }\n /**\n * @returns True if this item is a directory.\n */\n isDirectory() {\n return (this.mode & S_IFMT) === S_IFDIR;\n }\n /**\n * @returns true if this item is a symbolic link\n */\n isSymbolicLink() {\n return (this.mode & S_IFMT) === S_IFLNK;\n }\n // Currently unsupported\n isSocket() {\n return false;\n }\n isBlockDevice() {\n return false;\n }\n isCharacterDevice() {\n return false;\n }\n isFIFO() {\n return false;\n }\n /**\n * Checks if a given user/group has access to this item\n * @param mode The request access as 4 bits (unused, read, write, execute)\n * @param uid The requesting UID\n * @param gid The requesting GID\n * @returns True if the request has access, false if the request does not\n * @internal\n */\n hasAccess(mode, cred) {\n if (cred.euid === 0 || cred.egid === 0) {\n //Running as root\n return true;\n }\n const perms = this.mode & ~S_IFMT;\n let uMode = 0xf, gMode = 0xf, wMode = 0xf;\n if (cred.euid == this.uid) {\n const uPerms = (0xf00 & perms) >> 8;\n uMode = (mode ^ uPerms) & mode;\n }\n if (cred.egid == this.gid) {\n const gPerms = (0xf0 & perms) >> 4;\n gMode = (mode ^ gPerms) & mode;\n }\n const wPerms = 0xf & perms;\n wMode = (mode ^ wPerms) & mode;\n /*\n Result = 0b0xxx (read, write, execute)\n If any bits are set that means the request does not have that permission.\n */\n const result = uMode & gMode & wMode;\n return !result;\n }\n /**\n * Convert the current stats object into a cred object\n * @internal\n */\n getCred(uid = Number(this.uid), gid = Number(this.gid)) {\n return new Cred(uid, gid, Number(this.uid), Number(this.gid), uid, gid);\n }\n /**\n * Change the mode of the file. We use this helper function to prevent messing\n * up the type of the file, which is encoded in mode.\n * @internal\n */\n chmod(mode) {\n this.mode = this._convert((this.mode & S_IFMT) | mode);\n }\n /**\n * Change the owner user/group of the file.\n * This function makes sure it is a valid UID/GID (that is, a 32 unsigned int)\n * @internal\n */\n chown(uid, gid) {\n uid = Number(uid);\n gid = Number(gid);\n if (!isNaN(uid) && 0 <= uid && uid < 2 ** 32) {\n this.uid = this._convert(uid);\n }\n if (!isNaN(gid) && 0 <= gid && gid < 2 ** 32) {\n this.gid = this._convert(gid);\n }\n }\n}\n/**\n * Implementation of Node's `Stats`.\n *\n * Attribute descriptions are from `man 2 stat'\n * @see http://nodejs.org/api/fs.html#fs_class_fs_stats\n * @see http://man7.org/linux/man-pages/man2/stat.2.html\n */\nexport class Stats extends StatsCommon {\n constructor() {\n super(...arguments);\n this._isBigint = false;\n }\n /**\n * Clones the stats object.\n * @deprecated use `new Stats(stats)`\n */\n static clone(stats) {\n return new Stats(stats);\n }\n}\nStats;\n/**\n * Stats with bigint\n * @todo Implement with bigint instead of wrapping Stats\n */\nexport class BigIntStats extends StatsCommon {\n constructor() {\n super(...arguments);\n this._isBigint = true;\n }\n /**\n * Clone a stats object.\n * @deprecated use `new BigIntStats(stats)`\n */\n static clone(stats) {\n return new BigIntStats(stats);\n }\n}\nBigIntStats;\n", "import { Stats } from './stats.js';\n/**\n * Max 32-bit integer\n * @hidden\n */\nexport const size_max = 2 ** 32 - 1;\n/**\n * Room inode\n * @hidden\n */\nexport const rootIno = 0n;\n/**\n * Generates a random 32 bit integer, then converts to a hex string\n */\nfunction _random() {\n return Math.round(Math.random() * 2 ** 32).toString(16);\n}\n/**\n * Generate a random ino\n * @internal\n */\nexport function randomIno() {\n return BigInt('0x' + _random() + _random());\n}\n/**\n * Offsets for inode members\n */\nvar Offset;\n(function (Offset) {\n Offset[Offset[\"ino\"] = 0] = \"ino\";\n Offset[Offset[\"size\"] = 8] = \"size\";\n Offset[Offset[\"mode\"] = 12] = \"mode\";\n Offset[Offset[\"nlink\"] = 14] = \"nlink\";\n Offset[Offset[\"uid\"] = 18] = \"uid\";\n Offset[Offset[\"gid\"] = 22] = \"gid\";\n Offset[Offset[\"atime\"] = 26] = \"atime\";\n Offset[Offset[\"birthtime\"] = 34] = \"birthtime\";\n Offset[Offset[\"mtime\"] = 42] = \"mtime\";\n Offset[Offset[\"ctime\"] = 50] = \"ctime\";\n Offset[Offset[\"end\"] = 58] = \"end\";\n})(Offset || (Offset = {}));\n/**\n * Generic inode definition that can easily be serialized.\n */\nexport class Inode {\n get data() {\n return new Uint8Array(this.buffer);\n }\n constructor(buffer) {\n const setDefaults = !buffer;\n buffer ?? (buffer = new ArrayBuffer(Offset.end));\n if (buffer?.byteLength < Offset.end) {\n throw new RangeError(`Can not create an inode from a buffer less than ${Offset.end} bytes`);\n }\n this.view = new DataView(buffer);\n this.buffer = buffer;\n if (!setDefaults) {\n return;\n }\n // set defaults on a fresh inode\n this.ino = randomIno();\n this.nlink = 1;\n this.size = 4096;\n const now = Date.now();\n this.atimeMs = now;\n this.mtimeMs = now;\n this.ctimeMs = now;\n this.birthtimeMs = now;\n }\n get ino() {\n return this.view.getBigUint64(Offset.ino, true);\n }\n set ino(value) {\n this.view.setBigUint64(Offset.ino, value, true);\n }\n get size() {\n return this.view.getUint32(Offset.size, true);\n }\n set size(value) {\n this.view.setUint32(Offset.size, value, true);\n }\n get mode() {\n return this.view.getUint16(Offset.mode, true);\n }\n set mode(value) {\n this.view.setUint16(Offset.mode, value, true);\n }\n get nlink() {\n return this.view.getUint32(Offset.nlink, true);\n }\n set nlink(value) {\n this.view.setUint32(Offset.nlink, value, true);\n }\n get uid() {\n return this.view.getUint32(Offset.uid, true);\n }\n set uid(value) {\n this.view.setUint32(Offset.uid, value, true);\n }\n get gid() {\n return this.view.getUint32(Offset.gid, true);\n }\n set gid(value) {\n this.view.setUint32(Offset.gid, value, true);\n }\n get atimeMs() {\n return this.view.getFloat64(Offset.atime, true);\n }\n set atimeMs(value) {\n this.view.setFloat64(Offset.atime, value, true);\n }\n get birthtimeMs() {\n return this.view.getFloat64(Offset.birthtime, true);\n }\n set birthtimeMs(value) {\n this.view.setFloat64(Offset.birthtime, value, true);\n }\n get mtimeMs() {\n return this.view.getFloat64(Offset.mtime, true);\n }\n set mtimeMs(value) {\n this.view.setFloat64(Offset.mtime, value, true);\n }\n get ctimeMs() {\n return this.view.getFloat64(Offset.ctime, true);\n }\n set ctimeMs(value) {\n this.view.setFloat64(Offset.ctime, value, true);\n }\n /**\n * Handy function that converts the Inode to a Node Stats object.\n */\n toStats() {\n return new Stats(this);\n }\n /**\n * Updates the Inode using information from the stats object. Used by file\n * systems at sync time, e.g.:\n * - Program opens file and gets a File object.\n * - Program mutates file. File object is responsible for maintaining\n * metadata changes locally -- typically in a Stats object.\n * - Program closes file. File object's metadata changes are synced with the\n * file system.\n * @return True if any changes have occurred.\n */\n update(stats) {\n let hasChanged = false;\n if (this.size !== stats.size) {\n this.size = stats.size;\n hasChanged = true;\n }\n if (this.mode !== stats.mode) {\n this.mode = stats.mode;\n hasChanged = true;\n }\n if (this.nlink !== stats.nlink) {\n this.nlink = stats.nlink;\n hasChanged = true;\n }\n if (this.uid !== stats.uid) {\n this.uid = stats.uid;\n hasChanged = true;\n }\n if (this.uid !== stats.uid) {\n this.uid = stats.uid;\n hasChanged = true;\n }\n if (this.atimeMs !== stats.atimeMs) {\n this.atimeMs = stats.atimeMs;\n hasChanged = true;\n }\n if (this.mtimeMs !== stats.mtimeMs) {\n this.mtimeMs = stats.mtimeMs;\n hasChanged = true;\n }\n if (this.ctimeMs !== stats.ctimeMs) {\n this.ctimeMs = stats.ctimeMs;\n hasChanged = true;\n }\n return hasChanged;\n }\n}\n", "import { ApiError, ErrorCode } from './ApiError.js';\nimport { O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY, S_IFMT } from './emulation/constants.js';\nimport { size_max } from './inode.js';\nimport { Stats } from './stats.js';\n/**\n * @hidden\n */\nexport var ActionType;\n(function (ActionType) {\n // Indicates that the code should not do anything.\n ActionType[ActionType[\"NOP\"] = 0] = \"NOP\";\n // Indicates that the code should throw an exception.\n ActionType[ActionType[\"THROW\"] = 1] = \"THROW\";\n // Indicates that the code should truncate the file, but only if it is a file.\n ActionType[ActionType[\"TRUNCATE\"] = 2] = \"TRUNCATE\";\n // Indicates that the code should create the file.\n ActionType[ActionType[\"CREATE\"] = 3] = \"CREATE\";\n})(ActionType = ActionType || (ActionType = {}));\n/**\n * Represents one of the following file flags. A convenience object.\n *\n * - r: \tOpen file for reading. An exception occurs if the file does not exist.\n * - r+: \tOpen file for reading and writing. An exception occurs if the file does not exist.\n * - rs: \tOpen file for reading in synchronous mode. Instructs the filesystem to not cache writes.\n * - rs+: \tOpen file for reading and writing, and opens the file in synchronous mode.\n * - w: \tOpen file for writing. The file is created (if it does not exist) or truncated (if it exists).\n * - wx: \tLike 'w' but opens the file in exclusive mode.\n * - w+: \tOpen file for reading and writing. The file is created (if it does not exist) or truncated (if it exists).\n * - wx+: \tLike 'w+' but opens the file in exclusive mode.\n * - a: \tOpen file for appending. The file is created if it does not exist.\n * - ax: \tLike 'a' but opens the file in exclusive mode.\n * - a+: \tOpen file for reading and appending. The file is created if it does not exist.\n * - ax+: \tLike 'a+' but opens the file in exclusive mode.\n *\n * Exclusive mode ensures that the file path is newly created.\n */\nexport class FileFlag {\n /**\n * Get an object representing the given file flag.\n * @param flag The string or number representing the flag\n * @return The FileFlag object representing the flag\n * @throw when the flag string is invalid\n */\n static Get(flag) {\n // Check cache first.\n if (!FileFlag.cache.has(flag)) {\n FileFlag.cache.set(flag, new FileFlag(flag));\n }\n return FileFlag.cache.get(flag);\n }\n /**\n * @param flag The string or number representing the flag\n * @throw when the flag is invalid\n */\n constructor(flag) {\n if (typeof flag == 'number') {\n flag = FileFlag.StringOf(flag);\n }\n if (!FileFlag.validStrings.includes(flag)) {\n throw new ApiError(ErrorCode.EINVAL, 'Invalid flag string: ' + flag);\n }\n this._flag = flag;\n }\n /**\n * @param flag The number representing the flag\n * @returns The string representing the flag\n * @throws when the flag number is invalid\n */\n static StringOf(flag) {\n // based on https://github.com/nodejs/node/blob/abbdc3efaa455e6c907ebef5409ac8b0f222f969/lib/internal/fs/utils.js#L619\n switch (flag) {\n case O_RDONLY:\n return 'r';\n case O_RDONLY | O_SYNC:\n return 'rs';\n case O_RDWR:\n return 'r+';\n case O_RDWR | O_SYNC:\n return 'rs+';\n case O_TRUNC | O_CREAT | O_WRONLY:\n return 'w';\n case O_TRUNC | O_CREAT | O_WRONLY | O_EXCL:\n return 'wx';\n case O_TRUNC | O_CREAT | O_RDWR:\n return 'w+';\n case O_TRUNC | O_CREAT | O_RDWR | O_EXCL:\n return 'wx+';\n case O_APPEND | O_CREAT | O_WRONLY:\n return 'a';\n case O_APPEND | O_CREAT | O_WRONLY | O_EXCL:\n return 'ax';\n case O_APPEND | O_CREAT | O_RDWR:\n return 'a+';\n case O_APPEND | O_CREAT | O_RDWR | O_EXCL:\n return 'ax+';\n default:\n throw new ApiError(ErrorCode.EINVAL, 'Invalid flag number: ' + flag);\n }\n }\n /**\n * @param flag The string representing the flag\n * @returns The number representing the flag\n * @throws when the flag string is invalid\n */\n static NumberOf(flag) {\n switch (flag) {\n case 'r':\n return O_RDONLY;\n case 'rs':\n return O_RDONLY | O_SYNC;\n case 'r+':\n return O_RDWR;\n case 'rs+':\n return O_RDWR | O_SYNC;\n case 'w':\n return O_TRUNC | O_CREAT | O_WRONLY;\n case 'wx':\n return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL;\n case 'w+':\n return O_TRUNC | O_CREAT | O_RDWR;\n case 'wx+':\n return O_TRUNC | O_CREAT | O_RDWR | O_EXCL;\n case 'a':\n return O_APPEND | O_CREAT | O_WRONLY;\n case 'ax':\n return O_APPEND | O_CREAT | O_WRONLY | O_EXCL;\n case 'a+':\n return O_APPEND | O_CREAT | O_RDWR;\n case 'ax+':\n return O_APPEND | O_CREAT | O_RDWR | O_EXCL;\n default:\n throw new ApiError(ErrorCode.EINVAL, 'Invalid flag string: ' + flag);\n }\n }\n /**\n * Get the underlying flag string for this flag.\n */\n toString() {\n return this._flag;\n }\n /**\n * Get the equivalent mode (0b0xxx: read, write, execute)\n * Note: Execute will always be 0\n */\n get mode() {\n let mode = 0;\n mode <<= 1;\n mode += +this.isReadable();\n mode <<= 1;\n mode += +this.isWriteable();\n mode <<= 1;\n return mode;\n }\n /**\n * Returns true if the file is readable.\n */\n isReadable() {\n return this._flag.indexOf('r') != -1 || this._flag.indexOf('+') != -1;\n }\n /**\n * Returns true if the file is writeable.\n */\n isWriteable() {\n return this._flag.indexOf('w') != -1 || this._flag.indexOf('a') != -1 || this._flag.indexOf('+') != -1;\n }\n /**\n * Returns true if the file mode should truncate.\n */\n isTruncating() {\n return this._flag.indexOf('w') !== -1;\n }\n /**\n * Returns true if the file is appendable.\n */\n isAppendable() {\n return this._flag.indexOf('a') !== -1;\n }\n /**\n * Returns true if the file is open in synchronous mode.\n */\n isSynchronous() {\n return this._flag.indexOf('s') !== -1;\n }\n /**\n * Returns true if the file is open in exclusive mode.\n */\n isExclusive() {\n return this._flag.indexOf('x') !== -1;\n }\n /**\n * Returns one of the static fields on this object that indicates the\n * appropriate response to the path existing.\n */\n pathExistsAction() {\n if (this.isExclusive()) {\n return ActionType.THROW;\n }\n if (this.isTruncating()) {\n return ActionType.TRUNCATE;\n }\n return ActionType.NOP;\n }\n /**\n * Returns one of the static fields on this object that indicates the\n * appropriate response to the path not existing.\n */\n pathNotExistsAction() {\n if ((this.isWriteable() || this.isAppendable()) && this._flag != 'r+') {\n return ActionType.CREATE;\n }\n return ActionType.THROW;\n }\n}\n/**\n * Contains cached FileMode instances.\n */\nFileFlag.cache = new Map();\n/**\n * Array of valid mode strings.\n */\nFileFlag.validStrings = ['r', 'r+', 'rs', 'rs+', 'w', 'wx', 'w+', 'wx+', 'a', 'ax', 'a+', 'ax+'];\nexport class File {\n /**\n * Asynchronous `datasync`.\n *\n * Default implementation maps to `sync`.\n */\n datasync() {\n return this.sync();\n }\n /**\n * Synchronous `datasync`.\n *\n * Default implementation maps to `syncSync`.\n */\n datasyncSync() {\n return this.syncSync();\n }\n}\n/**\n * An implementation of the File interface that operates on a file that is\n * completely in-memory. PreloadFiles are backed by a Uint8Array.\n *\n * This is also an abstract class, as it lacks an implementation of 'sync' and\n * 'close'. Each filesystem that wishes to use this file representation must\n * extend this class and implement those two methods.\n * @todo 'close' lever that disables functionality once closed.\n */\nexport class PreloadFile extends File {\n /**\n * Creates a file with the given path and, optionally, the given contents. Note\n * that, if contents is specified, it will be mutated by the file!\n * @param _mode The mode that the file was opened using.\n * Dictates permissions and where the file pointer starts.\n * @param stats The stats object for the given file.\n * PreloadFile will mutate this object. Note that this object must contain\n * the appropriate mode that the file was opened as.\n * @param buffer A buffer containing the entire\n * contents of the file. PreloadFile will mutate this buffer. If not\n * specified, we assume it is a new file.\n */\n constructor(\n /**\n * The file system that created the file.\n */\n fs, \n /**\n * Path to the file\n */\n path, flag, stats, _buffer = new Uint8Array(new ArrayBuffer(0, { maxByteLength: size_max }))) {\n super();\n this.fs = fs;\n this.path = path;\n this.flag = flag;\n this.stats = stats;\n this._buffer = _buffer;\n this._position = 0;\n this._dirty = false;\n /*\n Note:\n This invariant is *not* maintained once the file starts getting modified.\n It only actually matters if file is readable, as writeable modes may truncate/append to file.\n */\n if (this.stats.size == _buffer.byteLength) {\n return;\n }\n if (this.flag.isReadable()) {\n throw new Error(`Size mismatch: buffer length ${_buffer.byteLength}, stats size ${this.stats.size}`);\n }\n this._dirty = true;\n }\n /**\n * Get the underlying buffer for this file. Mutating not recommended and will mess up dirty tracking.\n */\n get buffer() {\n return this._buffer;\n }\n /**\n * Get the current file position.\n *\n * We emulate the following bug mentioned in the Node documentation:\n * > On Linux, positional writes don't work when the file is opened in append\n * mode. The kernel ignores the position argument and always appends the data\n * to the end of the file.\n * @return The current file position.\n */\n get position() {\n if (this.flag.isAppendable()) {\n return this.stats.size;\n }\n return this._position;\n }\n /**\n * Set the file position.\n * @param newPos new position\n */\n set position(newPos) {\n this._position = newPos;\n }\n /**\n * Asynchronous `stat`.\n */\n async stat() {\n return new Stats(this.stats);\n }\n /**\n * Synchronous `stat`.\n */\n statSync() {\n return new Stats(this.stats);\n }\n /**\n * Asynchronous truncate.\n * @param len\n */\n truncate(len) {\n this.truncateSync(len);\n if (this.flag.isSynchronous() && !this.fs.metadata().synchronous) {\n return this.sync();\n }\n }\n /**\n * Synchronous truncate.\n * @param len\n */\n truncateSync(len) {\n this._dirty = true;\n if (!this.flag.isWriteable()) {\n throw new ApiError(ErrorCode.EPERM, 'File not opened with a writeable mode.');\n }\n this.stats.mtimeMs = Date.now();\n if (len > this._buffer.length) {\n const buf = new Uint8Array(len - this._buffer.length);\n // Write will set stats.size for us.\n this.writeSync(buf, 0, buf.length, this._buffer.length);\n if (this.flag.isSynchronous() && this.fs.metadata().synchronous) {\n this.syncSync();\n }\n return;\n }\n this.stats.size = len;\n // Truncate buffer to 'len'.\n this._buffer = this._buffer.subarray(0, len);\n if (this.flag.isSynchronous() && this.fs.metadata().synchronous) {\n this.syncSync();\n }\n }\n /**\n * Write buffer to the file.\n * Note that it is unsafe to use fs.write multiple times on the same file\n * without waiting for the callback.\n * @param buffer Uint8Array containing the data to write to\n * the file.\n * @param offset Offset in the buffer to start reading data from.\n * @param length The amount of bytes to write to the file.\n * @param position Offset from the beginning of the file where this\n * data should be written. If position is null, the data will be written at\n * the current position.\n */\n async write(buffer, offset = 0, length = this.stats.size, position = 0) {\n return this.writeSync(buffer, offset, length, position);\n }\n /**\n * Write buffer to the file.\n * Note that it is unsafe to use fs.writeSync multiple times on the same file\n * without waiting for the callback.\n * @param buffer Uint8Array containing the data to write to\n * the file.\n * @param offset Offset in the buffer to start reading data from.\n * @param length The amount of bytes to write to the file.\n * @param position Offset from the beginning of the file where this\n * data should be written. If position is null, the data will be written at\n * the current position.\n * @returns bytes written\n */\n writeSync(buffer, offset = 0, length = this.stats.size, position = 0) {\n this._dirty = true;\n position ?? (position = this.position);\n if (!this.flag.isWriteable()) {\n throw new ApiError(ErrorCode.EPERM, 'File not opened with a writeable mode.');\n }\n const endFp = position + length;\n if (endFp > this.stats.size) {\n this.stats.size = endFp;\n if (endFp > this._buffer.byteLength) {\n if (this._buffer.buffer.resizable && this._buffer.buffer.maxByteLength <= endFp) {\n this._buffer.buffer.resize(endFp);\n }\n else {\n // Extend the buffer!\n const newBuffer = new Uint8Array(new ArrayBuffer(endFp, { maxByteLength: size_max }));\n newBuffer.set(this._buffer);\n this._buffer = newBuffer;\n }\n }\n }\n this._buffer.set(buffer.slice(offset, offset + length), position);\n const len = this._buffer.byteOffset;\n this.stats.mtimeMs = Date.now();\n if (this.flag.isSynchronous()) {\n this.syncSync();\n return len;\n }\n this.position = position + len;\n return len;\n }\n /**\n * Read data from the file.\n * @param buffer The buffer that the data will be\n * written to.\n * @param offset The offset within the buffer where writing will\n * start.\n * @param length An integer specifying the number of bytes to read.\n * @param position An integer specifying where to begin reading from\n * in the file. If position is null, data will be read from the current file\n * position.\n */\n async read(buffer, offset = 0, length = this.stats.size, position = 0) {\n return { bytesRead: this.readSync(buffer, offset, length, position), buffer };\n }\n /**\n * Read data from the file.\n * @param buffer The buffer that the data will be\n * written to.\n * @param offset The offset within the buffer where writing will start.\n * @param length An integer specifying the number of bytes to read.\n * @param position An integer specifying where to begin reading from\n * in the file. If position is null, data will be read from the current file\n * position.\n * @returns number of bytes written\n */\n readSync(buffer, offset = 0, length = this.stats.size, position = 0) {\n if (!this.flag.isReadable()) {\n throw new ApiError(ErrorCode.EPERM, 'File not opened with a readable mode.');\n }\n position ?? (position = this.position);\n let end = position + length;\n if (end > this.stats.size) {\n end = position + Math.max(this.stats.size - position, 0);\n }\n this.stats.atimeMs = Date.now();\n this._position = end;\n const bytesRead = end - position;\n if (bytesRead == 0) {\n // No copy/read. Return immediatly for better performance\n return bytesRead;\n }\n buffer.set(this._buffer.slice(position, end), offset);\n return bytesRead;\n }\n /**\n * Asynchronous `fchmod`.\n * @param mode the mode\n */\n async chmod(mode) {\n this.chmodSync(mode);\n }\n /**\n * Synchronous `fchmod`.\n * @param mode\n */\n chmodSync(mode) {\n if (!this.fs.metadata().supportsProperties) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n this._dirty = true;\n this.stats.chmod(mode);\n this.syncSync();\n }\n /**\n * Asynchronous `fchown`.\n * @param uid\n * @param gid\n */\n async chown(uid, gid) {\n this.chownSync(uid, gid);\n }\n /**\n * Synchronous `fchown`.\n * @param uid\n * @param gid\n */\n chownSync(uid, gid) {\n if (!this.fs.metadata().supportsProperties) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n this._dirty = true;\n this.stats.chown(uid, gid);\n this.syncSync();\n }\n async utimes(atime, mtime) {\n this.utimesSync(atime, mtime);\n }\n utimesSync(atime, mtime) {\n if (!this.fs.metadata().supportsProperties) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n this._dirty = true;\n this.stats.atime = atime;\n this.stats.mtime = mtime;\n this.syncSync();\n }\n isDirty() {\n return this._dirty;\n }\n /**\n * Resets the dirty bit. Should only be called after a sync has completed successfully.\n */\n resetDirty() {\n this._dirty = false;\n }\n _setType(type) {\n this._dirty = true;\n this.stats.mode = (this.stats.mode & ~S_IFMT) | type;\n return this.sync();\n }\n _setTypeSync(type) {\n this._dirty = true;\n this.stats.mode = (this.stats.mode & ~S_IFMT) | type;\n this.syncSync();\n }\n}\n/**\n * For synchronous file systems\n */\nexport class SyncFile extends PreloadFile {\n constructor(_fs, _path, _flag, _stat, contents) {\n super(_fs, _path, _flag, _stat, contents);\n }\n async sync() {\n this.syncSync();\n }\n syncSync() {\n if (this.isDirty()) {\n this.fs.syncSync(this.path, this._buffer, this.stats);\n this.resetDirty();\n }\n }\n async close() {\n this.closeSync();\n }\n closeSync() {\n this.syncSync();\n }\n}\n/**\n * For the filesystems which do not sync to anything..\n */\nexport class NoSyncFile extends PreloadFile {\n constructor(_fs, _path, _flag, _stat, contents) {\n super(_fs, _path, _flag, _stat, contents);\n }\n /**\n * Asynchronous sync. Doesn't do anything, simply calls the cb.\n */\n async sync() {\n return;\n }\n /**\n * Synchronous sync. Doesn't do anything.\n */\n syncSync() {\n // NOP.\n }\n /**\n * Asynchronous close. Doesn't do anything, simply calls the cb.\n */\n async close() {\n return;\n }\n /**\n * Synchronous close. Doesn't do anything.\n */\n closeSync() {\n // NOP.\n }\n}\n", "import { ApiError, ErrorCode } from './ApiError.js';\n/**\n * Structure for a filesystem. All BrowserFS FileSystems must implement this.\n *\n * This class includes some default implementations\n *\n * Assume the following about arguments passed to each API method:\n *\n * - Every path is an absolute path. `.`, `..`, and other items are resolved into an absolute form.\n * - All arguments are present. Any optional arguments at the Node API level have been passed in with their default values.\n */\nexport class FileSystem {\n metadata() {\n return {\n name: this.constructor.name,\n readonly: false,\n synchronous: false,\n supportsProperties: false,\n totalSpace: 0,\n freeSpace: 0,\n };\n }\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n constructor(options) {\n // unused\n }\n /**\n * Test whether or not the given path exists by checking with the file system.\n */\n async exists(path, cred) {\n try {\n await this.stat(path, cred);\n return true;\n }\n catch (e) {\n return false;\n }\n }\n /**\n * Test whether or not the given path exists by checking with the file system.\n */\n existsSync(path, cred) {\n try {\n this.statSync(path, cred);\n return true;\n }\n catch (e) {\n return false;\n }\n }\n}\n/**\n * Implements the asynchronous API in terms of the synchronous API.\n */\nexport function Sync(FS) {\n /**\n * Implements the asynchronous API in terms of the synchronous API.\n */\n class _SyncFileSystem extends FS {\n metadata() {\n return { ...super.metadata(), synchronous: true };\n }\n async ready() {\n return this;\n }\n async exists(path, cred) {\n return this.existsSync(path, cred);\n }\n async rename(oldPath, newPath, cred) {\n return this.renameSync(oldPath, newPath, cred);\n }\n async stat(path, cred) {\n return this.statSync(path, cred);\n }\n async createFile(path, flag, mode, cred) {\n return this.createFileSync(path, flag, mode, cred);\n }\n async openFile(path, flag, cred) {\n return this.openFileSync(path, flag, cred);\n }\n async unlink(path, cred) {\n return this.unlinkSync(path, cred);\n }\n async rmdir(path, cred) {\n return this.rmdirSync(path, cred);\n }\n async mkdir(path, mode, cred) {\n return this.mkdirSync(path, mode, cred);\n }\n async readdir(path, cred) {\n return this.readdirSync(path, cred);\n }\n async link(srcpath, dstpath, cred) {\n return this.linkSync(srcpath, dstpath, cred);\n }\n async sync(path, data, stats) {\n return this.syncSync(path, data, stats);\n }\n }\n return _SyncFileSystem;\n}\nexport function Async(FS) {\n class _AsyncFileSystem extends FS {\n metadata() {\n return { ...super.metadata(), synchronous: false };\n }\n /* eslint-disable @typescript-eslint/no-unused-vars */\n renameSync(oldPath, newPath, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n statSync(path, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n createFileSync(path, flag, mode, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n openFileSync(path, flag, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n unlinkSync(path, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n rmdirSync(path, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n mkdirSync(path, mode, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n readdirSync(path, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n linkSync(srcpath, dstpath, cred) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n syncSync(path, data, stats) {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n }\n /* eslint-enable @typescript-eslint/no-unused-vars */\n return _AsyncFileSystem;\n}\nexport function Readonly(FS) {\n class _ReadonlyFileSystem extends FS {\n metadata() {\n return { ...super.metadata(), readonly: true };\n }\n /* eslint-disable @typescript-eslint/no-unused-vars */\n async rename(oldPath, newPath, cred) {\n throw new ApiError(ErrorCode.EROFS);\n }\n renameSync(oldPath, newPath, cred) {\n throw new ApiError(ErrorCode.EROFS);\n }\n async createFile(path, flag, mode, cred) {\n throw new ApiError(ErrorCode.EROFS);\n }\n createFileSync(path, flag, mode, cred) {\n throw new ApiError(ErrorCode.EROFS);\n }\n async unlink(path, cred) {\n throw new ApiError(ErrorCode.EROFS);\n }\n unlinkSync(path, cred) {\n throw new ApiError(ErrorCode.EROFS);\n }\n async rmdir(path, cred) {\n throw new ApiError(ErrorCode.EROFS);\n }\n rmdirSync(path, cred) {\n throw new ApiError(ErrorCode.EROFS);\n }\n async mkdir(path, mode, cred) {\n throw new ApiError(ErrorCode.EROFS);\n }\n mkdirSync(path, mode, cred) {\n throw new ApiError(ErrorCode.EROFS);\n }\n async link(srcpath, dstpath, cred) {\n throw new ApiError(ErrorCode.EROFS);\n }\n linkSync(srcpath, dstpath, cred) {\n throw new ApiError(ErrorCode.EROFS);\n }\n async sync(path, data, stats) {\n throw new ApiError(ErrorCode.EROFS);\n }\n syncSync(path, data, stats) {\n throw new ApiError(ErrorCode.EROFS);\n }\n }\n return _ReadonlyFileSystem;\n}\n", "import { basename, dirname, join } from '@zenfs/core/emulation/path.js';\nimport { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';\nimport { FileFlag, PreloadFile } from '@zenfs/core/file.js';\nimport { FileSystem, Async, type FileSystemMetadata } from '@zenfs/core/filesystem.js';\nimport { Stats, FileType } from '@zenfs/core/stats.js';\nimport type { Backend } from '@zenfs/core/backends/backend.js';\n\ndeclare global {\n\tinterface FileSystemDirectoryHandle {\n\t\t[Symbol.iterator](): IterableIterator<[string, FileSystemHandle]>;\n\t\tentries(): IterableIterator<[string, FileSystemHandle]>;\n\t\tkeys(): IterableIterator<string>;\n\t\tvalues(): IterableIterator<FileSystemHandle>;\n\t}\n}\n\ninterface FileSystemAccessOptions {\n\thandle: FileSystemDirectoryHandle;\n}\n\nconst handleError = (path = '', error: Error) => {\n\tif (error.name === 'NotFoundError') {\n\t\tthrow ApiError.ENOENT(path);\n\t}\n\n\tthrow error as ApiError;\n};\n\nexport class FileSystemAccessFile extends PreloadFile<FileSystemAccessFS> {\n\tconstructor(_fs: FileSystemAccessFS, _path: string, _flag: FileFlag, _stat: Stats, contents?: Uint8Array) {\n\t\tsuper(_fs, _path, _flag, _stat, contents);\n\t}\n\n\tpublic syncSync(): void {\n\t\tthrow new ApiError(ErrorCode.ENOTSUP);\n\t}\n\n\tpublic async sync(): Promise<void> {\n\t\tif (this.isDirty()) {\n\t\t\tawait this.fs.sync(this.path, this.buffer, this.stats);\n\t\t\tthis.resetDirty();\n\t\t}\n\t}\n\n\tpublic async close(): Promise<void> {\n\t\tawait this.sync();\n\t}\n\n\tpublic closeSync(): void {\n\t\tthrow new ApiError(ErrorCode.ENOTSUP);\n\t}\n}\n\nexport class FileSystemAccessFS extends Async(FileSystem) {\n\tprivate _handles: Map<string, FileSystemHandle> = new Map();\n\n\tpublic async ready(): Promise<this> {\n\t\treturn this;\n\t}\n\n\tpublic constructor({ handle }: FileSystemAccessOptions) {\n\t\tsuper();\n\t\tthis._handles.set('/', handle);\n\t}\n\n\tpublic metadata(): FileSystemMetadata {\n\t\treturn {\n\t\t\t...super.metadata(),\n\t\t\tname: 'FileSystemAccess',\n\t\t};\n\t}\n\n\tpublic async sync(p: string, data: Uint8Array, stats: Stats): Promise<void> {\n\t\tconst currentStats = await this.stat(p);\n\t\tif (stats.mtime !== currentStats!.mtime) {\n\t\t\tawait this.writeFile(p, data);\n\t\t}\n\t}\n\n\tpublic async rename(oldPath: string, newPath: string): Promise<void> {\n\t\ttry {\n\t\t\tconst handle = await this.getHandle(oldPath);\n\t\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\t\tconst files = await this.readdir(oldPath);\n\n\t\t\t\tawait this.mkdir(newPath);\n\t\t\t\tif (files.length == 0) {\n\t\t\t\t\tawait this.unlink(oldPath);\n\t\t\t\t} else {\n\t\t\t\t\tfor (const file of files) {\n\t\t\t\t\t\tawait this.rename(join(oldPath, file), join(newPath, file));\n\t\t\t\t\t\tawait this.unlink(oldPath);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!(handle instanceof FileSystemFileHandle)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst oldFile = await handle.getFile(),\n\t\t\t\tdestFolder = await this.getHandle(dirname(newPath));\n\t\t\tif (!(destFolder instanceof FileSystemDirectoryHandle)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst newFile = await destFolder.getFileHandle(basename(newPath), { create: true });\n\t\t\tconst writable = await newFile.createWritable();\n\t\t\tconst buffer = await oldFile.arrayBuffer();\n\t\t\tawait writable.write(buffer);\n\n\t\t\twritable.close();\n\t\t\tawait this.unlink(oldPath);\n\t\t} catch (err) {\n\t\t\thandleError(oldPath, err);\n\t\t}\n\t}\n\n\tpublic async writeFile(fname: string, data: Uint8Array): Promise<void> {\n\t\tconst handle = await this.getHandle(dirname(fname));\n\t\tif (!(handle instanceof FileSystemDirectoryHandle)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst file = await handle.getFileHandle(basename(fname), { create: true });\n\t\tconst writable = await file.createWritable();\n\t\tawait writable.write(data);\n\t\tawait writable.close();\n\t}\n\n\tpublic async createFile(path: string, flag: FileFlag): Promise<FileSystemAccessFile> {\n\t\tawait this.writeFile(path, new Uint8Array());\n\t\treturn this.openFile(path, flag);\n\t}\n\n\tpublic async stat(path: string): Promise<Stats> {\n\t\tconst handle = await this.getHandle(path);\n\t\tif (!handle) {\n\t\t\tthrow ApiError.OnPath(ErrorCode.ENOENT, path);\n\t\t}\n\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\treturn new Stats({ mode: 0o777 | FileType.DIRECTORY, size: 4096 });\n\t\t}\n\t\tif (handle instanceof FileSystemFileHandle) {\n\t\t\tconst { lastModified, size } = await handle.getFile();\n\t\t\treturn new Stats({ mode: 0o777 | FileType.FILE, size, mtimeMs: lastModified });\n\t\t}\n\t}\n\n\tpublic async openFile(path: string, flag: FileFlag): Promise<FileSystemAccessFile> {\n\t\tconst handle = await this.getHandle(path);\n\t\tif (handle instanceof FileSystemFileHandle) {\n\t\t\tconst file = await handle.getFile();\n\t\t\tconst data = new Uint8Array(await file.arrayBuffer());\n\t\t\tconst stats = new Stats({ mode: 0o777 | FileType.FILE, size: file.size, mtimeMs: file.lastModified });\n\t\t\treturn new FileSystemAccessFile(this, path, flag, stats, data);\n\t\t}\n\t}\n\n\tpublic async unlink(path: string): Promise<void> {\n\t\tconst handle = await this.getHandle(dirname(path));\n\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\ttry {\n\t\t\t\tawait handle.removeEntry(basename(path), { recursive: true });\n\t\t\t} catch (e) {\n\t\t\t\thandleError(path, e);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic async link(): Promise<void> {\n\t\tthrow new ApiError(ErrorCode.ENOTSUP);\n\t}\n\n\tpublic async rmdir(path: string): Promise<void> {\n\t\treturn this.unlink(path);\n\t}\n\n\tpublic async mkdir(path: string): Promise<void> {\n\t\tconst existingHandle = await this.getHandle(path);\n\t\tif (existingHandle) {\n\t\t\tthrow ApiError.EEXIST(path);\n\t\t}\n\n\t\tconst handle = await this.getHandle(dirname(path));\n\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\tawait handle.getDirectoryHandle(basename(path), { create: true });\n\t\t}\n\t}\n\n\tpublic async readdir(path: string): Promise<string[]> {\n\t\tconst handle = await this.getHandle(path);\n\t\tif (!(handle instanceof FileSystemDirectoryHandle)) {\n\t\t\tthrow ApiError.ENOTDIR(path);\n\t\t}\n\t\tconst _keys: string[] = [];\n\t\tfor await (const key of handle.keys()) {\n\t\t\t_keys.push(join(path, key));\n\t\t}\n\t\treturn _keys;\n\t}\n\n\tprotected async getHandle(path: string): Promise<FileSystemHandle> {\n\t\tif (this._handles.has(path)) {\n\t\t\treturn this._handles.get(path);\n\t\t}\n\n\t\tlet walkedPath = '/';\n\t\tconst [, ...pathParts] = path.split('/');\n\t\tconst getHandleParts = async ([pathPart, ...remainingPathParts]: string[]) => {\n\t\t\tconst walkingPath = join(walkedPath, pathPart);\n\t\t\tconst continueWalk = (handle: FileSystemHandle) => {\n\t\t\t\twalkedPath = walkingPath;\n\t\t\t\tthis._handles.set(walkedPath, handle);\n\n\t\t\t\tif (remainingPathParts.length === 0) {\n\t\t\t\t\treturn this._handles.get(path);\n\t\t\t\t}\n\n\t\t\t\tgetHandleParts(remainingPathParts);\n\t\t\t};\n\t\t\tconst handle = this._handles.get(walkedPath) as FileSystemDirectoryHandle;\n\n\t\t\ttry {\n\t\t\t\treturn continueWalk(await handle.getDirectoryHandle(pathPart));\n\t\t\t} catch (error) {\n\t\t\t\tif (error.name === 'TypeMismatchError') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn continueWalk(await handle.getFileHandle(pathPart));\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\thandleError(walkingPath, err);\n\t\t\t\t\t}\n\t\t\t\t} else if (error.message === 'Name is not allowed.') {\n\t\t\t\t\tthrow new ApiError(ErrorCode.ENOENT, error.message, walkingPath);\n\t\t\t\t} else {\n\t\t\t\t\thandleError(walkingPath, error);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\treturn await getHandleParts(pathParts);\n\t}\n}\n\nexport const FileSystemAccess: Backend = {\n\tname: 'FileSystemAccess',\n\n\toptions: {\n\t\thandle: {\n\t\t\ttype: 'object',\n\t\t\trequired: true,\n\t\t\tdescription: 'The directory handle to use for the root',\n\t\t},\n\t},\n\n\tisAvailable(): boolean {\n\t\treturn typeof FileSystemHandle == 'function';\n\t},\n\n\tcreate(options: FileSystemAccessOptions) {\n\t\treturn new FileSystemAccessFS(options);\n\t},\n};\n", "import { ApiError, ErrorCode } from './ApiError.js';\nimport { dirname } from './emulation/path.js';\n/**\n * Synchronous recursive makedir.\n * @hidden\n */\nexport function mkdirpSync(p, mode, cred, fs) {\n if (!fs.existsSync(p, cred)) {\n mkdirpSync(dirname(p), mode, cred, fs);\n fs.mkdirSync(p, mode, cred);\n }\n}\nfunction _min(d0, d1, d2, bx, ay) {\n return Math.min(d0 + 1, d1 + 1, d2 + 1, bx === ay ? d1 : d1 + 1);\n}\n/**\n * Calculates levenshtein distance.\n * @hidden\n */\nexport function levenshtein(a, b) {\n if (a === b) {\n return 0;\n }\n if (a.length > b.length) {\n [a, b] = [b, a]; // Swap a and b\n }\n let la = a.length;\n let lb = b.length;\n // Trim common suffix\n while (la > 0 && a.charCodeAt(la - 1) === b.charCodeAt(lb - 1)) {\n la--;\n lb--;\n }\n let offset = 0;\n // Trim common prefix\n while (offset < la && a.charCodeAt(offset) === b.charCodeAt(offset)) {\n offset++;\n }\n la -= offset;\n lb -= offset;\n if (la === 0 || lb === 1) {\n return lb;\n }\n const vector = new Array(la << 1);\n for (let y = 0; y < la;) {\n vector[la + y] = a.charCodeAt(offset + y);\n vector[y] = ++y;\n }\n let x;\n let d0;\n let d1;\n let d2;\n let d3;\n for (x = 0; x + 3 < lb;) {\n const bx0 = b.charCodeAt(offset + (d0 = x));\n const bx1 = b.charCodeAt(offset + (d1 = x + 1));\n const bx2 = b.charCodeAt(offset + (d2 = x + 2));\n const bx3 = b.charCodeAt(offset + (d3 = x + 3));\n let dd = (x += 4);\n for (let y = 0; y < la;) {\n const ay = vector[la + y];\n const dy = vector[y];\n d0 = _min(dy, d0, d1, bx0, ay);\n d1 = _min(d0, d1, d2, bx1, ay);\n d2 = _min(d1, d2, d3, bx2, ay);\n dd = _min(d2, d3, dd, bx3, ay);\n vector[y++] = dd;\n d3 = d2;\n d2 = d1;\n d1 = d0;\n d0 = dy;\n }\n }\n let dd = 0;\n for (; x < lb;) {\n const bx0 = b.charCodeAt(offset + (d0 = x));\n dd = ++x;\n for (let y = 0; y < la; y++) {\n const dy = vector[y];\n vector[y] = dd = dy < d0 || dd < d0 ? (dy > dd ? dd + 1 : dy + 1) : bx0 === vector[la + y] ? d0 : d0 + 1;\n d0 = dy;\n }\n }\n return dd;\n}\n/** Waits n ms. */\nexport function wait(ms) {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n/**\n * @hidden\n */\nexport const setImmediate = typeof globalThis.setImmediate == 'function' ? globalThis.setImmediate : cb => setTimeout(cb, 0);\n/**\n * Encodes a string into a buffer\n * @internal\n */\nexport function encode(input, encoding = 'utf8') {\n if (typeof input != 'string') {\n throw new ApiError(ErrorCode.EINVAL, 'Can not encode a non-string');\n }\n switch (encoding) {\n case 'ascii':\n case 'latin1':\n case 'binary':\n return new Uint8Array(Array.from(input).map(char => char.charCodeAt(0)));\n case 'utf8':\n case 'utf-8':\n return new Uint8Array(Array.from(input).flatMap(char => {\n const code = char.charCodeAt(0);\n if (code < 0x80) {\n return code;\n }\n const a = (code & 0x3f) | 0x80;\n if (code < 0x800) {\n return [(code >> 6) | 0xc0, a];\n }\n const b = ((code >> 6) & 0x3f) | 0x80;\n if (code < 0x10000) {\n return [(code >> 12) | 0xe0, b, a];\n }\n return [(code >> 18) | 0xf0, ((code >> 12) & 0x3f) | 0x80, b, a];\n }));\n case 'base64':\n return encode(atob(input), 'utf-8');\n case 'base64url':\n return encode(input.replace('_', '/').replace('-', '+'), 'base64');\n case 'hex':\n return new Uint8Array(input.match(/.{1,2}/g).map(e => parseInt(e, 16)));\n case 'utf16le':\n case 'ucs2':\n case 'ucs-2':\n const u16 = new Uint16Array(new ArrayBuffer(input.length * 2));\n for (let i = 0; i < input.length; i++) {\n u16[i] = input.charCodeAt(i);\n }\n return new Uint8Array(u16.buffer);\n default:\n throw new ApiError(ErrorCode.EINVAL, 'Invalid encoding: ' + encoding);\n }\n}\n/**\n * Decodes a string from a buffer\n * @internal\n */\nexport function decode(input, encoding = 'utf8') {\n if (!(input instanceof Uint8Array)) {\n throw new ApiError(ErrorCode.EINVAL, 'Can not decode a non-Uint8Array');\n }\n switch (encoding) {\n case 'ascii':\n case 'latin1':\n case 'binary':\n return Array.from(input)\n .map(char => String.fromCharCode(char))\n .join('');\n case 'utf8':\n case 'utf-8':\n let utf8String = '';\n for (let i = 0; i < input.length; i++) {\n let code;\n if (input[i] < 0x80) {\n code = input[i];\n }\n else if (input[i] < 0xe0) {\n code = ((input[i] & 0x1f) << 6) | (input[++i] & 0x3f);\n }\n else if (input[i] < 0xf0) {\n code = ((input[i] & 0x0f) << 12) | ((input[++i] & 0x3f) << 6) | (input[++i] & 0x3f);\n }\n else {\n code = ((input[i] & 0x07) << 18) | ((input[++i] & 0x3f) << 12) | ((input[++i] & 0x3f) << 6) | (input[++i] & 0x3f);\n }\n utf8String += String.fromCharCode(code);\n }\n return utf8String;\n case 'utf16le':\n case 'ucs2':\n case 'ucs-2':\n let utf16leString = '';\n for (let i = 0; i < input.length; i += 2) {\n const code = input[i] | (input[i + 1] << 8);\n utf16leString += String.fromCharCode(code);\n }\n return utf16leString;\n case 'base64':\n return btoa(decode(input, 'utf-8'));\n case 'base64url':\n return decode(input, 'base64').replace('/', '_').replace('+', '-');\n case 'hex':\n return Array.from(input)\n .map(e => e.toString(16).padStart(2, '0'))\n .join('');\n default:\n throw new ApiError(ErrorCode.EINVAL, 'Invalid encoding: ' + encoding);\n }\n}\n/**\n * Decodes a directory listing\n * @internal\n */\nexport function decodeDirListing(data) {\n return JSON.parse(decode(data), (k, v) => {\n if (k == '') {\n return v;\n }\n return BigInt(v);\n });\n}\n/**\n * Encodes a directory listing\n * @internal\n */\nexport function encodeDirListing(data) {\n return encode(JSON.stringify(data, (k, v) => {\n if (k == '') {\n return v;\n }\n return v.toString();\n }));\n}\n", "import { dirname, basename, join, resolve } from '../emulation/path.js';\nimport { ApiError, ErrorCode } from '../ApiError.js';\nimport { W_OK, R_OK } from '../emulation/constants.js';\nimport { PreloadFile } from '../file.js';\nimport { Async, FileSystem } from '../filesystem.js';\nimport { randomIno, Inode } from '../inode.js';\nimport { FileType } from '../stats.js';\nimport { encode, decodeDirListing, encodeDirListing } from '../utils.js';\nimport { rootIno } from '../inode.js';\n/**\n * Last Recently Used cache\n */\nclass LRUCache {\n constructor(limit) {\n this.limit = limit;\n this.cache = [];\n }\n set(key, value) {\n const existingIndex = this.cache.findIndex(node => node.key === key);\n if (existingIndex != -1) {\n this.cache.splice(existingIndex, 1);\n }\n else if (this.cache.length >= this.limit) {\n this.cache.shift();\n }\n this.cache.push({ key, value });\n }\n get(key) {\n const node = this.cache.find(n => n.key === key);\n if (!node) {\n return;\n }\n // Move the accessed item to the end of the cache (most recently used)\n this.set(key, node.value);\n return node.value;\n }\n remove(key) {\n const index = this.cache.findIndex(node => node.key === key);\n if (index !== -1) {\n this.cache.splice(index, 1);\n }\n }\n reset() {\n this.cache = [];\n }\n}\n/**\n * Async preload file for usage with AsyncStore\n * @internal\n */\nexport class AsyncFile extends PreloadFile {\n constructor(_fs, _path, _flag, _stat, contents) {\n super(_fs, _path, _flag, _stat, contents);\n }\n async sync() {\n if (!this.isDirty()) {\n return;\n }\n await this.fs.sync(this.path, this._buffer, this.stats);\n this.resetDirty();\n }\n syncSync() {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n async close() {\n this.sync();\n }\n closeSync() {\n throw new ApiError(ErrorCode.ENOTSUP);\n }\n}\n/**\n * An asynchronous file system which uses an async store to store its data.\n * @see AsyncStore\n * @internal\n */\nexport class AsyncStoreFS extends Async(FileSystem) {\n ready() {\n return this._ready;\n }\n metadata() {\n return {\n ...super.metadata(),\n name: this.store.name,\n };\n }\n constructor({ store, cacheSize }) {\n super();\n if (cacheSize > 0) {\n this._cache = new LRUCache(cacheSize);\n }\n this._ready = this._initialize(store);\n }\n /**\n * Initializes the file system. Typically called by subclasses' async\n * constructors.\n */\n async _initialize(store) {\n this.store = await store;\n // INVARIANT: Ensure that the root exists.\n await this.makeRootDirectory();\n return this;\n }\n /**\n * Delete all contents stored in the file system.\n */\n async empty() {\n if (this._cache) {\n this._cache.reset();\n }\n await this.store.clear();\n // INVARIANT: Root always exists.\n await this.makeRootDirectory();\n }\n /**\n * @todo Make rename compatible with the cache.\n */\n async rename(oldPath, newPath, cred) {\n const c = this._cache;\n if (this._cache) {\n // Clear and disable cache during renaming process.\n this._cache = null;\n c.reset();\n }\n try {\n const tx = this.store.beginTransaction('readwrite'), oldParent = dirname(oldPath), oldName = basename(oldPath), newParent = dirname(newPath), newName = basename(newPath), \n // Remove oldPath from parent's directory listing.\n oldDirNode = await this.findINode(tx, oldParent), oldDirList = await this.getDirListing(tx, oldDirNode, oldParent);\n if (!oldDirNode.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(oldPath);\n }\n if (!oldDirList[oldName]) {\n throw ApiError.ENOENT(oldPath);\n }\n const nodeId = oldDirList[oldName];\n delete oldDirList[oldName];\n // Invariant: Can't move a folder inside itself.\n // This funny little hack ensures that the check passes only if oldPath\n // is a subpath of newParent. We append '/' to avoid matching folders that\n // are a substring of the bottom-most folder in the path.\n if ((newParent + '/').indexOf(oldPath + '/') === 0) {\n throw new ApiError(ErrorCode.EBUSY, oldParent);\n }\n // Add newPath to parent's directory listing.\n let newDirNode, newDirList;\n if (newParent === oldParent) {\n // Prevent us from re-grabbing the same directory listing, which still\n // contains oldName.\n newDirNode = oldDirNode;\n newDirList = oldDirList;\n }\n else {\n newDirNode = await this.findINode(tx, newParent);\n newDirList = await this.getDirListing(tx, newDirNode, newParent);\n }\n if (newDirList[newName]) {\n // If it's a file, delete it.\n const newNameNode = await this.getINode(tx, newDirList[newName], newPath);\n if (newNameNode.toStats().isFile()) {\n try {\n await tx.remove(newNameNode.ino);\n await tx.remove(newDirList[newName]);\n }\n catch (e) {\n await tx.abort();\n throw e;\n }\n }\n else {\n // If it's a directory, throw a permissions error.\n throw ApiError.EPERM(newPath);\n }\n }\n newDirList[newName] = nodeId;\n // Commit the two changed directory listings.\n try {\n await tx.put(oldDirNode.ino, encodeDirListing(oldDirList), true);\n await tx.put(newDirNode.ino, encodeDirListing(newDirList), true);\n }\n catch (e) {\n await tx.abort();\n throw e;\n }\n await tx.commit();\n }\n finally {\n if (c) {\n this._cache = c;\n }\n }\n }\n async stat(p, cred) {\n const tx = this.store.beginTransaction('readonly');\n const inode = await this.findINode(tx, p);\n if (!inode) {\n throw ApiError.ENOENT(p);\n }\n const stats = inode.toStats();\n if (!stats.hasAccess(R_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n return stats;\n }\n async createFile(p, flag, mode, cred) {\n const tx = this.store.beginTransaction('readwrite'), data = new Uint8Array(0), newFile = await this.commitNewFile(tx, p, FileType.FILE, mode, cred, data);\n // Open the file.\n return new AsyncFile(this, p, flag, newFile.toStats(), data);\n }\n async openFile(p, flag, cred) {\n const tx = this.store.beginTransaction('readonly'), node = await this.findINode(tx, p), data = await tx.get(node.ino);\n if (!node.toStats().hasAccess(flag.mode, cred)) {\n throw ApiError.EACCES(p);\n }\n if (!data) {\n throw ApiError.ENOENT(p);\n }\n return new AsyncFile(this, p, flag, node.toStats(), data);\n }\n async unlink(p, cred) {\n return this.removeEntry(p, false, cred);\n }\n async rmdir(p, cred) {\n // Check first if directory is empty.\n const list = await this.readdir(p, cred);\n if (list.length > 0) {\n throw ApiError.ENOTEMPTY(p);\n }\n await this.removeEntry(p, true, cred);\n }\n async mkdir(p, mode, cred) {\n const tx = this.store.beginTransaction('readwrite'), data = encode('{}');\n await this.commitNewFile(tx, p, FileType.DIRECTORY, mode, cred, data);\n }\n async readdir(p, cred) {\n const tx = this.store.beginTransaction('readonly');\n const node = await this.findINode(tx, p);\n if (!node.toStats().hasAccess(R_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n return Object.keys(await this.getDirListing(tx, node, p));\n }\n /**\n * Updated the inode and data node at the given path\n * @todo Ensure mtime updates properly, and use that to determine if a data update is required.\n */\n async sync(p, data, stats) {\n const tx = this.store.beginTransaction('readwrite'), \n // We use the _findInode helper because we actually need the INode id.\n fileInodeId = await this._findINode(tx, dirname(p), basename(p)), fileInode = await this.getINode(tx, fileInodeId, p), inodeChanged = fileInode.update(stats);\n try {\n // Sync data.\n await tx.put(fileInode.ino, data, true);\n // Sync metadata.\n if (inodeChanged) {\n await tx.put(fileInodeId, fileInode.data, true);\n }\n }\n catch (e) {\n await tx.abort();\n throw e;\n }\n await tx.commit();\n }\n async link(existing, newpath, cred) {\n const tx = this.store.beginTransaction('readwrite'), existingDir = dirname(existing), existingDirNode = await this.findINode(tx, existingDir);\n if (!existingDirNode.toStats().hasAccess(R_OK, cred)) {\n throw ApiError.EACCES(existingDir);\n }\n const newDir = dirname(newpath), newDirNode = await this.findINode(tx, newDir), newListing = await this.getDirListing(tx, newDirNode, newDir);\n if (!newDirNode.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(newDir);\n }\n const ino = await this._findINode(tx, existingDir, basename(existing));\n const node = await this.getINode(tx, ino, existing);\n if (!node.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(newpath);\n }\n node.nlink++;\n newListing[basename(newpath)] = ino;\n try {\n tx.put(ino, node.data, true);\n tx.put(newDirNode.ino, encodeDirListing(newListing), true);\n }\n catch (e) {\n tx.abort();\n throw e;\n }\n tx.commit();\n }\n /**\n * Checks if the root directory exists. Creates it if it doesn't.\n */\n async makeRootDirectory() {\n const tx = this.store.beginTransaction('readwrite');\n if ((await tx.get(rootIno)) === undefined) {\n // Create new inode. o777, owned by root:root\n const dirInode = new Inode();\n dirInode.mode = 0o777 | FileType.DIRECTORY;\n // If the root doesn't exist, the first random ID shouldn't exist,\n // either.\n await tx.put(dirInode.ino, encode('{}'), false);\n await tx.put(rootIno, dirInode.data, false);\n await tx.commit();\n }\n }\n /**\n * Helper function for findINode.\n * @param parent The parent directory of the file we are attempting to find.\n * @param filename The filename of the inode we are attempting to find, minus\n * the parent.\n */\n async _findINode(tx, parent, filename, visited = new Set()) {\n const currentPath = join(parent, filename);\n if (visited.has(currentPath)) {\n throw new ApiError(ErrorCode.EIO, 'Infinite loop detected while finding inode', currentPath);\n }\n visited.add(currentPath);\n if (this._cache) {\n const id = this._cache.get(currentPath);\n if (id) {\n return id;\n }\n }\n if (parent === '/') {\n if (filename === '') {\n // BASE CASE #1: Return the root's ID.\n if (this._cache) {\n this._cache.set(currentPath, rootIno);\n }\n return rootIno;\n }\n else {\n // BASE CASE #2: Find the item in the root node.\n const inode = await this.getINode(tx, rootIno, parent);\n const dirList = await this.getDirListing(tx, inode, parent);\n if (dirList[filename]) {\n const id = dirList[filename];\n if (this._cache) {\n this._cache.set(currentPath, id);\n }\n return id;\n }\n else {\n throw ApiError.ENOENT(resolve(parent, filename));\n }\n }\n }\n else {\n // Get the parent directory's INode, and find the file in its directory\n // listing.\n const inode = await this.findINode(tx, parent, visited);\n const dirList = await this.getDirListing(tx, inode, parent);\n if (dirList[filename]) {\n const id = dirList[filename];\n if (this._cache) {\n this._cache.set(currentPath, id);\n }\n return id;\n }\n else {\n throw ApiError.ENOENT(resolve(parent, filename));\n }\n }\n }\n /**\n * Finds the Inode of the given path.\n * @param p The path to look up.\n * @todo memoize/cache\n */\n async findINode(tx, p, visited = new Set()) {\n const id = await this._findINode(tx, dirname(p), basename(p), visited);\n return this.getINode(tx, id, p);\n }\n /**\n * Given the ID of a node, retrieves the corresponding Inode.\n * @param tx The transaction to use.\n * @param p The corresponding path to the file (used for error messages).\n * @param id The ID to look up.\n */\n async getINode(tx, id, p) {\n const data = await tx.get(id);\n if (!data) {\n throw ApiError.ENOENT(p);\n }\n return new Inode(data.buffer);\n }\n /**\n * Given the Inode of a directory, retrieves the corresponding directory\n * listing.\n */\n async getDirListing(tx, inode, p) {\n if (!inode.toStats().isDirectory()) {\n throw ApiError.ENOTDIR(p);\n }\n const data = await tx.get(inode.ino);\n if (!data) {\n /*\n Occurs when data is undefined, or corresponds to something other\n than a directory listing. The latter should never occur unless\n the file system is corrupted.\n */\n throw ApiError.ENOENT(p);\n }\n return decodeDirListing(data);\n }\n /**\n * Adds a new node under a random ID. Retries 5 times before giving up in\n * the exceedingly unlikely chance that we try to reuse a random ino.\n */\n async addNewNode(tx, data) {\n let retries = 0;\n const reroll = async () => {\n if (++retries === 5) {\n // Max retries hit. Return with an error.\n throw new ApiError(ErrorCode.EIO, 'Unable to commit data to key-value store.');\n }\n else {\n // Try again.\n const ino = randomIno();\n const committed = await tx.put(ino, data, false);\n if (!committed) {\n return reroll();\n }\n else {\n return ino;\n }\n }\n };\n return reroll();\n }\n /**\n * Commits a new file (well, a FILE or a DIRECTORY) to the file system with\n * the given mode.\n * Note: This will commit the transaction.\n * @param p The path to the new file.\n * @param type The type of the new file.\n * @param mode The mode to create the new file with.\n * @param cred The UID/GID to create the file with\n * @param data The data to store at the file's data node.\n */\n async commitNewFile(tx, p, type, mode, cred, data) {\n const parentDir = dirname(p), fname = basename(p), parentNode = await this.findINode(tx, parentDir), dirListing = await this.getDirListing(tx, parentNode, parentDir);\n //Check that the creater has correct access\n if (!parentNode.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n // Invariant: The root always exists.\n // If we don't check this prior to taking steps below, we will create a\n // file with name '' in root should p == '/'.\n if (p === '/') {\n throw ApiError.EEXIST(p);\n }\n // Check if file already exists.\n if (dirListing[fname]) {\n await tx.abort();\n throw ApiError.EEXIST(p);\n }\n try {\n // Commit data.\n const inode = new Inode();\n inode.ino = await this.addNewNode(tx, data);\n inode.mode = mode | type;\n inode.uid = cred.uid;\n inode.gid = cred.gid;\n inode.size = data.length;\n // Update and commit parent directory listing.\n dirListing[fname] = await this.addNewNode(tx, inode.data);\n await tx.put(parentNode.ino, encodeDirListing(dirListing), true);\n await tx.commit();\n return inode;\n }\n catch (e) {\n tx.abort();\n throw e;\n }\n }\n /**\n * Remove all traces of the given path from the file system.\n * @param p The path to remove from the file system.\n * @param isDir Does the path belong to a directory, or a file?\n * @todo Update mtime.\n */\n /**\n * Remove all traces of the given path from the file system.\n * @param p The path to remove from the file system.\n * @param isDir Does the path belong to a directory, or a file?\n * @todo Update mtime.\n */\n async removeEntry(p, isDir, cred) {\n if (this._cache) {\n this._cache.remove(p);\n }\n const tx = this.store.beginTransaction('readwrite'), parent = dirname(p), parentNode = await this.findINode(tx, parent), parentListing = await this.getDirListing(tx, parentNode, parent), fileName = basename(p);\n if (!parentListing[fileName]) {\n throw ApiError.ENOENT(p);\n }\n const fileIno = parentListing[fileName];\n // Get file inode.\n const fileNode = await this.getINode(tx, fileIno, p);\n if (!fileNode.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n // Remove from directory listing of parent.\n delete parentListing[fileName];\n if (!isDir && fileNode.toStats().isDirectory()) {\n throw ApiError.EISDIR(p);\n }\n if (isDir && !fileNode.toStats().isDirectory()) {\n throw ApiError.ENOTDIR(p);\n }\n try {\n await tx.put(parentNode.ino, encodeDirListing(parentListing), true);\n if (--fileNode.nlink < 1) {\n // remove file\n await tx.remove(fileNode.ino);\n await tx.remove(fileIno);\n }\n }\n catch (e) {\n await tx.abort();\n throw e;\n }\n // Success.\n await tx.commit();\n }\n}\n", "import { AsyncROTransaction, AsyncRWTransaction, AsyncStore, AsyncStoreFS } from '@zenfs/core/backends/AsyncStore.js';\nimport { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';\nimport type { Backend } from '@zenfs/core/backends/backend.js';\nimport type { Ino } from '@zenfs/core/inode.js';\n\n/**\n * Converts a DOMException or a DOMError from an IndexedDB event into a\n * standardized ZenFS API error.\n * @hidden\n */\nfunction convertError(e: { name: string }, message: string = e.toString()): ApiError {\n\tswitch (e.name) {\n\t\tcase 'NotFoundError':\n\t\t\treturn new ApiError(ErrorCode.ENOENT, message);\n\t\tcase 'QuotaExceededError':\n\t\t\treturn new ApiError(ErrorCode.ENOSPC, message);\n\t\tdefault:\n\t\t\t// The rest do not seem to map cleanly to standard error codes.\n\t\t\treturn new ApiError(ErrorCode.EIO, message);\n\t}\n}\n\n/**\n * @hidden\n */\nexport class IndexedDBROTransaction implements AsyncROTransaction {\n\tconstructor(public tx: IDBTransaction, public store: IDBObjectStore) {}\n\n\tpublic get(key: Ino): Promise<Uint8Array> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\ttry {\n\t\t\t\tconst req: IDBRequest = this.store.get(key.toString());\n\t\t\t\treq.onerror = e => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\treject(new ApiError(ErrorCode.EIO));\n\t\t\t\t};\n\t\t\t\treq.onsuccess = () => {\n\t\t\t\t\t// IDB returns the value 'undefined' when you try to get keys that\n\t\t\t\t\t// don't exist. The caller expects this behavior.\n\t\t\t\t\tconst result = req.result;\n\t\t\t\t\tif (result === undefined) {\n\t\t\t\t\t\tresolve(result);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// IDB data is stored as an ArrayUint8Array\n\t\t\t\t\t\tresolve(Uint8Array.from(result));\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t} catch (e) {\n\t\t\t\treject(convertError(e));\n\t\t\t}\n\t\t});\n\t}\n}\n\n/**\n * @hidden\n */\nexport class IndexedDBRWTransaction extends IndexedDBROTransaction implements AsyncRWTransaction, AsyncROTransaction {\n\tconstructor(tx: IDBTransaction, store: IDBObjectStore) {\n\t\tsuper(tx, store);\n\t}\n\n\t/**\n\t * @todo return false when add has a key conflict (no error)\n\t */\n\tpublic put(key: Ino, data: Uint8Array, overwrite: boolean): Promise<boolean> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\ttry {\n\t\t\t\tconst req: IDBRequest = overwrite ? this.store.put(data, key.toString()) : this.store.add(data, key.toString());\n\t\t\t\treq.onerror = e => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\treject(new ApiError(ErrorCode.EIO));\n\t\t\t\t};\n\t\t\t\treq.onsuccess = () => resolve(true);\n\t\t\t} catch (e) {\n\t\t\t\treject(convertError(e));\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic remove(key: Ino): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\ttry {\n\t\t\t\tconst req: IDBRequest = this.store.delete(key.toString());\n\t\t\t\treq.onerror = e => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\treject(new ApiError(ErrorCode.EIO));\n\t\t\t\t};\n\t\t\t\treq.onsuccess = () => resolve;\n\t\t\t} catch (e) {\n\t\t\t\treject(convertError(e));\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic commit(): Promise<void> {\n\t\treturn new Promise(resolve => setTimeout(resolve, 0));\n\t}\n\n\tpublic async abort(): Promise<void> {\n\t\ttry {\n\t\t\tthis.tx.abort();\n\t\t} catch (e) {\n\t\t\tthrow convertError(e);\n\t\t}\n\t}\n}\n\nexport class IndexedDBStore implements AsyncStore {\n\tpublic static create(storeName: string, indexedDB: IDBFactory): Promise<IndexedDBStore> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst req: IDBOpenDBRequest = indexedDB.open(storeName, 1);\n\n\t\t\treq.onupgradeneeded = () => {\n\t\t\t\tconst db: IDBDatabase = req.result;\n\t\t\t\t// This should never happen; we're at version 1. Why does another database exist?\n\t\t\t\tif (db.objectStoreNames.contains(storeName)) {\n\t\t\t\t\tdb.deleteObjectStore(storeName);\n\t\t\t\t}\n\t\t\t\tdb.createObjectStore(storeName);\n\t\t\t};\n\n\t\t\treq.onsuccess = () => resolve(new IndexedDBStore(req.result, storeName));\n\n\t\t\treq.onerror = e => {\n\t\t\t\te.preventDefault();\n\t\t\t\treject(new ApiError(ErrorCode.EACCES));\n\t\t\t};\n\t\t});\n\t}\n\n\tconstructor(protected db: IDBDatabase, protected storeName: string) {}\n\n\tpublic get name(): string {\n\t\treturn IndexedDB.name + ':' + this.storeName;\n\t}\n\n\tpublic clear(): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\ttry {\n\t\t\t\tconst req: IDBRequest = this.db.transaction(this.storeName, 'readwrite').objectStore(this.storeName).clear();\n\t\t\t\treq.onsuccess = () => setTimeout(resolve, 0);\n\t\t\t\treq.onerror = e => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\treject(new ApiError(ErrorCode.EIO));\n\t\t\t\t};\n\t\t\t} catch (e) {\n\t\t\t\treject(convertError(e));\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic beginTransaction(type: 'readonly'): AsyncROTransaction;\n\tpublic beginTransaction(type: 'readwrite'): AsyncRWTransaction;\n\tpublic beginTransaction(type: 'readonly' | 'readwrite' = 'readonly'): AsyncROTransaction {\n\t\tconst tx = this.db.transaction(this.storeName, type),\n\t\t\tobjectStore = tx.objectStore(this.storeName);\n\t\tif (type === 'readwrite') {\n\t\t\treturn new IndexedDBRWTransaction(tx, objectStore);\n\t\t}\n\n\t\tif (type === 'readonly') {\n\t\t\treturn new IndexedDBROTransaction(tx, objectStore);\n\t\t}\n\n\t\tthrow new ApiError(ErrorCode.EINVAL, 'Invalid transaction type.');\n\t}\n}\n\n/**\n * Configuration options for the IndexedDB file system.\n */\nexport interface IndexedDBOptions {\n\t/**\n\t * The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.\n\t */\n\tstoreName?: string;\n\n\t/**\n\t * The size of the inode cache. Defaults to 100. A size of 0 or below disables caching.\n\t */\n\tcacheSize?: number;\n\n\t/**\n\t * The IDBFactory to use. Defaults to `globalThis.indexedDB`.\n\t */\n\tidbFactory?: IDBFactory;\n}\n\n/**\n * A file system that uses the IndexedDB key value file system.\n */\n\nexport const IndexedDB: Backend = {\n\tname: 'IndexedDB',\n\n\toptions: {\n\t\tstoreName: {\n\t\t\ttype: 'string',\n\t\t\trequired: false,\n\t\t\tdescription: 'The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.',\n\t\t},\n\t\tcacheSize: {\n\t\t\ttype: 'number',\n\t\t\trequired: false,\n\t\t\tdescription: 'The size of the inode cache. Defaults to 100. A size of 0 or below disables caching.',\n\t\t},\n\t\tidbFactory: {\n\t\t\ttype: 'object',\n\t\t\trequired: false,\n\t\t\tdescription: 'The IDBFactory to use. Defaults to globalThis.indexedDB.',\n\t\t},\n\t},\n\n\tisAvailable(idbFactory: IDBFactory = globalThis.indexedDB): boolean {\n\t\ttry {\n\t\t\tif (!(idbFactory instanceof IDBFactory)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst req = idbFactory.open('__zenfs_test');\n\t\t\tif (!req) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treq.onsuccess = () => idbFactory.deleteDatabase('__zenfs_test');\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\tcreate({ cacheSize = 100, storeName = 'zenfs', idbFactory = globalThis.indexedDB }: IndexedDBOptions) {\n\t\tconst store = IndexedDBStore.create(storeName, idbFactory);\n\t\tconst fs = new AsyncStoreFS({ cacheSize, store });\n\t\treturn fs;\n\t},\n};\n", "import { dirname, basename, join, resolve, sep } from '../emulation/path.js';\nimport { ApiError, ErrorCode } from '../ApiError.js';\nimport { W_OK, R_OK } from '../emulation/constants.js';\nimport { PreloadFile } from '../file.js';\nimport { FileSystem, Sync } from '../filesystem.js';\nimport { randomIno, Inode } from '../inode.js';\nimport { FileType } from '../stats.js';\nimport { decodeDirListing, encode, encodeDirListing } from '../utils.js';\nimport { rootIno } from '../inode.js';\n/**\n * A simple RW transaction for simple synchronous key-value stores.\n */\nexport class SimpleSyncRWTransaction {\n constructor(store) {\n this.store = store;\n /**\n * Stores data in the keys we modify prior to modifying them.\n * Allows us to roll back commits.\n */\n this.originalData = new Map();\n /**\n * List of keys modified in this transaction, if any.\n */\n this.modifiedKeys = new Set();\n }\n get(ino) {\n const val = this.store.get(ino);\n this.stashOldValue(ino, val);\n return val;\n }\n put(ino, data, overwrite) {\n this.markModified(ino);\n return this.store.put(ino, data, overwrite);\n }\n remove(ino) {\n this.markModified(ino);\n this.store.remove(ino);\n }\n commit() {\n /* NOP */\n }\n abort() {\n // Rollback old values.\n for (const key of this.modifiedKeys) {\n const value = this.originalData.get(key);\n if (!value) {\n // Key didn't exist.\n this.store.remove(key);\n }\n else {\n // Key existed. Store old value.\n this.store.put(key, value, true);\n }\n }\n }\n /**\n * Stashes given key value pair into `originalData` if it doesn't already\n * exist. Allows us to stash values the program is requesting anyway to\n * prevent needless `get` requests if the program modifies the data later\n * on during the transaction.\n */\n stashOldValue(ino, value) {\n // Keep only the earliest value in the transaction.\n if (!this.originalData.has(ino)) {\n this.originalData.set(ino, value);\n }\n }\n /**\n * Marks the given key as modified, and stashes its value if it has not been\n * stashed already.\n */\n markModified(ino) {\n this.modifiedKeys.add(ino);\n if (!this.originalData.has(ino)) {\n this.originalData.set(ino, this.store.get(ino));\n }\n }\n}\n/**\n * File backend by a SyncStoreFS\n * @internal\n */\nexport class SyncStoreFile extends PreloadFile {\n constructor(_fs, _path, _flag, _stat, contents) {\n super(_fs, _path, _flag, _stat, contents);\n }\n async sync() {\n this.syncSync();\n }\n syncSync() {\n if (this.isDirty()) {\n this.fs.syncSync(this.path, this._buffer, this.stats);\n this.resetDirty();\n }\n }\n async close() {\n this.closeSync();\n }\n closeSync() {\n this.syncSync();\n }\n}\n/**\n * A synchronous key-value file system. Uses a SyncStore to store the data.\n *\n * We use a unique ID for each node in the file system. The root node has a fixed ID.\n * @todo Introduce Node ID caching.\n * @todo Check modes.\n * @internal\n */\nexport class SyncStoreFS extends Sync(FileSystem) {\n constructor(options) {\n super();\n this.store = options.store;\n // INVARIANT: Ensure that the root exists.\n this.makeRootDirectory();\n }\n metadata() {\n return {\n ...super.metadata(),\n name: this.store.name,\n };\n }\n /**\n * Delete all contents stored in the file system.\n */\n empty() {\n this.store.clear();\n // INVARIANT: Root always exists.\n this.makeRootDirectory();\n }\n renameSync(oldPath, newPath, cred) {\n const tx = this.store.beginTransaction('readwrite'), oldParent = dirname(oldPath), oldName = basename(oldPath), newParent = dirname(newPath), newName = basename(newPath), \n // Remove oldPath from parent's directory listing.\n oldDirNode = this.findINode(tx, oldParent), oldDirList = this.getDirListing(tx, oldDirNode, oldParent);\n if (!oldDirNode.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(oldPath);\n }\n if (!oldDirList[oldName]) {\n throw ApiError.ENOENT(oldPath);\n }\n const ino = oldDirList[oldName];\n delete oldDirList[oldName];\n // Invariant: Can't move a folder inside itself.\n // This funny little hack ensures that the check passes only if oldPath\n // is a subpath of newParent. We append '/' to avoid matching folders that\n // are a substring of the bottom-most folder in the path.\n if ((newParent + '/').indexOf(oldPath + '/') == 0) {\n throw new ApiError(ErrorCode.EBUSY, oldParent);\n }\n // Add newPath to parent's directory listing.\n let newDirNode, newDirList;\n if (newParent === oldParent) {\n // Prevent us from re-grabbing the same directory listing, which still\n // contains oldName.\n newDirNode = oldDirNode;\n newDirList = oldDirList;\n }\n else {\n newDirNode = this.findINode(tx, newParent);\n newDirList = this.getDirListing(tx, newDirNode, newParent);\n }\n if (newDirList[newName]) {\n // If it's a file, delete it.\n const newNameNode = this.getINode(tx, newDirList[newName], newPath);\n if (newNameNode.toStats().isFile()) {\n try {\n tx.remove(newNameNode.ino);\n tx.remove(newDirList[newName]);\n }\n catch (e) {\n tx.abort();\n throw e;\n }\n }\n else {\n // If it's a directory, throw a permissions error.\n throw ApiError.EPERM(newPath);\n }\n }\n newDirList[newName] = ino;\n // Commit the two changed directory listings.\n try {\n tx.put(oldDirNode.ino, encodeDirListing(oldDirList), true);\n tx.put(newDirNode.ino, encodeDirListing(newDirList), true);\n }\n catch (e) {\n tx.abort();\n throw e;\n }\n tx.commit();\n }\n statSync(p, cred) {\n // Get the inode to the item, convert it into a Stats object.\n const stats = this.findINode(this.store.beginTransaction('readonly'), p).toStats();\n if (!stats.hasAccess(R_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n return stats;\n }\n createFileSync(p, flag, mode, cred) {\n this.commitNewFile(p, FileType.FILE, mode, cred);\n return this.openFileSync(p, flag, cred);\n }\n openFileSync(p, flag, cred) {\n const tx = this.store.beginTransaction('readonly'), node = this.findINode(tx, p), data = tx.get(node.ino);\n if (!node.toStats().hasAccess(flag.mode, cred)) {\n throw ApiError.EACCES(p);\n }\n if (data === null) {\n throw ApiError.ENOENT(p);\n }\n return new SyncStoreFile(this, p, flag, node.toStats(), data);\n }\n unlinkSync(p, cred) {\n this.removeEntry(p, false, cred);\n }\n rmdirSync(p, cred) {\n // Check first if directory is empty.\n if (this.readdirSync(p, cred).length > 0) {\n throw ApiError.ENOTEMPTY(p);\n }\n else {\n this.removeEntry(p, true, cred);\n }\n }\n mkdirSync(p, mode, cred) {\n this.commitNewFile(p, FileType.DIRECTORY, mode, cred, encode('{}'));\n }\n readdirSync(p, cred) {\n const tx = this.store.beginTransaction('readonly');\n const node = this.findINode(tx, p);\n if (!node.toStats().hasAccess(R_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n return Object.keys(this.getDirListing(tx, node, p));\n }\n syncSync(p, data, stats) {\n // @todo Ensure mtime updates properly, and use that to determine if a data\n // update is required.\n const tx = this.store.beginTransaction('readwrite'), \n // We use the _findInode helper because we actually need the INode id.\n fileInodeId = this._findINode(tx, dirname(p), basename(p)), fileInode = this.getINode(tx, fileInodeId, p), inodeChanged = fileInode.update(stats);\n try {\n // Sync data.\n tx.put(fileInode.ino, data, true);\n // Sync metadata.\n if (inodeChanged) {\n tx.put(fileInodeId, fileInode.data, true);\n }\n }\n catch (e) {\n tx.abort();\n throw e;\n }\n tx.commit();\n }\n linkSync(existing, newpath, cred) {\n const tx = this.store.beginTransaction('readwrite'), existingDir = dirname(existing), existingDirNode = this.findINode(tx, existingDir);\n if (!existingDirNode.toStats().hasAccess(R_OK, cred)) {\n throw ApiError.EACCES(existingDir);\n }\n const newDir = dirname(newpath), newDirNode = this.findINode(tx, newDir), newListing = this.getDirListing(tx, newDirNode, newDir);\n if (!newDirNode.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(newDir);\n }\n const ino = this._findINode(tx, existingDir, basename(existing));\n const node = this.getINode(tx, ino, existing);\n if (!node.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(newpath);\n }\n node.nlink++;\n newListing[basename(newpath)] = ino;\n try {\n tx.put(ino, node.data, true);\n tx.put(newDirNode.ino, encodeDirListing(newListing), true);\n }\n catch (e) {\n tx.abort();\n throw e;\n }\n tx.commit();\n }\n /**\n * Checks if the root directory exists. Creates it if it doesn't.\n */\n makeRootDirectory() {\n const tx = this.store.beginTransaction('readwrite');\n if (tx.get(rootIno)) {\n return;\n }\n // Create new inode, mode o777, owned by root:root\n const inode = new Inode();\n inode.mode = 0o777 | FileType.DIRECTORY;\n // If the root doesn't exist, the first random ID shouldn't exist either.\n tx.put(inode.ino, encode('{}'), false);\n tx.put(rootIno, inode.data, false);\n tx.commit();\n }\n /**\n * Helper function for findINode.\n * @param parent The parent directory of the file we are attempting to find.\n * @param filename The filename of the inode we are attempting to find, minus\n * the parent.\n * @return string The ID of the file's inode in the file system.\n */\n _findINode(tx, parent, filename, visited = new Set()) {\n const currentPath = join(parent, filename);\n if (visited.has(currentPath)) {\n throw new ApiError(ErrorCode.EIO, 'Infinite loop detected while finding inode', currentPath);\n }\n visited.add(currentPath);\n if (parent != '/') {\n const ino = this._findINode(tx, dirname(parent), basename(parent), visited);\n const dir = this.getDirListing(tx, this.getINode(tx, ino, parent + sep + filename), parent);\n if (!(filename in dir)) {\n throw ApiError.ENOENT(resolve(parent, filename));\n }\n return dir[filename];\n }\n if (filename != '') {\n // Find the item in the root node.\n const dir = this.getDirListing(tx, this.getINode(tx, rootIno, parent), parent);\n if (!(filename in dir)) {\n throw ApiError.ENOENT(resolve(parent, filename));\n }\n return dir[filename];\n }\n // Return the root's ID.\n return rootIno;\n }\n /**\n * Finds the Inode of the given path.\n * @param p The path to look up.\n * @return The Inode of the path p.\n * @todo memoize/cache\n */\n findINode(tx, p) {\n const ino = this._findINode(tx, dirname(p), basename(p));\n return this.getINode(tx, ino, p);\n }\n /**\n * Given the ID of a node, retrieves the corresponding Inode.\n * @param tx The transaction to use.\n * @param p The corresponding path to the file (used for error messages).\n * @param id The ID to look up.\n */\n getINode(tx, id, p) {\n const data = tx.get(id);\n if (!data) {\n throw ApiError.ENOENT(p);\n }\n const inode = new Inode(data.buffer);\n return inode;\n }\n /**\n * Given the Inode of a directory, retrieves the corresponding directory listing.\n */\n getDirListing(tx, inode, p) {\n if (!inode.toStats().isDirectory()) {\n throw ApiError.ENOTDIR(p);\n }\n const data = tx.get(inode.ino);\n if (!data) {\n throw ApiError.ENOENT(p);\n }\n return decodeDirListing(data);\n }\n /**\n * Creates a new node under a random ID. Retries 5 times before giving up in\n * the exceedingly unlikely chance that we try to reuse a random GUID.\n * @return The GUID that the data was stored under.\n */\n addNewNode(tx, data) {\n const retries = 0;\n let ino;\n while (retries < 5) {\n try {\n ino = randomIno();\n tx.put(ino, data, false);\n return ino;\n }\n catch (e) {\n // Ignore and reroll.\n }\n }\n throw new ApiError(ErrorCode.EIO, 'Unable to commit data to key-value store.');\n }\n /**\n * Commits a new file (well, a FILE or a DIRECTORY) to the file system with the given mode.\n * Note: This will commit the transaction.\n * @param p The path to the new file.\n * @param type The type of the new file.\n * @param mode The mode to create the new file with.\n * @param data The data to store at the file's data node.\n * @return The Inode for the new file.\n */\n commitNewFile(p, type, mode, cred, data = new Uint8Array()) {\n const tx = this.store.beginTransaction('readwrite'), parentDir = dirname(p), fname = basename(p), parentNode = this.findINode(tx, parentDir), dirListing = this.getDirListing(tx, parentNode, parentDir);\n //Check that the creater has correct access\n if (!parentNode.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n /* Invariant: The root always exists.\n If we don't check this prior to taking steps below,\n we will create a file with name '' in root should p == '/'.\n */\n if (p === '/') {\n throw ApiError.EEXIST(p);\n }\n // Check if file already exists.\n if (dirListing[fname]) {\n throw ApiError.EEXIST(p);\n }\n const fileNode = new Inode();\n try {\n // Commit data.\n fileNode.ino = this.addNewNode(tx, data);\n fileNode.size = data.length;\n fileNode.mode = mode | type;\n fileNode.uid = cred.uid;\n fileNode.gid = cred.gid;\n // Update and commit parent directory listing.\n dirListing[fname] = this.addNewNode(tx, fileNode.data);\n tx.put(parentNode.ino, encodeDirListing(dirListing), true);\n }\n catch (e) {\n tx.abort();\n throw e;\n }\n tx.commit();\n return fileNode;\n }\n /**\n * Remove all traces of the given path from the file system.\n * @param p The path to remove from the file system.\n * @param isDir Does the path belong to a directory, or a file?\n * @todo Update mtime.\n */\n removeEntry(p, isDir, cred) {\n const tx = this.store.beginTransaction('readwrite'), parent = dirname(p), parentNode = this.findINode(tx, parent), parentListing = this.getDirListing(tx, parentNode, parent), fileName = basename(p), fileIno = parentListing[fileName];\n if (!fileIno) {\n throw ApiError.ENOENT(p);\n }\n // Get file inode.\n const fileNode = this.getINode(tx, fileIno, p);\n if (!fileNode.toStats().hasAccess(W_OK, cred)) {\n throw ApiError.EACCES(p);\n }\n // Remove from directory listing of parent.\n delete parentListing[fileName];\n if (!isDir && fileNode.toStats().isDirectory()) {\n throw ApiError.EISDIR(p);\n }\n if (isDir && !fileNode.toStats().isDirectory()) {\n throw ApiError.ENOTDIR(p);\n }\n try {\n // Update directory listing.\n tx.put(parentNode.ino, encodeDirListing(parentListing), true);\n if (--fileNode.nlink < 1) {\n // remove file\n tx.remove(fileNode.ino);\n tx.remove(fileIno);\n }\n }\n catch (e) {\n tx.abort();\n throw e;\n }\n // Success.\n tx.commit();\n }\n}\n", "import { SyncStore, SimpleSyncStore, SimpleSyncRWTransaction, SyncRWTransaction, SyncStoreFS } from '@zenfs/core/backends/SyncStore.js';\nimport { ApiError, ErrorCode } from '@zenfs/core/ApiError.js';\nimport { type Backend } from '@zenfs/core/backends/backend.js';\nimport { decode, encode } from '@zenfs/core/utils.js';\nimport type { Ino } from '@zenfs/core/inode.js';\n\n/**\n * A synchronous key-value store backed by Storage.\n */\nexport class StorageStore implements SyncStore, SimpleSyncStore {\n\tpublic get name(): string {\n\t\treturn Storage.name;\n\t}\n\n\tconstructor(protected _storage: Storage) {}\n\n\tpublic clear(): void {\n\t\tthis._storage.clear();\n\t}\n\n\tpublic beginTransaction(): SyncRWTransaction {\n\t\t// No need to differentiate.\n\t\treturn new SimpleSyncRWTransaction(this);\n\t}\n\n\tpublic get(key: Ino): Uint8Array | undefined {\n\t\tconst data = this._storage.getItem(key.toString());\n\t\tif (typeof data != 'string') {\n\t\t\treturn;\n\t\t}\n\n\t\treturn encode(data);\n\t}\n\n\tpublic put(key: Ino, data: Uint8Array, overwrite: boolean): boolean {\n\t\ttry {\n\t\t\tif (!overwrite && this._storage.getItem(key.toString()) !== null) {\n\t\t\t\t// Don't want to overwrite the key!\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis._storage.setItem(key.toString(), decode(data));\n\t\t\treturn true;\n\t\t} catch (e) {\n\t\t\tthrow new ApiError(ErrorCode.ENOSPC, 'Storage is full.');\n\t\t}\n\t}\n\n\tpublic remove(key: Ino): void {\n\t\ttry {\n\t\t\tthis._storage.removeItem(key.toString());\n\t\t} catch (e) {\n\t\t\tthrow new ApiError(ErrorCode.EIO, 'Unable to delete key ' + key + ': ' + e);\n\t\t}\n\t}\n}\n\n/**\n * Options to pass to the StorageFileSystem\n */\nexport interface StorageOptions {\n\t/**\n\t * The Storage to use. Defaults to globalThis.localStorage.\n\t */\n\tstorage: Storage;\n}\n\n/**\n * A synchronous file system backed by a `Storage` (e.g. localStorage).\n */\nexport const Storage: Backend = {\n\tname: 'Storage',\n\n\toptions: {\n\t\tstorage: {\n\t\t\ttype: 'object',\n\t\t\trequired: false,\n\t\t\tdescription: 'The Storage to use. Defaults to globalThis.localStorage.',\n\t\t},\n\t},\n\n\tisAvailable(storage: Storage = globalThis.localStorage): boolean {\n\t\treturn storage instanceof globalThis.Storage;\n\t},\n\n\tcreate({ storage = globalThis.localStorage }: StorageOptions) {\n\t\treturn new SyncStoreFS({ store: new StorageStore(storage) });\n\t},\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["src_exports", "__export", "FileSystemAccess", "FileSystemAccessFS", "FileSystemAccessFile", "IndexedDB", "IndexedDBROTransaction", "IndexedDBRWTransaction", "IndexedDBStore", "Storage", "StorageStore", "cwd", "sep", "validateString", "str", "name", "__name", "normalizeString", "path", "allowAboveRoot", "res", "lastSegmentLength", "lastSlash", "dots", "char", "i", "lastSlashIndex", "__name", "resolve", "args", "resolvedPath", "resolvedAbsolute", "i", "path", "cwd", "validateString", "normalizeString", "__name", "normalize", "isAbsolute", "trailingSeparator", "join", "args", "joined", "i", "arg", "validateString", "normalize", "__name", "dirname", "path", "validateString", "hasRoot", "end", "matchedSlash", "__name", "basename", "suffix", "start", "extIdx", "firstNonSlashEnd", "i", "ErrorCode", "ErrorStrings", "ApiError", "json", "err", "code", "path", "errno", "message", "__name", "Cred", "uid", "gid", "suid", "sgid", "euid", "egid", "__name", "FileType", "StatsCommon", "arg", "value", "atimeMs", "mtimeMs", "ctimeMs", "birthtimeMs", "uid", "gid", "size", "mode", "currentTime", "resolveT", "__name", "val", "_default", "itemType", "cred", "perms", "uMode", "gMode", "wMode", "uPerms", "gPerms", "wPerms", "Cred", "Stats", "stats", "size_max", "rootIno", "_random", "__name", "randomIno", "Offset", "Inode", "buffer", "setDefaults", "now", "value", "Stats", "stats", "hasChanged", "ActionType", "FileFlag", "flag", "ApiError", "ErrorCode", "mode", "__name", "File", "PreloadFile", "fs", "path", "stats", "_buffer", "size_max", "newPos", "Stats", "len", "buf", "buffer", "offset", "length", "position", "endFp", "newBuffer", "end", "bytesRead", "uid", "gid", "atime", "mtime", "type", "FileSystem", "options", "path", "cred", "__name", "Sync", "FS", "_SyncFileSystem", "oldPath", "newPath", "flag", "mode", "srcpath", "dstpath", "data", "stats", "Async", "_AsyncFileSystem", "ApiError", "ErrorCode", "handleError", "__name", "path", "error", "ApiError", "FileSystemAccessFile", "PreloadFile", "_fs", "_path", "_flag", "_stat", "contents", "ErrorCode", "FileSystemAccessFS", "Async", "FileSystem", "handle", "p", "data", "stats", "currentStats", "oldPath", "newPath", "files", "file", "join", "oldFile", "destFolder", "dirname", "writable", "basename", "buffer", "err", "fname", "flag", "Stats", "FileType", "lastModified", "size", "e", "_keys", "key", "walkedPath", "pathParts", "getHandleParts", "pathPart", "remainingPathParts", "walkingPath", "continueWalk", "FileSystemAccess", "options", "setImmediate", "cb", "encode", "input", "encoding", "ApiError", "ErrorCode", "char", "code", "a", "b", "e", "u16", "i", "__name", "decode", "utf8String", "utf16leString", "decodeDirListing", "data", "k", "v", "encodeDirListing", "LRUCache", "limit", "key", "value", "existingIndex", "node", "n", "index", "__name", "AsyncFile", "PreloadFile", "_fs", "_path", "_flag", "_stat", "contents", "ApiError", "ErrorCode", "AsyncStoreFS", "Async", "FileSystem", "store", "cacheSize", "oldPath", "newPath", "cred", "c", "tx", "oldParent", "dirname", "oldName", "basename", "newParent", "newName", "oldDirNode", "oldDirList", "nodeId", "newDirNode", "newDirList", "newNameNode", "e", "encodeDirListing", "p", "inode", "stats", "flag", "mode", "data", "newFile", "FileType", "encode", "fileInodeId", "fileInode", "inodeChanged", "existing", "newpath", "existingDir", "newDir", "newListing", "ino", "rootIno", "dirInode", "Inode", "parent", "filename", "visited", "currentPath", "join", "id", "dirList", "resolve", "decodeDirListing", "retries", "reroll", "randomIno", "type", "parentDir", "fname", "parentNode", "dirListing", "isDir", "parentListing", "fileName", "fileIno", "fileNode", "convertError", "e", "message", "ApiError", "ErrorCode", "__name", "IndexedDBROTransaction", "tx", "store", "key", "resolve", "reject", "req", "result", "IndexedDBRWTransaction", "data", "overwrite", "IndexedDBStore", "db", "storeName", "indexedDB", "IndexedDB", "type", "objectStore", "idbFactory", "cacheSize", "AsyncStoreFS", "SimpleSyncRWTransaction", "store", "ino", "val", "data", "overwrite", "key", "value", "__name", "SyncStoreFile", "PreloadFile", "_fs", "_path", "_flag", "_stat", "contents", "SyncStoreFS", "Sync", "FileSystem", "options", "oldPath", "newPath", "cred", "tx", "oldParent", "dirname", "oldName", "basename", "newParent", "newName", "oldDirNode", "oldDirList", "ApiError", "ErrorCode", "newDirNode", "newDirList", "newNameNode", "e", "encodeDirListing", "p", "stats", "flag", "mode", "FileType", "node", "encode", "fileInodeId", "fileInode", "inodeChanged", "existing", "newpath", "existingDir", "newDir", "newListing", "rootIno", "inode", "Inode", "parent", "filename", "visited", "currentPath", "join", "dir", "sep", "resolve", "id", "decodeDirListing", "randomIno", "type", "parentDir", "fname", "parentNode", "dirListing", "fileNode", "isDir", "parentListing", "fileName", "fileIno", "StorageStore", "_storage", "Storage", "SimpleSyncRWTransaction", "key", "data", "encode", "overwrite", "decode", "ApiError", "ErrorCode", "__name", "storage", "SyncStoreFS"]
|
|
7
7
|
}
|