@fpjs/overture
Version:
A Javascript prelude
81 lines (67 loc) • 2 kB
JavaScript
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
import fs from "fs";
import path from "path";
import repl from "repl";
const die = (msg, exitCode=1) => {
process.stderr.write(msg + "\n", "utf-8");
process.exit(exitCode);
};
const profile = (s, n=10000) => (f) => {
console.time(s);
try {
for (let i = 0; i < n-1; i++) {
f();
}
return f();
} finally {
console.timeEnd(s);
}
};
const findModules = (dir) => {
let modules = [];
for (const file of fs.readdirSync(dir, {withFileTypes: true})) {
if (file.isDirectory()) {
modules = modules.concat(findModules(path.join(dir, file.name)));
} else if (file.isFile()) {
modules.push(path.resolve(path.join(dir, file.name)));
}
};
return modules;
};
const npmModuleFromExec = (exec) => {
const {root, dir} = path.parse (exec);
const findNpmModule = (dir) => {
if (dir === root) {
die(`${exec} is not located inside an NPM module`);
}
if (fs.existsSync (path.join (dir, "package.json"))) {
return dir;
}
return findNpmModule (path.dirname (dir));
};
return findNpmModule (fs.realpathSync (exec));
};
const main = async () => {
const [_node, overture, ...args] = process.argv;
const overtureModule = npmModuleFromExec (overture);
const r = repl.start({
ignoreUndefined: true,
prompt: 'λ ',
replMode: repl.REPL_MODE_STRICT,
useGlobal: true,
});
const modules = await Promise.all(
findModules(path.join(overtureModule, "./src"))
.map((module) => import(module))
);
Object.assign(
r.context,
...modules,
{ profile },
);
r.context.patchBuiltins();
}
main();