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

@calcit/finger-vec

v0.1.1

Published

Persistent vector for the Calcit runtime: chunked relaxed B-tree with front and back buffers

Readme

FingerVec (TypeScript)

A persistent (immutable, structurally shared) vector built for the Calcit JavaScript runtime. It replaces the list part of @calcit/ternary-tree. The Rust twin lives in finger-vec.rs; both use the same layout and algorithms.

npm

Layout

front buffer | relaxed B-tree of chunks | back buffer
  • Elements live in chunks of up to 32 items; lists of 32 items or fewer are one array.
  • The middle is a relaxed B-tree (branching factor 32, cumulative sizes, all leaves at the same depth), as in RRB vectors.
  • Buffers at both ends make pushes and pops cheap. Appending to the newest version of a list writes into its own back array instead of copying; older versions never read past their own end, so they are unaffected.
  • Concatenation joins along the seam and merges the nodes there, so concatenating in a loop keeps the height logarithmic.

| Operation | Cost | | --- | --- | | get, assoc | O(log₃₂ n) | | pushLeft, pushRight, dropLeft, dropRight | amortized O(1) plus a chunk copy | | concat, split, slice, insert, dissoc | O(log n) | | FingerVec.from(array) | O(n) |

Usage

import { FingerVec } from "@calcit/finger-vec";

const xs = FingerVec.of(1, 2, 3);
const ys = xs.pushRight(4).pushLeft(0);
ys.toArray(); // [0, 1, 2, 3, 4]
xs.len(); // 3, unchanged

const [left, right] = ys.split(2);
left.concat(right).equals(ys); // true
ys.slice(1, 3).toArray(); // [1, 2]
for (const x of ys) console.log(x);

Main methods: len, get, first, last, pushLeft/prepend, pushRight/append, dropLeft, dropRight, rest, butlast, assoc, dissoc, insert(idx, item, after), insertAt, assocBefore, assocAfter, split, slice, take, skip, concat, FingerVec.concatAll, reverse, map, forEach, findIndex, indexOf, toArray, equals, items() and for...of. get returns undefined out of range; rest, butlast, assoc, dissoc, insert and slice throw on invalid input, matching the ternary-tree functions Calcit used.

Performance

Measured against @calcit/ternary-tree 0.0.26 on Node 22, Linux x86-64, single runs:

| Case | ternary-tree | FingerVec | Speedup | | --- | ---: | ---: | ---: | | append 100k | 70.00 ms | 24.87 ms | 2.8× | | prepend 100k | 82.35 ms | 48.84 ms | 1.7× | | from array 100k | 19.46 ms | 0.95 ms | 20× | | random get 100k | 58.10 ms | 20.59 ms | 2.8× | | rest until empty, 100k | 32.91 ms | 18.94 ms | 1.7× | | random assoc 100k | 148.21 ms | 90.48 ms | 1.6× | | concat acc [x] 5k, then get every item | 118.18 ms | 1.65 ms | 72× | | insert in the middle 3k | 174.84 ms | 32.33 ms | 5.4× | | queue: append + rest 100k | 110.77 ms | 22.44 ms | 4.9× | | 32-item list: from array ×300k | 543.96 ms | 30.94 ms | 18× | | 8-item list: append to the same base ×300k | 24.65 ms | 48.42 ms | 0.5× | | concat acc [x] 5k | 6.33 ms | 9.41 ms | 0.7× |

Appending repeatedly to one shared small list copies its chunk each time, which is slower than ternary-tree's small nodes. The ternary tree, on the other hand, reaches depth 2,501 after 5,000 concatenations and overflows the stack after a few thousand middle insertions; FingerVec stays at depth 3–4. Run npm run bench for FingerVec numbers on your machine.

Development

打包和发布时会自动执行 TypeScript 构建。运行 npm run test:package 会检查真实 tarball 的文件列表,并在独立临时项目中验证公开类型与 Node 导入;测试不依赖仓库内的源码或本地模块链接。

发布通过 .github/workflows/npm-publish.yaml 使用 npm OIDC trusted publishing,不依赖发布 token。 npm 的 trusted publisher 配置须指定 calcit-lang/finger-vec.ts 和文件名 npm-publish.yaml;当前 job 没有 GitHub Environment,该选项留空。保存配置后可通过 Release 或手动运行同一 workflow 发布;2FA 保持启用。

npm install
npx tsc
node lib/test.mjs
node lib/bench.mjs

Tests compare random operation sequences against arrays, check structural invariants after every step, and assert depth bounds for concatenation loops and middle insertion.

License

MIT