shelving/apimodule
Typed, provider-based framework for HTTP API access. Define your routes as Endpoint definitions, then call them through a composable provider stack — the same pattern the shelving/db module uses for databases.
Shelving is a TypeScript toolkit for working with typed data. At its core it is a schema validation library — every schema has a Schema.validate() method that returns a typed value or throws a human-readable error. On top of that it provides a database provider abstraction, an API provider abstraction, observable state stores, React integration, and a large set of typed utility functions.
Note: Shelving is in active development and does not yet follow semver.
npm install shelvingShelving is an ES module. Import from the main package or from individual module subpaths:
import { STRING, DataSchema } from "shelving"
import { MemoryDBProvider } from "shelving/db"See Releases on GitHub.
Typed, provider-based framework for HTTP API access. Define your routes as Endpoint definitions, then call them through a composable provider stack — the same pattern the shelving/db module uses for databases.
DBProvider implementation for PostgreSQL using Bun's built-in Bun.sql API. No external database driver is required.
DBProvider implementations for Cloudflare Workers. Two backends are available: Workers KV for simple key-value storage and D1 for relational SQL.
Typed database provider abstraction. Define your schema once as a Collection, then swap providers (in-memory, SQLite, Firestore, Cloudflare D1, …) without changing any call sites. Providers are composable wrappers — add validation, logging, or caching by stacking them in a chain.
Typed error classes for system and transport failures.
Turn a folder of source files into a navigable tree of documentation. extract is the engine behind the Shelving documentation site itself.
FirestoreClientProvider for the full Firebase JS SDK (firebase/firestore). Use this in browser apps or any environment where you need offline persistence or realtime subscriptions.
FirestoreLiteProvider for the Firebase Lite SDK (firebase/firestore/lite). Use this when you want Firestore in the browser or on the server but do not need realtime subscriptions and prefer a smaller bundle.
FirestoreServerProvider for the Firebase Admin SDK (@google-cloud/firestore). Use this in Node.js backends, Cloud Functions, or any server environment that authenticates via a service account or Application Default Credentials.
A rule-based Markdown renderer that turns user-facing text into React nodes.
React hooks and context helpers for integrating Shelving shelving/store, async sequences, and API/DB providers into React components. The module is built on useSyncExternalStore and standard React patterns — no magic, no global state.
Schema validation for TypeScript. A Schema<T> describes how to coerce and validate an unknown value into a typed T. Schemas are the foundation of shelving — database collections, API endpoints, and form handlers all build on them.
Async-iterator primitives used throughout the shelving library. A "sequence" is an AsyncIterable<T> — something you can consume with for await...of. This module provides the building blocks for producing and connecting sequences, most importantly DeferredSequence, which lets external code drive an async iterator by resolving or rejecting it on demand.
Observable value containers for reactive state. A Store<T> holds a single current value, broadcasts changes to all active consumers, and integrates with React Suspense out of the box. Stores suppress duplicate emissions using deep equality, so consumers only see genuine changes.
Shared test fixtures and assertion helpers for Shelving's own unit tests.
A React component library for building Shelving apps — forms, content, layout, routing, dialogs, and the documentation-site components, all in one place.
Small utilities for generating random numbers, characters, and short human-readable keys. Useful for placeholder IDs, test data, and UI token generation.
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.
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.
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.
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.
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.
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.
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.
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.
A quicksort implementation and type-aware comparators that handle mixed-type values gracefully. Used internally by shelving/util/query when applying $order to items.
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.
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.
Advanced TypeScript utility types used internally across Shelving. Import these when you need to manipulate generic type algebra in your own code.
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.
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.
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.
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.
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.
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.
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.
Core helpers for checking, converting, sanitising, and transforming strings. Used throughout Shelving wherever user input is cleaned or URLs are generated.
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.
These types and helpers describe a tree of elements — a hierarchical structure built on top of shelving/util/element, used to represent a documentation site's content hierarchy. The shelving/extract module builds trees of TreeElement nodes from source files; the shelving/ui component renders them.
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.
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.
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.
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.
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.
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.
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.
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 shelving/db uses for all collection reads.
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.
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.
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.
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.
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.
These types and helpers describe a React-compatible element structure (type, props, key) and the generic tools for walking, filtering, and flattening collections of them. The tree-shaped layer built on top of Element — TreeElement, path resolution, and tree flattening — lives in a sibling file; see shelving/util/tree.
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.
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.
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.
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.
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.
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.
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.
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.
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 /.
Helpers for working with promises and async values: detecting sync/async values, running concurrent promises safely, creating deferreds, and handling cancellation with AbortSignal.
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, 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.
Typed helpers for working with JavaScript Set objects. Covers type guards, conversion, membership checks, and mutable add/delete operations.
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.
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.
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.
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.
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.
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.
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 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.
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.
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.
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.
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 shelving/db layer when writing documents.
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.
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.