@rimbu/base
Foundational immutable array and utility primitives powering all other Rimbu collections.
@rimbu/base exposes a small, efficient set of low-level utilities (array operations, tuple helpers, type predicates, error types) used internally across Rimbu’s high-level data structures. While primarily an implementation substrate, you can use these helpers directly for performance‑aware immutable array manipulation and advanced type constraints.
Think: ultra-focused building blocks for persistent & type‑rich collections.
Full documentation: Rimbu Docs · Rimbu API
Table of Contents
- Why Rimbu Base?
- Feature Highlights
- Quick Start
- Immutable Array Operations (
Arr) - Tuple & Token Utilities
- Type Utilities (
plain-object) - Error Types (
RimbuError) - Installation
- FAQ
- Contributing
- License
- Attributions
- Quick Reference
Why Rimbu Base?
High‑level persistent collections depend on fast, predictable low‑level primitives. Instead of rewriting array cloning, sparse copying, index‑safe mutation, and structured error handling in every package, @rimbu/base centralizes these operations:
- Consistency – shared implementations eliminate subtle divergence.
- Performance – leverages modern
Arrayprototype methods (toSpliced,toReversed,with,at) when available; falls back gracefully. - Immutability by default – every operation returns a new array only when changes occur (structural sharing where possible).
- Sparse array awareness – preserves sparsity for specialized internal block layouts.
- Type guards & predicates – compile‑time discrimination for plain objects vs. functions/iterables.
- Focused surface – zero external runtime dependencies (aside from internal Rimbu type modules).
Use it directly if you need ergonomic immutable array helpers without pulling in full collection abstractions.
Feature Highlights
ArrImmutable Ops –append,prepend,concat,reverse,update,mod,insert,splice,tail,init,last,mapSparse,copySparse.- Conditional Optimization – automatically chooses modern O(1) helpers when your runtime supports them.
- Tuple Helpers –
Entry.first,Entry.secondfor lightweight entry handling in map-like structures. - Type Predicates –
IsPlainObj,IsArray,IsAny, plus runtimeisPlainObj,isIterable. - Structured Errors – clear error signaling via custom error classes (e.g.
InvalidStateError). - Sentinel Token – a shared
Tokensymbol for internal identity and tagging. - Tree-shakable – import only what you use:
import { Arr } from '@rimbu/base';.
Quick Start
import { Arr } from '@rimbu/base';
const base = [1, 2, 3];
// Pure modification: only clones when the value actually changes
const incremented = Arr.mod(base, 1, (v) => v + 1); // [1, 3, 3]
// Structural no-op returns original reference for efficiency
const same = Arr.mod(base, 5, (v) => v); // index out of range → original
// Append without mutating
const appended = Arr.append(incremented, 4); // [1, 3, 3, 4]
// Reverse slice
const reversed = Arr.reverse(appended); // [4, 3, 3, 1]
console.log(base); // [1, 2, 3]Immutable Array Operations (Arr)
All functions accept a readonly T[] input and return either the original array (when unchanged) or an optimized clone.
| Function | Purpose |
|---|---|
append |
Add element at end (non-empty array optimization). |
prepend |
Add element at start efficiently. |
concat |
Smart concat – reuses original when one side empty. |
reverse |
Fast reversed copy (range slice optional). |
forEach |
Controlled traversal with optional reverse + halt state. |
map / reverseMap |
Indexed transformation forward or backward. |
last |
O(1) last element access (uses .at(-1) when available). |
update |
Apply Update<T> logic at index (no-op preserved). |
mod |
Lightweight element modification via (value)=>value'. |
insert |
Insert at index. |
tail / init |
Drop first / last element. |
splice |
Immutable variant of native splice. |
copySparse |
Preserve holes in sparse arrays. |
mapSparse |
Transform only present indices, keeping sparsity. |
Design details:
- Uses native copy-on-write style helpers when available for speed.
- Avoids unnecessary cloning when an update is identity.
- Preserves array holes for internal block structures requiring sparse layout semantics.
Tuple & Token Utilities
import { Entry, Token } from '@rimbu/base';
const pair: readonly [string, number] = ['age', 42];
Entry.first(pair); // 'age'
Entry.second(pair); // 42
// Shared sentinel for internal tagging / identity
if (someValue === Token) {
/* special branch */
}Type Utilities (plain-object)
Compile-time predicates for discriminating plain data objects from complex / functional structures:
| Type | Description |
|---|---|
IsPlainObj<T> |
True only for non-iterable, non-function object types without function properties. |
PlainObj<T> |
Narrows to T if IsPlainObj<T>; otherwise never. |
IsArray<T> |
Resolves to true if T is a (readonly) array type. |
IsAny<T> |
Detects any. |
isPlainObj(obj) |
Runtime guard for plain data objects. |
isIterable(obj) |
Runtime guard for Iterable. |
Use these when building APIs that must reject iterables or functions while retaining strong type discrimination.
Error Types (RimbuError)
Structured error classes provide meaningful failure contexts internally and externally:
| Error Class | Trigger Scenario |
|---|---|
EmptyCollectionAssumedNonEmptyError |
An operation expected a non-empty collection. |
ModifiedBuilderWhileLoopingOverItError |
Mutating a builder mid-iteration. |
InvalidStateError |
Internal invariant breach (should not happen). |
InvalidUsageError |
Consumer used an API incorrectly. |
Helper throw functions exist for concise signaling (throwInvalidStateError(), etc.). Prefer them for consistency.
Installation
Compabitity
Package Managers
Yarn:
yarn add @rimbu/basenpm:
npm install @rimbu/baseBun:
bun add @rimbu/baseDeno:
deno add npm:@rimbu/baseUsage
import { Arr } from '@rimbu/base';
const arr = [1, 2, 3];
console.log(Arr.mod(arr, 1, (v) => v + 1));
// [1, 3, 3]
console.log(arr);
// [1, 2, 3]Author
Created and maintained by Arvid Nicolaas.
Contributing
We welcome contributions! Please read our Contributing guide.
Contributors
Made with contributors-img.
License
This project is licensed under the MIT License. See the LICENSE for details.