moonlifedb
Version:
A JSON database with a bunch of tools and typescript support.
121 lines (120 loc) • 4.16 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Snowflake = void 0;
class Snowflake {
worker;
epoch;
seq;
lastTime;
/**
* Class constructor of an ID generator, based on Twitter Snowflake.
* @example const Generator = new Snowflake({ worker: 0, epoch: 1640995200000 })
* @param {(number|undefined)} worker worker ID in number or bigint (Converts to bigint). By default it's 0
* @param {(number|undefined)} epoch epoch ofset where to start generating. Requires milliseconds.
*/
constructor(settings) {
this.worker = settings.worker != undefined ? settings.worker : 0; // starts from 0
this.epoch = settings.epoch != undefined ? settings.epoch : 0;
this.seq = 0;
this.lastTime = 0;
if (this.worker < 0) {
const integerError = "worker must be greater or equal to 0.";
throw new Error(integerError);
}
if (this.epoch < 0) {
const epochError = "epoch must be greater or equal to 0.";
throw new Error(epochError);
}
}
/**
* Generate a 63 bits long unique ID.
* @example const ID = Snowflake.generate();
* @returns {snowflake} snowflake
*/
generate() {
var time = BigInt(Date.now()), t = (time - BigInt(this.epoch)).toString(2);
if (this.lastTime == time) {
this.seq++;
if (this.seq > 4095) {
this.seq = 0;
while (Date.now() <= time) { }
}
}
else
this.seq = 0;
this.lastTime = time;
let s = this.seq.toString(2), w = this.worker.toString(2);
while (t.length < 41)
t = "0" + t;
while (w.length < 10)
w = "0" + w;
while (s.length < 12)
s = "0" + s;
const sid = t + w + s;
let id = "";
for (let i = sid.length; i > 0; i -= 4)
id = parseInt(sid.substring(i - 4, i), 2).toString(16) + id;
let res = BigInt("0x" + id);
return String(res);
}
/**
* Generate a 63 bits long unique ID.
* @example const ID = Snowflake.generateRaw();
* @returns {object} snowflake
*/
generateRaw() {
var time = BigInt(Date.now()), t = (time - BigInt(this.epoch)).toString(2);
if (this.lastTime == time) {
this.seq++;
if (this.seq > 4095) {
this.seq = 0;
while (Date.now() <= time) { }
}
}
else
this.seq = 0;
this.lastTime = time;
let s = this.seq.toString(2), w = this.worker.toString(2);
while (t.length < 41)
t = "0" + t;
while (w.length < 10)
w = "0" + w;
while (s.length < 12)
s = "0" + s;
const sid = t + w + s;
let id = "";
for (let i = sid.length; i > 0; i -= 4)
id = parseInt(sid.substring(i - 4, i), 2).toString(16) + id;
let res = BigInt("0x" + id);
var object = {};
object['result'] = String(res);
object['raw'] = {
result: sid,
epoch: parseInt(t, 2),
epochBinary: t,
sequence: parseInt(s, 2),
sequenceBinary: s,
worker: parseInt(w, 2),
workerBinary: w
};
return object;
}
/**
* Decode a 63 bits long unique ID into an object.
* @example const ID = Snowflake.decode(snowflake);
*
* @param snowflake string
* @returns {object} snowflake
*/
decode(snowflake) {
const sf = BigInt(snowflake).toString(2).padStart(63, '0');
const be = sf.substring(0, 41);
const bw = sf.substring(41, 51);
const bs = sf.substring(51, 63);
const epoch = BigInt(parseInt(be, 2));
const worker = parseInt(bw, 2);
const sequence = parseInt(bs, 2);
return { epoch, worker, sequence };
}
}
exports.Snowflake = Snowflake;