class Snowflake {
private twepoch;
private workerIdBits;
private dataCenterIdBits;
private maxWrokerId;
private maxDataCenterId;
private sequenceBits;
private workerIdShift;
private dataCenterIdShift;
private timestampLeftShift;
private sequenceMask;
private lastTimestamp;
private workerId;
private dataCenterId;
private sequence;
constructor(_workerId: any, _dataCenterId: any, _sequence: any) {
this.twepoch = 1288834974657n;
this.workerIdBits = 5n;
this.dataCenterIdBits = 5n;
this.maxWrokerId = -1n ^ (-1n << this.workerIdBits);
this.maxDataCenterId = -1n ^ (-1n << this.dataCenterIdBits);
this.sequenceBits = 12n;
this.workerIdShift = this.sequenceBits;
this.dataCenterIdShift = this.sequenceBits + this.workerIdBits;
this.timestampLeftShift =
this.sequenceBits + this.workerIdBits + this.dataCenterIdBits;
this.sequenceMask = -1n ^ (-1n << this.sequenceBits);
this.lastTimestamp = -1n;
this.workerId = 1n;
this.dataCenterId = 1n;
this.sequence = 0n;
if (this.workerId > this.maxWrokerId || this.workerId < 0) {
throw new Error(
`_workerId must max than 0 and small than maxWrokerId-[${this.maxWrokerId}]`
);
}
if (this.dataCenterId > this.maxDataCenterId || this.dataCenterId < 0) {
throw new Error(
`_dataCenterId must max than 0 and small than maxDataCenterId-[${this.maxDataCenterId}]`
);
}
this.workerId = BigInt(_workerId);
this.dataCenterId = BigInt(_dataCenterId);
this.sequence = BigInt(_sequence);
}
tilNextMillis(lastTimestamp: any) {
let timestamp = this.timeGen();
while (timestamp <= lastTimestamp) {
timestamp = this.timeGen();
}
return BigInt(timestamp);
}
timeGen() {
return BigInt(Date.now());
}
nextId() {
let timestamp = this.timeGen();
if (timestamp < this.lastTimestamp) {
throw new Error(
`Clock moved backwards. Refusing to generate id for ${
this.lastTimestamp - timestamp
}`
);
}
if (this.lastTimestamp === timestamp) {
this.sequence = (this.sequence + 1n) & this.sequenceMask;
if (this.sequence === 0n) {
timestamp = this.tilNextMillis(this.lastTimestamp);
}
} else {
this.sequence = 0n;
}
this.lastTimestamp = timestamp;
return (
((timestamp - this.twepoch) << this.timestampLeftShift) |
(this.dataCenterId << this.dataCenterIdShift) |
(this.workerId << this.workerIdShift) |
this.sequence
);
}
}
export { Snowflake };
import { Snowflake } from "../hooks/snowflake";
const snowflake = new Snowflake(1n, 1n, 0n);
const id = snowflake.nextId().toString();