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

@bradkovach/guid

v1.0.1

Published

Zero-dependency RFC 4122-compliant GUID/UUID generation library.

Downloads

8

Readme

Zero-dependency RFC 4122-compliant GUID/UUID library written with TypeScript, modern crypto and a proper internal byte representation.

Quick Start

Install from npm

npm install --save @bradkovach/guid

Create, Parse, Serialize!

import { Guid } from '@bradkovach/guid';

// Create

// Random, valid v4 GUID/UUID
let guid = Guid.newGuid();

// Random, sequential v4 "COMB" GUID/UUID
// These are time based and also use an internal
// serial number to ensure that they are always sequential
// even if they are generated in a loop
let combGuid = Guid.newCombGuid();

// Empty GUID
let emptyGuid = Guid.Empty;

// Parse

// parse any guid-like string from bin/oct/dec/hex bases
let parsedFromString = Guid.fromString(myString);

// create a guid from existing byte array
let parsedFromBytes = Guid.fromBytes(myBytes);

// Serialize

// To hex
let hex = guid.toString();

// To decimal
let dec = guid.toString(10);

// To octal
let oct = guid.toString(8);

// To binary
let bin = guid.toString(2);

Usage

Creation of new Guid instances is performed by calling static methods on the Guid class. Guid does not offer a public constructor.

Static Methods

Create from string

Guid.fromString(guidString:string): Guid

This library can parse GUID/UUID strings in binary, octal, decimal and hexadecimal formats and normalizes internally to accommodate lots of common formats, including braced (Microsoft-style), padded with whitespace inside braces, uppercase/lowercase variants.

import { Guid } from '@bradkovach/guid';

// all will work
let guid0 = Guid.fromString('c87c33e1-f9a9-43a7-bebb-d33a70883dc6');
let guid1 = Guid.fromString('83870266-9493-42CE-9EE6-8F3AA9D04401');
let guid2 = Guid.fromString('{fa20be72-8325-42e8-b62b-149ba613edcd}');
let guid3 = Guid.fromString('{18F66861-F882-4E95-BDEE-9499C7022C63}');
let guid4 = Guid.fromString('{ fa20be72-8325-42e8-b62b-149ba613edcd }');
let guid5 = Guid.fromString('{ 18F66861-F882-4E95-BDEE-9499C7022C63 }');

// as a binary string
let guid6 = Guid.fromString(
    '10010111110000110101110110110111111110011010101001001101001000001011101111010011010000010000100111000000110011010000100111000110'
);
let guid7 = Guid.fromString(
    '{10010111110000110101110110110111111110011010101001001101001000001011101111010011010000010000100111000000110011010000100111000110}'
);
let guid8 = Guid.fromString(
    '{10010111110000110101110110110111111110011010101001001101001000001011101111010011010000010000100111000000110011010000100111000110}'
);

Create from bytes

Guid.fromBytes(bytes: Uint8Array): Guid

The static Guid.fromBytes(bytes) method will construct a new Guid instance. fromBytes will set the version and variant bits, ensuring that the resulting Guid represents a valid v4 GUID/UUID.

import { Guid } from '@bradkovach/guid';

// construct from existing 16-byte array
// This will set version and variant fields
let myBytes = getExistingGuidBytes();
let guid = Guid.fromBytes(myBytes);

Memoization

Call static member Guid.memoize(base) to improve the performance of serialization. Internally, Guid caches the string representation for the base and byte value when toString(base) is called. In benchmarks, this improves serialization performance about 7x.

If you need to clear the memoized string store, call Guid.clearMemoizedStrings().

Serializing bytes

Call static Guid.getByteSerializer(base) to get a function that will turn a valid byte (number from 0-255) into a string representation in any supported javascript base (2-36).

import { Guid } from '@bradkovach/guid';

const hexSerializer = Guid.getByteSerializer(16);
const hexString = [1, 2, 3, 4, 5].map(hexSerializer).join('');

Resize random bytes pool

Guid.resizePool(guidCount)

If you intend to generate a lot of Guid instances (in a loop), you may want to resize the random byte pool to a larger number to improve performance.

By default the pool is large enough for 256 Guids. Provide a guidCount integer greater than zero to allocate guidCount * BYTES_IN_GUID bytes of random data. If the bytes are used, the pool will refill with new random data.

The random bytes pool is not accessible publicly, but the RandomBytesPool class is available.

Instance Methods

These methods can be called on a Guid instance.

toBytes(): Uint8Array

Returns a copy of the internal byte array.

toString(base: number = 16): string

Returns a string representing the Guid in your chosen base. This can be called with any supported JS base from 2 through 36. Unit tests support bin/oct/dec/hex.

