refactor(api): tidy the api and shared packages (#2733)

This commit is contained in:
Hampus authored and GitHub committed 2026-09-13 17:37:48 +02:00
1 parent 580401d2dc
commit 5afbf67a70
333 files changed
+10180 -7910

No files matched your search

+19 -33
View File
@@ -28,12 +28,6 @@ export interface SnowflakeParts {
sequence: number;
}
interface SnowflakeBitParts {
relativeTimestamp: bigint;
workerId: bigint;
sequence: bigint;
}
interface ResolvedSnowflakeGeneratorOptions {
workerId: number;
now: () => number;
@@ -82,12 +76,16 @@ function assertValidSequence(sequence: number): bigint {
return sequenceBigInt;
}
function toRelativeTimestamp(timestamp: number | bigint): bigint {
const timestampBigInt = BigInt(timestamp);
const relativeTimestamp = timestampBigInt - FLUXER_EPOCH;
function assertValidRelativeTimestamp(relativeTimestamp: bigint): void {
if (relativeTimestamp < 0n) {
throw new Error('Timestamp must be on or after the Fluxer epoch');
}
}
function toRelativeTimestamp(timestamp: number | bigint): bigint {
const timestampBigInt = BigInt(timestamp);
const relativeTimestamp = timestampBigInt - FLUXER_EPOCH;
assertValidRelativeTimestamp(relativeTimestamp);
return relativeTimestamp;
}
@@ -95,14 +93,6 @@ function toEpochTimestamp(relativeTimestamp: bigint): bigint {
return relativeTimestamp + FLUXER_EPOCH;
}
function toSnowflakeBitParts(snowflake: bigint): SnowflakeBitParts {
return {
relativeTimestamp: snowflake >> TIMESTAMP_SHIFT,
workerId: (snowflake >> WORKER_ID_SHIFT) & MAX_WORKER_ID,
sequence: snowflake & MAX_SEQUENCE,
};
}
function createSnowflakeBigInt(relativeTimestamp: bigint, workerId: bigint, sequence: bigint): bigint {
return (relativeTimestamp << TIMESTAMP_SHIFT) | (workerId << WORKER_ID_SHIFT) | sequence;
}
@@ -128,16 +118,18 @@ export class SnowflakeGenerator {
if (timestamp < this.lastTimestamp) {
timestamp = this.lastTimestamp;
}
assertValidRelativeTimestamp(timestamp);
let sequence = 0n;
if (timestamp === this.lastTimestamp) {
this.sequence = (this.sequence + 1n) & MAX_SEQUENCE;
if (this.sequence === 0n) {
sequence = (this.sequence + 1n) & MAX_SEQUENCE;
if (sequence === 0n) {
timestamp = this.waitUntilNextTimestamp();
}
} else {
this.sequence = 0n;
}
const snowflake = createSnowflakeBigInt(timestamp, this.workerId, sequence);
this.sequence = sequence;
this.lastTimestamp = timestamp;
return createSnowflakeBigInt(timestamp, this.workerId, this.sequence);
return snowflake;
}
getWorkerId(): number {
@@ -189,16 +181,14 @@ export function createSnowflakeFromTimestamp(timestamp: number | bigint, workerI
}
export function snowflakeToDate(snowflake: bigint): Date {
const bitParts = toSnowflakeBitParts(snowflake);
return new Date(Number(toEpochTimestamp(bitParts.relativeTimestamp)));
return new Date(Number(toEpochTimestamp(snowflake >> TIMESTAMP_SHIFT)));
}
export function parseSnowflake(snowflake: bigint): SnowflakeParts {
const bitParts = toSnowflakeBitParts(snowflake);
return {
timestamp: new Date(Number(toEpochTimestamp(bitParts.relativeTimestamp))),
workerId: Number(bitParts.workerId),
sequence: Number(bitParts.sequence),
timestamp: snowflakeToDate(snowflake),
workerId: Number((snowflake >> WORKER_ID_SHIFT) & MAX_WORKER_ID),
sequence: Number(snowflake & MAX_SEQUENCE),
};
}
@@ -209,12 +199,8 @@ export function isValidSnowflake(value: unknown): value is bigint {
if (value < 0n) {
return false;
}
const bitParts = toSnowflakeBitParts(value);
const timestamp = toEpochTimestamp(bitParts.relativeTimestamp);
const timestamp = toEpochTimestamp(value >> TIMESTAMP_SHIFT);
const timestampNumber = Number(timestamp);
if (timestampNumber < Number(FLUXER_EPOCH)) {
return false;
}
if (timestampNumber > Date.now() + MAX_FUTURE_DRIFT_MS) {
return false;
}
+1 -1
View File
@@ -26,7 +26,7 @@ function createBucketRange(startBucket: number, endBucket: number): Array<number
export function makeBucket(snowflake: bigint | null): number {
const timestamp = getRelativeTimestampForBucket(snowflake);
return Math.floor(Number(timestamp / SNOWFLAKE_BUCKET_SIZE_MS));
return Number(timestamp / SNOWFLAKE_BUCKET_SIZE_MS);
}
export function makeBucketString(snowflake: string | null): number {
+4 -25
View File
@@ -41,11 +41,7 @@ function assertValidSequenceValue(sequence: number): void {
}
export function extractTimestamp(snowflake: string): number {
try {
return extractTimestampWithEpoch(BigInt(snowflake), FLUXER_EPOCH);
} catch (_error) {
return Number.NaN;
}
return extractTimestampFromSnowflake(snowflake);
}
export function extractTimestampBigInt(snowflake: bigint): number {
@@ -53,11 +49,7 @@ export function extractTimestampBigInt(snowflake: bigint): number {
}
export function fromTimestamp(timestamp: number): string {
const clampedTimestamp = toClampedTimestamp(timestamp);
if (clampedTimestamp === FLUXER_EPOCH_NUMBER) {
return '0';
}
return createSnowflake({timestamp: clampedTimestamp}).toString();
return fromTimestampBigInt(timestamp).toString();
}
export function fromTimestampBigInt(timestamp: number): bigint {
@@ -131,13 +123,7 @@ export function compareBigInt(snowflake1: bigint | null, snowflake2: bigint | nu
if (snowflake1 == null) {
return -1;
}
if (snowflake1 > snowflake2) {
return 1;
}
if (snowflake1 < snowflake2) {
return -1;
}
return 0;
return snowflake1 > snowflake2 ? 1 : -1;
}
export function isProbablyAValidSnowflake(value: string | null | undefined): boolean {
@@ -178,9 +164,6 @@ export function age(snowflake: string): number {
export function ageBigInt(snowflake: bigint): number {
const timestamp = extractTimestampBigInt(snowflake);
if (Number.isNaN(timestamp)) {
return 0;
}
return Date.now() - timestamp;
}
@@ -202,11 +185,7 @@ export function extractTimestampFromSnowflakeAsDate(snowflake: string, epoch?: s
}
export function extractTimestampFromSnowflakeAsDateBigInt(snowflake: bigint): Date {
const timestamp = extractTimestampBigInt(snowflake);
if (Number.isNaN(timestamp)) {
return new Date();
}
return new Date(timestamp);
return new Date(extractTimestampBigInt(snowflake));
}
export interface SnowflakeSequenceOptions {