Time slots app prototype
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.2 KiB

const { sep, resolve: pathResolve } = require("path");
const { cleanPath } = require("../utils");
const fns = require("./fns");
const readdirOpts = { withFileTypes: true };
function init(dir, options, callback, isSync) {
if (options.resolvePaths) dir = pathResolve(dir);
if (options.normalizePath) dir = cleanPath(dir);
/* We use a local state object instead of direct global variables so that each function
* execution is independent of each other.
*/
const state = {
// Perf: we explicitly tell the compiler to optimize for String arrays
paths: [""].slice(0, 0),
queue: 0,
counts: { files: 0, dirs: 0 },
options,
callback,
};
/*
* Perf: We conditionally change functions according to options. This gives a slight
* performance boost. Since these functions are so small, they are automatically inlined
* by the engine so there's no function call overhead (in most cases).
*/
buildFunctions(options, isSync);
return { state, callbackInvoker, dir };
}
function walkSingleDir(walk, state, dir, dirents, currentDepth, callback) {
pushDir(dir, state.paths);
// in cases where we have / as path
if (dir === sep) dir = "";
const files = getArray(state);
for (var i = 0; i < dirents.length; ++i) {
const dirent = dirents[i];
if (dirent.isFile()) {
const filename = joinPath(dirent.name, dir);
pushFile(filename, files, dir, state);
} else if (dirent.isDirectory()) {
let dirPath = `${dir}${sep}${dirent.name}`;
walkDir(walk, state, dirPath, dirent.name, currentDepth - 1, callback);
}
}
groupFiles(dir, files, state);
}
function buildFunctions(options, isSync) {
const {
filters,
onlyCountsVar,
includeBasePath,
includeDirs,
groupVar,
excludeFn,
} = options;
buildPushFile(filters, onlyCountsVar);
pushDir = includeDirs ? fns.pushDir : fns.empty;
// build function for joining paths
joinPath = includeBasePath ? fns.joinPathWithBasePath : fns.joinPath;
// build recursive walk directory function
walkDir = excludeFn ? fns.walkDirExclude(excludeFn) : fns.walkDir;
// build groupFiles function for grouping files
groupFiles = groupVar ? fns.groupFiles : fns.empty;
getArray = groupVar ? fns.getArrayGroup : fns.getArray;
buildCallbackInvoker(onlyCountsVar, isSync);
}
module.exports = { buildFunctions, init, walkSingleDir, readdirOpts };
function buildPushFile(filters, onlyCountsVar) {
if (filters.length && onlyCountsVar) {
pushFile = fns.pushFileFilterAndCount(filters);
} else if (filters.length) {
pushFile = fns.pushFileFilter(filters);
} else if (onlyCountsVar) {
pushFile = fns.pushFileCount;
} else {
pushFile = fns.pushFile;
}
}
function buildCallbackInvoker(onlyCountsVar, isSync) {
if (onlyCountsVar) {
callbackInvoker = isSync
? fns.callbackInvokerOnlyCountsSync
: fns.callbackInvokerOnlyCountsAsync;
} else {
callbackInvoker = isSync
? fns.callbackInvokerDefaultSync
: fns.callbackInvokerDefaultAsync;
}
}
/* Dummies that will be filled later conditionally based on options */
var pushFile = fns.empty;
var pushDir = fns.empty;
var walkDir = fns.empty;
var joinPath = fns.empty;
var groupFiles = fns.empty;
var callbackInvoker = fns.empty;
var getArray = fns.empty;