[generated] sandpack files from: codesandbox-client
This commit is contained in:
364
sandpack-generated/static/browserfs11/node/generic/file_index.js
Normal file
364
sandpack-generated/static/browserfs11/node/generic/file_index.js
Normal file
@@ -0,0 +1,364 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isDirInode = exports.isFileInode = exports.DirInode = exports.FileInode = exports.FileIndex = void 0;
|
||||
var path = require("path");
|
||||
var node_fs_stats_1 = require("../core/node_fs_stats");
|
||||
/**
|
||||
* A simple class for storing a filesystem index. Assumes that all paths passed
|
||||
* to it are *absolute* paths.
|
||||
*
|
||||
* Can be used as a partial or a full index, although care must be taken if used
|
||||
* for the former purpose, especially when directories are concerned.
|
||||
*/
|
||||
var FileIndex = /** @class */ (function () {
|
||||
/**
|
||||
* Constructs a new FileIndex.
|
||||
*/
|
||||
function FileIndex() {
|
||||
// _index is a single-level key,value store that maps *directory* paths to
|
||||
// DirInodes. File information is only contained in DirInodes themselves.
|
||||
this._index = {};
|
||||
// Create the root directory.
|
||||
this.addPath('/', new DirInode());
|
||||
}
|
||||
/**
|
||||
* Static method for constructing indices from a JSON listing.
|
||||
* @param listing Directory listing generated by tools/XHRIndexer.coffee
|
||||
* @return A new FileIndex object.
|
||||
*/
|
||||
FileIndex.fromListing = function (listing) {
|
||||
var idx = new FileIndex();
|
||||
// Add a root DirNode.
|
||||
var rootInode = new DirInode();
|
||||
idx._index['/'] = rootInode;
|
||||
var queue = [['', listing, rootInode]];
|
||||
while (queue.length > 0) {
|
||||
var inode = void 0;
|
||||
var next = queue.pop();
|
||||
var pwd = next[0];
|
||||
var tree = next[1];
|
||||
var parent_1 = next[2];
|
||||
for (var node in tree) {
|
||||
if (tree.hasOwnProperty(node)) {
|
||||
var children = tree[node];
|
||||
var name_1 = "".concat(pwd, "/").concat(node);
|
||||
if (children) {
|
||||
idx._index[name_1] = inode = new DirInode();
|
||||
queue.push([name_1, children, inode]);
|
||||
}
|
||||
else {
|
||||
// This inode doesn't have correct size information, noted with -1.
|
||||
inode = new FileInode(new node_fs_stats_1.default(node_fs_stats_1.FileType.FILE, -1, 0x16D));
|
||||
}
|
||||
if (parent_1) {
|
||||
parent_1._ls[node] = inode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
};
|
||||
FileIndex.fromUnpkg = function (listing) {
|
||||
var idx = new FileIndex();
|
||||
function handleDir(dirPath, entry) {
|
||||
var dirInode = new DirInode();
|
||||
entry.files.forEach(function (child) {
|
||||
var inode;
|
||||
if (child.type === 'file') {
|
||||
inode = new FileInode(new node_fs_stats_1.default(node_fs_stats_1.FileType.FILE, child.size));
|
||||
// @ts-ignore
|
||||
dirInode._ls[path.basename(child.path)] = inode;
|
||||
}
|
||||
else {
|
||||
idx._index[child.path] = inode = handleDir(child.path, child);
|
||||
}
|
||||
});
|
||||
return dirInode;
|
||||
}
|
||||
idx._index['/'] = handleDir('/', listing);
|
||||
return idx;
|
||||
};
|
||||
FileIndex.fromJSDelivr = function (listing) {
|
||||
var idx = new FileIndex();
|
||||
listing.files.forEach(function (file) {
|
||||
var inode = new FileInode(new node_fs_stats_1.default(node_fs_stats_1.FileType.FILE, file.size));
|
||||
idx.addPathFast(file.name, inode);
|
||||
});
|
||||
return idx;
|
||||
};
|
||||
/**
|
||||
* Runs the given function over all files in the index.
|
||||
*/
|
||||
FileIndex.prototype.fileIterator = function (cb) {
|
||||
for (var path_1 in this._index) {
|
||||
if (this._index.hasOwnProperty(path_1)) {
|
||||
var dir = this._index[path_1];
|
||||
var files = dir.getListing();
|
||||
for (var _i = 0, files_1 = files; _i < files_1.length; _i++) {
|
||||
var file = files_1[_i];
|
||||
var item = dir.getItem(file);
|
||||
if (isFileInode(item)) {
|
||||
cb(item.getData(), path_1 + '/' + file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Adds the given absolute path to the index if it is not already in the index.
|
||||
* Creates any needed parent directories.
|
||||
* @param path The path to add to the index.
|
||||
* @param inode The inode for the
|
||||
* path to add.
|
||||
* @return 'True' if it was added or already exists, 'false' if there
|
||||
* was an issue adding it (e.g. item in path is a file, item exists but is
|
||||
* different).
|
||||
* @todo If adding fails and implicitly creates directories, we do not clean up
|
||||
* the new empty directories.
|
||||
*/
|
||||
FileIndex.prototype.addPath = function (path, inode) {
|
||||
if (!inode) {
|
||||
throw new Error('Inode must be specified');
|
||||
}
|
||||
if (path[0] !== '/') {
|
||||
throw new Error('Path must be absolute, got: ' + path);
|
||||
}
|
||||
// Check if it already exists.
|
||||
if (this._index.hasOwnProperty(path)) {
|
||||
return this._index[path] === inode;
|
||||
}
|
||||
var splitPath = this._split_path(path);
|
||||
var dirpath = splitPath[0];
|
||||
var itemname = splitPath[1];
|
||||
// Try to add to its parent directory first.
|
||||
var parent = this._index[dirpath];
|
||||
if (parent === undefined && path !== '/') {
|
||||
// Create parent.
|
||||
parent = new DirInode();
|
||||
if (!this.addPath(dirpath, parent)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Add myself to my parent.
|
||||
if (path !== '/') {
|
||||
if (!parent.addItem(itemname, inode)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// If I'm a directory, add myself to the index.
|
||||
if (isDirInode(inode)) {
|
||||
this._index[path] = inode;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
* Adds the given absolute path to the index if it is not already in the index.
|
||||
* The path is added without special treatment (no joining of adjacent separators, etc).
|
||||
* Creates any needed parent directories.
|
||||
* @param path The path to add to the index.
|
||||
* @param inode The inode for the
|
||||
* path to add.
|
||||
* @return 'True' if it was added or already exists, 'false' if there
|
||||
* was an issue adding it (e.g. item in path is a file, item exists but is
|
||||
* different).
|
||||
* @todo If adding fails and implicitly creates directories, we do not clean up
|
||||
* the new empty directories.
|
||||
*/
|
||||
FileIndex.prototype.addPathFast = function (path, inode) {
|
||||
var itemNameMark = path.lastIndexOf('/');
|
||||
var parentPath = itemNameMark === 0 ? "/" : path.substring(0, itemNameMark);
|
||||
var itemName = path.substring(itemNameMark + 1);
|
||||
// Try to add to its parent directory first.
|
||||
var parent = this._index[parentPath];
|
||||
if (parent === undefined) {
|
||||
// Create parent.
|
||||
parent = new DirInode();
|
||||
this.addPathFast(parentPath, parent);
|
||||
}
|
||||
if (!parent.addItem(itemName, inode)) {
|
||||
return false;
|
||||
}
|
||||
// If adding a directory, add to the index as well.
|
||||
if (inode.isDir()) {
|
||||
this._index[path] = inode;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
* Removes the given path. Can be a file or a directory.
|
||||
* @return The removed item,
|
||||
* or null if it did not exist.
|
||||
*/
|
||||
FileIndex.prototype.removePath = function (path) {
|
||||
var splitPath = this._split_path(path);
|
||||
var dirpath = splitPath[0];
|
||||
var itemname = splitPath[1];
|
||||
// Try to remove it from its parent directory first.
|
||||
var parent = this._index[dirpath];
|
||||
if (parent === undefined) {
|
||||
return null;
|
||||
}
|
||||
// Remove myself from my parent.
|
||||
var inode = parent.remItem(itemname);
|
||||
if (inode === null) {
|
||||
return null;
|
||||
}
|
||||
// If I'm a directory, remove myself from the index, and remove my children.
|
||||
if (isDirInode(inode)) {
|
||||
var children = inode.getListing();
|
||||
for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
|
||||
var child = children_1[_i];
|
||||
this.removePath(path + '/' + child);
|
||||
}
|
||||
// Remove the directory from the index, unless it's the root.
|
||||
if (path !== '/') {
|
||||
delete this._index[path];
|
||||
}
|
||||
}
|
||||
return inode;
|
||||
};
|
||||
/**
|
||||
* Retrieves the directory listing of the given path.
|
||||
* @return An array of files in the given path, or 'null' if it does not exist.
|
||||
*/
|
||||
FileIndex.prototype.ls = function (path) {
|
||||
var item = this._index[path];
|
||||
if (item === undefined) {
|
||||
return null;
|
||||
}
|
||||
return item.getListing();
|
||||
};
|
||||
/**
|
||||
* Returns the inode of the given item.
|
||||
* @return Returns null if the item does not exist.
|
||||
*/
|
||||
FileIndex.prototype.getInode = function (path) {
|
||||
var splitPath = this._split_path(path);
|
||||
var dirpath = splitPath[0];
|
||||
var itemname = splitPath[1];
|
||||
// Retrieve from its parent directory.
|
||||
var parent = this._index[dirpath];
|
||||
if (parent === undefined) {
|
||||
return null;
|
||||
}
|
||||
// Root case
|
||||
if (dirpath === path) {
|
||||
return parent;
|
||||
}
|
||||
return parent.getItem(itemname);
|
||||
};
|
||||
/**
|
||||
* Split into a (directory path, item name) pair
|
||||
*/
|
||||
FileIndex.prototype._split_path = function (p) {
|
||||
var dirpath = path.dirname(p);
|
||||
var itemname = p.substr(dirpath.length + (dirpath === "/" ? 0 : 1));
|
||||
return [dirpath, itemname];
|
||||
};
|
||||
return FileIndex;
|
||||
}());
|
||||
exports.FileIndex = FileIndex;
|
||||
/**
|
||||
* Inode for a file. Stores an arbitrary (filesystem-specific) data payload.
|
||||
*/
|
||||
var FileInode = /** @class */ (function () {
|
||||
function FileInode(data) {
|
||||
this.data = data;
|
||||
}
|
||||
FileInode.prototype.isFile = function () { return true; };
|
||||
FileInode.prototype.isDir = function () { return false; };
|
||||
FileInode.prototype.getData = function () { return this.data; };
|
||||
FileInode.prototype.setData = function (data) { this.data = data; };
|
||||
return FileInode;
|
||||
}());
|
||||
exports.FileInode = FileInode;
|
||||
/**
|
||||
* Inode for a directory. Currently only contains the directory listing.
|
||||
*/
|
||||
var DirInode = /** @class */ (function () {
|
||||
/**
|
||||
* Constructs an inode for a directory.
|
||||
*/
|
||||
function DirInode(data) {
|
||||
if (data === void 0) { data = null; }
|
||||
this.data = data;
|
||||
this._ls = {};
|
||||
}
|
||||
DirInode.prototype.isFile = function () {
|
||||
return false;
|
||||
};
|
||||
DirInode.prototype.isDir = function () {
|
||||
return true;
|
||||
};
|
||||
DirInode.prototype.getData = function () { return this.data; };
|
||||
/**
|
||||
* Return a Stats object for this inode.
|
||||
* @todo Should probably remove this at some point. This isn't the
|
||||
* responsibility of the FileIndex.
|
||||
*/
|
||||
DirInode.prototype.getStats = function () {
|
||||
return new node_fs_stats_1.default(node_fs_stats_1.FileType.DIRECTORY, 4096, 0x16D);
|
||||
};
|
||||
/**
|
||||
* Returns the directory listing for this directory. Paths in the directory are
|
||||
* relative to the directory's path.
|
||||
* @return The directory listing for this directory.
|
||||
*/
|
||||
DirInode.prototype.getListing = function () {
|
||||
return Object.keys(this._ls);
|
||||
};
|
||||
/**
|
||||
* Returns the inode for the indicated item, or null if it does not exist.
|
||||
* @param p Name of item in this directory.
|
||||
*/
|
||||
DirInode.prototype.getItem = function (p) {
|
||||
var item = this._ls[p];
|
||||
return item && this._ls.hasOwnProperty(p) ? item : null;
|
||||
};
|
||||
/**
|
||||
* Add the given item to the directory listing. Note that the given inode is
|
||||
* not copied, and will be mutated by the DirInode if it is a DirInode.
|
||||
* @param p Item name to add to the directory listing.
|
||||
* @param inode The inode for the
|
||||
* item to add to the directory inode.
|
||||
* @return True if it was added, false if it already existed.
|
||||
*/
|
||||
DirInode.prototype.addItem = function (p, inode) {
|
||||
if (p in this._ls) {
|
||||
return false;
|
||||
}
|
||||
this._ls[p] = inode;
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
* Removes the given item from the directory listing.
|
||||
* @param p Name of item to remove from the directory listing.
|
||||
* @return Returns the item
|
||||
* removed, or null if the item did not exist.
|
||||
*/
|
||||
DirInode.prototype.remItem = function (p) {
|
||||
var item = this._ls[p];
|
||||
if (item === undefined) {
|
||||
return null;
|
||||
}
|
||||
delete this._ls[p];
|
||||
return item;
|
||||
};
|
||||
return DirInode;
|
||||
}());
|
||||
exports.DirInode = DirInode;
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
function isFileInode(inode) {
|
||||
return !!inode && inode.isFile();
|
||||
}
|
||||
exports.isFileInode = isFileInode;
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
function isDirInode(inode) {
|
||||
return !!inode && inode.isDir();
|
||||
}
|
||||
exports.isDirInode = isDirInode;
|
||||
//# sourceMappingURL=file_index.js.map
|
||||
Reference in New Issue
Block a user