CloudtoidCloudtoid / interprocess

Node.js & TypeScript API reference

Send typed byte arrays and receive Node Buffers, with promises and AbortSignal for waiting.

npm package ↗ · TypeScript declarations ↗ · JavaScript API source ↗

Install

Requires Node.js 18 or later. Platform binaries install as optional packages; do not omit optional dependencies. TypeScript users need TypeScript 5.2 or later for the Symbol.dispose declarations. Linux prebuilt binaries require glibc 2.34 or later.

npm install @cloudtoid/interprocess

Send and receive

Save as example.mjs and run with node example.mjs. CommonJS can instead use require('@cloudtoid/interprocess').

import { Publisher, Subscriber } from '@cloudtoid/interprocess';

const subscriber = new Subscriber('example', 65536);
const publisher = new Publisher('example', 65536);
try {
  if (!publisher.trySend(Buffer.from('hello'))) {
    throw new Error('Queue is full or recovering');
  }
  const message = await subscriber.receive({
    signal: AbortSignal.timeout(1000)
  });
  console.log(message.toString('utf8'));
} finally {
  publisher.close();
  subscriber.close();
}

Publisher

new Publisher(name: string, capacity: number, path?: string)

Creates or joins a queue. The optional Unix directory defaults to the OS temporary directory and is ignored on Windows. All participants must use matching identity and capacity.

trySend(data: Uint8Array): boolean

Accepts Uint8Array, including Buffer. Returns true after committing the message, or false when full or recovering. Other failures throw.

trySendBatch(messages: Uint8Array[]): number

Returns the committed prefix length. A short count can mean full capacity, recovery, or a mid-batch error. Retry the unsent suffix to surface a persistent error. An error before any commit throws immediately. The batch is not atomic.

close(): void / [Symbol.dispose](): void

Releases the publisher. Repeated close is safe; operations after close throw ERR_CLOSED.

Subscriber

new Subscriber(name: string, capacity: number, path?: string)

Opens a competing subscriber with the same configuration rules as Publisher.

tryReceive(): Buffer | null

Consumes a ready message and returns an owned Buffer. null means no message is ready. An empty Buffer is a real message.

receive(options?: { signal?: AbortSignal }): Promise<Buffer>

Checks immediately, then waits until a message arrives, the signal aborts, the endpoint closes, or an error occurs. Cancellation rejects with signal.reason. Use AbortSignal.timeout(milliseconds) for a deadline.

close(): void / [Symbol.dispose](): void

Releases the endpoint. Pending receives reject when they next observe closure. Repeated close is safe.

Errors

Queue failures expose an error.code: ERR_INVALID_ARGUMENT, ERR_CAPACITY_MISMATCH, ERR_PUBLISHER_LIMIT, ERR_EXHAUSTED, ERR_CORRUPT, ERR_IO, or ERR_CLOSED. Binding-level type errors can also occur for invalid JavaScript arguments.

ERR_NATIVE_UNAVAILABLE means the native addon could not load. Check the platform package, optional dependencies, and Linux glibc requirement, or build from source. Cancellation uses the signal's reason rather than a queue error code.

Scheduling and cleanup

Idle receives use timer backoff of 1, 2, 4, 8, then 10 ms, without occupying libuv workers. A new receive starts with an immediate check. Scheduling can delay timers and cancellation beyond those intervals. Prefer one receive loop per subscriber instead of many pending receives.

Always close both endpoints in a finally block or use explicit resource management where your runtime supports it. No public receive-into API is exposed by this binding. See transient queue lifetime before splitting publishers and subscribers into separate processes.