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 🙏

© 2026 – Pkg Stats / Ryan Hefner

catsa-janga

v1.0.1

Published

Save and restore data for long-running processes.

Readme

catsa-janga

wakatime Node.js CI GitHub License GitHub Release codecov 0 Dependencies Size typescript Types npm npm GitHub issues GitHub stars Node & Bun Maintenance

A utility library for automatically saving and restoring progress in long-running Bun applications.

Features

  • 💾 Automatically saves progress data to a file
  • 🔄 Restores progress data when restarting a process
  • 🛑 Handles process termination signals (SIGINT, SIGTERM)
  • ⚠️ Captures unhandled exceptions and promise rejections
  • 🔍 Lightweight with no external dependencies
  • 📝 TypeScript support

Installation

# Using Bun
bun add catsa-janga

# Using npm
npm install catsa-janga

Usage

Basic Example

The recommended way to use CatsaJanga is:

import { CatsaJanga } from 'catsa-janga';

// Define your data structure
type MyData = {
    items: string[];
    processedCount: number;
    timestamp: Date;
};

// Create initial data
const data: MyData = {
    items: [],
    processedCount: 0,
    timestamp: new Date(),
};

// Create a progress saver
const saver = new CatsaJanga<MyData>({
    getData: () => ({
        ...data,
        timestamp: new Date(), // Update timestamp on save
    }),
    logger: console, // Use console as logger
    outputFile: 'progress.json',
});

Object.assign(data, await saver.restore());

// Your long-running process
async function processItems() {
    for (let i = 0; i < 1000; i++) {
        // Simulate work
        await new Promise((resolve) => setTimeout(resolve, 100));

        // Update data
        data.items.push(`Item ${i}`);
        data.processedCount++;

        // Optionally save progress periodically
        if (i % 100 === 0) {
            await saver.saveProgress();
        }
    }

    // Save final progress
    await saver.saveProgress();
}

// Start processing
await processItems();

Real-world example

Here's how you might use it in a scraping or OCR application:

import { CatsaJanga } from 'catsa-janga';

// Define your data structure
type OCRResult = {
    pages: Array<{ page: number; text: string }>;
    timestamp: Date;
};

// Create initial data
const initialData: OCRResult = {
    pages: [],
    timestamp: new Date(),
};

// Create and restore in one step
const saver = new CatsaJanga<OCRResult>({
    getData: () => ({
        ...data,
        pages: data.pages.toSorted((a, b) => a.page - b.page),
        timestamp: new Date(),
    }),
    logger: console,
    outputFile: 'ocr-progress.json',
});

Object.assign(data, await saver.restore());

// Process pages (if we crash, we'll resume where we left off)
for (const file of files) {
    if (data.pages.some((p) => p.page === file.pageNumber)) {
        console.log(`Skipping already processed page ${file.pageNumber}`);
        continue;
    }

    const result = await processOCR(file);
    data.pages.push({ page: file.pageNumber, text: result });

    // Save periodically
    if (data.pages.length % 10 === 0) {
        await saver.saveProgress();
    }
}

// Final save
await saver.saveProgress();

API

CatsaJanga

The main class for saving and restoring progress.

Constructor

constructor(options: CatsaJangaOptions<T>)

Options:

  • getData: Function that returns the current data to save
  • logger: Logger object with at least info and error methods (compatible with console, Pino, etc.)
  • outputFile: File path where progress will be saved
  • initialData (optional): Initial data to use if no saved data exists

Methods

restore
async restore(): Promise<T | undefined>

Checks for an existing progress file and restores data if present. Returns the restored data, the initialData (if provided and no saved data exists), or undefined.

saveProgress
async saveProgress(): Promise<void>

Saves the current progress to the output file.

Interfaces

Logger

interface Logger {
    error: (message: string, ...args: any[]) => void;
    info: (message: string, ...args: any[]) => void;
    warn?: (message: string, ...args: any[]) => void;
}

Compatible with console, Pino loggers, and other similar logging libraries.

CatsaJangaOptions

interface CatsaJangaOptions<T> {
    getData: () => T;
    logger: Logger;
    outputFile: string;
    initialData?: T;
}

Error Handling

catsa-janga automatically registers handlers for:

  • SIGINT (Ctrl+C)
  • SIGTERM (process termination)
  • uncaughtException (unhandled errors)
  • unhandledRejection (unhandled promise rejections)

When any of these events occur, the progress will be saved before the process exits.

License

MIT