tiny-ulid
Version:
Make and decode ULIDs.
114 lines (113 loc) • 5.16 kB
TypeScript
import type { Brand, LaxPartial } from "@samual/types";
/** A 16-byte {@linkcode ArrayBuffer}. */
export type UlidBuffer = Brand<ArrayBuffer, {
readonly UlidBuffer: unique symbol;
}[`UlidBuffer`]>;
/** A valid [ULID](https://github.com/ulid/spec#readme) string. */
export type Ulid = Brand<string, {
readonly Ulid: unique symbol;
}[`Ulid`]>;
/** Check if the given {@linkcode ArrayBuffer}'s length is 16, if so narrow it to a {@linkcode UlidBuffer}. */
export declare const isUlidBuffer: (arrayBuffer: ArrayBuffer) => arrayBuffer is UlidBuffer;
/** If the {@linkcode ArrayBuffer} has a length of 16, it'll be returned as a {@linkcode UlidBuffer}, otherwise throws. */
export declare const toUlidBuffer: (arrayBuffer: ArrayBuffer) => UlidBuffer;
/** Check if the given string is a valid [ULID](https://github.com/ulid/spec#readme), if so narrow it to a {@linkcode Ulid}. */
export declare const isUlid: (string: string) => string is Ulid;
/** If the string is a valid [ULID](https://github.com/ulid/spec#readme), it'll be returned as a `Ulid`, otherwise throws. */
export declare const toUlid: (string: string) => Ulid;
/**
* Make an empty 16-byte {@linkcode ArrayBuffer} that's narrowed to a {@linkcode UlidBuffer}.
*
* This can be useful if you don't want to use {@linkcode makeUlid()} or {@linkcode makeUlidBuffer()} to for example use
* a custom random function.
* @example
* ```js
* const ulidBuffer = makeEmptyUlidBuffer()
*
* setUlidBufferTime(ulidBuffer, 1469922850259)
*
* const bytes = new Uint8Array(ulidBuffer)
*
* for (let index = 6; index < 16; index++)
* bytes[index] = customRandomByteFunction()
* ```
*/
export declare const makeEmptyUlidBuffer: () => UlidBuffer;
/**
* Set or update the time of a {@linkcode UlidBuffer}.
* @example
* ```js
* // Set to a specific time
* setUlidBufferTime(ulidBuffer, 1469922850259)
*
* // Set to the current time
* setUlidBufferTime(ulidBuffer)
* ```
*/
export declare const setUlidBufferTime: (buffer: UlidBuffer, time?: number) => void;
/**
* Retrieve the time from a {@linkcode UlidBuffer}.
* @example
* ```js
* const ulid = toUlid(`01ARZ3NDEKTSV4RRFFQ69G5FAV`)
* const ulidBuffer = decodeUlid(ulid)
* const time = getUlidBufferTime(ulidBuffer)
* const date = new Date(time)
*
* console.log(date.toLocaleString()) // "31/07/2016, 00:54:10"
* ```
*/
export declare const getUlidBufferTime: (buffer: UlidBuffer) => number;
/**
* Make a {@linkcode UlidBuffer}.
*
* This can be useful if you need it as an `ArrayBuffer` first, you can then stringify after.
* @example
* ```js
* const ulidBuffer = makeUlidBuffer()
*
* database.user.create({ id: new Uint8Array(ulidBuffer), … })
*
* console.log(`Created user with id ${makeUlid({ buffer: ulidBuffer })}`)
* ```
*/
export declare const makeUlidBuffer: ({ ulidBuffer, time }?: LaxPartial<{
/** Reuse a previously used {@linkcode UlidBuffer}. Will be completely overwritten. @default makeEmptyUlidBuffer() */
ulidBuffer: UlidBuffer;
/** The time in milliseconds that'll be written into the buffer. @default Date.now() */ time: number;
}>) => UlidBuffer;
/** Make a [ULID](https://github.com/ulid/spec#readme) string that's narrowed to a {@linkcode Ulid}. */
export declare const makeUlid: ({ time, ulidBuffer }?: LaxPartial<{
/** The {@linkcode UlidBuffer} to turn into a {@linkcode Ulid}. @default makeUlidBuffer() */ ulidBuffer: UlidBuffer;
/**
* The time in milliseconds used when creating the default {@linkcode UlidBuffer} if you didn't pass in your own.
*
* This will have no affect if you passed in your own {@linkcode UlidBuffer}.
* @default Date.now()
*/
time: number;
}>) => Ulid;
/** Turn a {@linkcode Ulid} back into an {@linkcode UlidBuffer}. */
export declare const decodeUlid: (ulid: Ulid) => UlidBuffer;
/** Increment the random part of the given {@linkcode UlidBuffer} by 1. */
export declare const incrementUlidBuffer: (ulidBuffer: UlidBuffer, { throwOnOverflow }?: LaxPartial<{
throwOnOverflow: boolean;
}>) => void;
/** Clone a {@linkcode UlidBuffer}. */
export declare const cloneUlidBuffer: (ulidBuffer: UlidBuffer) => UlidBuffer;
/**
* Make a monotonically incrementing {@linkcode UlidBuffer} generation function. This means if you generate 2
* `UlidBuffer`s using the returned function within the same millisecond, the next one'll simply be an incremented
* version of the previous one.
* @throws If you try to generate another `UlidBuffer` and the previous's random section bytes is all `0xFF`.
* This is mitigated with `mitigateOverflow` which is on by default.
*/
export declare const makeMonotonicallyIncrementingUlidBufferFunction: ({ mitigateOverflow }?: LaxPartial<{
/**
* Mitigate the chance of overflow by setting the most significant bit to `0` after generating a new {UlidBuffer}
* (not when incrementing the previously generated `UlidBuffer`). This should in theory guarantee that you have at
* least 604 sextillion increments before you hit the overflow which I imagine is incredibly hard, especially in
* JavaScript.
*/
mitigateOverflow: boolean;
}>) => () => UlidBuffer;