Skip to content

API Overview

SymbolPurposeExecutionCommon gotcha
groupByGroup values by key (prototype-pollution guarded)SyncRoot export
chunk / zip / compactTyped collection transformsSyncAvailable from /array
range / average / medianNumeric generation and aggregationSyncAvailable from /math
assertAssert and narrow a conditionSyncAvailable from /function
retryRetry async workAsyncRethrows final error
taskPoolBound concurrent tasksAsyncAvailable from /async
cacheIn-memory identity-keyed cacheAsyncAvailable from /cache
fuzzyFilterFilter string or selected object fieldsSyncObject collections require select
fuzzyScoreRank string or selected object fieldsSyncObject collections require select
tryParseJsonPreserve JSON syntax resultSyncReturns unknown on success
getPathOptional object lookup (safe-path guarded)SyncAvailable from /object
allocateLossless proportional distributionSyncAvailable from /math
isEqualStructural equalitySyncRoot export
hashDeterministic serialization for cache keysSyncAvailable from /object

Package Entry Points

ImportPurpose
@vielzeug/arsenalCurated common utilities
@vielzeug/arsenal/arrayImmutable transforms, set operations, sorting, fuzzy search
@vielzeug/arsenal/asyncRetry, cancellation, task pool, timing
@vielzeug/arsenal/cacheIn-memory cache and memoization
@vielzeug/arsenal/functionAssertions, composition, timing, teardown
@vielzeug/arsenal/guardsType guards, predicate combinators, equality guards
@vielzeug/arsenal/mathRanges, aggregation, statistics, interpolation, exact allocation
@vielzeug/arsenal/objectPaths, transforms, hash, JSON parse result
@vielzeug/arsenal/randomCryptographic-entropy selection and shuffle
@vielzeug/arsenal/stringUnicode-aware case transforms and similarity

Array

Typed transforms

ts
chunk<T>(input: readonly T[], size?: number): T[][]
compact<T>(array: readonly T[]): Array<Exclude<T, false | '' | 0 | 0n | null | undefined>>
first<T>(array: readonly T[], fallback?: T): T | undefined
last<T>(array: readonly T[], fallback?: T): T | undefined
replace<T>(array: readonly T[], predicate: (value: T) => boolean, value: T): T[]
rotate<T>(array: readonly T[], positions: number, options?: { wrap?: boolean }): T[]
zip(...arrays): Array<tuple>
unzip(rows): tupleOfArrays

take, takeLast, drop, and dropLast return new arrays and normalize negative counts to zero. Set operations accept optional selectors for object identity.

fuzzyFilter / fuzzyScore

ts
fuzzyFilter(strings: readonly string[], query: string, options?: FuzzyOptions): string[]
fuzzyFilter<T>(items: readonly T[], query: string, options: FuzzySelection<T>): T[]
fuzzyScore(strings: readonly string[], query: string, options?: FuzzyOptions): ScoredResult<string>[]
fuzzyScore<T>(items: readonly T[], query: string, options: FuzzySelection<T>): ScoredResult<T>[]

fuzzyFilter preserves input order. fuzzyScore orders results by descending score.

ts
import { fuzzyFilter } from '@vielzeug/arsenal/array';

const users = [{ email: 'alice@example.com', name: 'Alice' }];
const matches = fuzzyFilter(users, 'alice', { select: (user) => [user.name, user.email] });

Async

taskPool

ts
interface TaskPool {
  run<T>(task: (signal: AbortSignal) => Promise<T>): Promise<T>;
  idle(): Promise<void>;
  dispose(reason?: unknown): void;
  readonly active: number;
  readonly pending: number;
  readonly disposed: boolean;
  readonly disposalSignal: AbortSignal;
}

taskPool(options?: { concurrency?: number }): TaskPool

dispose() aborts running cooperative tasks and rejects pending tasks.

ts
import { taskPool } from '@vielzeug/arsenal/async';

const pool = taskPool({ concurrency: 2 });
const user = await pool.run((signal) => fetch('/user', { signal }).then((response) => response.json()));
pool.dispose();

Cache

cache

ts
interface Cache<K, T> {
  entries(): ReadonlyArray<readonly [K, T]>;
  get(key: K): T | undefined;
  set(key: K, value: T, options?: { ttlMs?: number }): void;
  getOrLoad(key: K, load: () => Promise<T>): Promise<T>;
  delete(key: K): boolean;
  clear(): void;
  readonly size: number;
}

cache<K, T>(options?: CacheOptions): Cache<K, T>

Keys use native Map identity. Expiry is lazy, evaluated by get, getOrLoad, set, and entries. entries() trims expired values and returns a new insertion-ordered snapshot without exposing internal storage. The size getter does not evict expired entries.

ts
import { cache } from '@vielzeug/arsenal/cache';

const profiles = cache<string, Profile>({ ttlMs: 60_000 });
const profile = await profiles.getOrLoad('me', loadProfile);

Object

tryParseJson

ts
type JsonParseResult = { ok: true; value: unknown } | { error: SyntaxError; ok: false };

tryParseJson(text: string): JsonParseResult

Use a schema validator after success to refine unknown data.

ts
import { tryParseJson } from '@vielzeug/arsenal/object';

const result = tryParseJson(raw);
if (!result.ok) throw result.error;

getPath

ts
getPath<T extends Record<string, unknown>, P extends string>(item: T, path: P): PathValue<T, P> | undefined
getPathOr<T extends Record<string, unknown>, P extends string, F>(item: T, path: P, fallback: F): PathValue<T, P> | F
requirePath<T extends Record<string, unknown>, P extends string>(item: T, path: P): Exclude<PathValue<T, P>, undefined>

hash

ts
hash(value: unknown, options?: HashOptions): string

Produces a deterministic, order-independent serialization. Handles Date, RegExp, Set, Map, and bigint. Circular references produce a sentinel. Useful for stable cache keys.


Math

Numeric toolkit

ts
range(stop: number): number[]
range(start: number, stop: number, step?: number): number[]
clamp(value: number, min?: number, max?: number): number
sum<T>(values: readonly T[], select?: (value: T) => number): number
average<T>(values: readonly T[], select?: (value: T) => number): number | undefined
median<T>(values: readonly T[], select?: (value: T) => number): number | undefined
variance<T>(values: readonly T[], select?: (value: T) => number): number
standardDeviation<T>(values: readonly T[], select?: (value: T) => number): number

sum and average reject non-finite values. gcd and lcm require safe integers. linspace requires finite bounds and a positive integer point count. variance and standardDeviation compute population statistics.

allocate

ts
allocate(amount: number, ratios: number[] | number): number[]
allocate(amount: bigint, ratios: number[] | number): bigint[]

Distributes an amount proportionally across ratios. The indivisible remainder is applied to the last bucket so the sum equals the original amount exactly — critical for financial operations.

Types

ts
type FuzzyOptions = {
  normalize?: boolean;
  threshold?: number;
};

type FuzzySelection<T> = FuzzyOptions & {
  select: (item: T) => string | readonly string[];
};

type ScoredResult<T> = { item: T; score: number };

type CacheOptions = {
  capacity?: number;
  now?: () => number;
  ttlMs?: number;
};

Errors

  • RangeError — invalid numeric bounds, capacity, concurrency, or retry count.
  • TypeError — invalid value types, unsupported comparison, or required path missing.
  • ArsenalSerializationError — memo or hash cannot serialize supplied input.