node-comfortv2.0.0

nc.utils

Everyday helpers: wait, when, dontCrash, and JSON functions that don't throw. They are also available at the top level (nc.wait()).

const { utils } = require("@ix-xs/node-comfort");
import { wait } from "@ix-xs/node-comfort/utils";

These functions are also available at the top level: nc.wait() is nc.utils.wait().

await nc.wait("1.5s");
const settings = nc.JSONParse(text, {});
GuideExplanations and examples for nc.utils.
Read the guide →

Functions

nc.utils.wait()

wait(duration: string | number, options?: WaitOptions): Promise<void>

Resolves after a delay, given in milliseconds or as a duration string.

Parameters

NameTypeDescription
durationnumber | stringMilliseconds, or a string like "250ms", "2s", "1m30s".
optionsoptionalWaitOptions

Returns Promise<void>

Throws AbortError If the signal is aborted.; TypeError If the duration can't be parsed.

Example

await nc.wait(500);
await nc.wait("2s");
await nc.wait("1m", { signal: controller.signal });

nc.utils.when()

when(predicate: boolean | PromiseLike<boolean> | (() => unknown), payload?: any, options?: WhenOptions): WhenTask

Checks a condition at a regular interval and tells you when it's true. Call .start() once your listeners are in place. If you just want to await a condition, nc.async.poll() is simpler.

Parameters

NameTypeDescription
predicateboolean | PromiseLike<boolean> | (() => unknown)The condition, or a function (sync or async) that returns it.
payloadoptionalanyPassed to the "trigger" and "timeout" listeners.Default: {}
optionsoptionalWhenOptions

Returns WhenTask

Example

nc.when(() => queue.length > 0, { reason: "jobs waiting" }, { interval: 500, max: 1, timeout: 10_000 })
  .on("trigger", (payload) => nc.info(payload.reason))
  .on("timeout", () => nc.warn("Nothing happened in 10s"))
  .start();

nc.utils.dontCrash()

dontCrash(): DontCrashController

Keeps the process alive when something goes wrong. Uncaught exceptions and unhandled rejections are logged instead of crashing, and SIGINT/SIGTERM are logged before a clean exit. Customize any of it with .on().

Only its own handlers are ever removed; listeners added by your code or by other libraries are left alone.

Returns DontCrashController

Example

nc.dontCrash()
  .on("error", (error) => sentry.captureException(error))
  .on("sig", async () => {
    await server.close();
    process.exit(0);
  });

nc.utils.JSONString()

JSONString(value: unknown, spaces?: number): string

JSON.stringify that never throws. Circular references become "[Circular]", bigints become strings, Maps become objects and Sets become arrays.

Parameters

NameTypeDescription
valueunknown
spacesoptionalnumberIndentation. Use 0 for a single line.Default: 4

Returns string: The JSON text, or "undefined" for values JSON can't represent.

Example

nc.JSONString({ a: 1 });                          // '{\n    "a": 1\n}'
nc.JSONString({ id: 10n, tags: new Set(["x"]) }, 0); // '{"id":"10","tags":["x"]}'

nc.utils.JSONParse()

JSONParse<T = any>(text: string, fallback?: T, ...args: any[]): T

JSON.parse with an optional fallback. With a fallback, invalid input returns it instead of throwing.

Parameters

NameTypeDescription
textstring
fallbackoptionalTReturned when text isn't valid JSON.
...argsany[]

Returns T

Throws SyntaxError If text is invalid and there's no fallback.

Example

nc.JSONParse('{"a":1}');    // { a: 1 }
nc.JSONParse("oops", null); // null
nc.JSONParse("oops");       // throws SyntaxError

Types

Import any of them in TypeScript with import type { DontCrashController } from "@ix-xs/node-comfort", or in JavaScript with import("@ix-xs/node-comfort").DontCrashController.

DontCrashController

Returned by dontCrash().

PropertyTypeDescription
on<E extends DontCrashEvent>(event: E, handler?: (E extends "error" ? (error: unknown) => void : E extends "sig" ? (signal: Signals) => void : (code: number) => void) | undefined) => DontCrashControllerReplaces the handler for an event. Call it without a handler to restore the default one.
dispose() => voidRemoves everything dontCrash() installed.

DontCrashEvent

Events you can customize on dontCrash().

type DontCrashEvent = "error" | "exit" | "sig" | "beforeExit"

WaitOptions

Options for wait().

PropertyTypeDescription
signaloptionalAbortSignalCancels the wait; the promise rejects with an AbortError.
unrefoptionalbooleanLet the process exit even if the timer is still pending.

WhenOptions

Options for when().

PropertyTypeDescription
intervaloptionalnumberMilliseconds between two checks. Defaults to 50.
timeoutoptionalnumber | nullGive up after this many milliseconds and emit "timeout".
maxoptionalnumber | nullStop after this many triggers.

WhenTask

The task returned by when(). Every method returns the task, so calls chain.

PropertyTypeDescription
start() => WhenTaskStarts checking. A stopped task can't be restarted.
stop() => WhenTaskStops checking and clears the timers.
on<E extends "trigger" | "error" | "timeout">(event: E, handler: E extends "error" ? (error: unknown) => void : (payload: any) => void) => WhenTaskListens to "trigger" (the condition is true), "error" (it threw) or "timeout".
node-comfort v2.0.0View the source