Buckets:
| /** | |
| * @license | |
| * Copyright 2015 The Emscripten Authors | |
| * SPDX-License-Identifier: MIT | |
| */ | |
| #if !ENVIRONMENT_MAY_BE_WORKER | |
| #error "libworkerfs.js requires worker to be in ENVIRONMENT" | |
| #endif | |
| addToLibrary({ | |
| $WORKERFS__deps: ['$FS'], | |
| $WORKERFS: { | |
| DIR_MODE: {{{ cDefs.S_IFDIR | 0o777 }}}, | |
| FILE_MODE: {{{ cDefs.S_IFREG | 0o777 }}}, | |
| reader: null, | |
| mount(mount) { | |
| assert(ENVIRONMENT_IS_WORKER); | |
| WORKERFS.reader ??= new FileReaderSync(); | |
| var root = WORKERFS.createNode(null, '/', WORKERFS.DIR_MODE, 0); | |
| var createdParents = {}; | |
| function ensureParent(path) { | |
| // return the parent node, creating subdirs as necessary | |
| var parts = path.split('/'); | |
| var parent = root; | |
| for (var i = 0; i < parts.length-1; i++) { | |
| var curr = parts.slice(0, i+1).join('/'); | |
| // Issue 4254: Using curr as a node name will prevent the node | |
| // from being found in FS.nameTable when FS.open is called on | |
| // a path which holds a child of this node, | |
| // given that all FS functions assume node names | |
| // are just their corresponding parts within their given path, | |
| // rather than incremental aggregates which include their parent's | |
| // directories. | |
| createdParents[curr] ||= WORKERFS.createNode(parent, parts[i], WORKERFS.DIR_MODE, 0); | |
| parent = createdParents[curr]; | |
| } | |
| return parent; | |
| } | |
| function base(path) { | |
| var parts = path.split('/'); | |
| return parts[parts.length-1]; | |
| } | |
| // We also accept FileList here | |
| for (var file of (mount.opts["files"] || [])) { | |
| WORKERFS.createNode(ensureParent(file.name), base(file.name), WORKERFS.FILE_MODE, 0, file, file.lastModifiedDate); | |
| } | |
| for (var obj of (mount.opts["blobs"] || [])) { | |
| WORKERFS.createNode(ensureParent(obj["name"]), base(obj["name"]), WORKERFS.FILE_MODE, 0, obj["data"]); | |
| } | |
| for (var pack of (mount.opts["packages"] || [])) { | |
| for (var file of pack['metadata'].files) { | |
| var name = file.filename.slice(1); // remove initial slash | |
| WORKERFS.createNode(ensureParent(name), base(name), WORKERFS.FILE_MODE, 0, pack['blob'].slice(file.start, file.end)); | |
| } | |
| } | |
| return root; | |
| }, | |
| createNode(parent, name, mode, dev, contents, mtime) { | |
| var node = FS.createNode(parent, name, mode); | |
| node.mode = mode; | |
| node.node_ops = WORKERFS.node_ops; | |
| node.stream_ops = WORKERFS.stream_ops; | |
| node.atime = node.mtime = node.ctime = (mtime || new Date).getTime(); | |
| assert(WORKERFS.FILE_MODE !== WORKERFS.DIR_MODE); | |
| if (mode === WORKERFS.FILE_MODE) { | |
| node.size = contents.size; | |
| node.contents = contents; | |
| } else { | |
| node.size = 4096; | |
| node.contents = {}; | |
| } | |
| if (parent) { | |
| parent.contents[name] = node; | |
| } | |
| return node; | |
| }, | |
| node_ops: { | |
| getattr(node) { | |
| return { | |
| dev: 1, | |
| ino: node.id, | |
| mode: node.mode, | |
| nlink: 1, | |
| uid: 0, | |
| gid: 0, | |
| rdev: 0, | |
| size: node.size, | |
| atime: new Date(node.atime), | |
| mtime: new Date(node.mtime), | |
| ctime: new Date(node.ctime), | |
| blksize: 4096, | |
| blocks: Math.ceil(node.size / 4096), | |
| }; | |
| }, | |
| setattr(node, attr) { | |
| for (const key of ["mode", "atime", "mtime", "ctime"]) { | |
| if (attr[key] != null) { | |
| node[key] = attr[key]; | |
| } | |
| } | |
| }, | |
| lookup(parent, name) { | |
| throw new FS.ErrnoError({{{ cDefs.ENOENT }}}); | |
| }, | |
| mknod(parent, name, mode, dev) { | |
| throw new FS.ErrnoError({{{ cDefs.EPERM }}}); | |
| }, | |
| rename(oldNode, newDir, newName) { | |
| throw new FS.ErrnoError({{{ cDefs.EPERM }}}); | |
| }, | |
| unlink(parent, name) { | |
| throw new FS.ErrnoError({{{ cDefs.EPERM }}}); | |
| }, | |
| rmdir(parent, name) { | |
| throw new FS.ErrnoError({{{ cDefs.EPERM }}}); | |
| }, | |
| readdir(node) { | |
| var entries = ['.', '..']; | |
| for (var key of Object.keys(node.contents)) { | |
| entries.push(key); | |
| } | |
| return entries; | |
| }, | |
| symlink(parent, newName, oldPath) { | |
| throw new FS.ErrnoError({{{ cDefs.EPERM }}}); | |
| }, | |
| }, | |
| stream_ops: { | |
| read(stream, buffer, offset, length, position) { | |
| if (position >= stream.node.size) return 0; | |
| var chunk = stream.node.contents.slice(position, position + length); | |
| var ab = WORKERFS.reader.readAsArrayBuffer(chunk); | |
| buffer.set(new Uint8Array(ab), offset); | |
| return chunk.size; | |
| }, | |
| write(stream, buffer, offset, length, position) { | |
| throw new FS.ErrnoError({{{ cDefs.EIO }}}); | |
| }, | |
| llseek(stream, offset, whence) { | |
| var position = offset; | |
| if (whence === {{{ cDefs.SEEK_CUR }}}) { | |
| position += stream.position; | |
| } else if (whence === {{{ cDefs.SEEK_END }}}) { | |
| if (FS.isFile(stream.node.mode)) { | |
| position += stream.node.size; | |
| } | |
| } | |
| if (position < 0) { | |
| throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); | |
| } | |
| return position; | |
| }, | |
| }, | |
| }, | |
| }); | |
| if (WASMFS) { | |
| error("using -lworkerfs is not currently supported in WasmFS."); | |
| } | |
Xet Storage Details
- Size:
- 5.36 kB
- Xet hash:
- fbc3033b23c73c02f78878197911fa1351de430229462a0ee1db561f63fdd2cb
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.