pika-id
Version:
The pragmatic ID system
91 lines (88 loc) • 3.11 kB
TypeScript
declare type EpochResolvable = number | bigint | Date;
interface DeconstructedSnowflake {
id: bigint;
timestamp: bigint;
nodeId: number;
seq: number;
epoch: bigint;
}
interface PikaPrefixDefinition<P extends string> {
prefix: P;
description?: string;
secure?: boolean;
metadata?: Record<string, unknown>;
}
interface DecodedPika<P extends string> extends Omit<DeconstructedSnowflake, 'id'> {
prefix: P;
/**
* The tail after the prefix, which is base64 encoding of the snowflake.
*
* However, if the pika is cryptographically secure, then the base64 decoded string value will start with an `s_` prefix,
* followed by a cryptographically random string, then followed by another underscore and the Snowflake ID.
*/
tail: string;
/**
* The snowfake that was generated for this ID
*/
snowflake: bigint;
/**
* The ID this Pika was generated from.
*/
nodeId: number;
/**
* A rolling number between 1 to 4096 to introduce entropy.
* Allows for doing 4096 ids per ms per node.
*/
seq: number;
/**
* The version of the pika encoding.
*/
version: 1;
/**
* The definition for this prefix
*/
prefixRecord: PikaPrefixDefinition<P>;
/**
* @deprecated use `.prefixRecord` instead
*/
prefix_record: PikaPrefixDefinition<P>;
}
interface PikaInitializationOptions {
epoch?: EpochResolvable;
nodeId?: number;
suppressPrefixWarnings?: boolean;
disableLowercase?: boolean;
}
declare type PrefixInit<V extends string> = V | PikaPrefixDefinition<V>;
declare type LowercasePrefixInit<V extends string> = Lowercase<V> extends V ? PrefixInit<V> : PrefixInit<Lowercase<V>>;
declare class Pika<Prefixes extends string> {
#private;
readonly prefixes: Record<string, PikaPrefixDefinition<Prefixes>>;
/**
* @param prefixes a list of PikaPrefixRecords to initialize pika with
* @param opts misc. options to initialize pika with
*/
constructor(prefixes: readonly LowercasePrefixInit<Prefixes>[], { nodeId, ...opts }?: PikaInitializationOptions);
/**
* Validates something that might be an ID is valid with our prefix set
* @param maybeId the ID to validate
* @param expectPrefix the prefix to expect
* @returns
*/
validate<T extends Prefixes = Prefixes>(maybeId: string, expectPrefix?: T): maybeId is `${T}_${string}`;
gen<Prefix extends Prefixes>(prefix: Prefix): `${Prefix}_${string}`;
/**
* Gen a Snowflake, if you really need one
*/
genSnowflake(): string;
decode(id: string): DecodedPika<Prefixes>;
/**
* Derives this machine's node ID from the MAC address of the first
* public network interface it finds
* @returns The computed node ID (0-1023)
*/
private computeNodeId;
}
declare type InferPrefixes<T extends Pika<any>> = T extends Pika<infer P> ? P : never;
declare type InferIds<T extends Pika<any>> = T extends Pika<infer P> ? `${P}_${string}` : never;
export { InferIds, InferPrefixes, Pika, Pika as default };