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

@dokebi/worker

v0.4.1

Published

Worker thread pool for CPU-heavy functions in a Dokebi app.

Readme

@dokebi/worker

An optional plugin that sends CPU work to Node.js worker threads. core ^0.4.0, Node.js 24.0.0 or later, version 0.4.1 (unpublished). Cluster processes and HTTP port sharing belong to other packages. AI agents start with AI.md.

schemaVersion: 1
options:
  dokebi-worker:
    module: src/infra/worker/tasks.ts
    size: 2
    maxPending: 128
    startupTimeoutMs: 5000
    executionTimeoutMs: 0
    maxThreadCrashes: 5
    threadCrashWindowMs: 60000

| Key | Type | Default | Description | |---|---|---|---| | module | string | src/infra/worker/tasks.ts | Local path or file URL exporting a default function | | size | integer 1–64 | 1–4 by CPU count | Threads | | maxPending | integer 0–100000 | 128 | Waiting tasks, running ones excluded | | startupTimeoutMs | integer ms | 5000 | Module load deadline | | executionTimeoutMs | integer ms | 0 (off) | Per-task deadline from dispatch | | maxThreadCrashes | integer 0–1000 | 5 | Crashes replaced within the window | | threadCrashWindowMs | integer ms | 60000 | Crash counting window |

module is a local path or file URL that exports a default function; a relative path is resolved from cwd. Remote URLs are not allowed. 0.4.0 renamed maxQueue to maxPending (D-0071); the old name still works with an OPTION_DEPRECATED warning.

createPlugin({ app: app.view, options? }) is a plugin contract v2 (definePlugin) factory. app is required and must be the app.view core created. Without options it uses app.config['dokebi-worker'] ({} when null); given options are used alone. A configuration error is INVALID_PLUGIN_OPTIONS (its cause has the code INVALID_OPTIONS); unknown input such as dependencies is INVALID_PLUGIN_INPUT. After the app starts use app.get(plugin); consumers get the same pool with a descriptor declared in metadata.dependencies and context.getDependency(descriptor), or with context.get(plugin). The plugin owns the shutdown in the lifecycle.

The CLI install manifest is schemaVersion 2 and creates src/infra/worker/tasks.ts from scaffold/tasks.ts through dokebi.install.files. The file is user-owned, and remove keeps it when modified.

Outside an app use WorkerPool.open(options, { signal? }) and close it in finally. That signal covers startup only; aborting it after the pool is ready does not close the pool.

pool.run(input, { signal?, transferList?, executionTimeoutMs? }) returns Promise<unknown>. signal cancels only queued tasks with ABORTED and never stops a running task. Input and output follow Node's structured clone rules.

transferList holds at most 1024 items and only the list is copied at submit. The input and buffer contents belong to the caller until dispatch, so do not change them after submitting. The resources move at dispatch, and cancelling a queued task does not detach buffers. Duplicate or non-transferable items are rejected at dispatch with CLONE_FAILED, and later tasks go on.

The execution deadline starts at dispatch and excludes queue waiting. Only the task past it gets EXECUTION_TIMEOUT, and only its thread is terminated and replaced. Other active and queued tasks continue. A thread crash (error, unexpected exit, messageerror, a message outside the protocol) ends only the task that thread was running with WORKER_FAILED (cause: the original error) and replaces the thread. When crashes exceed maxThreadCrashes within threadCrashWindowMs, the whole pool closes with WORKER_CRASH_LOOP; when a replacement thread cannot start (module load failure, startup deadline passed) it closes with WORKER_REPLACEMENT_FAILED. Timeouts do not count as crashes. Tasks are never rerun. Timers depend on the parent event loop making progress. See D-0050.

maxPending: 0 still dispatches at once to an idle thread. The queue is FIFO; size, queued and active show the state. pool.status is a snapshot of state, closeCode, size, ready, active, queued, replaced, crashes and timeouts. Repeated close calls return the same completion Promise, which waits for thread termination after rejecting every task.

The main errors are INVALID_OPTIONS, STARTUP_TIMEOUT, ABORTED, QUEUE_FULL, CLONE_FAILED, TASK_FAILED, EXECUTION_TIMEOUT, WORKER_FAILED, WORKER_CRASH_LOOP, WORKER_REPLACEMENT_FAILED and POOL_CLOSED, all core DokebiErrors with fix/hint where a fix is known. WORKER_EXIT and INVALID_MESSAGE come as the cause of WORKER_FAILED (directly during open). TASK_FAILED keeps the thrown error as its cause (name, message, stack, a string or number code, the cause chain), so never put sensitive data in task errors.

Install with the CLI: npx dokebi add @dokebi/worker. Example 13 shows transfer, the execution deadline and thread replacement.