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

@sovereignbase/sequencer

v1.0.0

Published

A causality-encoding engine written in TypeScript and C++ to build high-performance, conflict-free replicated data types for use on the web.

Readme

npm version JSR CI codecov license

Sequencer

Sequencer provides a deterministic total ordering for distributed data. It allows independently operating actors to make concurrent changes and eventually converge on the same state without relying on network arrival order or perfectly synchronized clocks.

Usage

Simple typed API

import { Projection } from '@sovereignbase/sequencer'

const projection = new Projection<string>(1)

const gossip0 = projection.insert(['Hello World'], 0)
console.log(projection.value(0)) // "Hello World"
const gossip1 = projection.replace(['Hello Dude'], 0, 0)
console.log(projection.value(0)) // "Hello Dude"
const gossip2 = projection.remove(0, 0)
console.log(projection.value(0)) // undefined

projection.destroy()

See documentation

Benchmarks

Moderate bundle size

| Format | Raw (KiB) | Minified (KiB) | Minified + gzip (KiB) | | -------- | --------: | -------------: | --------------------: | | ESM | 123.83 | 100.04 | 36.07 | | CommonJS | 123.94 | 100.86 | 36.28 |

Both bundles include WASM. Terser uses three compression passes; gzip uses level 9.

Average throughput during editing to checkpoint

Arithmetic means of 3 runs, in ops/s, from each phase's start to checkpoint. Strips contain 1–100 Frames (visible entries). Headers show Strip counts and mean Frame counts.

↑ Scale up (0 → 25,000 Strips)

| Method / case | 1,000 Strips50,871 Frames | 5,000 Strips252,214 Frames | 10,000 Strips504,871 Frames | 15,000 Strips758,280 Frames | 20,000 Strips1,010,749 Frames | 25,000 Strips1,264,003 Frames | | -------------- | ----------------------------: | -----------------------------: | ------------------------------: | ------------------------------: | --------------------------------: | --------------------------------: | | apply.random | 146,512 | 50,162 | 35,425 | 25,372 | 17,992 | 13,401 | | insert.head | 1,103,240 | 627,952 | 723,841 | 741,193 | 692,500 | 629,581 | | insert.random | 423,106 | 138,442 | 91,906 | 64,213 | 44,063 | 33,092 | | insert.tail | 1,247,342 | 779,594 | 895,027 | 892,070 | 830,660 | 765,706 | | remove.head | — | — | — | — | — | — | | remove.random | 258,681 | 95,210 | 65,861 | 46,668 | 31,655 | 23,556 | | remove.tail | — | — | — | — | — | — | | replace.head | 380,869 | 309,212 | 303,788 | 291,544 | 270,032 | 245,792 | | replace.random | 253,774 | 94,640 | 63,352 | 45,272 | 31,633 | 23,736 | | replace.tail | 392,296 | 315,718 | 313,645 | 310,052 | 268,791 | 247,351 | | value.head | 2,283,059 | 2,095,440 | 1,999,974 | 2,016,602 | 1,907,994 | 1,721,581 | | value.random | 569,971 | 133,693 | 78,867 | 51,725 | 34,540 | 25,316 | | value.tail | 4,749,438 | 3,636,984 | 3,461,656 | 3,227,876 | 2,914,996 | 2,408,625 |

↓ Scale down (25,000 → 0 Strips)

| Method / case | 20,000 Strips1,012,742 Frames | 15,000 Strips755,860 Frames | 10,000 Strips504,103 Frames | 5,000 Strips251,203 Frames | 1,000 Strips51,057 Frames | 0 Strips0 Frames | | -------------- | --------------------------------: | ------------------------------: | ------------------------------: | -----------------------------: | ----------------------------: | -------------------: | | apply.random | 7,268 | 7,592 | 8,263 | 8,783 | 9,083 | 9,219 | | insert.head | — | — | — | — | — | — | | insert.random | 17,296 | 18,458 | 20,290 | 21,279 | 22,052 | 22,459 | | insert.tail | — | — | — | — | — | — | | remove.head | 157,981 | 165,917 | 180,514 | 178,894 | 181,826 | 183,709 | | remove.random | 13,036 | 13,992 | 15,527 | 16,535 | 17,163 | 17,459 | | remove.tail | 192,199 | 192,220 | 203,528 | 209,615 | 209,694 | 210,394 | | replace.head | 176,953 | 178,240 | 186,921 | 185,389 | 181,259 | 161,071 | | replace.random | 13,038 | 14,084 | 15,647 | 16,708 | 17,397 | 17,697 | | replace.tail | 190,938 | 184,284 | 193,773 | 187,715 | 182,304 | 182,496 | | value.head | 794,128 | 838,606 | 885,880 | 922,502 | 940,112 | 948,944 | | value.random | 13,677 | 14,768 | 16,600 | 18,037 | 18,894 | 19,271 | | value.tail | 1,070,897 | 1,038,948 | 1,093,604 | 1,140,368 | 1,178,006 | 1,192,164 |

API throughput at checkpoint

Checkpoint calls, in ops/s, averaged across runs.

↑ Scale up (0 → 25,000 Strips)

| Method | 1,000 Strips50,871 Frames | 5,000 Strips252,214 Frames | 10,000 Strips504,871 Frames | 15,000 Strips758,280 Frames | 20,000 Strips1,010,749 Frames | 25,000 Strips1,264,003 Frames | | --------------------------------- | ----------------------------: | -----------------------------: | ------------------------------: | ------------------------------: | --------------------------------: | --------------------------------: | | new Projection(actorID, sequence) | 2,513 | 795 | 408 | 215 | 154 | 107 | | sequence() | 375 | 66 | 33 | 18 | 11 | 6 | | values() | 480 | 163 | 108 | 70 | 49 | 32 |

