@rimbu/common
v2.0.5
Published
Common types and objects used in many other Rimbu packages
Maintainers
Readme
@rimbu/common
Shared utility types and helpers for the Rimbu ecosystem.
@rimbu/common provides the low-level building blocks used throughout Rimbu:
- Equality & comparison helpers (
Eq,Comp) for consistent value semantics. - Range & index utilities (
Range,IndexRange) for working with slices and windows. - Lazy values & updates (
OptLazy,OptLazyOr,AsyncOptLazy,Update) for ergonomic APIs. - Traversal helpers (
CollectFun,TraverseState) for efficient collection operations. - Type-level utilities (
SuperOf,SubOf,RelatedTo,ArrayNonEmpty,StringNonEmpty,ToJSON) for stronger TypeScript modelling.
Use this package directly in your own code, or consume it indirectly when using other Rimbu packages.
Table of Contents
- Why
@rimbu/common? - Feature Highlights
- Quick Start
- Core Concepts & Types
- Working with Equality & Comparison
- Lazy Values, Updates & Async
- Ranges & Indices
- Type Utilities
- Installation
- Ecosystem & Links
- Contributing
- License
Why @rimbu/common?
Many Rimbu collections (and your own APIs) need consistent behaviour for:
- Comparing values (e.g. custom sort orders, structural vs reference equality).
- Handling optional or deferred values (lazy evaluation, async computations).
- Working with index or value ranges in a uniform way.
- Expressing richer type relationships in TypeScript.
Instead of re‑implementing these patterns, @rimbu/common provides:
- Well-tested primitives shared across all Rimbu packages.
- Reusable utilities you can depend on directly in your own libraries and apps.
- Type-safe building blocks that integrate smoothly with the rest of the Rimbu ecosystem.
Feature Highlights
- Pluggable equality & comparison –
EqandCompinstances for primitives, objects, iterables, JSON, case-insensitive strings, and more. - Lazy & async helpers –
OptLazy,OptLazyOr,AsyncOptLazy,MaybePromiseto keep APIs flexible without sacrificing clarity. - Declarative ranges –
Range<T>andIndexRangeto describe open/closed and offset-based ranges in a single, typed shape. - Traversal utilities –
CollectFunandTraverseStatefor customizable, short‑circuitable traversals. - Type-level helpers – utilities like
ArrayNonEmpty,StringNonEmpty, andToJSONto express invariants and serializable shapes.
Quick Start
import { Eq, Comp, OptLazy, Update } from '@rimbu/common';
// Equality: deep structural comparison
const eq = Eq.anyDeepEq<Record<string, unknown>>();
console.log(eq({ a: 1, b: 2 }, { b: 2, a: 1 }));
// => true
// Comparison: natural number ordering
const numComp = Comp.numberComp();
console.log(numComp.compare(3, 5) < 0);
// => true
// Lazy values: compute only when needed
const lazyValue = OptLazy(() => 1 + 2);
console.log(lazyValue); // 3
// Updates: accept either a value or an updater function
const next = Update(1, (v) => v + 1);
console.log(next); // 2Try Rimbu (including @rimbu/common) live in the browser using the
Rimbu Sandbox on CodeSandbox.
Core Concepts & Types
Exported Types & Utilities
| Name | Description |
| ------------------ | -------------------------------------------------------------------------------------------------- |
| CollectFun | Types used by collect-style functions to map/filter in a single pass with skip & halt support. |
| AsyncCollectFun | Asynchronous version of CollectFun, returning MaybePromise of a collected value or skip token. |
| Comp | Interface and implementations for comparing values (ordering / sorting). |
| Eq | Interface and implementations for checking value equality. |
| Err, ErrBase | Helpers to throw consistent custom errors from fallback handlers. |
| IndexRange | Range specification for numeric indices (e.g. slicing arrays or collections). |
| Range<T> | Range specification for ordered values of type T. |
| OptLazy | A value or a function returning a value (lazy). |
| OptLazyOr | Like OptLazy, but can return a provided default value instead. |
| AsyncOptLazy | Potentially lazy and/or async values built on OptLazy + MaybePromise. |
| MaybePromise<T> | A value of type T or a Promise<T>. |
| TraverseState | Object to track progress & early termination in traversals. |
| Update | Value or updater function used to derive a new value from the old one. |
| SuperOf, SubOf | Type utilities for expressing upper/lower bounds between types. |
| RelatedTo | Type utility accepting related types where one extends the other. |
| ArrayNonEmpty | Tuple type representing non-empty arrays. |
| StringNonEmpty | Type representing non-empty string types. |
| ToJSON | Helper interface for JSON-serializable wrapper objects. |
See the full Common API reference for all members and overloads.
Working with Equality & Comparison
Equality with Eq
import { Eq } from '@rimbu/common';
// Deep structural equality
const deepEq = Eq.anyDeepEq<Record<string, unknown>>();
console.log(deepEq({ a: 1, b: 2 }, { b: 2, a: 1 }));
// => true
// Shallow equality: one level into objects / iterables
const shallowEq = Eq.anyShallowEq<Record<string, unknown>>();
console.log(shallowEq({ a: 1, b: 2 }, { b: 2, a: 1 }));
// => true
// Flat equality: composed values compared using Object.is
const flatEq = Eq.anyFlatEq<Record<string, unknown>>();
console.log(flatEq({ a: 1, b: 2 }, { b: 2, a: 1 }));
// => false
// Case-insensitive string equality
const ci = Eq.stringCaseInsentitiveEq();
console.log(ci('AbC', 'aBc'));
// => trueComparison with Comp
import { Comp } from '@rimbu/common';
// Numbers: natural ordering with special handling for NaN and infinities
const numberComp = Comp.numberComp();
numberComp.compare(3, 5); // < 0
// Strings: locale-aware comparison
const stringComp = Comp.stringComp('en');
stringComp.compare('a', 'b'); // < 0
// Deep comparison of arbitrary values
const anyDeepComp = Comp.anyDeepComp<unknown>();
anyDeepComp.compare({ a: 1 }, { a: 1 }); // 0
// Convert a comparison into an equality function
const objectEq = Comp.toEq(Comp.objectComp());
console.log(objectEq({ a: 1, b: 2 }, { b: 2, a: 1 }));
// => trueLazy Values, Updates & Async
OptLazy and OptLazyOr
import { OptLazy, OptLazyOr } from '@rimbu/common';
// Eager or lazy values
OptLazy(1); // => 1
OptLazy(() => 1); // => 1
// With a default "other" value
OptLazyOr(1, 'a'); // => 1
OptLazyOr(() => 1, 'a'); // => 1
OptLazyOr((none) => none, 'a'); // => 'a'Update
import { Update } from '@rimbu/common';
Update(1, 2); // => 2
Update(1, () => 10); // => 10
Update(1, (v) => v + 1); // => 2AsyncOptLazy and MaybePromise
import { AsyncOptLazy } from '@rimbu/common';
// Get a value or promised value
await AsyncOptLazy.toPromise(1); // Promise(1)
await AsyncOptLazy.toPromise(() => 1); // Promise(1)
await AsyncOptLazy.toPromise(async () => 1); // Promise(1)
await AsyncOptLazy.toPromise(Promise.resolve(1)); // Promise(1)Ranges & Indices
Range<T>
import { Range } from '@rimbu/common';
// Inclusive start, exclusive end
const r1: Range<number> = { start: [0, true], end: [10, false] };
// Only end (inclusive by default)
const r2: Range<number> = { end: 5 };
// Normalize for easier handling
const normalized = Range.getNormalizedRange(r1);
// => { start: [0, true], end: [10, false] }IndexRange
import { IndexRange } from '@rimbu/common';
const ir: IndexRange = { start: [0, true], amount: 3 };
// Extract concrete indices for a given length
IndexRange.getIndicesFor(ir, 10); // [0, 2]Type Utilities
import type {
SuperOf,
SubOf,
RelatedTo,
ArrayNonEmpty,
StringNonEmpty,
ToJSON,
} from '@rimbu/common';
type A = SuperOf<string, 'a' | 'b'>; // string
type B = SubOf<'a' | 'b', string>; // 'a' | 'b'
type R = RelatedTo<'a', string>; // 'a' | string
type NonEmptyNumbers = ArrayNonEmpty<number>; // [number, ...number[]]
type NonEmptyString = StringNonEmpty<'a' | ''>; // 'a'
interface UserJSON extends ToJSON<{ id: number }, 'User'> {}Installation
Node / Bun / npm / Yarn
npm install @rimbu/common
# or
yarn add @rimbu/common
# or
bun add @rimbu/common
# or
deno add npm:@rimbu/commonThen:
import { Eq } from '@rimbu/common/mod.ts';Browser / ESM
@rimbu/common ships both ESM and CJS builds. Use it with any modern bundler
(Vite, Webpack, esbuild, Bun, etc.) or directly in Node ESM projects.
Ecosystem & Links
- Part of the broader Rimbu collection ecosystem – interoperates with
@rimbu/collection-types,@rimbu/hashed,@rimbu/ordered,@rimbu/stream, and more. - Main documentation: rimbu.org
- Package docs: Common docs
- API reference: Common API
Contributing
We welcome contributions! See the Contributing guide for details.
Made with contributors-img.
License
MIT © Rimbu contributors. See LICENSE for details.
Attributions
Created and maintained by Arvid Nicolaas. Logo © Rimbu.
