mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 21:15:32 +09:00
refactor(api): tidy the api and shared packages (#2733)
This commit is contained in:
1 parent
580401d2dc
commit
5afbf67a70
333 files changed
+10180
-7910
No files matched your search
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in new issue
Block a user