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

fractional-indexing-jittered

v0.9.1

Published

Fractional index library with jittering and generator

Downloads

3,178

Readme

Fractional indexing jittered

Goal of this package is a abstraction to use Fractional indexing, a technique to generate new order keys in between a existing list without having to reorder all the existing keys.

This package supports Jittering the key to have a high probability of a unique key.

The package consist of two parts:

  • Fractional index API is a collection of functions to generate order keys, either jittered or not
  • Generator is a class to help with the generator process, with support for groups

This package builds on a solid foundation both in writing and in code, see credits

Some examples using react are available in the examples folder and can be viewed on Github Pages

Jittering

Both the low level API and generator the support jittering, see credits for more background info. This means that the keys are with high probability unique even when multiple actors insert on the same spot at the same time

The default character set has a chance of roughly one in 47.000 to generate the same key for the same input at the cost of making the keys 3 characters longer on average. (Not taking into account that Math.random is not 100% random)

Fractional index API

4 functions to generate keys:

  • generateKeyBetween -> generates a single key between two keys or at the start or end of the list
  • generateNKeysBetween -> generate N consecutive keys between two keys or at the start or end of the list
  • generateJitteredKeyBetween -> generates a single key with Jittering
  • generateNJitteredKeysBetween > generate N consecutive keys with Jittering

1 utility functions

  • indexCharacterSet -> create a custom character set if you want more control

See Fractional index API

Generator Quick Start

The easiest way is to use the index generator, the generator should be updated with the latest list after you processed the generated order keys, or if there are updates from other sources like the server/CRDT.

The default will use a base62 character set, with generated keys starting from 'a0', 'a1', 'a2' etc, with random jitter

Read more about Generator Groups and the API at the Generator Docs

import { IndexGenerator } from 'fractional-indexing-jittered';
const generator = new IndexGenerator([]);

// dummy code, would normally be stored in database or CRDT and updated from there
const list: string[] = [];
function updateList(newKey: string) {
  list.push(newKey);
  generator.updateList(list);
}

// "a01TB" a0 with jitter
const firstKey = generator.keyStart(); 
updateList(firstKey);

// "a10Vt" a1 with jitter
const secondKey = generator.keyEnd(); 
updateList(secondKey);

// "a0fMq" jittered midpoint between firstKey and secondKey
const keyInBetween = generator.keyAfter(firstKey); 
updateList(keyInBetween);

// "a0M3o" jittered midpoint between firstKey and keyInBetween
const anotherKeyInBetween = generator.keyBefore(keyInBetween); 
updateList(anotherKeyInBetween);

// [ 'a01TB', 'a0M3o', 'a0fMq', 'a10Vt' ] 
// [ firstKey, anotherKeyInBetween, keyInBetween, secondKey ]
console.log(list.sort()); 

Credits

This package builds on a solid foundation both in writing and in code, the two most influential sources are listed below.

fractional-indexing

Starting point for this package was the fractional-indexing package.

Kudos to them and David Greenspan, this implementation also includes a slightly adjusted version of variable-length integers, and the prepend/append optimization described in David's article.

Random Jitter

The idea for adding random jitter to this package comes from this excellent post by Even Wallace called CRDT: Fractional Indexing. It was another post by Even Wallace, that put me on the path to use fractional indexing in our app.

Questions

What about interleaving?

If two peers both simultaneously insert at the same location, the resulting objects may be interleaved. Protecting against interleaving comes at the cost of added complexity or rapidly growing order key length.

This means that this package is not well suited for situations where object adjacency is critical (like character order in collaborative text editing)

What if I do have an identical key (even with jittering)?

Identical keys still possible if two peers both simultaneously insert at the same location, even with jittering on, and likely if you do not use jittering.

Best practice is use another ID as tiebreaker like the object ID. If you detect an Identical key, you can always just regenerate one (or both)

How long can the keys get?

There is no limit on how long the keys can get, and theoretically can get quite long if inserting on the same spot hundreds or thousand of times. But with human input the length of the order keys will normally stay reasonable.