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

nmid

v1.0.0

Published

Generate unique identifiers for any items

Readme

nmid - numeric id

English | 中文

A toolkit for managing auto-increment numeric IDs. Provides ID generation, registration and management capabilities.

Installation

npm i nmid

Usage

import { 
    NmidProductor, 
    NmidMemo,
    NmidRegistrar,
    NmidMap,
    NmidManager 
} from "nmid"

// Basic ID producer
const productor = new NmidProductor()
console.log(productor.next()) // 0
console.log(productor.next()) // 1

// ID memo
const memo = new NmidMemo()
memo.regId(1)
memo.regId(2)
console.log(memo.has(1))        // true
console.log([...memo.ids()])    // [1, 2]
memo.delete(2)
console.log(memo.max)           // 1

// ID registrar is a combination of ID producer and memo
const registrar = new NmidRegistrar()
registrar.regId(5)
console.log(registrar.has(5)) // true
console.log(registrar.next()) // 6
console.log(registrar.next()) // 7

// ID-value map
const map = new NmidMap<string>()
const id = map.newValue("test-0")
console.log(id, map.get(id))    // 0, "test-0"
map.regPair(1, "test-1")
map.regPairs([[2, "test-2"], [3, "test-3"]])
map.regValues(["test-4", "test-5"], str => parseInt(str.slice(-1)))

// ID-value map with tags
const manager = new NmidManager<string, {time: Date}>()
function newTag() { return { time: new Date() } }
const itemId = manager.newItem("item-0", newTag())
console.log(itemId, manager.get(itemId)) // 0, ["item-0", { time: ... }]
manager.regTuple(1, "item-1", newTag())
manager.regTuples([[2, "item-2", newTag()], [3, "item-3", newTag()]])
manager.regItems(["item-4", "item-5"], str => parseInt(str.slice(-1)), newTag)

API Reference

NmidProductor

Generates auto-increment numeric IDs.

Constructor

  • new NmidProductor(from?: number = 0, invalid?: number = -1)
    • from: Starting ID value
    • invalid: Default Invalid ID value, must be less than from

Properties

  • from: number - Starting ID value
  • nextId: number - Next ID to be generated
  • invalid: number - Default Invalid ID value

Methods

  • next(): number
    • Returns: Next available ID
    • Example: productor.next() // returns 0, then 1, then 2...
  • reset(from?: number, setFrom: boolean = false): void
    • from: New next ID value. If undefined, resets to initial from value
    • setFrom: If true, also updates the starting value
    • Throws: Error if from is invalid
    • Example:
      productor.reset(5)    // Sets next ID to 5
      productor.reset()     // Resets to initial from value
  • setNextIfNeeded(from: number): void
    • from: Minimum next ID value
    • Only resets if current nextId is less than from
  • isValid(id: number): boolean
    • Returns: true if id is an integer and >= from

NmidMemo

Keeps track of registered IDs.

Constructor

  • new NmidMemo()
    • Creates empty memo

Properties

  • min: number | undefined - Minimum registered ID, undefined if empty
  • max: number | undefined - Maximum registered ID, undefined if empty

Methods

  • regId(id: number): void
    • Registers single ID
  • regIds(ids: Iterable<number>): void
    • Registers multiple IDs
  • delete(id: number): void
    • Removes ID from memo
  • has(id: number): boolean
    • Returns: true if ID exists in memo
  • clear(): void
    • Removes all IDs
  • ids(): Iterable<number>
    • Returns: Iterator of all registered IDs

NmidRegistrar

Combines ID producer and memo functionality.

Constructor

  • new NmidRegistrar(from = 0, invalid = -1, memo?: NmidMemo)
    • from: Starting ID value
    • invalid: Default Invalid ID value, must be less than from
    • memo: Optional ID memo, creates new one if not provided

Properties

  • from: number - Starting ID value from producer
  • nextId: number - Next ID to be generated
  • invalid: number - Default Invalid ID value from producer
  • min: number | undefined - Minimum registered ID
  • max: number | undefined - Maximum registered ID

