Source

lib/snowflake.ts

import { hexToDec } from "./hex2dec";

/**
 * Helper class for snowflake generation
 */
class FlakeId {
    seq: number;
    mid: number;
    iid: number;
    timeOffset: number;
    lastTime: number;
    time: number;

    /**
     * creates new snowflake object
     * @param {any} options
     */
    constructor(options: any) {
        options = options || {};
        this.seq = options.seq || 0;
        this.mid = (options.mid || 1) % 511;
        this.iid = (options.miid || 1) % 511;
        this.timeOffset = options.timeOffset || 0;
        this.lastTime = options.lastTime || 0;
        this.time = options.time || Date.now();
    }

    /**
     * Generates snowflake
     * @return {number}
     */
    gen() {
        const time = this.time;
        const bTime = (time - this.timeOffset).toString(2);

        // get the sequence number
        if(this.lastTime == time) {
            this.seq++;

            if(this.seq > 4095) {
                this.seq = 0;

                // make system wait till time is been shifted by one millisecond
                while(Date.now() <= time) { }
            }
        } else {
            this.seq = 0;
        }

        this.lastTime = time;

        let bSeq = this.seq.toString(2);
        let bMid = this.mid.toString(2);
        let bIid = this.iid.toString(2);

        // create sequence binary bit
        bSeq = bSeq.padStart(12, "0");

        bMid = bMid.padStart(5, "0");
        bIid = bIid.padStart(5, "0");

        const bid = bTime + bMid + bIid + bSeq;
        let id = "";

        for(let i = bid.length; i > 0; i -= 4) {
            id = parseInt(bid.substring(i - 4, i), 2).toString(16) + id;
        }

        return hexToDec(id)!;
    }
}

export default FlakeId;