@storm-stack/unique-identifier
Version:
This package provides a simple way to generate various types of unique identifiers.
48 lines (47 loc) • 1.51 kB
JavaScript
export const DEFAULT_SHARD_ID = 1;
export const DEFAULT_EPOCH = Date.UTC(1970, 0, 1).valueOf();
let sequence = 1;
function ToBinaryString(snowflake2) {
const cached64BitZeros = "0000000000000000000000000000000000000000000000000000000000000000";
const binValue = BigInt(snowflake2).toString(2);
return binValue.length < 64 ? cached64BitZeros.slice(0, Math.max(0, 64 - binValue.length)) + binValue : binValue;
}
function extractBits(snowflake2, start, length) {
return Number.parseInt(
length ? ToBinaryString(snowflake2).slice(start, start + length) : ToBinaryString(snowflake2).slice(Math.max(0, start)),
2
);
}
export function snowflake({
shardId,
epoch,
timestamp
}) {
let result = BigInt(
timestamp ? timestamp instanceof Date ? timestamp.valueOf() : new Date(timestamp).valueOf() : Date.now()
) - BigInt(epoch ?? DEFAULT_EPOCH) << BigInt(22);
result |= BigInt((shardId ?? DEFAULT_SHARD_ID) % 1024) << BigInt(12);
result |= BigInt(sequence++ % 4096);
return result.toString();
}
export function deconstructSnowflake(snowflake2) {
const binary = ToBinaryString(snowflake2);
return {
snowflake: snowflake2,
timestamp: extractBits(snowflake2, 1, 41),
shard_id: extractBits(snowflake2, 42, 10),
sequence: extractBits(snowflake2, 52),
binary
};
}
export function isValidSnowflake(snowflake2) {
if (!/^\d{19}$/.test(snowflake2)) {
return false;
}
try {
deconstructSnowflake(snowflake2);
return true;
} catch {
return false;
}
}