Skip to content

Instantly share code, notes, and snippets.

@developit
Last active July 19, 2024 13:23
Show Gist options
  • Save developit/a09befd9ba8ad2c9bde9ce1505035d9b to your computer and use it in GitHub Desktop.
Save developit/a09befd9ba8ad2c9bde9ce1505035d9b to your computer and use it in GitHub Desktop.

Revisions

  1. developit revised this gist Jul 19, 2024. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -25,6 +25,6 @@ The run2 package installs two commands for you to use: `run` and `exec`.
    ### TypeScript

    If you have `esbuild` installed, TypeScript is supported anywhere you can use JS - in scripts and `exec foo.ts`.
    If your scripts reference `ts-node`, they will automatically use Nobe's TypeScript support instead (it's 10-20x faster).
    If your scripts reference `ts-node`, they will automatically use Run2's TypeScript support instead (it's 10-20x faster).

    To install esbuild: `npm i esbuild` or `npm i -g esbuild` for global.
  2. developit revised this gist Jul 19, 2024. No changes.
  3. developit revised this gist Jul 19, 2024. 3 changed files with 15 additions and 5 deletions.
    6 changes: 4 additions & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,11 @@
    # Nobe: Node, but faster
    # run2: Node, but faster

    Installation: `npm i -g nobe`
    Installation: `npm i -g run2`

    ### Usage

    The run2 package installs two commands for you to use: `run` and `exec`.

    **`run`** runs an npm script from your package.json.

    ```diff
    12 changes: 10 additions & 2 deletions package-lock.json
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,11 @@
    {
    "name": "nobe",
    "name": "run2",
    "version": "0.0.1",
    "lockfileVersion": 3,
    "requires": true,
    "packages": {
    "": {
    "name": "nobe",
    "name": "run2",
    "version": "0.0.1",
    "license": "MIT",
    "bin": {
    @@ -15,6 +15,14 @@
    },
    "devDependencies": {
    "esbuild": "^0.21.4"
    },
    "peerDependencies": {
    "esbuild": "*"
    },
    "peerDependenciesMeta": {
    "esbuild": {
    "optional": true
    }
    }
    },
    "node_modules/@esbuild/aix-ppc64": {
    2 changes: 1 addition & 1 deletion package.json
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    {
    "name": "nobe",
    "name": "run2",
    "version": "0.0.1",
    "bin": {
    "nobe": "index.js",
  4. developit created this gist Jun 5, 2024.
    1 change: 1 addition & 0 deletions .gitignore
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    node_modules
    28 changes: 28 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,28 @@
    # Nobe: Node, but faster

    Installation: `npm i -g nobe`

    ### Usage

    **`run`** runs an npm script from your package.json.

    ```diff
    - npm run build
    - pnpm run build
    - node --run build
    + run build
    ```

    **`exec`** runs a script/module file.

    ```diff
    - node foo.js
    + exec foo.js
    ```

    ### TypeScript

    If you have `esbuild` installed, TypeScript is supported anywhere you can use JS - in scripts and `exec foo.ts`.
    If your scripts reference `ts-node`, they will automatically use Nobe's TypeScript support instead (it's 10-20x faster).

    To install esbuild: `npm i esbuild` or `npm i -g esbuild` for global.
    463 changes: 463 additions & 0 deletions index.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,463 @@
    #!/usr/bin/env node

    const path = require('node:path');
    const {Worker} = require('node:worker_threads');

    const DEBUG = {parsing: false, timing: false};
    const debugEnv = process.env.DEBUG;
    if (debugEnv) {
    for (const name in DEBUG) {
    DEBUG[name] =
    debugEnv === 'true' || debugEnv === '1' || debugEnv.includes(name);
    }
    }
    const readFile = (file) => require('node:fs/promises').readFile(file, 'utf-8');
    const exists = (filename) =>
    require('node:fs/promises')
    .access(filename)
    .then(() => true)
    .catch(() => false);

    const $env = (env) => (env ? {...process.env, ...env} : process.env);

    let markId = 0;
    function measure(name, parent = '', depth = 0) {
    const start = `${parent}:${name}:${++markId}`;
    performance.mark(start);
    function end() {
    performance.measure(name, {
    start,
    detail: {depth, parent},
    });
    }
    end.submeasure = (sub) => measure(sub, start, depth + 1);
    return end;
    }

    const color = (code, end) => (str) => `\x1B[${code}m${str}\x1B[${end}m`;
    const bold = color(1, 22);
    const dim = color(2, 22);
    const red = color(31, 39);
    const panic = (message) => {
    console.log(red(bold('Error: ') + message));
    process.exit(1);
    };

    function json5(json) {
    try {
    return JSON.parse(json);
    } catch (_2) {
    return (0, eval)(`(${json})`);
    }
    }

    const endPkgParse = measure('parse package.json');
    let pkg;
    const pkgPromise = readFile('package.json').then((json) => {
    pkg = json5(json);
    endPkgParse();
    return pkg;
    });

    const INITIAL = 0;
    const COMMAND = 1;
    const ARGS = 2;

    function parseShell(script) {
    script += ' ';
    const tokenizer = /(if|then|fi|&&|\|\||[ ;"'`()=])/g;
    const expectedOps = {
    ')': '(',
    fi: 'if',
    };
    const stack = [];
    const logic = [];
    let context = INITIAL;
    let token;
    let index = 0;
    let lastOp;
    let lastEnv;
    let buf = '';
    let command = {name: '', args: [], env: {}};
    const root = [];
    let seq = root;
    const commit = () => {
    if (context === INITIAL) {
    if (lastEnv) {
    if (!command) seq.push((command = {name: '', args: [], env: {}}));
    command.env[lastEnv] = buf;
    lastEnv = undefined;
    } else if (buf) {
    if (!command) seq.push((command = {name: '', args: [], env: {}}));
    command.name = buf;
    context = ARGS;
    }
    } else if (context === ARGS) {
    // unquote
    if (buf[0] === "'" && buf.at(-1) === "'") {
    buf = buf.slice(1, -1);
    } else if (buf[0] === '"' && buf.at(-1) === '"') {
    buf = buf.slice(1, -1).replaceAll('\\"', '"');
    }
    command.args.push(buf);
    }
    buf = '';
    };
    while ((token = tokenizer.exec(script))) {
    let op = token[0];
    buf += script.substring(index, token.index);
    index = tokenizer.lastIndex;
    switch (op) {
    case '&&':
    case '||':
    if (lastOp) continue;
    seq.push({type: op});
    case ';':
    if (lastOp) continue;
    commit();
    command = null;
    context = INITIAL;
    break;
    case ' ':
    if (!buf) continue;
    if (lastOp) {
    if (buf) buf += ' ';
    continue;
    }
    commit();
    break;
    case '=':
    if (context === INITIAL && !lastOp) {
    lastEnv = buf;
    buf = '';
    } else {
    buf += op;
    }
    break;
    case 'if':
    if (context !== INITIAL) {
    buf += op;
    continue;
    }
    logic.push({
    type: 'conditional',
    test: [],
    consequent: [],
    alternate: [],
    });
    seq = logic.at(-1)?.test;
    command = null;
    context = INITIAL;
    break;
    case 'then':
    if (context !== INITIAL) {
    buf += op;
    continue;
    }
    seq = logic.at(-1)?.consequent;
    command = null;
    context = INITIAL;
    break;
    case 'else':
    if (context !== INITIAL) {
    buf += op;
    continue;
    }
    seq = logic.at(-1)?.alternate;
    command = null;
    context = INITIAL;
    break;
    case 'fi':
    if (context !== INITIAL) {
    buf += op;
    continue;
    }
    seq = root;
    if (logic.length) seq.push(logic.pop());
    break;
    case '(':
    case ')':
    case '"':
    case `'`:
    case '`':
    buf += op;
    default:
    if (op in expectedOps) {
    const start = expectedOps[op];
    if (lastOp !== start) {
    const line = `${script}\n${'-'.repeat(token.index)}^`;
    panic(`unexpected "${op}"\n${dim(line)}`);
    }
    op = start;
    }
    if (lastOp === op) {
    stack.pop();
    lastOp = stack.at(-1);
    } else {
    stack.push(op);
    lastOp = op;
    }
    break;
    }
    }
    if (command && seq.at(-1) !== command) seq.push(command);
    return seq;
    }

    async function run(seq, env = {}) {
    let prev = true;
    for (const node of seq) {
    switch (node.type) {
    case '&&':
    if (!prev) return;
    break;
    case '||':
    if (prev) return prev;
    break;
    case 'conditional':
    if (await run(node.test, env)) {
    prev = await run(node.consequent, env);
    } else if (node.alternate) {
    prev = await run(node.alternate, env);
    }
    break;
    default:
    if (node.name === '$npm_execpath' || node.name === 'npm') {
    let script = node.args.shift();
    if (script === 'run') script = node.args.shift();
    prev = await runScript(script, node.args, {...env, ...node.env});
    } else if (node.name === 'node') {
    const script = node.args.shift();
    prev = await runNode(script, node.args, {...env, ...node.env});
    } else if (node.name === 'test') {
    const a1 = node.args[0].replace(
    /$([a-z0-9_]+)/g,
    (_, c) => process.env[c] ?? _,
    );
    const a2 = node.args[2].replace(
    /$([a-z0-9_]+)/g,
    (_, c) => process.env[c] ?? _,
    );
    if (node.args[1] === '=') prev = a1 === a2;
    else if (node.args[1] === '!=') prev = a1 !== a2;
    } else if (node.name) {
    // panic(`Unknown command ${node.name} (${node.args})`);
    prev = await runBin(node.name, node.args, node.env);
    } else {
    panic(`Unknown node ${JSON.stringify(node)}`);
    }
    }
    }
    return prev;
    }

    const workerShim = `
    const {parentPort} = require('node:worker_threads');
    const {dirname, basename, sep} = require('path');
    parentPort.once('message', ([mod, filename, args, env, compiledCode]) => {
    process.stdout.isTTY = process.stdin.isTTY = process.stderr.isTTY = true;
    process.argv = [process.argv[0], filename].concat(args);
    module.id = basename(filename);
    module.filename = __filename = filename;
    module.path = __dirname = dirname(__filename);
    Object.assign(process.env, env);
    parentPort.postMessage(0);
    const exit = process.exit.bind(process);
    process.exit = (exitCode) => {
    process.stdout.end();
    process.setUncaughtExceptionCaptureCallback(() => {});
    setTimeout(exit, 0, exitCode);
    };
    if (mod && !compiledCode) return import(filename);
    require = require('node:module').createRequire(require.resolve(filename));
    require('vm').runInThisContext(compiledCode || require('fs').readFileSync(filename, 'utf-8'), {filename});
    });
    `;
    const workerPool = {
    workers: [],
    get: () => workerPool.workers.pop() ?? workerPool.create(),
    create: () => new Worker(workerShim, {eval: true}),
    };
    workerPool.workers.push(workerPool.create());

    const pkgCache = new Map();
    function getPkg(filename) {
    const index = filename.lastIndexOf('/node_modules/');
    if (index === -1) return pkgPromise;
    const pkgName = filename.slice(index + 14).match(/^(@[^/]+\/)?[^/]+/g)[0];
    const pkgFile = `${filename.slice(0, index + 14)}${pkgName}/package.json`;
    const cached = pkgCache.get(pkgFile);
    if (cached) return cached;
    const prom = readFile(pkgFile).then(json5);
    pkgCache.set(pkgFile, prom);
    return prom;
    }

    async function runNode(script, args, env, compiledCode) {
    if (
    process.env.ESBUILD === 'force' &&
    compiledCode === undefined &&
    !script.endsWith('.built.mjs')
    ) {
    return runTs(script, args, env);
    }
    const scriptId = `node(${script} ${args.join(' ')})`;
    const done = measure(scriptId);
    const filename = path.resolve(script);

    const isModule =
    filename.endsWith('.mjs') ||
    ((await getPkg(filename)).type === 'module' && !filename.endsWith('.cjs'));

    return new Promise((resolve) => {
    const end = done.submeasure('worker start');
    const worker = workerPool.get();
    worker.postMessage([isModule, filename, args, $env(env), compiledCode]);
    worker.once('message', done.submeasure('worker init'));
    worker.once('exit', done);
    worker.once('exit', resolve);
    end();
    });
    }

    async function runTs(script, args, env) {
    const end = measure(`esbuild(${script})`);
    const {build} = require('esbuild');
    const outfile = script.endsWith('.mjs')
    ? script.replace(/([^/]+)\.mjs$/, '.$1.built.mjs')
    : undefined;
    if (!outfile && !/\.[a-z]+$/.test(script)) {
    const [ext, index] = await Promise.all([
    exists(`${script}.ts`),
    exists(`${script}/index.ts`),
    ]);
    if (ext) script += '.ts';
    else if (index) script += '/index.ts';
    }
    const result = await build({
    bundle: true,
    entryPoints: [script],
    target: 'node20',
    platform: 'node',
    format: outfile ? 'esm' : 'cjs',
    packages: 'external',
    write: Boolean(outfile),
    outfile,
    treeShaking: true,
    minifyIdentifiers: true,
    minifySyntax: true,
    nodePaths: [],
    });
    if (result.errors.length) {
    panic(`TS build of ${script} failed:\n${result.errors.join('\n')}`);
    }

    if (outfile) {
    end();
    try {
    return await runNode(outfile, args, env);
    } finally {
    require('node:fs').unlink(outfile, Object);
    }
    }
    let code = result.outputFiles[0].text;

    // move top-level requires to callsites so they only get evaluated when surrounding code is executed
    const idents = {};
    code = code.replace(
    /(?:^var (import_[a-zA-Z0-9_$]+) = ((?:__toESM\()?require\("[^"]+"\)\)?);?$|\b(import_[a-zA-Z0-9_$]+)\b)/gm,
    (_, ident, req, ident2) => {
    if (ident2) return idents[ident2] ?? ident2;
    idents[ident] = req;
    return '';
    },
    );
    end();
    // process.setSourceMapsEnabled(true);
    return runNode(script, args, env, code);
    }

    const BIN = {
    'ts-node': (args, env) => {
    let script;
    const remainingArgs = args.filter((arg) => {
    if (arg[0] === '-' || script) return true;
    script = arg;
    return false;
    });
    return runTs(script, remainingArgs, env);
    },
    };

    async function runBin(bin, args, env) {
    if (Object.prototype.hasOwnProperty.call(BIN, bin)) {
    return BIN[bin](args, env);
    }
    let resolvedBin = bin;
    try {
    const done = measure(`resolve-bin(${bin} ${args.join(' ')})`);
    const code = await readFile(`node_modules/.bin/${bin}`);
    resolvedBin = `node_modules/.bin/${bin}`;
    // exec node "$basedir/../vite/bin/vite.js" "$@"
    const match = code.match(/exec +node +"([^"]+)" +"\$@"/)?.[1];
    if (!match) throw Error(`Unknown format at node_modules/.bin/${bin}`);
    const binFile = path.resolve(
    match.replace('$basedir', './node_modules/.bin'),
    );
    const binRel = path.relative('.', binFile);
    done();
    return runNode(binRel, args, env);
    } catch (err) {
    const done = measure(`run-bin(${bin} ${args.join(' ')})`);
    // console.error(`failed to run "${bin}" seamlessly:`, err);
    return new Promise((resolve) => {
    const {spawn} = require('node:child_process');
    const proc = spawn(resolvedBin, args, {env: $env(env), stdio: 'inherit'});
    // proc.on('error', reject);
    proc.once('exit', (exitCode) => {
    done();
    resolve(exitCode);
    });
    });
    }
    }

    async function runScript(scriptName, args, env) {
    const script = (await pkgPromise).scripts[scriptName];
    if (!script) {
    const bin = path.basename(scriptName);
    if (await exists(`node_modules/.bin/${bin}`)) {
    return runBin(bin, args, env);
    }
    panic(`Unknown script "${scriptName}".`);
    }
    let scriptWithArgs = script;
    for (const arg of args) scriptWithArgs += ` ${arg}`;
    const done = measure('parse');
    const parsed = parseShell(scriptWithArgs);
    if (DEBUG.parsing) console.log('parsed: ', scriptWithArgs, parsed);
    done();
    return run(parsed, env);
    }

    (async () => {
    const start = performance.now();
    const cmd = path.basename(process.argv[1]);
    const runner = cmd === 'exec' ? runBin : runScript;
    const name = process.argv[2];
    if (!name) panic('No script name provided.');
    try {
    process.exitCode = await runner(name, process.argv.slice(3));
    } finally {
    let worker;
    while ((worker = workerPool.workers?.pop())) worker.terminate();
    if (DEBUG.timing) {
    console.log(bold(dim(`Done in ${(performance.now() - start) | 0}ms:`)));
    const dur = (ms) => (ms < 1 ? `${(ms * 1000) | 0}µs` : `${ms | 0}ms`);
    for (const entry of performance.getEntriesByType('measure')) {
    const pfx = entry.detail.depth ? ' '.repeat(entry.detail.depth) : '';
    console.log(dim(`${pfx}${dur(entry.duration)}: ${entry.name}`));
    }
    }
    }
    })();
    427 changes: 427 additions & 0 deletions package-lock.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,427 @@
    {
    "name": "nobe",
    "version": "0.0.1",
    "lockfileVersion": 3,
    "requires": true,
    "packages": {
    "": {
    "name": "nobe",
    "version": "0.0.1",
    "license": "MIT",
    "bin": {
    "exec": "index.js",
    "nobe": "index.js",
    "run": "index.js"
    },
    "devDependencies": {
    "esbuild": "^0.21.4"
    }
    },
    "node_modules/@esbuild/aix-ppc64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.4.tgz",
    "integrity": "sha512-Zrm+B33R4LWPLjDEVnEqt2+SLTATlru1q/xYKVn8oVTbiRBGmK2VIMoIYGJDGyftnGaC788IuzGFAlb7IQ0Y8A==",
    "cpu": [
    "ppc64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "aix"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/android-arm": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.4.tgz",
    "integrity": "sha512-E7H/yTd8kGQfY4z9t3nRPk/hrhaCajfA3YSQSBrst8B+3uTcgsi8N+ZWYCaeIDsiVs6m65JPCaQN/DxBRclF3A==",
    "cpu": [
    "arm"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "android"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/android-arm64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.4.tgz",
    "integrity": "sha512-fYFnz+ObClJ3dNiITySBUx+oNalYUT18/AryMxfovLkYWbutXsct3Wz2ZWAcGGppp+RVVX5FiXeLYGi97umisA==",
    "cpu": [
    "arm64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "android"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/android-x64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.4.tgz",
    "integrity": "sha512-mDqmlge3hFbEPbCWxp4fM6hqq7aZfLEHZAKGP9viq9wMUBVQx202aDIfc3l+d2cKhUJM741VrCXEzRFhPDKH3Q==",
    "cpu": [
    "x64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "android"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/darwin-arm64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.4.tgz",
    "integrity": "sha512-72eaIrDZDSiWqpmCzVaBD58c8ea8cw/U0fq/PPOTqE3c53D0xVMRt2ooIABZ6/wj99Y+h4ksT/+I+srCDLU9TA==",
    "cpu": [
    "arm64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "darwin"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/darwin-x64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.4.tgz",
    "integrity": "sha512-uBsuwRMehGmw1JC7Vecu/upOjTsMhgahmDkWhGLWxIgUn2x/Y4tIwUZngsmVb6XyPSTXJYS4YiASKPcm9Zitag==",
    "cpu": [
    "x64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "darwin"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/freebsd-arm64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.4.tgz",
    "integrity": "sha512-8JfuSC6YMSAEIZIWNL3GtdUT5NhUA/CMUCpZdDRolUXNAXEE/Vbpe6qlGLpfThtY5NwXq8Hi4nJy4YfPh+TwAg==",
    "cpu": [
    "arm64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "freebsd"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/freebsd-x64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.4.tgz",
    "integrity": "sha512-8d9y9eQhxv4ef7JmXny7591P/PYsDFc4+STaxC1GBv0tMyCdyWfXu2jBuqRsyhY8uL2HU8uPyscgE2KxCY9imQ==",
    "cpu": [
    "x64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "freebsd"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/linux-arm": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.4.tgz",
    "integrity": "sha512-2rqFFefpYmpMs+FWjkzSgXg5vViocqpq5a1PSRgT0AvSgxoXmGF17qfGAzKedg6wAwyM7UltrKVo9kxaJLMF/g==",
    "cpu": [
    "arm"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "linux"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/linux-arm64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.4.tgz",
    "integrity": "sha512-/GLD2orjNU50v9PcxNpYZi+y8dJ7e7/LhQukN3S4jNDXCKkyyiyAz9zDw3siZ7Eh1tRcnCHAo/WcqKMzmi4eMQ==",
    "cpu": [
    "arm64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "linux"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/linux-ia32": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.4.tgz",
    "integrity": "sha512-pNftBl7m/tFG3t2m/tSjuYeWIffzwAZT9m08+9DPLizxVOsUl8DdFzn9HvJrTQwe3wvJnwTdl92AonY36w/25g==",
    "cpu": [
    "ia32"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "linux"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/linux-loong64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.4.tgz",
    "integrity": "sha512-cSD2gzCK5LuVX+hszzXQzlWya6c7hilO71L9h4KHwqI4qeqZ57bAtkgcC2YioXjsbfAv4lPn3qe3b00Zt+jIfQ==",
    "cpu": [
    "loong64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "linux"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/linux-mips64el": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.4.tgz",
    "integrity": "sha512-qtzAd3BJh7UdbiXCrg6npWLYU0YpufsV9XlufKhMhYMJGJCdfX/G6+PNd0+v877X1JG5VmjBLUiFB0o8EUSicA==",
    "cpu": [
    "mips64el"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "linux"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/linux-ppc64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.4.tgz",
    "integrity": "sha512-yB8AYzOTaL0D5+2a4xEy7OVvbcypvDR05MsB/VVPVA7nL4hc5w5Dyd/ddnayStDgJE59fAgNEOdLhBxjfx5+dg==",
    "cpu": [
    "ppc64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "linux"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/linux-riscv64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.4.tgz",
    "integrity": "sha512-Y5AgOuVzPjQdgU59ramLoqSSiXddu7F3F+LI5hYy/d1UHN7K5oLzYBDZe23QmQJ9PIVUXwOdKJ/jZahPdxzm9w==",
    "cpu": [
    "riscv64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "linux"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/linux-s390x": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.4.tgz",
    "integrity": "sha512-Iqc/l/FFwtt8FoTK9riYv9zQNms7B8u+vAI/rxKuN10HgQIXaPzKZc479lZ0x6+vKVQbu55GdpYpeNWzjOhgbA==",
    "cpu": [
    "s390x"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "linux"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/linux-x64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.4.tgz",
    "integrity": "sha512-Td9jv782UMAFsuLZINfUpoF5mZIbAj+jv1YVtE58rFtfvoKRiKSkRGQfHTgKamLVT/fO7203bHa3wU122V/Bdg==",
    "cpu": [
    "x64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "linux"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/netbsd-x64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.4.tgz",
    "integrity": "sha512-Awn38oSXxsPMQxaV0Ipb7W/gxZtk5Tx3+W+rAPdZkyEhQ6968r9NvtkjhnhbEgWXYbgV+JEONJ6PcdBS+nlcpA==",
    "cpu": [
    "x64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "netbsd"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/openbsd-x64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.4.tgz",
    "integrity": "sha512-IsUmQeCY0aU374R82fxIPu6vkOybWIMc3hVGZ3ChRwL9hA1TwY+tS0lgFWV5+F1+1ssuvvXt3HFqe8roCip8Hg==",
    "cpu": [
    "x64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "openbsd"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/sunos-x64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.4.tgz",
    "integrity": "sha512-hsKhgZ4teLUaDA6FG/QIu2q0rI6I36tZVfM4DBZv3BG0mkMIdEnMbhc4xwLvLJSS22uWmaVkFkqWgIS0gPIm+A==",
    "cpu": [
    "x64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "sunos"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/win32-arm64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.4.tgz",
    "integrity": "sha512-UUfMgMoXPoA/bvGUNfUBFLCh0gt9dxZYIx9W4rfJr7+hKe5jxxHmfOK8YSH4qsHLLN4Ck8JZ+v7Q5fIm1huErg==",
    "cpu": [
    "arm64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "win32"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/win32-ia32": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.4.tgz",
    "integrity": "sha512-yIxbspZb5kGCAHWm8dexALQ9en1IYDfErzjSEq1KzXFniHv019VT3mNtTK7t8qdy4TwT6QYHI9sEZabONHg+aw==",
    "cpu": [
    "ia32"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "win32"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/@esbuild/win32-x64": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.4.tgz",
    "integrity": "sha512-sywLRD3UK/qRJt0oBwdpYLBibk7KiRfbswmWRDabuncQYSlf8aLEEUor/oP6KRz8KEG+HoiVLBhPRD5JWjS8Sg==",
    "cpu": [
    "x64"
    ],
    "dev": true,
    "optional": true,
    "os": [
    "win32"
    ],
    "engines": {
    "node": ">=12"
    }
    },
    "node_modules/esbuild": {
    "version": "0.21.4",
    "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.4.tgz",
    "integrity": "sha512-sFMcNNrj+Q0ZDolrp5pDhH0nRPN9hLIM3fRPwgbLYJeSHHgnXSnbV3xYgSVuOeLWH9c73VwmEverVzupIv5xuA==",
    "dev": true,
    "hasInstallScript": true,
    "bin": {
    "esbuild": "bin/esbuild"
    },
    "engines": {
    "node": ">=12"
    },
    "optionalDependencies": {
    "@esbuild/aix-ppc64": "0.21.4",
    "@esbuild/android-arm": "0.21.4",
    "@esbuild/android-arm64": "0.21.4",
    "@esbuild/android-x64": "0.21.4",
    "@esbuild/darwin-arm64": "0.21.4",
    "@esbuild/darwin-x64": "0.21.4",
    "@esbuild/freebsd-arm64": "0.21.4",
    "@esbuild/freebsd-x64": "0.21.4",
    "@esbuild/linux-arm": "0.21.4",
    "@esbuild/linux-arm64": "0.21.4",
    "@esbuild/linux-ia32": "0.21.4",
    "@esbuild/linux-loong64": "0.21.4",
    "@esbuild/linux-mips64el": "0.21.4",
    "@esbuild/linux-ppc64": "0.21.4",
    "@esbuild/linux-riscv64": "0.21.4",
    "@esbuild/linux-s390x": "0.21.4",
    "@esbuild/linux-x64": "0.21.4",
    "@esbuild/netbsd-x64": "0.21.4",
    "@esbuild/openbsd-x64": "0.21.4",
    "@esbuild/sunos-x64": "0.21.4",
    "@esbuild/win32-arm64": "0.21.4",
    "@esbuild/win32-ia32": "0.21.4",
    "@esbuild/win32-x64": "0.21.4"
    }
    }
    }
    }
    23 changes: 23 additions & 0 deletions package.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,23 @@
    {
    "name": "nobe",
    "version": "0.0.1",
    "bin": {
    "nobe": "index.js",
    "run": "index.js",
    "exec": "index.js"
    },
    "description": "Node, but faster.",
    "author": "Jason Miller (https://jasonformat.com)",
    "license": "MIT",
    "devDependencies": {
    "esbuild": "^0.21.4"
    },
    "peerDependencies": {
    "esbuild": "*"
    },
    "peerDependenciesMeta": {
    "esbuild": {
    "optional": true
    }
    }
    }