Null and nullish helpers
Type guards, assertions, and utility types for null and nullish (null | undefined) values. Use these instead of inline === null checks to get proper TypeScript type narrowing and consistent error messages.
Low-level utility functions, types, and constants used throughout shelving — the foundation the higher-level modules are built on.
Unlike the other modules there is no single integration story here: each file is an independent, self-contained set of helpers for one topic — arrays, objects, strings, numbers, dates, equality, data objects, items, queries, updates, and much more. See each file's own page for its helpers and usage examples.
Type guards, assertions, and utility types for null and nullish (null | undefined) values. Use these instead of inline === null checks to get proper TypeScript type narrowing and consistent error messages.
Type guards for ArrayBuffer, ArrayBufferView, and typed arrays. Use these when a function receives an unknown binary value and needs to distinguish between a raw buffer and its various view types.
Typed helpers for reading, validating, and immutably transforming arrays. All immutable operations return the original reference when nothing changed, which keeps React state and memoisation stable.
A collection of helpers for converting typed values into user-readable strings. All formatters respect the browser's locale by default and accept an optional locale override — they delegate to the Intl APIs where possible so internationalisation and translation are handled automatically.
Type definitions and helper functions for working with Map instances. Covers type guards, conversions from plain objects or iterables, mutable set/remove operations, and safe key lookups.
These types and helpers describe a tree of elements — a React-compatible structure used to represent a documentation site's content hierarchy. The extract module builds trees of TreeElement nodes from source files; the ui/tree component renders them.
A Query<T> is a plain object that describes filters, ordering, and a result limit for a set of data items. These helpers parse, apply, and paginate queries — the same Query type that db uses for all collection reads.
Small set of guards and assertions for undefined. Useful in filter pipelines and for writing intent-revealing code where a plain === undefined check would be less clear.
Validate ISO 4217 currency codes and retrieve display metadata (symbol, smallest unit step) using the runtime's built-in Intl API. The list of supported codes comes from Intl.supportedValuesOf("currency") so it stays current without a bundled lookup table.
Typed helpers for working with { [key: string]: T } objects — called dictionaries to distinguish them from the more permissive Data type. Mirrors the naming conventions of the array and object helpers: with* for immutable updates, set*/delete* for mutable by-reference mutations.
Timeout is a thin wrapper around setTimeout that tracks its own reference and cancels any in-flight timer before setting a new one. It removes the boilerplate of saving and clearing timeout handles manually.
Parse, validate, format, and manipulate dates. The central idea is PossibleDate — a value that could be a date — which the helpers accept everywhere so you rarely need to call new Date() yourself.
Core immutable helpers for reading and updating plain objects, plus utility types for mutable/readonly/partial transformations. These are the building blocks for safe state management — every mutating helper returns the original reference when nothing changed.
An entity is a compact "type:id" string that encodes both the kind of resource and its identifier in one value, e.g. "challenge:a1b2c3". These helpers parse and validate those strings so callers never need to split on : themselves.
Secure password hashing and verification using PBKDF2-SHA-512, plus a helper for generating cryptographically random bytes. Uses the Web Crypto API so it works in browsers, Node.js, and edge runtimes without additional dependencies.
A Color class and accompanying helpers for parsing, representing, and converting CSS hex colours. Useful for theming, accessibility checks, and anywhere a component or tool needs to inspect or manipulate a colour value.
Lightweight generic filter utilities for synchronous iterables, arrays, and async sequences. They exist to avoid having to repeat the for…of / if match / yield pattern everywhere a match function is used as a predicate.
Three small helpers for generating and validating UUIDs. They exist to provide a normalised, dash-free UUID format and a safe way to parse untrusted input strings.
Typed utilities for building and parsing Request and Response objects using the standard Fetch API. The helpers handle content-type negotiation, body serialisation, and error-to-response conversion so you don't have to repeat that logic in every endpoint or client.
Lightweight, deterministic string-to-number hashing. Useful for consistently mapping a string to a bucket — for example picking a stable colour, avatar, or index for a user or entity name without storing anything.
Serialise and deserialise class instances across a network boundary. dehydrate converts a value containing class instances into a plain JSON-safe structure; hydrate reconstructs the original instances on the other side using a shared Hydrations map.
A tiny utility for values that may be supplied either as a plain value or as a factory function. Use Lazy<T> as a parameter type wherever you want callers to be able to defer construction, then call getLazy() to materialise the value.
These helpers define the Validator<T> interface and utility functions for applying validators to single values, arrays, dictionaries, and full data objects. They exist to give all Shelving validators a common contract and to collect field-level errors before throwing — rather than stopping at the first failure.
The Item type and its helpers. An Item is a Data object — a plain JSON-safe record — that also carries an id of type string | number. Every database collection in Shelving operates on items, so this is the fundamental unit of persisted data.
Named constants for common numeric magnitudes, time durations, whitespace characters, and control symbols. Import these instead of magic numbers to keep code readable and consistent.
Tiny helpers for splitting filenames into base name and extension. They exist so callers never need to hand-roll lastIndexOf(".") logic or handle the dotfile edge case themselves.
Browser utility for locating the first focusable element inside a DOM subtree. Useful when you need to programmatically move keyboard focus into a dialog, panel, or other container after it becomes visible.
Immutably merge two values — objects, arrays, or primitives. All merge functions return the left reference unchanged when nothing actually changed, making them safe to use in memoised or reactive contexts.
The Data type and its helpers are the foundation of Shelving's data layer. A Data object is a plain Record<string, unknown> — a JSON-safe object with no class prototype. Every database document, query result, and schema-validated value is a Data.
These helpers read process.env safely across Node, edge runtimes, and browser environments, where process may not exist. They follow the standard get* / require* pattern: get* returns undefined on miss, require* throws RequiredError.
Safe, aggregate disposal of resources using the TC39 Symbol.dispose / Symbol.asyncDispose protocol. When multiple disposables are cleaned up together, all of them run even if some throw — errors are collected and re-thrown as a single Errors aggregate.
A quicksort implementation and type-aware comparators that handle mixed-type values gracefully. Used internally by query helpers when applying $order to items.
These helpers measure the distance between two dates — in milliseconds, seconds, minutes, hours, days, weeks, months, or years — and format that distance for display. They exist so callers never have to do raw date arithmetic or wrangle Intl.DurationFormat directly.
These helpers model physical units of measure — mass, length, speed, area, volume, temperature, angles, percentages, and more — and let you convert amounts between units and format them for display. They exist so callers never have to hard-code conversion factors or wrangle Intl.NumberFormat unit options directly.
Constants and a helper for wrapping terminal output in ANSI escape codes. Use these when writing CLI tools or test reporters that need colour and style without pulling in a third-party library.
Helpers for working with promises and async values: detecting sync/async values, running concurrent promises safely, creating deferreds, and handling cancellation with AbortSignal.
Encode and decode data to and from standard Base64 and URL-safe Base64 (Base64URL). Useful for binary payloads, JWTs, cryptographic keys, and any context that needs ASCII-safe binary representation.
Map and transform values across arrays, objects, dictionaries, and async sequences. These are higher-order utilities that apply a function to every element or property of a collection.
Core type definitions and small utilities for working with functions. This file is the source of the AnyCaller type that threads through the whole library to produce accurate stack traces, and provides BLACKHOLE and PASSTHROUGH — two no-op sentinels used throughout as safe default callbacks.
A single serialise() function that converts any JavaScript value to a stable, deterministic string. Designed for fingerprinting and cache-key generation, not for data transport.
Encode, decode, and verify JSON Web Tokens signed with HMAC SHA-512. Also provides convenience helpers for reading and writing Bearer tokens on Request objects.
Manage processes that have a start callback and an optional stop callback. Starter prevents double-starts and wraps errors, making it easy to build safe, disposable lifecycle objects.
Type guards, conversion, and assertion for Uint8Array<ArrayBuffer> byte sequences. Used throughout the library wherever raw binary data is accepted — cryptographic operations, Base64 encoding, and binary I/O.
Strict and structural equality predicates used throughout the library. The three tiers — exact, shallow, and deep — map to the same left is T type-guard pattern so they can be used interchangeably anywhere a Match function is expected.
Match placeholders out of a string, or render values into one. Useful when a full regular expression is overkill and you just want to extract named segments from a path or pattern.
Country codes, names, and address formatting. Provides the COUNTRIES lookup (ISO 3166-1 alpha-2), typed Country and AddressData types, and helpers for parsing and displaying country information.
Low-level helpers for working with error messages as plain strings. They exist to give call-site code a uniform way to extract, split, join, and annotate messages without caring whether the source is an Error object, a plain string, or any other value.
Two small helpers for producing XML strings from data objects. They exist for cases where you need to serialise a plain data structure to XML without pulling in a full XML library.
An entry is a readonly [key, value] pair — the shape produced by Map.entries(), Object.entries(), and Array.entries(). These helpers provide a uniform way to iterate, extract, and type entries across all of those sources.
Resolve any link-shaped value — a site path, relative reference, or full URI — into an absolute URI string. Useful when building components or routing logic that must handle all three forms uniformly.
Two helpers for traversing a chain of Sourceable objects — objects with a .source property — and returning the first instance of a given class. Used to unwrap layered or decorated objects back to their underlying implementation.
Type guards and assertion functions for boolean values. These follow the standard is* / assert* naming convention and pair naturally with schema validation and runtime checks.
Updates<T> is the mutation language for Shelving data objects. An updates object uses encoded key prefixes to describe how each field should change — set, increment, or add/remove array items — and updateData() applies those changes immutably. This is the format consumed by the db layer when writing documents.
General-purpose utilities for working with any Iterable<T> — arrays, sets, generators, and custom iterables alike. These complement the array-specific helpers by operating lazily on any sequence without forcing materialisation.
Type utilities and runtime helpers for working with class constructors and instances. Useful when you need to check whether a value is a constructor, whether an object is an instance of a particular class, or when you need to inspect property descriptors.
Convert any JavaScript value to a readable debug string. Use these when building error messages, logging, or printing diagnostic output — they produce compact, human-readable representations without relying on JSON.stringify (which omits undefined, symbols, functions, and circular refs).
Advanced TypeScript utility types used internally across Shelving. Import these when you need to manipulate generic type algebra in your own code.
Core helpers for checking, converting, sanitising, and transforming strings. Used throughout Shelving wherever user input is cleaned or URLs are generated.
Compute the minimal transformation needed to turn one value into another. Used internally by the update and sync layers to avoid sending unchanged data. Returns the special SAME symbol when the two values are deeply equal.
Helpers for working with AsyncIterable sequences — repeating, driving, merging, and side-effecting streams of values. Used internally for real-time database subscriptions and polling loops.
These helpers work specifically with hierarchical scheme://host URLs (a strict subset of URIs), and add path-matching, base-URL resolution, and active/proud link detection. They exist to handle the common navigation and routing tasks that plain URI helpers do not cover.
Three thin wrappers around console.log/console.error that format HTTP Request and Response objects with ANSI arrow decorators. Intended for server-side request logging in development and production.
Typed helpers for working with filesystem and URL paths. Used throughout the router to represent and manipulate AbsolutePath values — strings that always start with /.
Typed wrappers and combinators for working with regular expressions. They let you test, escape, compose, and extract matches with cleaner types than the raw RegExp API.
Typed helpers for working with JavaScript Set objects. Covers type guards, conversion, membership checks, and mutable add/delete operations.
Small utilities for generating random numbers, characters, and short human-readable keys. Useful for placeholder IDs, test data, and UI token generation.
These helpers work with any valid URI — including non-hierarchical ones like urn:isbn:... or mailto: — and provide typed wrappers, query-param manipulation, and safe conversion utilities. They exist because the built-in URL class has loose typing and is mutable, which can cause subtle bugs.
Type guards, conversions, rounding, clamping, and arithmetic utilities for numbers. The conversion functions (getNumber, getInteger) accept strings and Date instances as well as raw numbers, and always return a finite value or undefined — never NaN or Infinity.