Skip to content
GitHub Actions edited this page Sep 22, 2026 · 9 revisions

Utils

Core cross-runtime TypeScript building blocks — a typed Options + Events base class, BaseError, Singleton, and helpers for config/env, memoize, throttle, IP/subnet, and free-port lookup.

JSR JSR Score Deno Bun Node.js Cloudflare Workers Browsers

Overview

utils is the dependency-free foundation the rest of TundraLibs builds on: BaseError is the root of every package's error hierarchy, Options/Events is the base class most config-bearing classes extend, and Singleton backs classes that must have exactly one instance. Around that core sit small, independent helpers — decorators (Once/Memoize/Throttle), config/env loading, IP/subnet checks, syslog parsing, string templating — that have no dependency on each other or on the core classes; reach for only the ones you need.

Once, Memoize, and Throttle are TC39 standard decorators (no experimentalDecorators). Memoize and Throttle work on both methods and getters; Once is method-only — decorating a getter with @Once is a compile-time type error, not a supported (if degraded) case. Singleton is also available as its own subpath import (@tundralibs/utils/Singleton) for consumers who only need it.

See examples/connection-pool/ for a small runnable app that composes Options, Events, BaseError, and Singleton — the four core pieces — into one class.

Most of the surface — BaseError, Options/Events, Singleton, Once/Memoize/Throttle, variableReplacer, IP/subnet helpers — is pure and runs unchanged on Workers and in the browser; importing the barrel never throws there. Two exceptions need a real OS to mean anything: getFreePort() binds a real socket to probe availability, and Config/loadConfig() reads real files from disk — neither concept exists in a Worker or a browser, so don't reach for them there. Every module has its own subpath — @tundralibs/utils/syslog, @tundralibs/utils/envArgs, @tundralibs/utils/BaseError, one per file — so the barrel is a convenience, never the only way in. Prefer a subpath when bundle size matters: the barrel is one module graph, so importing it for a single symbol pulls the whole package in. Measured with deno info, @tundralibs/utils/syslog is a 2-module graph where the barrel is 158.

Installation

Deno:

deno add @tundralibs/utils

Bun:

bunx jsr add @tundralibs/utils

Node.js:

npx jsr add @tundralibs/utils

Utilities

Utility Description Documentation
BaseError Enhanced error class with context, chaining, and code snippets Docs
Config Multi-format configuration loader with environment variable support Docs
envArgs Environment variable and .env file loader with Docker secrets support Docs
Events Type-safe event system with async support Docs
getFreePort Find available TCP ports with configurable range and exclusions Docs
ipUtils IPv4/IPv6 validation, conversion, and range checking utilities Docs
isInSubnet Check if IP address is within a CIDR subnet range Docs
isPublicIP Detect if IP address is publicly routable Docs
isSubnet Validate CIDR subnet notation format Docs
memoize Function and method memoization with TTL and async support Docs
once Function execution control for single-call enforcement Docs
Options Abstract base class for options and event handling Docs
privateObject Private data encapsulation utility Docs
Singleton Singleton pattern decorator Docs
syslog RFC 3164 and RFC 5424 syslog parser and generator Docs
templatize Type-safe template string parser Docs
throttle Function throttling for rate-limiting execution Docs
Types Advanced TypeScript utility types for type manipulation Docs
variableReplacer Template placeholder replacement with dot notation support Docs

Quick Examples

Network Utilities

import { getFreePort, isInSubnet, isPublicIP } from '@tundralibs/utils';

// Find available port for dev server
const port = await getFreePort({ min: 3000, max: 4000 });

// Check if IP is in subnet
if (isInSubnet('192.168.1.10', '192.168.0.0/16')) {
  console.log('IP is in private network');
}

// Detect public vs private IP
if (isPublicIP('8.8.8.8')) {
  console.log('Public IP detected');
}

Configuration Management

import { loadConfig } from '@tundralibs/utils';

const config = await loadConfig({ path: './config' });
const dbHost = config.get<string>('database.host');

Error Handling

import { BaseError } from '@tundralibs/utils';

class ValidationError extends BaseError<{ field: string }> {
  // Enhanced error with context
}

throw new ValidationError('Invalid ${field}', { field: 'email' });

Performance Optimization

import { memoize, throttle } from '@tundralibs/utils';

const factorial = (n: number): number => (n <= 1 ? 1 : n * factorial(n - 1));
const updateUI = () => console.log('viewport changed');

const expensiveCalc = memoize((n: number) => factorial(n), 5000);
const handleScroll = throttle(() => updateUI(), 100);

Design Patterns

import { once, Singleton } from '@tundralibs/utils';

@Singleton
class DatabaseConnection {
  // Ensures single instance
}

const initialize = once(() => {
  // Runs only once
});

License

MIT © TundraLibs

Clone this wiki locally