Methods

  • next(): number
    • Returns: Next available ID
  • regId(id: number): void
    • Registers ID and updates producer if needed
    • Example:
      registrar.regId(5)  // Registers 5
      console.log(registrar.nextId) // 6
  • regIds(ids: Iterable<number>): void
    • Registers multiple IDs
    • Updates producer to highest ID + 1
  • delete(id: number, autoShrink: boolean = false): void
    • autoShrink: If true, may reduce nextId when deleting highest ID
  • has(id: number): boolean
    • Returns: true if ID is registered
  • clear(): void
    • Removes all IDs and resets producer
  • ids(): Iterable<number>
    • Returns: Iterator of all registered IDs
  • isValid(id: number): boolean
    • Returns: true if id is valid according to producer

NmidMap

Maps IDs to values.

Constructor

  • new NmidMap<T>(from = 0, invalid = -1)
    • from: Starting ID value
    • invalid: Default Invalid ID value, must be less than from

Properties

  • from: number - Starting ID value from producer
  • nextId: number - Next ID to be generated
  • invalid: number - Default Invalid ID value from producer
  • min: number | undefined - Minimum registered ID
  • max: number | undefined - Maximum registered ID

Methods

  • regPair(id: number, value: T): boolean
    • Returns: true if registered, false if ID exists with same value
    • Throws: Error if ID exists with different value
  • regPairs(pairs: Iterable<[number, T]>): void
    • Registers multiple ID-value pairs
    • Throws: Error if any ID exists with different value
  • regValues(values: Iterable<T>, getNmid: (value: T) => number): void
    • getNmid: Function to get ID from value
    • Example:
      map.regValues(["a1", "a2"], str => parseInt(str.slice(-1)))
  • newValue(value: T): number
    • Returns: New ID assigned to value
  • delete(id: number, autoShrink: boolean = false): void
    • Removes ID-value pair
    • autoShrink: If true, may reduce nextId when deleting highest ID
  • get(id: number): T | undefined
    • Returns: Value associated with ID, or undefined
  • has(id: number): boolean
    • Returns: true if ID exists
  • clear(): void
    • Removes all ID-value pairs
  • ids(): Iterable<number>
    • Returns: Iterator of all registered IDs
  • isValid(id: number): boolean
    • Returns: true if id is valid according to producer

NmidManager<T, TAG>

Maps IDs to values with tags.

Constructor

  • new NmidManager<T, TAG>(from = 0, invalid = -1)
    • from: Starting ID value
    • invalid: Default Invalid ID value, must be less than from

Properties

  • from: number - Starting ID value from producer
  • nextId: number - Next ID to be generated
  • invalid: number - Default Invalid ID value from producer
  • min: number | undefined - Minimum registered ID
  • max: number | undefined - Maximum registered ID

Methods

  • regTuple(id: number, item: T, tag: TAG): boolean
    • Returns: true if registered, false if exists with same item
    • Throws: Error if ID exists with different item
  • regTuples(tuples: Iterable<[number, T, TAG]>): void
    • Registers multiple ID-item-tag tuples
  • regItems(items: Iterable<T>, getNmid: (item: T) => number, getTag: (item: T) => TAG): void
    • Registers items with ID and tag getters
  • newItem(item: T, tag: TAG): number
    • Returns: New ID assigned to item-tag pair
  • get(id: number): [T, TAG] | undefined
    • Returns: [item, tag] tuple or undefined
  • delete(id: number, autoShrink: boolean = false): void
    • Removes ID-item-tag pair
    • autoShrink: If true, may reduce nextId when deleting highest ID
  • has(id: number): boolean
    • Returns: true if ID exists
  • clear(): void
    • Removes all ID-item-tag pairs
  • ids(): Iterable<number>
    • Returns: Iterator of all registered IDs
  • isValid(id: number): boolean
    • Returns: true if id is valid according to producer

Other methods same as NmidMap

Common Interface

All ID collection classes implement the GatheredNmids interface:

interface GatheredNmids {
    min: number | undefined       // Minimum registered ID
    max: number | undefined       // Maximum registered ID
    has(id: number): boolean      // Check if ID exists
    clear(): void                // Remove all IDs
    ids(): Iterable<number>      // Get iterator of all IDs
}

Notes

  1. All IDs must be integers
  2. Starting value must be greater than invalid value
  3. The autoShrink feature in delete operations may impact performance, use with caution
  4. When using NmidMap or NmidManager, make sure to handle the case where get() returns undefined

Type Definitions

Full TypeScript type definitions are included and available out of the box.