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

raindrop

v1.0.3

Published

Distributed id generation with customizable built-in attributes.

Downloads

44

Readme

Raindrop

NPM version Downloads

Build Status

Dependency status devDependency Status

Raindrop is a distributed id generation utility that mimics the MongoDB BSON ObjectID implementation, with a few key tweaks.

The Raindrop is a 24 character hex string that is automatically encoded into a compact 16 character string represented with the following alphabet:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_

The core hex identifier is represented with the following attributes:

  • 4-byte value representing the seconds since the Unix epoch (32-bit timestamp down to the second)
  • 3-byte process identifier (defaults to random value or user input)
  • 1-byte service id (defaults to 0 or user input)
  • 1-byte entity type id (defaults to 0 or user input)
  • 3-byte incremental counter, reset every second to a random start value

This means the physical structure of the identifier's 5 components is:

FFFFFFFF FFFFFF FF FF FFFFFF

Note: Once the 3-byte incremental counter hits the medium int maximum (12,777,215), it will roll over to 0 and start again

Raindrop is entirely deconstructable into its core values, to allow for the id to travel with key information regarding service origination id and domain-specific entity type identifiers.

Chance of collisions

Raindrops that are generated are highly likely to be unique across collections. The 3-byte incrementing counter is set to a random value every second an operation is performed. Therefore, a total of 16,777,215 unique ids could be inserted every second with the same unique process id and the same service id, without chance of collision.

As long as process id remains unique amongst all of your running processes, and your service id is always registered as being unique, and you do not try to store more than 16,777,215 ids per second, per process id, per service id, you will avoid collisions.

It's recommended to have your service instance pass in a process id likely a combination of machine identifier along with a process id such as a PM2 cluster process identifier.

Motivation

You may be asking yourself, why not just use a GUID? Or perhaps a UUID generator? Isn't that good enough? Maybe. But what if you care about storing some embedded internal domain specific data within your identifier? Why not have your identifier provide some information to help you out? Raindrop gives you:

  • Embeddable user-defined information to store 2 bytes of custom information, highly applicable across a tightly controlled service environment. Embed a marker with these attributes on issuing the id to help assist with type and service lookups later on.
  • Avoid unnecessary lookups to your data store to determine service issuer and entity type. Create efficiency and optimization by decoding and parsing the information inline as you receive it.
  • Reduces the overall id storage footprint by 32 bits over UUID.Raindrop is 96-bit, UUID is 128-bit. This can improve overall data storage efficiency.
  • Uses a custom URL-safe alphabet beyond hex to shrink the represented string even further to just 16 characters. UUID/GUID will contain 32-38 characters. This is ideal where sending lengthy strings in URLs or message strings can impact performance.
  • Based on an established distributed ID generation system in used by MongoDB. This is not reinventing the wheel; it's just painting the wheel a different color.

Install

$ npm install raindrop

Usage

'use strict'

const raindrop = require('../lib/raindrop')

// set options for entityTypeId (0 - 255)
// set options for processId (0 - 16777215)
// set options for serviceId (0 - 255)
const options = {
  'entityTypeId': 4,
  'processId': 7844,
  'serviceId': 1
}

// create new raindrop with options
const drop = raindrop(options)

// get Raindrop object
console.log(drop)

// get Raindrop version info (returns Raindrop object version)
console.log(`version: ${drop.version}`)

// get Raindrop object id as 16 character string
console.log(drop.id)

// get Raindrop object materials property
console.log(drop.materials)

// get Raindrop object decoded properties
console.log(drop.decoded())

// get Raindrop object as 24 character hex string
console.log(drop.decoded().hexId)

// get timestamp portion up to the second as ISO 8601 date from UTC
console.log(`timestamp: ${drop.decoded().timestamp}`)

// get entity type id decoded
console.log(`entity type id: ${drop.decoded().entityTypeId}`)

// get process id decoded
console.log(`process id: ${drop.decoded().processId}`)

// get service id decoded
console.log(`service id: ${drop.decoded().serviceId}`)

// get counter for that 1 second timestamp range decoded
console.log(`counter: ${drop.decoded().counter}`)

// see if one Raindrop object equals another

// true
console.log(drop.equals(drop))

const drop2 = raindrop(options)

// false
console.log(drop.equals(drop2))

License

MIT ©2016 codemouse