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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@web4/bittrie

v1.1.0

Published

Distributed single writer key/value store

Downloads

14

Readme

BitTrie

Distributed single writer key/value store

npm install @web4/bittrie

Uses a rolling hash array mapped trie to index key/value data on top of a unichain.

Useful if you just want a straight forward single writer kv store or if you are looking for a building block for building more complex multiwriter databases on top.

Usage

const bittrie = require('@web4/bittrie')
const db = bittrie('./trie.db', {valueEncoding: 'json'})

db.put('hello', 'world', function () {
  db.get('hello', console.log)
})

API

db = bittrie(storage, [key], [options])

Create a new database. Options include:

{
  feed: aUnichain, // use this feed instead of loading storage
  valueEncoding: 'json', // set value encoding
  subtype: undefined, // set subtype in the header message at feed.get(0) 
  alwaysUpdate: true // perform an ifAvailable update prior to every head operation
}

If you set options.feed then you can set storage to null.

db.get(key, [options], callback)

Lookup a key. Returns a result node if found or null otherwise. Options are passed through to unichain's get method.

db.put(key, value, [options], [callback])

Insert a value.

Options can include:

{
  condition: function (oldNode, newNode, cb(err, bool)) { ... } 
}

The optional condition function provides atomic compare-and-swap semantics, allowing you to optionally abort a put based on the current and intended node values. The condition callback should be used as follows:

  1. cb(new Error(...)): Abort with an error that will be forwarded through the put.
  2. cb(null, false): Abort the put, but do not produce an error.
  3. cb(null, true): Proceed with the put.

db.del(key, [options], [callback])

Delete a key from the database.

Options can include:

{
  condition: function (oldNode, cb(err, bool)) { ... }
}

The optional condition function behaves the same as the one in put, minus the newNode parameter.

db.batch(batch, [callback])

Insert/delete multiple values atomically. The batch objects should look like this:

{
  type: 'put' | 'del',
  key: 'key/we/are/updating',
  value: optionalValue
}

const watcher = db.watch(prefix, [onchange])

Watch a prefix of the db and get notified when it changes.

When there is a change watcher.on('change') is emitted. Use watcher.destroy() to stop watching.

db.on('ready')

Emitted when the db has loaded it's internal state.

You do not need to wait for this unless noted in the docs.

db.version

Returns the current version of the db (an incrementing integer).

Only available after ready has been emitted.

db.key

Returns the db public key. You need to pass this to other instances you want to replicate with.

Only available after ready has been emitted.

db.discoveryKey

Returns the db discovery key. Can be used to find other db peers.

Only available after ready has been emitted.

checkoutDb = db.checkout(version)

Returns a new db instance checked out at the version specified.

checkoutDb = db.snapshot()

Same as checkout but just returns the latest version as a checkout.

stream = db.replicate(isInitiator, [options])

Returns a unichain replication stream for the db. Pipe this together with another bittrie instance.

Replicate takes an isInitiator boolean which is used to indicate if this replication stream is the passive/active replicator.

All options are forwarded to unichains replicate method.

ite = db.iterator(prefix, [options])

Returns a nanoiterator that iterates the latest values in the prefix specified.

Options include:

{
  recursive: true,
  random: false // does a random order iteration
}

If you set recursive: false it will only iterate the immediate children (similar to readdir)

Additional options are passed through to unichain's get method.

stream = db.createReadStream(prefix, [options])

Same as above but as a stream

db.list(prefix, [options], callback)

Creates an iterator for the prefix with the specified options and buffers it into an array that is passed to the callback.

stream = db.createWriteStream()

A writable stream you can write batch objects to, to update the db.

ite = db.history([options])

Returns a nanoiterator that iterates over the feed in causal order.

Options include:

{
  gt: seq,
  lt: seq,
  gte: seq,
  lte: seq,
  reverse: false,
  live: false // set to true to keep iterating forever
}

stream = db.createHistoryStream([options])

Same as above but as a stream

ite = db.diff(version, [prefix], [options])

Returns a nanoiterator that iterates the diff between the current db and the version you specifiy. The objects returned look like this

{
  key: 'node-key-that-is-updated',
  left: <node>,
  right: <node>
}

If a node is in the current db but not in the version you are diffing against left will be set to the current node and right will be null and vice versa.

Options include:

{
  skipLeftNull: false,
  skipRightNull: false,
  hidden: false, // set to true to diff the hidden keyspace
  checkpoint: <checkpoint>
}

The order of messages emitted for a specific diff is predictable (ordered by key hash). It is possible to resume a diff at any position. To do so, call the .checkpoint method on the diff iterator. It returns a serialized buffer of the current position within the diff. To resume, create a new diff between the same versions and pass the checkpoint buffer as an option.

stream = db.createDiffStream(version, [prefix])

Same as above but as a stream

License

MIT