import { DeconstructedDiscordSnowflake } from '@src/utils/interfaces/DeconstructedSnowflake' ; import { DISCORD_EPOCH } from '@src/constants/common' ; import { DiscordooError } from '@src/utils/DiscordooError' ; const EPOCH = DISCORD_EPOCH ; let INCREMENT = 0 ; export class DiscordSnowflake { static generate ( timestamp = Date . now ( ) , workerId = 0 , processId = 0 , increment ? ) { if ( timestamp instanceof Date ) timestamp = timestamp . getTime ( ) ; if ( INCREMENT >= 4194302 ) INCREMENT = 0 ; if ( timestamp <= EPOCH ) { throw new DiscordooError ( 'DiscordSnowflake#generate' , 'Timestamp cannot be earlier than discord epoch (1420070400000).' ) ; } if ( increment && increment >= 4194302 ) { throw new DiscordooError ( 'DiscordSnowflake#generate' , 'Increment must be lower than 4194303.' ) ; } if ( workerId >= 0x1F ) { throw new DiscordooError ( 'DiscordSnowflake#generate' , 'Internal worker id must be lower than 31.' ) ; } if ( processId >= 0x1F ) { throw new DiscordooError ( 'DiscordSnowflake#generate' , 'Internal process id must be lower than 31.' ) ; } const b = BigInt ; const segments = [ b ( timestamp - EPOCH ) << b ( 22 ) , b ( workerId ) << b ( 17 ) , b ( processId ) << b ( 12 ) , b ( increment ?? INCREMENT ++ ) ] ; return segments . reduce ( ( prev , curr ) => prev + curr , b ( 0 ) ) . toString ( ) ; } static generatePartial ( timestamp = Date . now ( ) ) { if ( timestamp instanceof Date ) timestamp = timestamp . getTime ( ) ; const b = BigInt ; return ( b ( timestamp - EPOCH ) << b ( 22 ) ) . toString ( ) ; } static deconstruct ( snowflake ) { const b = BigInt , n = Number , bigSnowflake = b ( snowflake ) ; return { timestamp : n ( ( bigSnowflake >> b ( 22 ) ) + b ( EPOCH ) ) , workerId : n ( ( bigSnowflake & b ( 0x3E0000 ) ) >> b ( 17 ) ) , processId : n ( ( bigSnowflake & b ( 0x1F000 ) ) >> b ( 12 ) ) , increment : n ( bigSnowflake & b ( 0xFFF ) ) , get date ( ) { return new Date ( this . timestamp ) ; } } ; } }