npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

recursive-set

v8.0.0

Published

Mutable recursive sets with ZFC axioms for TypeScript. High-Performance Array Backend.

Readme

RecursiveSet

MIT License npm version

High-performance collection library for TypeScript supporting value semantics (deep equality) and recursive structures. Version 8 introduces a new hash-based architecture optimized for high-throughput workloads like SAT solvers and graph algorithms.

Overview

RecursiveSet provides mathematical sets and maps where equality is determined by structure/content rather than object reference (e.g., {1, 2} is equal to {2, 1}).

Key Architectural Features:

  • Open Addressing: Uses linear probing with a load factor of 0.75 for cache-efficient lookups.
  • Backshift Deletion: Maintains probe chain integrity without "tombstones," preventing performance degradation over time.
  • Zero-Allocation Hashing: Uses static buffers and raw bitwise operations to hash numbers without triggering the Garbage Collector.
  • Structure of Arrays (SoA): Data is stored in flat arrays to maximize CPU cache locality.

Installation

npm install recursive-set

Quickstart

Working with Sets

Sets automatically deduplicate elements based on their value or structure.

import { RecursiveSet } from "recursive-set";

// Primitive values
const numbers = new RecursiveSet(1, 2, 3);
numbers.add(1); // No effect, 1 is already present

// Recursive structures (Sets of Sets)
const setA = new RecursiveSet(1, 2);
const setB = new RecursiveSet(2, 1);
const metaSet = new RecursiveSet<RecursiveSet<number>>();

metaSet.add(setA);
metaSet.add(setB);

console.log(metaSet.size); // 1, because setA equals setB

Working with Maps

RecursiveMap allows using complex objects (like Tuples or Sets) as keys.

import { RecursiveMap, Tuple } from "recursive-set";

const transitions = new RecursiveMap<Tuple<[string, string]>, number>();
const edge = new Tuple("q0", "q1");

transitions.set(edge, 1);

// Retrieval using a new, structurally identical key
console.log(transitions.get(new Tuple("q0", "q1"))); // 1

Lifecycle (Mutable → Frozen)

To guarantee hash stability, collections become immutable (frozen) once their hash code is computed or they are inserted into another collection.

const A = new RecursiveSet(1);
const B = new RecursiveSet(A); // Accessing A's hash to store it in B freezes A.

try {
  A.add(2); // Throws Error: Frozen Set modified.
} catch (e) {
  // Expected behavior
}

// Use mutableCopy to continue editing
const C = A.mutableCopy();
C.add(2);

Contracts & Invariants

This library optimizes for raw speed and assumes strict adherence to the following contracts. Violating them leads to undefined behavior.

  1. Finite Numbers Only: NaN and Infinity are strictly forbidden. They break strict equality checks and integer optimization paths.
  2. Strict Value Semantics: Plain JavaScript objects ({}) are not supported. Keys must implement the Structural interface (provide equals, hashCode, and toString).
  3. Hash Quality: The $O(1)$ performance guarantee relies on a good distribution. Returning a constant hashCode (e.g., 42) forces all elements into a single bucket, degrading performance to $O(N)$.
  4. Deterministic Visualization: Custom toString() implementations must utilize compareVisualLogic for nested structures. Failing to do so results in unstable string output.
  5. Immutability: Once an object is added to a collection, its hashCode must not change.
  6. No Circular Dependencies: A RecursiveSet cannot contain itself, directly or indirectly. Runtime checks are omitted for performance; creating a cycle will cause a Stack Overflow during hashing.

API Reference

Core Types

type Primitive = number | string;
type Value = Primitive | Structural;

interface Structural {
  readonly hashCode: number;
  equals(other: unknown): boolean;
  toString(): string;
}

RecursiveSet

Construction

  • new RecursiveSet<T>(...elements: T[]): Creates a set from the given arguments.

Mutation (Unfrozen state only)

  • add(element: T): void: Adds an element ($O(1)$ amortized).
  • remove(element: T): void: Removes an element ($O(1)$ amortized).

Set Operations

All operations return a new RecursiveSet instance.

  • union(other): RecursiveSet<T>
  • intersection(other): RecursiveSet<T>
  • difference(other): RecursiveSet<T> ($A \setminus B$)
  • symmetricDifference(other): RecursiveSet<T>
  • cartesianProduct<U>(other): RecursiveSet<Tuple<[T, U]>>
  • powerset(): RecursiveSet<RecursiveSet<T>> (Throws if size > 20)

Properties

  • has(element: T): boolean
  • equals(other: unknown): boolean
  • isSubset(other): boolean
  • isSuperset(other): boolean
  • mutableCopy(): RecursiveSet<T>: Returns a shallow mutable clone.
  • size: number
  • hashCode: number: Computes hash and freezes the set.

RecursiveMap

A hash map supporting Value keys.

  • set(key: K, value: V): void
  • get(key: K): V | undefined
  • delete(key: K): boolean
  • has(key: K): boolean
  • mutableCopy(): RecursiveMap<K, V>

Tuple

An immutable, hashable sequence of values. Useful for composite keys.

  • new Tuple(...elements: T[])
  • get(index: number): T[index]
  • length: number

Credits

This library was developed as a student research project under the supervision of Karl Stroetmann.

Special thanks for his architectural guidance on homogeneous sets and the theoretical foundations required for high-performance set engines.

Contributing

git clone [https://github.com/cstrerath/recursive-set.git](https://github.com/cstrerath/recursive-set.git)
npm install
npm run build
npx tsx test/test.ts
npx tsx test/nqueens.ts

License

MIT License © 2025 Christian Strerath. See LICENSE.