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

intervalmap

v0.1.1

Published

AVL-backed map for exact, point, and overlap queries on closed numeric intervals

Downloads

59

Readme

IntervalMap.js

NPM Package MIT License

IntervalMap.js is a generic TypeScript map for closed numeric intervals. An AVL tree keeps updates and exact lookups balanced, while cached subtree endpoints accelerate point and overlap queries.

Intervals use closed semantics: [a, b] contains both endpoints, and intervals overlap when they share an endpoint.

Features

  • Generic IntervalMap<Value> API with generated declarations
  • Exact set, get, has, and delete operations
  • Point and overlap queries with subtree pruning
  • Sorted iteration by interval start and end
  • Balanced bulk construction with optional value-aware coalescing
  • Defensive interval snapshots that protect tree invariants
  • CommonJS, ESM, browser-global, AMD, and browser-ESM builds

Installation

npm install intervalmap

@rawify/interval is installed as a dependency. Node.js 20 or newer is required.

Usage

ES modules

import Interval from '@rawify/interval';
import IntervalMap from 'intervalmap';

const schedule = new IntervalMap<string>();
schedule.set(new Interval(0, 10), 'setup');
schedule.set(new Interval(8, 20), 'run');

console.log(schedule.get(new Interval(0, 10))); // 'setup'
console.log(schedule.getAt(9));                  // 'setup'
console.log(schedule.getAt(9, true).map(entry => entry.value));
// ['setup', 'run']

Default and named class exports are available:

import IntervalMap, { IntervalMap as NamedIntervalMap } from 'intervalmap';

CommonJS

const Interval = require('@rawify/interval');
const IntervalMap = require('intervalmap');

const map = new IntervalMap();
map.set(new Interval(1, 5), 'active');

Browser global

<script src="https://cdn.jsdelivr.net/npm/@rawify/[email protected]/dist/interval.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/intervalmap.min.js"></script>
<script>
  const map = new IntervalMap();
  map.set(new Interval(0, 10), 'active');
  console.log(map.getAt(5));
</script>

The same files are available from unpkg:

<script src="https://unpkg.com/@rawify/[email protected]/dist/interval.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/intervalmap.min.js"></script>

The browser-global build registers an AMD module when define.amd is present.

Browser ES modules

<script type="module">
  import Interval from 'https://cdn.jsdelivr.net/npm/@rawify/[email protected]/dist/interval.min.mjs';
  import IntervalMap from 'https://cdn.jsdelivr.net/npm/[email protected]/dist/intervalmap.min.mjs';

  const map = new IntervalMap();
  map.set(new Interval(0, 10), 'active');
</script>

Bundlers can select the minified browser ESM build explicitly:

import IntervalMap from 'intervalmap/browser';

Queries

Exact keys

const key = new Interval(10, 20);
map.set(key, 'value');

map.get(new Interval(10, 20));    // 'value'
map.has(new Interval(10, 20));    // true
map.delete(new Interval(10, 20)); // true

has() distinguishes a missing key from a key whose value is null or undefined.

Overlap queries

map.set(new Interval(0, 10), 'left');
map.set(new Interval(15, 20), 'right');

map.hasOverlap(new Interval(10, 15)); // true
map.getOverlapping(new Interval(8, 16));
// Both entries, sorted by interval start and end

Touching endpoints count as overlap because intervals are closed.

Point queries

map.getAt(9);       // First matching value in interval order, or null
map.getAt(9, true); // Every matching entry in interval order

The single-result overload avoids allocating an array. Use the second overload when all overlapping intervals are required.

Iteration

The map, entries(), keys(), and values() all iterate in interval order:

for (const { interval, value } of map) {
  console.log(interval.a, interval.b, value);
}

forEach(callback) uses the same order. toArray() returns a sorted snapshot.

Intervals are cloned on insertion and when returned by public methods. Mutating an input or returned interval does not alter the map. Values remain shared by reference.

Bulk Construction

IntervalMap.fromArray(entries, mergeSame) sorts entries and builds a minimal-height tree directly:

const map = IntervalMap.fromArray([
  { interval: new Interval(0, 2), value: 'X' },
  { interval: new Interval(2, 5), value: 'X' },
  { interval: new Interval(4, 6), value: 'Y' },
], true);

// X is stored once as [0, 5]; Y remains [4, 6].

With mergeSame = true, touching or overlapping intervals with strictly equal values are coalesced. Exact duplicate keys use normal map semantics: the last input value wins. Inputs are not mutated.

API

| Member | Description | | --- | --- | | size | Number of exact interval keys | | set(interval, value) | Insert or replace an entry and return the map | | get(interval) | Return an exact value or null | | has(interval) | Check for an exact key | | delete(interval) | Delete an exact key | | hasOverlap(interval) | Check whether any interval overlaps the query | | getOverlapping(interval) | Return every overlapping entry | | getAt(point) | Return the first value containing the point | | getAt(point, true) | Return every entry containing the point | | entries(), keys(), values() | Return sorted iterators | | forEach(callback) | Visit entries in sorted order | | toArray() | Return a sorted entry snapshot | | clear() | Remove all entries and return the map | | isEmpty() | Check whether the map is empty | | getSize() | Compatibility alias for size | | clone() | Clone nodes and intervals while retaining value references | | toString() | Format entries as [a, b] -> value | | IntervalMap.fromArray(entries, mergeSame) | Build a balanced map from entries |

TypeScript

ESM consumers can import the entry type directly:

import type { IntervalMapEntry } from 'intervalmap';

const entries: IntervalMapEntry<string>[] = [];

For TypeScript using CommonJS syntax, it is available through the class namespace:

import IntervalMap = require('intervalmap');

const entries: IntervalMap.Entry<string>[] = [];

Complexity

| Operation | Cost | | --- | ---: | | set, get, has, delete | O(log n) | | hasOverlap, single getAt | Typically O(log n), worst case O(n) | | All-match queries | Typically O(log n + k), worst case O(n) | | Sorted iteration | O(n) | | fromArray | O(n log n) sorting and O(n) construction |

Here, k is the number of returned matches. Heavy overlap can reduce pruning effectiveness.

Development

npm install
npm test

The test command rebuilds every distribution, type-checks ESM and CommonJS consumers, and runs runtime and package-export tests.

Copyright and License

Copyright (c) 2026 Robert Eisele

Licensed under the MIT license.