UNPKG

distid

Version:

Distributed ID generator for large-scale systems

72 lines (71 loc) 2.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DistIdGenerator = void 0; const utils_1 = require("./utils"); const logger_1 = require("./logger"); class DistIdGenerator { constructor(config) { this.counter = 0; this.lastTimestamp = 0; (0, utils_1.validateNodeId)(config.nodeId, DistIdGenerator.usedNodeIds); this.nodeId = config.nodeId & 0x3ff; // 10 bit DistIdGenerator.usedNodeIds.add(this.nodeId); this.epoch = config.epoch || new Date('2020-01-01').getTime(); this.counterBits = config.counterBits || 12; if (this.counterBits < 8 || this.counterBits > 20) { throw new Error('Counter bits must be between 8 and 20'); } this.logger = config.logger || logger_1.defaultLogger; this.logger(`Initialized DistIdGenerator with nodeId: ${this.nodeId}`); } getTimestamp() { return Date.now() - this.epoch; } incrementCounter(timestamp) { if (timestamp !== this.lastTimestamp) { this.counter = 0; this.lastTimestamp = timestamp; } const maxCounter = (1 << this.counterBits) - 1; if (this.counter > maxCounter) { this.logger('Counter overflow, waiting for next millisecond'); while (this.getTimestamp() === this.lastTimestamp) { // Wait for the next millisecond } return this.incrementCounter(this.getTimestamp()); } return this.counter++; } /** * Generates a distributed ID for large-scale systems. * @param format - The output format of the ID ('number', 'hex', 'base36', 'base62'). * @returns A unique ID in the specified format. * @example * const gen = new DistIdGenerator({ nodeId: 5 }); * console.log(gen.generate('hex')); // e.g., "13a8f5c00050007b" */ generate(format = 'number') { const timestamp = this.getTimestamp(); const counter = this.incrementCounter(timestamp); const id = (BigInt(timestamp) << BigInt(23)) | (BigInt(this.nodeId) << BigInt(this.counterBits)) | BigInt(counter); this.logger(`Generated ID: ${id} (format: ${format})`); switch (format) { case 'hex': return id.toString(16).padStart(16, '0'); case 'base36': return id.toString(36); case 'base62': return (0, utils_1.toBase62)(id); case 'number': default: return id; } } static resetNodeIds() { DistIdGenerator.usedNodeIds.clear(); } } exports.DistIdGenerator = DistIdGenerator; DistIdGenerator.usedNodeIds = new Set();