↓ Scale down (25,000 → 0 Strips)

| Method | 20,000 Strips1,012,742 Frames | 15,000 Strips755,860 Frames | 10,000 Strips504,103 Frames | 5,000 Strips251,203 Frames | 1,000 Strips51,057 Frames | 0 Strips0 Frames | | --------------------------------- | --------------------------------: | ------------------------------: | ------------------------------: | -----------------------------: | ----------------------------: | -------------------: | | new Projection(actorID, sequence) | 116 | 212 | 273 | 586 | 1,881 | 16,098 | | sequence() | 7 | 6 | 5 | 4 | 4 | 38,383 | | values() | 44 | 51 | 58 | 62 | 199 | 68,912 |

Sequence disk size at checkpoint

Complete exported Sequences, including Footage and acknowledgements. Sizes are in KiB.

↑ Scale up (0 → 25,000 Strips)

| Encoding | 1,000 Strips50,871 Frames | 5,000 Strips252,214 Frames | 10,000 Strips504,871 Frames | 15,000 Strips758,280 Frames | 20,000 Strips1,010,749 Frames | 25,000 Strips1,264,003 Frames | | ------------------ | ----------------------------: | -----------------------------: | ------------------------------: | ------------------------------: | --------------------------------: | --------------------------------: | | JSON | 277.17 | 1,621.65 | 3,261.72 | 4,901.02 | 7,041.25 | 9,162.75 | | JSON + gzip | 14.59 | 73.84 | 150.38 | 226.94 | 311.22 | 391.69 | | MessagePack | 164.81 | 818.88 | 1,639.69 | 3,529.41 | 5,081.04 | 6,483.22 | | MessagePack + gzip | 12.38 | 61.62 | 124.91 | 198.59 | 263.54 | 332.77 |

↓ Scale down (25,000 → 0 Strips)

| Encoding | 20,000 Strips1,012,742 Frames | 15,000 Strips755,860 Frames | 10,000 Strips504,103 Frames | 5,000 Strips251,203 Frames | 1,000 Strips51,057 Frames | 0 Strips0 Frames | | ------------------ | --------------------------------: | ------------------------------: | ------------------------------: | -----------------------------: | ----------------------------: | -------------------: | | JSON | 7,446.44 | 5,617.36 | 3,769.76 | 1,885.51 | 383.23 | 0.02 | | JSON + gzip | 323.23 | 244.45 | 163.91 | 80.61 | 16.33 | 0.03 | | MessagePack | 5,237.17 | 3,930.33 | 2,628.38 | 1,312.43 | 266.67 | 0.01 | | MessagePack + gzip | 274.96 | 207.78 | 137.38 | 67.41 | 13.67 | 0.03 |

Memory usage at checkpoint

One instance: WASM memory plus retained JS array slots, in KiB (1,024 bytes).

↑ Scale up (0 → 25,000 Strips)

| Measurement | 1,000 Strips50,871 Frames | 5,000 Strips252,214 Frames | 10,000 Strips504,871 Frames | 15,000 Strips758,280 Frames | 20,000 Strips1,010,749 Frames | 25,000 Strips1,264,003 Frames | | ---------------------- | ----------------------------: | -----------------------------: | ------------------------------: | ------------------------------: | --------------------------------: | --------------------------------: | | Estimated memory (KiB) | 5,343.67 | 25,100.58 | 50,470.89 | 82,701.27 | 98,036.35 | 153,462.93 |

↓ Scale down (25,000 → 0 Strips)

| Measurement | 20,000 Strips1,012,742 Frames | 15,000 Strips755,860 Frames | 10,000 Strips504,103 Frames | 5,000 Strips251,203 Frames | 1,000 Strips51,057 Frames | 0 Strips0 Frames | | ---------------------- | --------------------------------: | ------------------------------: | ------------------------------: | -----------------------------: | ----------------------------: | -------------------: | | Estimated memory (KiB) | 163,746.93 | 174,034.00 | 202,660.72 | 293,941.85 | 302,158.29 | 304,203.30 |

Measured on Node 24.16.0, V8 13.6.233.17-node.49, win32 x64, Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz. Peer synchronization, encoding and JS process garbage collection are outside API timings. Full lifecycle results · Throughput results.

Tests

Behaviour guaranteed by excessive tests

The latest verification passed 178 Vitest tests and 88 compatibility checks (1 failed). The configured 100% coverage threshold is met (100% statements, 100% branches, 100% functions, 100% lines). See the test suites and automated test report.

Works everywhere where JavaScript and Wasm works

Runtimes covered by the latest compatibility verification:

  • Node.js, ESM: passed
  • Node.js, CommonJS: passed
  • Deno: passed
  • Bun: passed
  • Edge Runtime: passed
  • Cloudflare Workers through workerd: passed
  • Chromium browser windows: passed
  • Firefox browser windows: failed (matching Playwright browser binary unavailable)
  • WebKit browser windows: passed

Tested realtime and offline text editing behaviour examples

  • Online and offline editors: six editors converge through delayed, reversed and shuffled delivery, including offline changes arriving during online editing.
  • Concurrent replacements: independent replacement histories retain the same surviving content across delivery orders.
  • Restart and redelivery: stored Sequences preserve visible content through hydration, duplicate delivery and further edits.
  • Peer-to-peer fanout: independently editing browser peers synchronize through BroadcastChannel.
  • WebSocket fanout: three browser peers converge through a stateless JSON Gossip relay.

Credits

This could not have been made without years of work from many great engineers of many great projects, to mention a few:

License

Apache-2.0