Generated GUID/UUID strings will include hyphens. Use the normalizeGuidString utility to strip these hyphens.

import { Guid } from '@bradkovach/guid';

let guid = Guid.newGuid();

let bin = guid.toString(2);
let oct = guid.toString(8);
let dec = guid.toString(10);
let hex = guid.toString(16);

valueOf(): BigInt

Converts the Guid into a BigInt. Creating Guid instances from a BigInt is not supported, however, the following should produce a string that can be parsed by Guid.fromString().

let bigInt = Guid.newGuid().valueOf();
let hexGuid = bigInt.toString(16).padStart(32, '0');
let cloned = Guid.fromString(hexGuid);

Equality and Comparison

When you're working with COMB Guid instances, or guids created from comb guids, you can compare using less-than/greater-than. This could be useful for comparing Correlation IDs to compare which correlation ID happened first.

import { Guid } from '@bradkovach/guid';

let guidOne = Guid.newCombGuid();
let guidTwo = Guid.newCombGuid();

// compare using LT/GT
let isLessThan = guidOne < guidTwo; // true
let isGreaterThan = guidOne > guidTwo; // false

// compare value equality
let guidOneClone = Guid.fromBytes(guidOne.toBytes());
let isEqualValue = guidOne.valueOf() === guidOneClone.valueOf(); // true

// compare object identity
let isEqualIdentity = guidOne === guidOneClone; // false

Helpful Constants

A number of constants are available. These should be used to cut down on arbitrary magic numbers.

BYTES_IN_GUID: number = 16

Used for instantiating arrays.

BYTE_MIN: number = 0

Minimum valid value of a byte. Used for comparing byte values and to make code intent clearer.

BYTE_MAX: number = 255

Maximum valid value of a byte. Used for comparing byte values and to make code intent clearer.

Class RandomBytePool

Guid uses a private static instance of RandomBytePool to manage its random data. RandomBytePool can be instantiated and used if you want a source of random bytes. RandomBytePool is a standalone class to ensure 100% test coverage of its functionality.

The pool will automatically resize itself if getBytes(count) is called with a count greater than the length of the pool. Guid uses RandomBytePool by allocating in increments of BYTES_IN_GUID, and it reads values in these increments as well. Although even multiples aren't required when reading bytes with getBytes(count), this is the most efficient memory allocation.

The pool can be resized after instantiation by calling resize(newSize). This can be used to shrink or expand the pool.

import { RandomBytePool, BYTES_IN_GUID } from '@bradkovach/guid';

// instantiate with 256 bytes
let rbp = new RandomBytePool(256);

// => returns 5 random bytes
let five = rbp.getBytes(5);

// => returns 1024 bytes, after resizing the pool.
let tooMany = rbp.getBytes(1024);

// resizes the pool to 128 Guids worth of random bytes
rbp.resize(128 * BYTES_IN_GUID);

// Returns false when the pool hasn't
// yet been read from.
let isInitialized = rbp.initialized;

// Returns the length of the internal array
console.log(rbp.length);

// Returns the index of the next random byte
console.log(rbp.currentIdx);

Utilities

These functions are used internally by Guid to safely verify and normalize strings before parsing. If you are dealing with inconsistent data, these functions may be helpful.

import * as util from '@bradkovach/guid/util';

// or

import { ensureByte, isValidVersion4GuidForBase, normalizeGuidString } from '@bradkovach/guid/util';

util.ensureByte(byte): void

Throws an error when byte is not a number between 0 and 255, inclusive. Can be used to stop execution of code.

util.isValidVersion4GuidForBase(guid, base): boolean

Normalizes and tests a guid string for validity in the provided base. Should work in all JS bases, but is tested in 2, 8, 10 and 16.

util.normalizeGuidString(guid): string

Normalizes a guid string by trimming, removing braces, removing hyphens and returning lowercase.

Acknowledgements

I used the following resources to learn everything there is to know about the RFC 4122 standard, and its implementation.

Contributing

Pull requests are welcome! Please ensure that new code includes test coverage.

# clone with http
https://github.com/bradkovach/guid.git

# clone with ssh
git clone [email protected]:bradkovach/guid.git

# open
cd guid

# restore packages
npm install

# run tests in watch mode
# probably the fastest way to develop
npm run test:watch

# check code coverage
npm run test:coverage

# build artifacts using bradkovach-guid-test package name
# this can be linked with `npm link` and used in another
# test project with `npm link bradkovach-guid-test`
npm run build-dev

# build artifacts using @bradkovach/guid package name
npm run build-prod

Motivation

  • Provide a proper TypeScript implementation of UUID/GUID generation using byte arrays.
  • Sharpen skills working with bits/bytes in TS/JS.
  • Build a high-performance COMB Guid implementation that I can use for logging.