FastPriorityQueue.js
A fast, dependency-free, heap-based priority queue for JavaScript and Node.js.
Repository Health
Technical Analysis
FastPriorityQueue.js implements a binary heap-based priority queue, a data structure that lets you insert elements and retrieve the smallest (or highest-priority) one quickly, in logarithmic time. It exposes a small, comparator-driven API: pass a function describing how two elements compare and the queue orders itself accordingly, ascending, descending, or by any custom priority rule.
The library is built for speed, benchmarking itself in its own test suite against a dozen competing JavaScript priority-queue implementations, and it adds a few operations most alternatives skip, including kSmallest() for retrieving the k smallest elements without draining the queue, replaceTop() for single-operation poll-then-add cycles common in streaming top-k workloads, and predicate-based removeOne()/removeMany() for removing items by condition rather than value.
What You Get
- A
FastPriorityQueueconstructor that accepts an optional comparator function, defaulting to ascending numeric/lexical order - Core heap operations:
add(),poll(),peek(), andisEmpty(), each running in O(log n) or O(1) time - Bulk and advanced operations:
heapify()to build a heap from an existing array, andkSmallest(k)to read the k smallest elements without mutating the queue - Predicate-based removal via
removeOne(callback)andremoveMany(callback, limit), plus value-basedremove() replaceTop()for combined poll+add in one O(log n) call, purpose-built for streaming top-k queriestrim()to reclaim unused array memory after high-churn add/remove cycles in long-running queues- Zero runtime dependencies and a bundled
.d.tsfile for full TypeScript generics support
Common Use Cases
- Task and job schedulers that must always process the next highest-priority item first
- Graph algorithms such as Dijkstra’s shortest path or A* search, using the queue as the frontier/open-set ordered by cost
- Streaming top-k analytics, using
replaceTop()to maintain a bounded set of the best-scoring items seen so far - Discrete-event simulation, processing simulated events in timestamp order as new events are generated
Under The Hood
Architecture
The library is a single CommonJS module (FastPriorityQueue.js) exporting one constructor function with all behavior attached via prototype methods, following the classic array-backed binary heap pattern: a flat this.array plus a this.size counter stand in for the heap, with parent/child relationships computed by index arithmetic ((i-1)>>1 for parent, (i<<1)+1 for left child) rather than pointer-based nodes. Two internal helpers, _percolateUp and _percolateDown, do the actual heap-invariant restoration and are reused by the public add, poll, heapify, and _removeAt methods, so the core rebalancing logic exists in exactly one place. There is no dependency injection or layering to speak of, by design: the entire public surface is a flat set of methods on one object, and changing the underlying storage (say, swapping the array for a typed array) would only require touching these two internal functions.
Tech Stack
The runtime code is plain, pre-ES6-style JavaScript (var declarations, 'use strict', module.exports) with zero runtime dependencies, so it loads in any Node.js version or browser without a build step. Type consumers get a hand-maintained FastPriorityQueue.d.ts declaration file with full generics (FastPriorityQueue<T>), letting TypeScript projects use it without a separate @types package. Development tooling is limited to mocha for the test runner and a benchmark devDependency (plus eleven competing priority-queue packages installed solely for comparative benchmarking in benchmark/test.js); there is no bundler, linter, or transpiler in the toolchain since the source ships as-is.
Code Quality
A 358-line Mocha suite (unit/basictests.js) covers ascending and descending comparators, iteration order via forEach, poll-driven draining, and edge cases like removal and empty-queue behavior, giving reasonable confidence in the core heap invariants. There are no TypeScript source files, static type checking, or linter configuration for the JavaScript itself — type safety is provided only externally via the .d.ts file — and error handling is minimal (methods return undefined or false for invalid input rather than throwing). CI is configured via a .travis.yml file, an older CI provider that suggests the automated-testing setup predates more current CI conventions and has not been modernized alongside the code.
API Design
The public API is intentionally tiny and consistent: every method name reads as a plain English verb (add, poll, peek, trim), the constructor’s only configuration point is a single comparator function, and getting started requires no setup beyond new FastPriorityQueue(). Beyond the baseline heap operations most competing libraries offer, it adds a few practical extras, kSmallest(), replaceTop(), and predicate-based removeOne/removeMany, that map directly onto real usage patterns like top-k streaming and conditional eviction, without expanding the constructor’s configuration surface or adding new concepts to learn.