Skip to content

Commit

Permalink
Add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Xander1233 committed Aug 12, 2021
1 parent 97ac53a commit def29fa
Showing 1 changed file with 51 additions and 2 deletions.
53 changes: 51 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
module.exports = class SnowflakeGenerator {
class SnowflakeGenerator {

/**
* SnowflakeGenerator constructor
* @param opts Options to configure the generator to the specific server id and process id
*/
constructor(opts = { epoch: 1609459201000n, worker: 1n, process: 1n, accumulator: 0n }) {
this.lastTimestamp = 0n;
Object.defineProperty(this, 'epoch', { value: opts.epoch, writable: false });
Expand All @@ -8,17 +12,38 @@ module.exports = class SnowflakeGenerator {
Object.defineProperty(this, 'accumulator', { value: opts.accumulator, writable: true });
}

/**
* Get a new generated snowflake as a string
* @return {string}
*/
get id() {
return this.generate().toString();
}

/**
* Generates a new id and returns it as a bigint (check "id" for strings)
* @return {bigint}
*/
generate() {
/**
* generate a new timestamp
* @type {bigint}
*/
let timestamp = this.generateTime();

/**
* check if the clock moved backwards. if this is true, a unique id can't be guaranteed => throw an error
*/
if (timestamp < this.lastTimestamp) {
throw new Error('Clock moved backwards!');
}

/**
* if the timestamp is equal to the last timestamp, check whether the id can be incremented (max value is
* 0xFFF (4069)) or not. If not, wait until the next millisecond timestamp and have a new unique timestamp
*
* otherwise, set accumulator to 0
*/
if (timestamp === this.lastTimestamp) {
this.accumulator = (this.accumulator + 1n) & 0xfffn;
if (this.accumulator === 0n) {
Expand All @@ -29,16 +54,34 @@ module.exports = class SnowflakeGenerator {

this.lastTimestamp = timestamp;

/**
* build the snowflake
*
* timestamp: bit 63 to bit 22 (42 bits)
* worker id: bit 21 to bit 17 (5 bits)
* process id: bit 16 to bit 12 (5 bits)
* accumulator/increment: bit 11 to 0 (12 bits)
*/
return (((timestamp - this.epoch) << 22n) |
(this.worker << 17n) |
(this.process << 12n) |
this.accumulator);
this.accumulator
);
}

/**
* returns the current UTC millisecond timestamp as bigint
* @return {bigint}
*/
generateTime() {
return BigInt(new Date(new Date().toUTCString()).getTime());
}

/**
* parser method for bigints. The number that should be parsed has to be of type number or bigint
* @param value {bigint|number}
* @return {bigint}
*/
parseBigInt(value) {
if (typeof value === 'bigint')
return value;
Expand All @@ -47,6 +90,10 @@ module.exports = class SnowflakeGenerator {
throw new Error('Value has to be of type number or bigint');
}

/**
* method to wait until the next millisecond timestamp. This method just waits for the next bigger timestamp
* @return {bigint}
*/
waitUntilNextMillisecond() {
let timestamp = this.generateTime();
while (timestamp <= this.lastTimestamp) {
Expand All @@ -55,3 +102,5 @@ module.exports = class SnowflakeGenerator {
return timestamp;
}
}

module.exports = { SnowflakeGenerator };

0 comments on commit def29fa

Please sign in to comment.