npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

shellbee

v0.5.29

Published

<p align='center'> <img src='assets/background.jpg'/> </p>

Downloads

5,804

Readme

Shellbee


Yet another shell command executor (cmd, bash) and NodeJS fork with Inter Process Communication (IPC).


Build Status NPM version

import { Shell } from 'shellbee'

// executes commmands and waits until they exit
let shell: Shell = await Shell.run(command: string | string[] | IShellParams);


// instatiate the new shell instance, attach all required event listeners, etc, and later call `run` to start executing
let shell = new Shell({ command: `git commit -am "foo"` });

interface IShellParams {
    command?: string | IProcessSingleParams
    commands?: (string | IProcessSingleParams)[]
    detached?: boolean
    cwd?: string

    /** Watches the output and emits ready event when the child process prints expected text to the std */
    matchReady?: RegExp
    silent?: boolean
    parallel?: boolean

    // command should container js file to fork
    fork?: boolean

    // Defines if a child_process supports IPC
    ipc?: boolean

    timeoutsMs?: number

    restartOnErrorExit?: boolean
}

interface IProcessSingleParams {
    command: string
    cwd?: string
    detached?: boolean
    matchReady?: RegExp
    extract: {[ key: string ]: (output: string) => any }
}

interface IShell {
    commands: ICommandOptions[]
    results = [] as ProcessResult[]

    std: string[] = [];
    stderr: string[] = [];
    stdout: string[] = [];

    start: Date
    end: Date
    busy: boolean

    /** Resolves after the all commands are settled */
    promise: Promise<Shell>

    run (): Promise<Shell>
    kill()


    onStart (cb: (data: { command: string }) => void): this
    onStdout (cb: (data: { command: string, buffer: string }) => void): this
    onStderr (cb: (data: { command: string, buffer: string }) => void): this
    onExit (cb: (data: { command: string, code: number, result: ProcessResult }) => void): this
    /** When rgxReady is specified the event will be called */
    onReady (cb: ({ command: string }) => void): this
    onComplete(cb: (shell: Shell) => void): this
}

Communication channel

Basic Configuration

// main.js
import { Shell } from 'shellbee'

let shell = new Shell({
    command: 'bar.js',
    fork: true,
    ipc: true
})
shell.run();
let result = await shell.send('doFoo', { foo: 1 });
// bar.js
import { Shell } from 'shellbee'

Shell.ipc({
    doFoo (...args) {
        console.log(args);
        return 'lorem';
    }
});

Advanced Configuration

  1. Fork a process as usual.

let shell = new Shell({ command: 'bar.js', fork: true });

shell.run();
  1. In the worker listen for a message
{
    id: string,
    method: string
    args: any[]
}

The child process should process the work and sends a message with the id and result back to parent process:

{
    id: string,
    data?: any,
    error?: Error
}

Simple Forked file example:

// worker.js
process.on('message', async (message: { id, method, args }) => {
    let result = await MyWorker.doWork(message.method, ...message.args);
    process.send({
        id: message.id,
        data: result,
        error: null
    });
});

CLI

Execute a CLI task and makes sure it restarts on error or when output got stalled. For example you want to run a script from npm scripts forever, e.g. "npm run foo"

shellbee run npm run foo
    --delay <ms_delay_between_restart>
    --restart <max_restart_count_within_window>
    --restart-window <ms_window_errors>
    --stalled-output <restart_on_ms_no_output>
  • dalay - Milliseconds before the process is started again
  • restart - Amount of restarts within a time window. For example if the process has been crashed for 10 times within 30 seconds, do not restart any more.
  • restart-window - Milliseconds, a time-frame to count crashes in, when to many crashes occur (defined by restart) shellbee stops restarting the process.
  • stalled-output - Milliseconds, if the process has no output (stdout, stderr) for this time, then we assume the process has stopped responding, so shellbee will restart it