npm.io
3.1.13 • Published 14h ago

@radically-straightforward/node

Licence
MIT
Version
3.1.13
Deps
1
Size
43 kB
Vulns
0
Weekly
0
Stars
61

Radically Straightforward · Node

Utilities for Node.js

Installation

$ npm install @radically-straightforward/node

Usage

import * as node from "@radically-straightforward/node";
Graceful Termination

Importing @radically-straightforward/node enables graceful termination, which gives your application the opportunity to clean up resources before exiting.

Graceful termination works by listening to the following signals:

  • SIGINT: Emitted by pressing ⌃C on the terminal.
  • SIGQUIT: Emitted by pressing ⌃\ on the terminal.
  • SIGBREAK: Emitted by pressing Ctrl+Break on the terminal on Windows.
  • SIGHUP: Emitted when the terminal is closed while the application is still running.
  • SIGTERM: Emitted by process managers that wish to terminate the application, for example, systemd, kill, and so forth.
  • SIGUSR2: Emitted by nodemon to indicate that the application should restart.

Note: Some signals, for example, SIGKILL, which may be sent by kill -9, cannot be handled and cause the process to terminate immediately without the opportunity to clean up resources.

When one of these signals is received, the process.once("gracefulTermination") event is emitted, and your application should handle it to close HTTP servers, clear timers, and so forth. The goal is to leave the Node.js event loop empty so that the process may terminate naturally.

Note: The "gracefulTermination" event is emitted only once.

As one last step before termination, you may handle Node.js’s process.once("beforeExit") event, which is emitted after the Node.js event loop is empty, but before the application terminates. This is useful, for example, to close a database connection, to log that the application terminated gracefully, and so forth.

Note: You may wish to close a database connection on "beforeExit" instead of "gracefulTermination" because during "gracefulTermination" an HTTP server may still need the database connection while it’s responding to the last undergoing requests before closing.

Note: According to Node.js’s documentation you may use "beforeExit" to add more work to the event loop and prevent the process from terminating, but we advise against using it that way.

Note: Use the "beforeExit" event instead of the "exit" event for the following reasons:

  1. The "exit" event handler runs in a constrained environment that only allows for synchronous operations, but your cleanup may need to be asynchronous.
  2. The "exit" event is emitted even when the process is terminating in abnormal conditions, for example, because of an uncaught exception, and under these abnormal conditions graceful termination isn’t appropriate.

After the "gracefulTermination" event is emitted, if the application doesn’t terminate in 10 seconds, then it’s terminated forcefully with process.exit(1).

exit()
export function exit(): void;

exit() emits the "gracefulTermination" event. Upon this event, the application must finish operations that are in progress (for example, finish answering to HTTP requests) and empty the event loop by closing HTTP servers, clearing timeouts, and so forth. If the application is still running 10 seconds after exit() is called, then it’s terminated forcefully with process.exit(1).

setInterval()
export function setInterval(
  utilitiesSetIntervalOptions: Parameters<typeof utilities.setInterval>[0],
  function_: Parameters<typeof utilities.setInterval>[1],
): ReturnType<typeof utilities.setInterval>;

This is an extension of @radically-straightforward/utilities’s setInterval() which adds support for graceful termination.

Example

import timers from "node:timers/promises";
import * as node from "@radically-straightforward/node";

node.setInterval({ duration: 3 * 1000 }, async () => {
  console.log("setInterval(): Running ‘function_’...");
  await timers.setTimeout(3 * 1000);
  console.log("setInterval(): ...finished running ‘function_’.");
});
childProcessKeepAlive()
export function childProcessKeepAlive(
  newChildProcess: () =>
    | ReturnType<(typeof childProcess)["spawn"]>
    | Promise<ReturnType<(typeof childProcess)["spawn"]>>,
): void;

Keep a child process alive. If the child process crashes, respawn it. When the process gracefully terminates, gracefully terminate the child process as well.

Example

node.childProcessKeepAlive(() =>
  childProcess.spawn("node", ["--eval", `http.createServer().listen(18000)`], {
    stdio: "inherit",
  }),
);
SymmetricEncryption
export class SymmetricEncryption;

Utilities for cryptography that make it secure and easy to use.

SymmetricEncryption.generateKey()
static async generateKey(): Promise<crypto.KeyObject>;
SymmetricEncryption.exportKey()
static exportKey(key: crypto.KeyObject): string;
SymmetricEncryption.importKey()
static importKey(keyString: string): crypto.KeyObject;
SymmetricEncryption.encrypt()
static encrypt(key: crypto.KeyObject, plainText: string): string;
SymmetricEncryption.decrypt()
static decrypt(key: crypto.KeyObject, encryptedText: string): string;
AsymmetricEncryption
export class AsymmetricEncryption;
AsymmetricEncryption.generateKeyPair()
static async generateKeyPair(): Promise<{
    privateKey: string;
    publicKey: string;
  }>;
TokenHash
export class TokenHash;
TokenHash.hash()
static hash(token: string): string;
TokenHash.verify()
static verify(hash: string, token: string): boolean;
PasswordHash
export class PasswordHash;
PasswordHash.hash()
static async hash(password: string): Promise<string>;
PasswordHash.verify()
static async verify(
    hashedPassword: string,
    password: string,
  ): Promise<boolean>;

Keywords