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 🙏

© 2025 – Pkg Stats / Ryan Hefner

jobba

v0.17.1

Published

Jobba the Hub

Downloads

6

Readme

Jobba

Jobba the Hub, a job scheduler and runner.

Description

Jobba is a wrapper around Bull, which makes it a lot easier to work with (at least for our uses). It is written in TypeScript and used internally by Whitebox. It has an exposed HTTP API built upon Yawk, a great HTTP router and server. It also serves a simple management interface, (our fork of) Arena.

Terminology

  • Jobba: The job hub itself, which is what you register and schedule Tasks with.
    • Jobba#register returns a Task.
  • Task: Handlers that you register, which can be scheduled to run (creating a Job).
    • Task#schedule schedules the run of a Task.
    • Upon run, a Job is created and passed to the Task's handler.
  • Job: A scheduled Task, which can be a one-off run of its handler or a recurring run.

Usage

Setup

import Jobba, { Job, JobbaConfig } from 'jobba';

const config: JobbaConfig = {
	yawk: {
		port: 5000
	}
};

function registrar(jobba: Jobba) {
	jobba.register({
		id: 'some-task',
		handler: async (job: Job) => {
			await job.log('The params passed to this job:', job.params);
			return 'some response';
		}
	});
}

const jobba = new Jobba(config, registrar);
jobba.start();

NOTE: The Job and JobbaConfig type annotations are not needed, but are shown for clarity.

There are three ways to interact with Jobba:

  1. the Node.js module
  2. the HTTP API
  3. the front-end

Module

// one-off run
jobba.schedule('some-task', { some: 'params' });

// recurring run
jobba.schedule('some-task', { some: 'params' }, {
	repeat: { cron: '0 * * * *' }
});

HTTP API

The API is served at /api. GET /api/routes returns a list of endpoints and in some cases their descriptions or expected input and output schemas.

The most important endpoint is POST /api/tasks/${taskId}/schedule, which supports passing optional params and options like in this example:

{
	"options": {
		"repeat": {
			"cron": "0 * * * *"
		}
	},
	"params": {
		"some": "params"
	}
}

Front-end

The front-end is served at /. In its current state it is quite simplistic, and is mostly read-only for now. You cannot yet schedule tasks, though you can see details about completed/failed tasks as well as cancel scheduled ones.

Features

Returns

Tasks do not need to return anything. Their return values are indeed reflected in the front-end, but in practice most of our tasks don't return anything.

Errors

Any errors thrown are captured and reflected in the front-end as well, with their error message and stack trace.

jobba.register({
	id: 'some-task',
	handler: (job: Job) => {
		throw new Error('uh oh...');
	}
});

Logging

Logs are recorded with their log level, a timestamp, and their contents.

jobba.register({
	id: 'some-task',
	handler: async (job: Job) => {
		await job.log('Logging can be convenient.');
		await job.info('Logging can be informative.');
		await job.debug('Logging can be introspective.');
		await job.warn('Logging can be dangerous.');
		await job.error('Logging can be unfortunate.');

		await job.log('logs', 'support', 'infinite', 'arguments');
		await job.log('logs', 'support', [ 'various' ], { types: true });
	}
});

Creating a Job subclass

export class MyCustomJob extends Job {

	public async init(): Promise<any> {
		// Code here executed before the job's `process` function is invoked. 
	}

	public async process(): Promise<any> {
		// Do some processing work...
	}

	public async onProcessCompleted(): Promise<any> {
		// The `process` function has completed.
		// Can use this function for cleanup, logging, etc.
	}

}

Misc

jobba.register({
	id: 'some-task',
	handler: async (job: Job) => {
		// you can set progress
		await job.progress(40)
	}
});