@andrew_l/snowflake 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +75 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -1
- package/dist/index.d.mts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.mjs +76 -52
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -5,6 +5,7 @@ const toolkit = require('@andrew_l/toolkit');
|
|
|
5
5
|
var MAX_WORKER_ID = 31;
|
|
6
6
|
var MAX_PROCESS_ID = 31;
|
|
7
7
|
var MAX_INCREMENT = 4095;
|
|
8
|
+
var ENCODE_BIGINT_BUFFER = new Uint8Array(8);
|
|
8
9
|
class Snowflake {
|
|
9
10
|
/**
|
|
10
11
|
* Alias for {@link deconstruct}
|
|
@@ -33,7 +34,12 @@ class Snowflake {
|
|
|
33
34
|
/**
|
|
34
35
|
* @internal
|
|
35
36
|
*/
|
|
36
|
-
|
|
37
|
+
_timestamp = 0;
|
|
38
|
+
__buf;
|
|
39
|
+
_packBuffer;
|
|
40
|
+
_packBigInt;
|
|
41
|
+
_unpackBuffer;
|
|
42
|
+
_unpackBigInt;
|
|
37
43
|
/**
|
|
38
44
|
* @param epoch the epoch to use
|
|
39
45
|
*/
|
|
@@ -49,7 +55,32 @@ class Snowflake {
|
|
|
49
55
|
this.processId = processId;
|
|
50
56
|
this.increment = increment;
|
|
51
57
|
}
|
|
52
|
-
|
|
58
|
+
const packer = toolkit.bitPack({
|
|
59
|
+
totalBits: 64,
|
|
60
|
+
fields: [
|
|
61
|
+
{ name: "_timestamp", bits: 42, take: "low" },
|
|
62
|
+
{ name: "_workerId", bits: 5, take: "low" },
|
|
63
|
+
{ name: "_processId", bits: 5, take: "low" },
|
|
64
|
+
{ name: "_increment", bits: 12, take: "low" }
|
|
65
|
+
],
|
|
66
|
+
optimize: true,
|
|
67
|
+
debug: true
|
|
68
|
+
});
|
|
69
|
+
const unpacker = toolkit.bitUnpack({
|
|
70
|
+
totalBits: 64,
|
|
71
|
+
fields: [
|
|
72
|
+
{ name: "timestamp", bits: 42, take: "low" },
|
|
73
|
+
{ name: "workerId", bits: 5, take: "low" },
|
|
74
|
+
{ name: "processId", bits: 5, take: "low" },
|
|
75
|
+
{ name: "increment", bits: 12, take: "low" }
|
|
76
|
+
],
|
|
77
|
+
debug: true
|
|
78
|
+
});
|
|
79
|
+
this.__buf = new Uint8Array(8);
|
|
80
|
+
this._packBigInt = packer.bigint;
|
|
81
|
+
this._packBuffer = packer.buffer;
|
|
82
|
+
this._unpackBigInt = unpacker.bigint;
|
|
83
|
+
this._unpackBuffer = unpacker.buffer;
|
|
53
84
|
}
|
|
54
85
|
/**
|
|
55
86
|
* The epoch for this snowflake, as a number
|
|
@@ -166,9 +197,10 @@ class Snowflake {
|
|
|
166
197
|
`"timestamp" argument must be a number or Date (received ${typeof timestamp})`
|
|
167
198
|
);
|
|
168
199
|
}
|
|
169
|
-
|
|
200
|
+
this._timestamp = timestamp - this._epoch;
|
|
201
|
+
var res = this._packBigInt(this);
|
|
170
202
|
this._increment = this._increment + 1 & MAX_INCREMENT;
|
|
171
|
-
return
|
|
203
|
+
return res;
|
|
172
204
|
}
|
|
173
205
|
/**
|
|
174
206
|
* Generates a Snowflake ID as a `Uint8Array` buffer.
|
|
@@ -187,23 +219,10 @@ class Snowflake {
|
|
|
187
219
|
`"timestamp" argument must be a number or Date (received ${typeof timestamp})`
|
|
188
220
|
);
|
|
189
221
|
}
|
|
190
|
-
|
|
222
|
+
this._timestamp = timestamp - this._epoch;
|
|
223
|
+
this._packBuffer(this);
|
|
191
224
|
this._increment = this._increment + 1 & MAX_INCREMENT;
|
|
192
|
-
|
|
193
|
-
var timestampHigh = Math.floor(timestampDelta / 4294967295);
|
|
194
|
-
var timestampLow = timestampDelta >>> 0;
|
|
195
|
-
var high32 = (timestampHigh << 22 | timestampLow >>> 10) >>> 0;
|
|
196
|
-
var low32 = (timestampLow << 22 | this._workerId << 17 | this._processId << 12 | increment & MAX_INCREMENT) >>> 0;
|
|
197
|
-
var buffer = this._buffer;
|
|
198
|
-
buffer[0] = high32 >>> 24;
|
|
199
|
-
buffer[1] = high32 >>> 16;
|
|
200
|
-
buffer[2] = high32 >>> 8;
|
|
201
|
-
buffer[3] = high32;
|
|
202
|
-
buffer[4] = low32 >>> 24;
|
|
203
|
-
buffer[5] = low32 >>> 16;
|
|
204
|
-
buffer[6] = low32 >>> 8;
|
|
205
|
-
buffer[7] = low32;
|
|
206
|
-
return buffer;
|
|
225
|
+
return this.__buf;
|
|
207
226
|
}
|
|
208
227
|
/**
|
|
209
228
|
* Generates a snowflake given an epoch and optionally a timestamp
|
|
@@ -215,8 +234,17 @@ class Snowflake {
|
|
|
215
234
|
* @returns A unique snowflake as Uint8Array
|
|
216
235
|
*/
|
|
217
236
|
generateBuffer(timestamp = Date.now()) {
|
|
218
|
-
|
|
219
|
-
|
|
237
|
+
if (timestamp instanceof Date) timestamp = timestamp.getTime();
|
|
238
|
+
if (!toolkit.isNumber(timestamp)) {
|
|
239
|
+
throw new Error(
|
|
240
|
+
`"timestamp" argument must be a number or Date (received ${typeof timestamp})`
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
this.__buf = new Uint8Array(8);
|
|
244
|
+
this._timestamp = timestamp - this._epoch;
|
|
245
|
+
this._packBuffer(this);
|
|
246
|
+
this._increment = this._increment + 1 & MAX_INCREMENT;
|
|
247
|
+
return this.__buf;
|
|
220
248
|
}
|
|
221
249
|
/**
|
|
222
250
|
* Deconstructs a snowflake given a snowflake ID
|
|
@@ -229,23 +257,20 @@ class Snowflake {
|
|
|
229
257
|
* ```
|
|
230
258
|
*/
|
|
231
259
|
deconstruct(id) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
260
|
+
if (toolkit.isString(id)) {
|
|
261
|
+
id = BigInt(id);
|
|
262
|
+
}
|
|
263
|
+
let result;
|
|
264
|
+
if (toolkit.isBigInt(id)) {
|
|
265
|
+
result = this._unpackBigInt(id);
|
|
266
|
+
result.id = id;
|
|
238
267
|
} else {
|
|
239
|
-
|
|
268
|
+
result = this._unpackBuffer(id);
|
|
269
|
+
result.id = toolkit.bigIntFromBytes(id);
|
|
240
270
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
workerId: low32 >>> 17 & MAX_WORKER_ID,
|
|
245
|
-
processId: low32 >>> 12 & MAX_PROCESS_ID,
|
|
246
|
-
increment: low32 & MAX_INCREMENT,
|
|
247
|
-
epoch: this._epoch
|
|
248
|
-
};
|
|
271
|
+
result.timestamp += this._epoch;
|
|
272
|
+
result.epoch = this._epoch;
|
|
273
|
+
return result;
|
|
249
274
|
}
|
|
250
275
|
/**
|
|
251
276
|
* Retrieves the timestamp field's value from a snowflake.
|
|
@@ -253,12 +278,7 @@ class Snowflake {
|
|
|
253
278
|
* @returns The UNIX timestamp that is stored in `id`.
|
|
254
279
|
*/
|
|
255
280
|
timestampFrom(id) {
|
|
256
|
-
|
|
257
|
-
return this.timestampFrom(Snowflake.bufferFrom(id));
|
|
258
|
-
}
|
|
259
|
-
var high32 = (id[0] << 24 | id[1] << 16 | id[2] << 8 | id[3]) >>> 0;
|
|
260
|
-
var low32 = (id[4] << 24 | id[5] << 16 | id[6] << 8 | id[7]) >>> 0;
|
|
261
|
-
return high32 * 1024 + (low32 >>> 22) + this._epoch;
|
|
281
|
+
return this.deconstruct(id).timestamp;
|
|
262
282
|
}
|
|
263
283
|
/**
|
|
264
284
|
* Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given
|
|
@@ -285,15 +305,19 @@ class Snowflake {
|
|
|
285
305
|
*/
|
|
286
306
|
static bufferFrom(value) {
|
|
287
307
|
if (toolkit.isString(value)) value = BigInt(value);
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
308
|
+
return new Uint8Array(bigintToBuffer(value));
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
function bigintToBuffer(value) {
|
|
312
|
+
if (value < 0n) {
|
|
313
|
+
value = value * -1n;
|
|
314
|
+
}
|
|
315
|
+
for (var i = 0; i < 8; i++) {
|
|
316
|
+
ENCODE_BIGINT_BUFFER[i] = Number(
|
|
317
|
+
value >> BigInt((8 - i - 1) * 8) & 0xffn
|
|
318
|
+
);
|
|
296
319
|
}
|
|
320
|
+
return ENCODE_BIGINT_BUFFER;
|
|
297
321
|
}
|
|
298
322
|
|
|
299
323
|
exports.MAX_INCREMENT = MAX_INCREMENT;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/Snowflake.ts"],"sourcesContent":["/**\n * Based on: https://github.com/sapphiredev/utilities/blob/main/packages/snowflake/src/lib/Snowflake.ts\n */\nimport {\n type AnyFunction,\n assert,\n bigIntBytes,\n bigIntFromBytes,\n isBigInt,\n isDate,\n isNumber,\n isString,\n timestampMs,\n} from '@andrew_l/toolkit';\n\n/**\n * Object returned by Snowflake#deconstruct\n */\nexport interface DeconstructedSnowflake {\n /**\n * The id as a number\n */\n id: bigint;\n\n /**\n * The timestamp stored in the snowflake\n */\n timestamp: number;\n\n /**\n * The worker id stored in the snowflake\n */\n workerId: number;\n\n /**\n * The process id stored in the snowflake\n */\n processId: number;\n\n /**\n * The increment stored in the snowflake\n */\n increment: number;\n\n /**\n * The epoch to use in the snowflake\n */\n epoch: number;\n}\n\n/**\n * Options for Snowflake\n */\nexport interface SnowflakeOptions {\n /**\n * Timestamp or date of the snowflake to generate\n */\n epoch: number | bigint | Date;\n\n /**\n * The increment to use\n * @default 0\n * @remark keep in mind that this number is auto-incremented between generate calls\n */\n increment?: number | bigint;\n\n /**\n * The worker ID to use, will be truncated to 5 bits (0-31)\n * @default 0\n */\n workerId?: number | bigint;\n\n /**\n * The process ID to use, will be truncated to 5 bits (0-31)\n * @default 1\n */\n processId?: number | bigint;\n}\n\n/**\n * The maximum value the `workerId` field accepts in snowflakes.\n */\nexport var MAX_WORKER_ID = 0x1f;\n\n/**\n * The maximum value the `processId` field accepts in snowflakes.\n */\nexport var MAX_PROCESS_ID = 0x1f;\n\n/**\n * The maximum value the `increment` field accepts in snowflakes.\n */\nexport var MAX_INCREMENT = 0xfff;\n\n/**\n * A class for generating and deconstructing Twitter snowflakes.\n *\n * A {@link https://developer.twitter.com/en/docs/twitter-ids Twitter snowflake}\n * is a 64-bit unsigned integer with 4 fields that have a fixed epoch value.\n *\n * If we have a snowflake `266241948824764416` we can represent it as binary:\n * ```\n * 64 22 17 12 0\n * 000000111011000111100001101001000101000000 00001 00000 000000000000\n * number of ms since epoch worker pid increment\n * ```\n *\n * @group Main\n */\nexport class Snowflake {\n /**\n * Alias for {@link deconstruct}\n */\n public decode = this.deconstruct;\n\n /**\n * Internal reference of the epoch passed in the constructor\n * @internal\n */\n private readonly _epoch: number;\n\n /**\n * Internal incrementor for generating snowflakes\n * @internal\n */\n private _increment = 0;\n\n /**\n * The process ID that will be used by default in the generate method\n * @internal\n */\n private _processId = 1;\n\n /**\n * The worker ID that will be used by default in the generate method\n * @internal\n */\n private _workerId = 0;\n\n /**\n * @internal\n */\n private _buffer: Uint8Array;\n\n /**\n * @param epoch the epoch to use\n */\n public constructor(opts: SnowflakeOptions | Date | number | bigint) {\n if (isDate(opts) || isNumber(opts)) {\n this._epoch = timestampMs(opts);\n } else if (isBigInt(opts)) {\n this._epoch = timestampMs(Number(opts));\n } else {\n const { increment = 0, processId = 1, workerId = 0, epoch } = opts;\n this._epoch = timestampMs(isBigInt(epoch) ? Number(epoch) : epoch);\n this.workerId = workerId;\n this.processId = processId;\n this.increment = increment;\n }\n\n this._buffer = new Uint8Array(8);\n }\n\n /**\n * The epoch for this snowflake, as a number\n */\n public get epoch(): number {\n return this._epoch;\n }\n\n /**\n * Gets the configured process ID\n */\n public get processId(): number {\n return this._processId;\n }\n\n /**\n * Sets the process ID that will be used by default for the {@link generate} method\n * @param value The new value, will be masked with `0b11111`\n */\n public set processId(value: number | bigint) {\n this._processId = Number(value) & MAX_PROCESS_ID;\n }\n\n /**\n * Gets the configured worker ID\n */\n public get workerId(): number {\n return this._workerId;\n }\n\n /**\n * Sets the worker ID that will be used by default for the {@link generate} method\n * @param value The new value, will be masked with `0b11111`\n */\n public set workerId(value: number | bigint) {\n this._workerId = Number(value) & MAX_WORKER_ID;\n }\n\n /**\n * Get incrementor for generating snowflakes\n */\n public get increment(): number {\n return this._increment;\n }\n\n /**\n * Sets the incrementor for generating snowflakes that will be used by default for the {@link generate} method\n * @param value The new value\n */\n public set increment(value: number | bigint) {\n this._increment = Number(value) & MAX_INCREMENT;\n }\n\n private _createSavePoint(): AnyFunction {\n var increment = this._increment;\n var workerId = this._workerId;\n var processId = this._processId;\n\n return () => {\n this._increment = increment;\n this._workerId = workerId;\n this._processId = processId;\n };\n }\n\n /**\n * Sets most lowest values for generating snowflakes that will be used by default for the {@link generate} method\n */\n setLowest(): void {\n this._increment = 0;\n this._workerId = 0;\n this._processId = 0;\n }\n\n /**\n * Sets most highest values for generating snowflakes that will be used by default for the {@link generate} method\n */\n setHighest(): void {\n this._increment = MAX_INCREMENT;\n this._workerId = MAX_WORKER_ID;\n this._processId = MAX_PROCESS_ID;\n }\n\n /**\n * Execute a function in context of most lowest values for generating snowflakes\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake();\n * const id = snowflake.withLowest((v) => v.generate(epoch)); // the lowest possible id for that epoch\n * ```\n */\n withLowest<Result = undefined>(fn: (instance: Snowflake) => Result): Result {\n assert.fn(fn, 'withLowest expected a function as first argument');\n\n var reset = this._createSavePoint();\n this.setLowest();\n\n var result = fn(this);\n reset();\n\n return result;\n }\n\n /**\n * Execute a function in context of most highest values for generating snowflakes\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake();\n * const id = snowflake.withLowest((v) => v.generate(epoch)); // the highest possible id for that epoch\n * ```\n */\n withHighest<Result = undefined>(fn: (instance: Snowflake) => Result): Result {\n assert.fn(fn, 'withHighest expected a function as first argument');\n\n var reset = this._createSavePoint();\n\n this.setHighest();\n\n var result = fn(this);\n reset();\n\n return result;\n }\n\n /**\n * Generates a Snowflake ID as bigint.\n */\n public generate(timestamp: Date | number = Date.now()): bigint {\n if (timestamp instanceof Date) timestamp = timestamp.getTime();\n if (!isNumber(timestamp)) {\n throw new Error(\n `\"timestamp\" argument must be a number or Date (received ${typeof timestamp})`,\n );\n }\n\n var increment = this._increment;\n this._increment = (this._increment + 1) & MAX_INCREMENT;\n\n return (\n (BigInt(timestamp - this._epoch) << 22n) |\n (BigInt(this._workerId & MAX_WORKER_ID) << 17n) |\n (BigInt(this._processId & MAX_PROCESS_ID) << 12n) |\n BigInt(increment & MAX_INCREMENT)\n );\n }\n\n /**\n * Generates a Snowflake ID as a `Uint8Array` buffer.\n *\n * ⚠️ Returns a reference to the **same** internal `Uint8Array` instance.\n * Its contents may be overwritten on the next ID generation call.\n *\n * This method is intended for high-performance scenarios where you\n * immediately transform the buffer (e.g., to base62) before calling again.\n * Avoid storing or mutating the returned buffer directly.\n */\n public generateBufferUnsafe(\n timestamp: Date | number = Date.now(),\n ): Uint8Array {\n if (timestamp instanceof Date) timestamp = timestamp.getTime();\n if (!isNumber(timestamp)) {\n throw new Error(\n `\"timestamp\" argument must be a number or Date (received ${typeof timestamp})`,\n );\n }\n\n var increment = this._increment;\n this._increment = (this._increment + 1) & MAX_INCREMENT;\n\n // Calculate the timestamp delta\n var timestampDelta = timestamp - this._epoch;\n\n // Split into 32-bit parts for bitwise operations\n var timestampHigh = Math.floor(timestampDelta / 0xffffffff);\n var timestampLow = timestampDelta >>> 0;\n\n var high32 = ((timestampHigh << 22) | (timestampLow >>> 10)) >>> 0;\n var low32 =\n ((timestampLow << 22) |\n (this._workerId << 17) |\n (this._processId << 12) |\n (increment & MAX_INCREMENT)) >>>\n 0;\n\n var buffer = this._buffer;\n\n buffer[0] = high32 >>> 24;\n buffer[1] = high32 >>> 16;\n buffer[2] = high32 >>> 8;\n buffer[3] = high32;\n buffer[4] = low32 >>> 24;\n buffer[5] = low32 >>> 16;\n buffer[6] = low32 >>> 8;\n buffer[7] = low32;\n\n return buffer;\n }\n\n /**\n * Generates a snowflake given an epoch and optionally a timestamp\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake({ epoch }).generate();\n * ```\n * @returns A unique snowflake as Uint8Array\n */\n public generateBuffer(timestamp: Date | number = Date.now()): Uint8Array {\n this.generateBufferUnsafe(timestamp);\n return new Uint8Array(this._buffer);\n }\n\n /**\n * Deconstructs a snowflake given a snowflake ID\n * @param id the snowflake to deconstruct\n * @returns a deconstructed snowflake\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake(epoch).deconstruct('3971046231244935168');\n * ```\n */\n public deconstruct(id: string | bigint | Uint8Array): DeconstructedSnowflake {\n var high32: number, low32: number;\n\n if (id instanceof Uint8Array) {\n // Convert from Uint8Array\n high32 = ((id[0] << 24) | (id[1] << 16) | (id[2] << 8) | id[3]) >>> 0;\n low32 = ((id[4] << 24) | (id[5] << 16) | (id[6] << 8) | id[7]) >>> 0;\n } else if (isBigInt(id)) {\n return this.deconstruct(bigIntBytes(id));\n } else {\n // Convert from string\n return this.deconstruct(bigIntBytes(BigInt(id)));\n }\n\n return {\n id: BigInt(high32) * 0x100000000n + BigInt(low32),\n timestamp: high32 * 0x400 + (low32 >>> 22) + this._epoch,\n workerId: (low32 >>> 17) & MAX_WORKER_ID,\n processId: (low32 >>> 12) & MAX_PROCESS_ID,\n increment: low32 & MAX_INCREMENT,\n epoch: this._epoch,\n };\n }\n\n /**\n * Retrieves the timestamp field's value from a snowflake.\n * @param id The snowflake to get the timestamp value from.\n * @returns The UNIX timestamp that is stored in `id`.\n */\n public timestampFrom(id: string | bigint | Uint8Array): number {\n if (isString(id) || isBigInt(id)) {\n return this.timestampFrom(Snowflake.bufferFrom(id));\n }\n\n var high32 = ((id[0] << 24) | (id[1] << 16) | (id[2] << 8) | id[3]) >>> 0;\n var low32 = ((id[4] << 24) | (id[5] << 16) | (id[6] << 8) | id[7]) >>> 0;\n\n return high32 * 0x400 + (low32 >>> 22) + this._epoch;\n }\n\n /**\n * Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given\n * snowflake in sort order.\n * @param a The first snowflake to compare.\n * @param b The second snowflake to compare.\n * @returns `-1` if `a` is older than `b`, `0` if `a` and `b` are equals, `1` if `a` is newer than `b`.\n */\n public static compare(\n a: string | bigint | Uint8Array,\n b: string | bigint | Uint8Array,\n ): -1 | 0 | 1 {\n if (isString(a)) {\n a = BigInt(a);\n } else if (a instanceof Uint8Array) {\n a = bigIntFromBytes(a);\n }\n\n if (isString(b)) {\n b = BigInt(b);\n } else if (b instanceof Uint8Array) {\n b = bigIntFromBytes(b);\n }\n\n return a === b ? 0 : a < b ? -1 : 1;\n }\n\n /**\n * Parse value as Uint8Array buffer\n */\n public static bufferFrom(value: bigint | string): Uint8Array {\n if (isString(value)) value = BigInt(value);\n\n var buf = bigIntBytes(value);\n var bufSize = buf.byteLength;\n\n // Add padding\n if (buf.byteLength < 8) {\n var buf2 = new Uint8Array(8);\n buf2.set(buf, 8 - bufSize);\n buf = buf2;\n }\n\n return buf;\n }\n}\n"],"names":["isDate","isNumber","timestampMs","isBigInt","assert","bigIntBytes","isString","bigIntFromBytes"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/Snowflake.ts"],"sourcesContent":["/**\n * Based on: https://github.com/sapphiredev/utilities/blob/main/packages/snowflake/src/lib/Snowflake.ts\n */\nimport {\n type AnyFunction,\n type BitPack,\n type BitUnpack,\n assert,\n bigIntFromBytes,\n bitPack,\n bitUnpack,\n isBigInt,\n isDate,\n isNumber,\n isString,\n timestampMs,\n} from '@andrew_l/toolkit';\n\n/**\n * Object returned by Snowflake#deconstruct\n */\nexport interface DeconstructedSnowflake {\n /**\n * The id as a number\n */\n id: bigint;\n\n /**\n * The timestamp stored in the snowflake\n */\n timestamp: number;\n\n /**\n * The worker id stored in the snowflake\n */\n workerId: number;\n\n /**\n * The process id stored in the snowflake\n */\n processId: number;\n\n /**\n * The increment stored in the snowflake\n */\n increment: number;\n\n /**\n * The epoch to use in the snowflake\n */\n epoch: number;\n}\n\n/**\n * Options for Snowflake\n */\nexport interface SnowflakeOptions {\n /**\n * Timestamp or date of the snowflake to generate\n */\n epoch: number | bigint | Date;\n\n /**\n * The increment to use\n * @default 0\n * @remark keep in mind that this number is auto-incremented between generate calls\n */\n increment?: number | bigint;\n\n /**\n * The worker ID to use, will be truncated to 5 bits (0-31)\n * @default 0\n */\n workerId?: number | bigint;\n\n /**\n * The process ID to use, will be truncated to 5 bits (0-31)\n * @default 1\n */\n processId?: number | bigint;\n}\n\n/**\n * The maximum value the `workerId` field accepts in snowflakes.\n */\nexport var MAX_WORKER_ID = 0x1f;\n\n/**\n * The maximum value the `processId` field accepts in snowflakes.\n */\nexport var MAX_PROCESS_ID = 0x1f;\n\n/**\n * The maximum value the `increment` field accepts in snowflakes.\n */\nexport var MAX_INCREMENT = 0xfff;\n\nvar ENCODE_BIGINT_BUFFER = new Uint8Array(8);\n\n/**\n * A class for generating and deconstructing Twitter snowflakes.\n *\n * A {@link https://developer.twitter.com/en/docs/twitter-ids Twitter snowflake}\n * is a 64-bit unsigned integer with 4 fields that have a fixed epoch value.\n *\n * If we have a snowflake `266241948824764416` we can represent it as binary:\n * ```\n * 64 22 17 12 0\n * 000000111011000111100001101001000101000000 00001 00000 000000000000\n * number of ms since epoch worker pid increment\n * ```\n *\n * @group Main\n */\nexport class Snowflake {\n /**\n * Alias for {@link deconstruct}\n */\n public decode = this.deconstruct;\n\n /**\n * Internal reference of the epoch passed in the constructor\n * @internal\n */\n private readonly _epoch: number;\n\n /**\n * Internal incrementor for generating snowflakes\n * @internal\n */\n private _increment = 0;\n\n /**\n * The process ID that will be used by default in the generate method\n * @internal\n */\n private _processId = 1;\n\n /**\n * The worker ID that will be used by default in the generate method\n * @internal\n */\n private _workerId = 0;\n\n /**\n * @internal\n */\n private _timestamp = 0;\n\n private __buf: Uint8Array;\n\n private _packBuffer: BitPack.Fn.Buffer<\n '_timestamp' | '_workerId' | '_processId' | '_increment'\n >;\n\n private _packBigInt: BitPack.Fn.BigInt<\n '_timestamp' | '_workerId' | '_processId' | '_increment'\n >;\n\n private _unpackBuffer: BitUnpack.Fn.Buffer<\n 'timestamp' | 'workerId' | 'processId' | 'increment'\n >;\n\n private _unpackBigInt: BitUnpack.Fn.BigInt<\n 'timestamp' | 'workerId' | 'processId' | 'increment'\n >;\n\n /**\n * @param epoch the epoch to use\n */\n public constructor(opts: SnowflakeOptions | Date | number | bigint) {\n if (isDate(opts) || isNumber(opts)) {\n this._epoch = timestampMs(opts);\n } else if (isBigInt(opts)) {\n this._epoch = timestampMs(Number(opts));\n } else {\n const { increment = 0, processId = 1, workerId = 0, epoch } = opts;\n this._epoch = timestampMs(isBigInt(epoch) ? Number(epoch) : epoch);\n this.workerId = workerId;\n this.processId = processId;\n this.increment = increment;\n }\n\n const packer = bitPack({\n totalBits: 64,\n fields: [\n { name: '_timestamp', bits: 42, take: 'low' },\n { name: '_workerId', bits: 5, take: 'low' },\n { name: '_processId', bits: 5, take: 'low' },\n { name: '_increment', bits: 12, take: 'low' },\n ],\n optimize: true,\n debug: true,\n });\n\n const unpacker = bitUnpack({\n totalBits: 64,\n fields: [\n { name: 'timestamp', bits: 42, take: 'low' },\n { name: 'workerId', bits: 5, take: 'low' },\n { name: 'processId', bits: 5, take: 'low' },\n { name: 'increment', bits: 12, take: 'low' },\n ],\n debug: true,\n });\n\n this.__buf = new Uint8Array(8);\n this._packBigInt = packer.bigint;\n this._packBuffer = packer.buffer;\n this._unpackBigInt = unpacker.bigint;\n this._unpackBuffer = unpacker.buffer;\n }\n\n /**\n * The epoch for this snowflake, as a number\n */\n public get epoch(): number {\n return this._epoch;\n }\n\n /**\n * Gets the configured process ID\n */\n public get processId(): number {\n return this._processId;\n }\n\n /**\n * Sets the process ID that will be used by default for the {@link generate} method\n * @param value The new value, will be masked with `0b11111`\n */\n public set processId(value: number | bigint) {\n this._processId = Number(value) & MAX_PROCESS_ID;\n }\n\n /**\n * Gets the configured worker ID\n */\n public get workerId(): number {\n return this._workerId;\n }\n\n /**\n * Sets the worker ID that will be used by default for the {@link generate} method\n * @param value The new value, will be masked with `0b11111`\n */\n public set workerId(value: number | bigint) {\n this._workerId = Number(value) & MAX_WORKER_ID;\n }\n\n /**\n * Get incrementor for generating snowflakes\n */\n public get increment(): number {\n return this._increment;\n }\n\n /**\n * Sets the incrementor for generating snowflakes that will be used by default for the {@link generate} method\n * @param value The new value\n */\n public set increment(value: number | bigint) {\n this._increment = Number(value) & MAX_INCREMENT;\n }\n\n private _createSavePoint(): AnyFunction {\n var increment = this._increment;\n var workerId = this._workerId;\n var processId = this._processId;\n\n return () => {\n this._increment = increment;\n this._workerId = workerId;\n this._processId = processId;\n };\n }\n\n /**\n * Sets most lowest values for generating snowflakes that will be used by default for the {@link generate} method\n */\n setLowest(): void {\n this._increment = 0;\n this._workerId = 0;\n this._processId = 0;\n }\n\n /**\n * Sets most highest values for generating snowflakes that will be used by default for the {@link generate} method\n */\n setHighest(): void {\n this._increment = MAX_INCREMENT;\n this._workerId = MAX_WORKER_ID;\n this._processId = MAX_PROCESS_ID;\n }\n\n /**\n * Execute a function in context of most lowest values for generating snowflakes\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake();\n * const id = snowflake.withLowest((v) => v.generate(epoch)); // the lowest possible id for that epoch\n * ```\n */\n withLowest<Result = undefined>(fn: (instance: Snowflake) => Result): Result {\n assert.fn(fn, 'withLowest expected a function as first argument');\n\n var reset = this._createSavePoint();\n this.setLowest();\n\n var result = fn(this);\n reset();\n\n return result;\n }\n\n /**\n * Execute a function in context of most highest values for generating snowflakes\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake();\n * const id = snowflake.withLowest((v) => v.generate(epoch)); // the highest possible id for that epoch\n * ```\n */\n withHighest<Result = undefined>(fn: (instance: Snowflake) => Result): Result {\n assert.fn(fn, 'withHighest expected a function as first argument');\n\n var reset = this._createSavePoint();\n\n this.setHighest();\n\n var result = fn(this);\n reset();\n\n return result;\n }\n\n /**\n * Generates a Snowflake ID as bigint.\n */\n public generate(timestamp: Date | number = Date.now()): bigint {\n if (timestamp instanceof Date) timestamp = timestamp.getTime();\n if (!isNumber(timestamp)) {\n throw new Error(\n `\"timestamp\" argument must be a number or Date (received ${typeof timestamp})`,\n );\n }\n\n this._timestamp = timestamp - this._epoch;\n var res = this._packBigInt(this as any);\n this._increment = (this._increment + 1) & MAX_INCREMENT;\n\n return res;\n }\n\n /**\n * Generates a Snowflake ID as a `Uint8Array` buffer.\n *\n * ⚠️ Returns a reference to the **same** internal `Uint8Array` instance.\n * Its contents may be overwritten on the next ID generation call.\n *\n * This method is intended for high-performance scenarios where you\n * immediately transform the buffer (e.g., to base62) before calling again.\n * Avoid storing or mutating the returned buffer directly.\n */\n public generateBufferUnsafe(\n timestamp: Date | number = Date.now(),\n ): Uint8Array {\n if (timestamp instanceof Date) timestamp = timestamp.getTime();\n if (!isNumber(timestamp)) {\n throw new Error(\n `\"timestamp\" argument must be a number or Date (received ${typeof timestamp})`,\n );\n }\n\n this._timestamp = timestamp - this._epoch;\n this._packBuffer(this as any);\n this._increment = (this._increment + 1) & MAX_INCREMENT;\n\n return this.__buf;\n }\n\n /**\n * Generates a snowflake given an epoch and optionally a timestamp\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake({ epoch }).generate();\n * ```\n * @returns A unique snowflake as Uint8Array\n */\n public generateBuffer(timestamp: Date | number = Date.now()): Uint8Array {\n if (timestamp instanceof Date) timestamp = timestamp.getTime();\n if (!isNumber(timestamp)) {\n throw new Error(\n `\"timestamp\" argument must be a number or Date (received ${typeof timestamp})`,\n );\n }\n\n this.__buf = new Uint8Array(8);\n this._timestamp = timestamp - this._epoch;\n this._packBuffer(this as any);\n this._increment = (this._increment + 1) & MAX_INCREMENT;\n\n return this.__buf;\n }\n\n /**\n * Deconstructs a snowflake given a snowflake ID\n * @param id the snowflake to deconstruct\n * @returns a deconstructed snowflake\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake(epoch).deconstruct('3971046231244935168');\n * ```\n */\n public deconstruct(id: string | bigint | Uint8Array): DeconstructedSnowflake {\n if (isString(id)) {\n id = BigInt(id);\n }\n\n let result: DeconstructedSnowflake;\n\n if (isBigInt(id)) {\n result = this._unpackBigInt(id) as DeconstructedSnowflake;\n result.id = id;\n } else {\n result = this._unpackBuffer(id) as DeconstructedSnowflake;\n result.id = bigIntFromBytes(id);\n }\n\n result.timestamp += this._epoch;\n result.epoch = this._epoch;\n\n return result;\n }\n\n /**\n * Retrieves the timestamp field's value from a snowflake.\n * @param id The snowflake to get the timestamp value from.\n * @returns The UNIX timestamp that is stored in `id`.\n */\n public timestampFrom(id: string | bigint | Uint8Array): number {\n return this.deconstruct(id).timestamp;\n }\n\n /**\n * Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given\n * snowflake in sort order.\n * @param a The first snowflake to compare.\n * @param b The second snowflake to compare.\n * @returns `-1` if `a` is older than `b`, `0` if `a` and `b` are equals, `1` if `a` is newer than `b`.\n */\n public static compare(\n a: string | bigint | Uint8Array,\n b: string | bigint | Uint8Array,\n ): -1 | 0 | 1 {\n if (isString(a)) {\n a = BigInt(a);\n } else if (a instanceof Uint8Array) {\n a = bigIntFromBytes(a);\n }\n\n if (isString(b)) {\n b = BigInt(b);\n } else if (b instanceof Uint8Array) {\n b = bigIntFromBytes(b);\n }\n\n return a === b ? 0 : a < b ? -1 : 1;\n }\n\n /**\n * Parse value as Uint8Array buffer\n */\n public static bufferFrom(value: bigint | string): Uint8Array {\n if (isString(value)) value = BigInt(value);\n\n return new Uint8Array(bigintToBuffer(value));\n }\n}\n\nfunction bigintToBuffer(value: bigint): Uint8Array {\n if (value < 0n) {\n value = value * -1n;\n }\n for (var i = 0; i < 8; i++) {\n ENCODE_BIGINT_BUFFER[i] = Number(\n (value >> BigInt((8 - i - 1) * 8)) & 0xffn,\n );\n }\n return ENCODE_BIGINT_BUFFER;\n}\n"],"names":["isDate","isNumber","timestampMs","isBigInt","bitPack","bitUnpack","assert","isString","bigIntFromBytes"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -107,7 +107,12 @@ declare class Snowflake {
|
|
|
107
107
|
/**
|
|
108
108
|
* @internal
|
|
109
109
|
*/
|
|
110
|
-
private
|
|
110
|
+
private _timestamp;
|
|
111
|
+
private __buf;
|
|
112
|
+
private _packBuffer;
|
|
113
|
+
private _packBigInt;
|
|
114
|
+
private _unpackBuffer;
|
|
115
|
+
private _unpackBigInt;
|
|
111
116
|
/**
|
|
112
117
|
* @param epoch the epoch to use
|
|
113
118
|
*/
|
package/dist/index.d.mts
CHANGED
|
@@ -107,7 +107,12 @@ declare class Snowflake {
|
|
|
107
107
|
/**
|
|
108
108
|
* @internal
|
|
109
109
|
*/
|
|
110
|
-
private
|
|
110
|
+
private _timestamp;
|
|
111
|
+
private __buf;
|
|
112
|
+
private _packBuffer;
|
|
113
|
+
private _packBigInt;
|
|
114
|
+
private _unpackBuffer;
|
|
115
|
+
private _unpackBigInt;
|
|
111
116
|
/**
|
|
112
117
|
* @param epoch the epoch to use
|
|
113
118
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -107,7 +107,12 @@ declare class Snowflake {
|
|
|
107
107
|
/**
|
|
108
108
|
* @internal
|
|
109
109
|
*/
|
|
110
|
-
private
|
|
110
|
+
private _timestamp;
|
|
111
|
+
private __buf;
|
|
112
|
+
private _packBuffer;
|
|
113
|
+
private _packBigInt;
|
|
114
|
+
private _unpackBuffer;
|
|
115
|
+
private _unpackBigInt;
|
|
111
116
|
/**
|
|
112
117
|
* @param epoch the epoch to use
|
|
113
118
|
*/
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { isDate, isNumber, timestampMs, isBigInt,
|
|
1
|
+
import { isDate, isNumber, timestampMs, isBigInt, bitPack, bitUnpack, assert, isString, bigIntFromBytes } from '@andrew_l/toolkit';
|
|
2
2
|
|
|
3
3
|
var MAX_WORKER_ID = 31;
|
|
4
4
|
var MAX_PROCESS_ID = 31;
|
|
5
5
|
var MAX_INCREMENT = 4095;
|
|
6
|
+
var ENCODE_BIGINT_BUFFER = new Uint8Array(8);
|
|
6
7
|
class Snowflake {
|
|
7
8
|
/**
|
|
8
9
|
* Alias for {@link deconstruct}
|
|
@@ -31,7 +32,12 @@ class Snowflake {
|
|
|
31
32
|
/**
|
|
32
33
|
* @internal
|
|
33
34
|
*/
|
|
34
|
-
|
|
35
|
+
_timestamp = 0;
|
|
36
|
+
__buf;
|
|
37
|
+
_packBuffer;
|
|
38
|
+
_packBigInt;
|
|
39
|
+
_unpackBuffer;
|
|
40
|
+
_unpackBigInt;
|
|
35
41
|
/**
|
|
36
42
|
* @param epoch the epoch to use
|
|
37
43
|
*/
|
|
@@ -47,7 +53,32 @@ class Snowflake {
|
|
|
47
53
|
this.processId = processId;
|
|
48
54
|
this.increment = increment;
|
|
49
55
|
}
|
|
50
|
-
|
|
56
|
+
const packer = bitPack({
|
|
57
|
+
totalBits: 64,
|
|
58
|
+
fields: [
|
|
59
|
+
{ name: "_timestamp", bits: 42, take: "low" },
|
|
60
|
+
{ name: "_workerId", bits: 5, take: "low" },
|
|
61
|
+
{ name: "_processId", bits: 5, take: "low" },
|
|
62
|
+
{ name: "_increment", bits: 12, take: "low" }
|
|
63
|
+
],
|
|
64
|
+
optimize: true,
|
|
65
|
+
debug: true
|
|
66
|
+
});
|
|
67
|
+
const unpacker = bitUnpack({
|
|
68
|
+
totalBits: 64,
|
|
69
|
+
fields: [
|
|
70
|
+
{ name: "timestamp", bits: 42, take: "low" },
|
|
71
|
+
{ name: "workerId", bits: 5, take: "low" },
|
|
72
|
+
{ name: "processId", bits: 5, take: "low" },
|
|
73
|
+
{ name: "increment", bits: 12, take: "low" }
|
|
74
|
+
],
|
|
75
|
+
debug: true
|
|
76
|
+
});
|
|
77
|
+
this.__buf = new Uint8Array(8);
|
|
78
|
+
this._packBigInt = packer.bigint;
|
|
79
|
+
this._packBuffer = packer.buffer;
|
|
80
|
+
this._unpackBigInt = unpacker.bigint;
|
|
81
|
+
this._unpackBuffer = unpacker.buffer;
|
|
51
82
|
}
|
|
52
83
|
/**
|
|
53
84
|
* The epoch for this snowflake, as a number
|
|
@@ -164,9 +195,10 @@ class Snowflake {
|
|
|
164
195
|
`"timestamp" argument must be a number or Date (received ${typeof timestamp})`
|
|
165
196
|
);
|
|
166
197
|
}
|
|
167
|
-
|
|
198
|
+
this._timestamp = timestamp - this._epoch;
|
|
199
|
+
var res = this._packBigInt(this);
|
|
168
200
|
this._increment = this._increment + 1 & MAX_INCREMENT;
|
|
169
|
-
return
|
|
201
|
+
return res;
|
|
170
202
|
}
|
|
171
203
|
/**
|
|
172
204
|
* Generates a Snowflake ID as a `Uint8Array` buffer.
|
|
@@ -185,23 +217,10 @@ class Snowflake {
|
|
|
185
217
|
`"timestamp" argument must be a number or Date (received ${typeof timestamp})`
|
|
186
218
|
);
|
|
187
219
|
}
|
|
188
|
-
|
|
220
|
+
this._timestamp = timestamp - this._epoch;
|
|
221
|
+
this._packBuffer(this);
|
|
189
222
|
this._increment = this._increment + 1 & MAX_INCREMENT;
|
|
190
|
-
|
|
191
|
-
var timestampHigh = Math.floor(timestampDelta / 4294967295);
|
|
192
|
-
var timestampLow = timestampDelta >>> 0;
|
|
193
|
-
var high32 = (timestampHigh << 22 | timestampLow >>> 10) >>> 0;
|
|
194
|
-
var low32 = (timestampLow << 22 | this._workerId << 17 | this._processId << 12 | increment & MAX_INCREMENT) >>> 0;
|
|
195
|
-
var buffer = this._buffer;
|
|
196
|
-
buffer[0] = high32 >>> 24;
|
|
197
|
-
buffer[1] = high32 >>> 16;
|
|
198
|
-
buffer[2] = high32 >>> 8;
|
|
199
|
-
buffer[3] = high32;
|
|
200
|
-
buffer[4] = low32 >>> 24;
|
|
201
|
-
buffer[5] = low32 >>> 16;
|
|
202
|
-
buffer[6] = low32 >>> 8;
|
|
203
|
-
buffer[7] = low32;
|
|
204
|
-
return buffer;
|
|
223
|
+
return this.__buf;
|
|
205
224
|
}
|
|
206
225
|
/**
|
|
207
226
|
* Generates a snowflake given an epoch and optionally a timestamp
|
|
@@ -213,8 +232,17 @@ class Snowflake {
|
|
|
213
232
|
* @returns A unique snowflake as Uint8Array
|
|
214
233
|
*/
|
|
215
234
|
generateBuffer(timestamp = Date.now()) {
|
|
216
|
-
|
|
217
|
-
|
|
235
|
+
if (timestamp instanceof Date) timestamp = timestamp.getTime();
|
|
236
|
+
if (!isNumber(timestamp)) {
|
|
237
|
+
throw new Error(
|
|
238
|
+
`"timestamp" argument must be a number or Date (received ${typeof timestamp})`
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
this.__buf = new Uint8Array(8);
|
|
242
|
+
this._timestamp = timestamp - this._epoch;
|
|
243
|
+
this._packBuffer(this);
|
|
244
|
+
this._increment = this._increment + 1 & MAX_INCREMENT;
|
|
245
|
+
return this.__buf;
|
|
218
246
|
}
|
|
219
247
|
/**
|
|
220
248
|
* Deconstructs a snowflake given a snowflake ID
|
|
@@ -227,23 +255,20 @@ class Snowflake {
|
|
|
227
255
|
* ```
|
|
228
256
|
*/
|
|
229
257
|
deconstruct(id) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
258
|
+
if (isString(id)) {
|
|
259
|
+
id = BigInt(id);
|
|
260
|
+
}
|
|
261
|
+
let result;
|
|
262
|
+
if (isBigInt(id)) {
|
|
263
|
+
result = this._unpackBigInt(id);
|
|
264
|
+
result.id = id;
|
|
236
265
|
} else {
|
|
237
|
-
|
|
266
|
+
result = this._unpackBuffer(id);
|
|
267
|
+
result.id = bigIntFromBytes(id);
|
|
238
268
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
workerId: low32 >>> 17 & MAX_WORKER_ID,
|
|
243
|
-
processId: low32 >>> 12 & MAX_PROCESS_ID,
|
|
244
|
-
increment: low32 & MAX_INCREMENT,
|
|
245
|
-
epoch: this._epoch
|
|
246
|
-
};
|
|
269
|
+
result.timestamp += this._epoch;
|
|
270
|
+
result.epoch = this._epoch;
|
|
271
|
+
return result;
|
|
247
272
|
}
|
|
248
273
|
/**
|
|
249
274
|
* Retrieves the timestamp field's value from a snowflake.
|
|
@@ -251,12 +276,7 @@ class Snowflake {
|
|
|
251
276
|
* @returns The UNIX timestamp that is stored in `id`.
|
|
252
277
|
*/
|
|
253
278
|
timestampFrom(id) {
|
|
254
|
-
|
|
255
|
-
return this.timestampFrom(Snowflake.bufferFrom(id));
|
|
256
|
-
}
|
|
257
|
-
var high32 = (id[0] << 24 | id[1] << 16 | id[2] << 8 | id[3]) >>> 0;
|
|
258
|
-
var low32 = (id[4] << 24 | id[5] << 16 | id[6] << 8 | id[7]) >>> 0;
|
|
259
|
-
return high32 * 1024 + (low32 >>> 22) + this._epoch;
|
|
279
|
+
return this.deconstruct(id).timestamp;
|
|
260
280
|
}
|
|
261
281
|
/**
|
|
262
282
|
* Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given
|
|
@@ -283,15 +303,19 @@ class Snowflake {
|
|
|
283
303
|
*/
|
|
284
304
|
static bufferFrom(value) {
|
|
285
305
|
if (isString(value)) value = BigInt(value);
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
306
|
+
return new Uint8Array(bigintToBuffer(value));
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
function bigintToBuffer(value) {
|
|
310
|
+
if (value < 0n) {
|
|
311
|
+
value = value * -1n;
|
|
312
|
+
}
|
|
313
|
+
for (var i = 0; i < 8; i++) {
|
|
314
|
+
ENCODE_BIGINT_BUFFER[i] = Number(
|
|
315
|
+
value >> BigInt((8 - i - 1) * 8) & 0xffn
|
|
316
|
+
);
|
|
294
317
|
}
|
|
318
|
+
return ENCODE_BIGINT_BUFFER;
|
|
295
319
|
}
|
|
296
320
|
|
|
297
321
|
export { MAX_INCREMENT, MAX_PROCESS_ID, MAX_WORKER_ID, Snowflake };
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/Snowflake.ts"],"sourcesContent":["/**\n * Based on: https://github.com/sapphiredev/utilities/blob/main/packages/snowflake/src/lib/Snowflake.ts\n */\nimport {\n type AnyFunction,\n assert,\n bigIntBytes,\n bigIntFromBytes,\n isBigInt,\n isDate,\n isNumber,\n isString,\n timestampMs,\n} from '@andrew_l/toolkit';\n\n/**\n * Object returned by Snowflake#deconstruct\n */\nexport interface DeconstructedSnowflake {\n /**\n * The id as a number\n */\n id: bigint;\n\n /**\n * The timestamp stored in the snowflake\n */\n timestamp: number;\n\n /**\n * The worker id stored in the snowflake\n */\n workerId: number;\n\n /**\n * The process id stored in the snowflake\n */\n processId: number;\n\n /**\n * The increment stored in the snowflake\n */\n increment: number;\n\n /**\n * The epoch to use in the snowflake\n */\n epoch: number;\n}\n\n/**\n * Options for Snowflake\n */\nexport interface SnowflakeOptions {\n /**\n * Timestamp or date of the snowflake to generate\n */\n epoch: number | bigint | Date;\n\n /**\n * The increment to use\n * @default 0\n * @remark keep in mind that this number is auto-incremented between generate calls\n */\n increment?: number | bigint;\n\n /**\n * The worker ID to use, will be truncated to 5 bits (0-31)\n * @default 0\n */\n workerId?: number | bigint;\n\n /**\n * The process ID to use, will be truncated to 5 bits (0-31)\n * @default 1\n */\n processId?: number | bigint;\n}\n\n/**\n * The maximum value the `workerId` field accepts in snowflakes.\n */\nexport var MAX_WORKER_ID = 0x1f;\n\n/**\n * The maximum value the `processId` field accepts in snowflakes.\n */\nexport var MAX_PROCESS_ID = 0x1f;\n\n/**\n * The maximum value the `increment` field accepts in snowflakes.\n */\nexport var MAX_INCREMENT = 0xfff;\n\n/**\n * A class for generating and deconstructing Twitter snowflakes.\n *\n * A {@link https://developer.twitter.com/en/docs/twitter-ids Twitter snowflake}\n * is a 64-bit unsigned integer with 4 fields that have a fixed epoch value.\n *\n * If we have a snowflake `266241948824764416` we can represent it as binary:\n * ```\n * 64 22 17 12 0\n * 000000111011000111100001101001000101000000 00001 00000 000000000000\n * number of ms since epoch worker pid increment\n * ```\n *\n * @group Main\n */\nexport class Snowflake {\n /**\n * Alias for {@link deconstruct}\n */\n public decode = this.deconstruct;\n\n /**\n * Internal reference of the epoch passed in the constructor\n * @internal\n */\n private readonly _epoch: number;\n\n /**\n * Internal incrementor for generating snowflakes\n * @internal\n */\n private _increment = 0;\n\n /**\n * The process ID that will be used by default in the generate method\n * @internal\n */\n private _processId = 1;\n\n /**\n * The worker ID that will be used by default in the generate method\n * @internal\n */\n private _workerId = 0;\n\n /**\n * @internal\n */\n private _buffer: Uint8Array;\n\n /**\n * @param epoch the epoch to use\n */\n public constructor(opts: SnowflakeOptions | Date | number | bigint) {\n if (isDate(opts) || isNumber(opts)) {\n this._epoch = timestampMs(opts);\n } else if (isBigInt(opts)) {\n this._epoch = timestampMs(Number(opts));\n } else {\n const { increment = 0, processId = 1, workerId = 0, epoch } = opts;\n this._epoch = timestampMs(isBigInt(epoch) ? Number(epoch) : epoch);\n this.workerId = workerId;\n this.processId = processId;\n this.increment = increment;\n }\n\n this._buffer = new Uint8Array(8);\n }\n\n /**\n * The epoch for this snowflake, as a number\n */\n public get epoch(): number {\n return this._epoch;\n }\n\n /**\n * Gets the configured process ID\n */\n public get processId(): number {\n return this._processId;\n }\n\n /**\n * Sets the process ID that will be used by default for the {@link generate} method\n * @param value The new value, will be masked with `0b11111`\n */\n public set processId(value: number | bigint) {\n this._processId = Number(value) & MAX_PROCESS_ID;\n }\n\n /**\n * Gets the configured worker ID\n */\n public get workerId(): number {\n return this._workerId;\n }\n\n /**\n * Sets the worker ID that will be used by default for the {@link generate} method\n * @param value The new value, will be masked with `0b11111`\n */\n public set workerId(value: number | bigint) {\n this._workerId = Number(value) & MAX_WORKER_ID;\n }\n\n /**\n * Get incrementor for generating snowflakes\n */\n public get increment(): number {\n return this._increment;\n }\n\n /**\n * Sets the incrementor for generating snowflakes that will be used by default for the {@link generate} method\n * @param value The new value\n */\n public set increment(value: number | bigint) {\n this._increment = Number(value) & MAX_INCREMENT;\n }\n\n private _createSavePoint(): AnyFunction {\n var increment = this._increment;\n var workerId = this._workerId;\n var processId = this._processId;\n\n return () => {\n this._increment = increment;\n this._workerId = workerId;\n this._processId = processId;\n };\n }\n\n /**\n * Sets most lowest values for generating snowflakes that will be used by default for the {@link generate} method\n */\n setLowest(): void {\n this._increment = 0;\n this._workerId = 0;\n this._processId = 0;\n }\n\n /**\n * Sets most highest values for generating snowflakes that will be used by default for the {@link generate} method\n */\n setHighest(): void {\n this._increment = MAX_INCREMENT;\n this._workerId = MAX_WORKER_ID;\n this._processId = MAX_PROCESS_ID;\n }\n\n /**\n * Execute a function in context of most lowest values for generating snowflakes\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake();\n * const id = snowflake.withLowest((v) => v.generate(epoch)); // the lowest possible id for that epoch\n * ```\n */\n withLowest<Result = undefined>(fn: (instance: Snowflake) => Result): Result {\n assert.fn(fn, 'withLowest expected a function as first argument');\n\n var reset = this._createSavePoint();\n this.setLowest();\n\n var result = fn(this);\n reset();\n\n return result;\n }\n\n /**\n * Execute a function in context of most highest values for generating snowflakes\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake();\n * const id = snowflake.withLowest((v) => v.generate(epoch)); // the highest possible id for that epoch\n * ```\n */\n withHighest<Result = undefined>(fn: (instance: Snowflake) => Result): Result {\n assert.fn(fn, 'withHighest expected a function as first argument');\n\n var reset = this._createSavePoint();\n\n this.setHighest();\n\n var result = fn(this);\n reset();\n\n return result;\n }\n\n /**\n * Generates a Snowflake ID as bigint.\n */\n public generate(timestamp: Date | number = Date.now()): bigint {\n if (timestamp instanceof Date) timestamp = timestamp.getTime();\n if (!isNumber(timestamp)) {\n throw new Error(\n `\"timestamp\" argument must be a number or Date (received ${typeof timestamp})`,\n );\n }\n\n var increment = this._increment;\n this._increment = (this._increment + 1) & MAX_INCREMENT;\n\n return (\n (BigInt(timestamp - this._epoch) << 22n) |\n (BigInt(this._workerId & MAX_WORKER_ID) << 17n) |\n (BigInt(this._processId & MAX_PROCESS_ID) << 12n) |\n BigInt(increment & MAX_INCREMENT)\n );\n }\n\n /**\n * Generates a Snowflake ID as a `Uint8Array` buffer.\n *\n * ⚠️ Returns a reference to the **same** internal `Uint8Array` instance.\n * Its contents may be overwritten on the next ID generation call.\n *\n * This method is intended for high-performance scenarios where you\n * immediately transform the buffer (e.g., to base62) before calling again.\n * Avoid storing or mutating the returned buffer directly.\n */\n public generateBufferUnsafe(\n timestamp: Date | number = Date.now(),\n ): Uint8Array {\n if (timestamp instanceof Date) timestamp = timestamp.getTime();\n if (!isNumber(timestamp)) {\n throw new Error(\n `\"timestamp\" argument must be a number or Date (received ${typeof timestamp})`,\n );\n }\n\n var increment = this._increment;\n this._increment = (this._increment + 1) & MAX_INCREMENT;\n\n // Calculate the timestamp delta\n var timestampDelta = timestamp - this._epoch;\n\n // Split into 32-bit parts for bitwise operations\n var timestampHigh = Math.floor(timestampDelta / 0xffffffff);\n var timestampLow = timestampDelta >>> 0;\n\n var high32 = ((timestampHigh << 22) | (timestampLow >>> 10)) >>> 0;\n var low32 =\n ((timestampLow << 22) |\n (this._workerId << 17) |\n (this._processId << 12) |\n (increment & MAX_INCREMENT)) >>>\n 0;\n\n var buffer = this._buffer;\n\n buffer[0] = high32 >>> 24;\n buffer[1] = high32 >>> 16;\n buffer[2] = high32 >>> 8;\n buffer[3] = high32;\n buffer[4] = low32 >>> 24;\n buffer[5] = low32 >>> 16;\n buffer[6] = low32 >>> 8;\n buffer[7] = low32;\n\n return buffer;\n }\n\n /**\n * Generates a snowflake given an epoch and optionally a timestamp\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake({ epoch }).generate();\n * ```\n * @returns A unique snowflake as Uint8Array\n */\n public generateBuffer(timestamp: Date | number = Date.now()): Uint8Array {\n this.generateBufferUnsafe(timestamp);\n return new Uint8Array(this._buffer);\n }\n\n /**\n * Deconstructs a snowflake given a snowflake ID\n * @param id the snowflake to deconstruct\n * @returns a deconstructed snowflake\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake(epoch).deconstruct('3971046231244935168');\n * ```\n */\n public deconstruct(id: string | bigint | Uint8Array): DeconstructedSnowflake {\n var high32: number, low32: number;\n\n if (id instanceof Uint8Array) {\n // Convert from Uint8Array\n high32 = ((id[0] << 24) | (id[1] << 16) | (id[2] << 8) | id[3]) >>> 0;\n low32 = ((id[4] << 24) | (id[5] << 16) | (id[6] << 8) | id[7]) >>> 0;\n } else if (isBigInt(id)) {\n return this.deconstruct(bigIntBytes(id));\n } else {\n // Convert from string\n return this.deconstruct(bigIntBytes(BigInt(id)));\n }\n\n return {\n id: BigInt(high32) * 0x100000000n + BigInt(low32),\n timestamp: high32 * 0x400 + (low32 >>> 22) + this._epoch,\n workerId: (low32 >>> 17) & MAX_WORKER_ID,\n processId: (low32 >>> 12) & MAX_PROCESS_ID,\n increment: low32 & MAX_INCREMENT,\n epoch: this._epoch,\n };\n }\n\n /**\n * Retrieves the timestamp field's value from a snowflake.\n * @param id The snowflake to get the timestamp value from.\n * @returns The UNIX timestamp that is stored in `id`.\n */\n public timestampFrom(id: string | bigint | Uint8Array): number {\n if (isString(id) || isBigInt(id)) {\n return this.timestampFrom(Snowflake.bufferFrom(id));\n }\n\n var high32 = ((id[0] << 24) | (id[1] << 16) | (id[2] << 8) | id[3]) >>> 0;\n var low32 = ((id[4] << 24) | (id[5] << 16) | (id[6] << 8) | id[7]) >>> 0;\n\n return high32 * 0x400 + (low32 >>> 22) + this._epoch;\n }\n\n /**\n * Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given\n * snowflake in sort order.\n * @param a The first snowflake to compare.\n * @param b The second snowflake to compare.\n * @returns `-1` if `a` is older than `b`, `0` if `a` and `b` are equals, `1` if `a` is newer than `b`.\n */\n public static compare(\n a: string | bigint | Uint8Array,\n b: string | bigint | Uint8Array,\n ): -1 | 0 | 1 {\n if (isString(a)) {\n a = BigInt(a);\n } else if (a instanceof Uint8Array) {\n a = bigIntFromBytes(a);\n }\n\n if (isString(b)) {\n b = BigInt(b);\n } else if (b instanceof Uint8Array) {\n b = bigIntFromBytes(b);\n }\n\n return a === b ? 0 : a < b ? -1 : 1;\n }\n\n /**\n * Parse value as Uint8Array buffer\n */\n public static bufferFrom(value: bigint | string): Uint8Array {\n if (isString(value)) value = BigInt(value);\n\n var buf = bigIntBytes(value);\n var bufSize = buf.byteLength;\n\n // Add padding\n if (buf.byteLength < 8) {\n var buf2 = new Uint8Array(8);\n buf2.set(buf, 8 - bufSize);\n buf = buf2;\n }\n\n return buf;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/Snowflake.ts"],"sourcesContent":["/**\n * Based on: https://github.com/sapphiredev/utilities/blob/main/packages/snowflake/src/lib/Snowflake.ts\n */\nimport {\n type AnyFunction,\n type BitPack,\n type BitUnpack,\n assert,\n bigIntFromBytes,\n bitPack,\n bitUnpack,\n isBigInt,\n isDate,\n isNumber,\n isString,\n timestampMs,\n} from '@andrew_l/toolkit';\n\n/**\n * Object returned by Snowflake#deconstruct\n */\nexport interface DeconstructedSnowflake {\n /**\n * The id as a number\n */\n id: bigint;\n\n /**\n * The timestamp stored in the snowflake\n */\n timestamp: number;\n\n /**\n * The worker id stored in the snowflake\n */\n workerId: number;\n\n /**\n * The process id stored in the snowflake\n */\n processId: number;\n\n /**\n * The increment stored in the snowflake\n */\n increment: number;\n\n /**\n * The epoch to use in the snowflake\n */\n epoch: number;\n}\n\n/**\n * Options for Snowflake\n */\nexport interface SnowflakeOptions {\n /**\n * Timestamp or date of the snowflake to generate\n */\n epoch: number | bigint | Date;\n\n /**\n * The increment to use\n * @default 0\n * @remark keep in mind that this number is auto-incremented between generate calls\n */\n increment?: number | bigint;\n\n /**\n * The worker ID to use, will be truncated to 5 bits (0-31)\n * @default 0\n */\n workerId?: number | bigint;\n\n /**\n * The process ID to use, will be truncated to 5 bits (0-31)\n * @default 1\n */\n processId?: number | bigint;\n}\n\n/**\n * The maximum value the `workerId` field accepts in snowflakes.\n */\nexport var MAX_WORKER_ID = 0x1f;\n\n/**\n * The maximum value the `processId` field accepts in snowflakes.\n */\nexport var MAX_PROCESS_ID = 0x1f;\n\n/**\n * The maximum value the `increment` field accepts in snowflakes.\n */\nexport var MAX_INCREMENT = 0xfff;\n\nvar ENCODE_BIGINT_BUFFER = new Uint8Array(8);\n\n/**\n * A class for generating and deconstructing Twitter snowflakes.\n *\n * A {@link https://developer.twitter.com/en/docs/twitter-ids Twitter snowflake}\n * is a 64-bit unsigned integer with 4 fields that have a fixed epoch value.\n *\n * If we have a snowflake `266241948824764416` we can represent it as binary:\n * ```\n * 64 22 17 12 0\n * 000000111011000111100001101001000101000000 00001 00000 000000000000\n * number of ms since epoch worker pid increment\n * ```\n *\n * @group Main\n */\nexport class Snowflake {\n /**\n * Alias for {@link deconstruct}\n */\n public decode = this.deconstruct;\n\n /**\n * Internal reference of the epoch passed in the constructor\n * @internal\n */\n private readonly _epoch: number;\n\n /**\n * Internal incrementor for generating snowflakes\n * @internal\n */\n private _increment = 0;\n\n /**\n * The process ID that will be used by default in the generate method\n * @internal\n */\n private _processId = 1;\n\n /**\n * The worker ID that will be used by default in the generate method\n * @internal\n */\n private _workerId = 0;\n\n /**\n * @internal\n */\n private _timestamp = 0;\n\n private __buf: Uint8Array;\n\n private _packBuffer: BitPack.Fn.Buffer<\n '_timestamp' | '_workerId' | '_processId' | '_increment'\n >;\n\n private _packBigInt: BitPack.Fn.BigInt<\n '_timestamp' | '_workerId' | '_processId' | '_increment'\n >;\n\n private _unpackBuffer: BitUnpack.Fn.Buffer<\n 'timestamp' | 'workerId' | 'processId' | 'increment'\n >;\n\n private _unpackBigInt: BitUnpack.Fn.BigInt<\n 'timestamp' | 'workerId' | 'processId' | 'increment'\n >;\n\n /**\n * @param epoch the epoch to use\n */\n public constructor(opts: SnowflakeOptions | Date | number | bigint) {\n if (isDate(opts) || isNumber(opts)) {\n this._epoch = timestampMs(opts);\n } else if (isBigInt(opts)) {\n this._epoch = timestampMs(Number(opts));\n } else {\n const { increment = 0, processId = 1, workerId = 0, epoch } = opts;\n this._epoch = timestampMs(isBigInt(epoch) ? Number(epoch) : epoch);\n this.workerId = workerId;\n this.processId = processId;\n this.increment = increment;\n }\n\n const packer = bitPack({\n totalBits: 64,\n fields: [\n { name: '_timestamp', bits: 42, take: 'low' },\n { name: '_workerId', bits: 5, take: 'low' },\n { name: '_processId', bits: 5, take: 'low' },\n { name: '_increment', bits: 12, take: 'low' },\n ],\n optimize: true,\n debug: true,\n });\n\n const unpacker = bitUnpack({\n totalBits: 64,\n fields: [\n { name: 'timestamp', bits: 42, take: 'low' },\n { name: 'workerId', bits: 5, take: 'low' },\n { name: 'processId', bits: 5, take: 'low' },\n { name: 'increment', bits: 12, take: 'low' },\n ],\n debug: true,\n });\n\n this.__buf = new Uint8Array(8);\n this._packBigInt = packer.bigint;\n this._packBuffer = packer.buffer;\n this._unpackBigInt = unpacker.bigint;\n this._unpackBuffer = unpacker.buffer;\n }\n\n /**\n * The epoch for this snowflake, as a number\n */\n public get epoch(): number {\n return this._epoch;\n }\n\n /**\n * Gets the configured process ID\n */\n public get processId(): number {\n return this._processId;\n }\n\n /**\n * Sets the process ID that will be used by default for the {@link generate} method\n * @param value The new value, will be masked with `0b11111`\n */\n public set processId(value: number | bigint) {\n this._processId = Number(value) & MAX_PROCESS_ID;\n }\n\n /**\n * Gets the configured worker ID\n */\n public get workerId(): number {\n return this._workerId;\n }\n\n /**\n * Sets the worker ID that will be used by default for the {@link generate} method\n * @param value The new value, will be masked with `0b11111`\n */\n public set workerId(value: number | bigint) {\n this._workerId = Number(value) & MAX_WORKER_ID;\n }\n\n /**\n * Get incrementor for generating snowflakes\n */\n public get increment(): number {\n return this._increment;\n }\n\n /**\n * Sets the incrementor for generating snowflakes that will be used by default for the {@link generate} method\n * @param value The new value\n */\n public set increment(value: number | bigint) {\n this._increment = Number(value) & MAX_INCREMENT;\n }\n\n private _createSavePoint(): AnyFunction {\n var increment = this._increment;\n var workerId = this._workerId;\n var processId = this._processId;\n\n return () => {\n this._increment = increment;\n this._workerId = workerId;\n this._processId = processId;\n };\n }\n\n /**\n * Sets most lowest values for generating snowflakes that will be used by default for the {@link generate} method\n */\n setLowest(): void {\n this._increment = 0;\n this._workerId = 0;\n this._processId = 0;\n }\n\n /**\n * Sets most highest values for generating snowflakes that will be used by default for the {@link generate} method\n */\n setHighest(): void {\n this._increment = MAX_INCREMENT;\n this._workerId = MAX_WORKER_ID;\n this._processId = MAX_PROCESS_ID;\n }\n\n /**\n * Execute a function in context of most lowest values for generating snowflakes\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake();\n * const id = snowflake.withLowest((v) => v.generate(epoch)); // the lowest possible id for that epoch\n * ```\n */\n withLowest<Result = undefined>(fn: (instance: Snowflake) => Result): Result {\n assert.fn(fn, 'withLowest expected a function as first argument');\n\n var reset = this._createSavePoint();\n this.setLowest();\n\n var result = fn(this);\n reset();\n\n return result;\n }\n\n /**\n * Execute a function in context of most highest values for generating snowflakes\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake();\n * const id = snowflake.withLowest((v) => v.generate(epoch)); // the highest possible id for that epoch\n * ```\n */\n withHighest<Result = undefined>(fn: (instance: Snowflake) => Result): Result {\n assert.fn(fn, 'withHighest expected a function as first argument');\n\n var reset = this._createSavePoint();\n\n this.setHighest();\n\n var result = fn(this);\n reset();\n\n return result;\n }\n\n /**\n * Generates a Snowflake ID as bigint.\n */\n public generate(timestamp: Date | number = Date.now()): bigint {\n if (timestamp instanceof Date) timestamp = timestamp.getTime();\n if (!isNumber(timestamp)) {\n throw new Error(\n `\"timestamp\" argument must be a number or Date (received ${typeof timestamp})`,\n );\n }\n\n this._timestamp = timestamp - this._epoch;\n var res = this._packBigInt(this as any);\n this._increment = (this._increment + 1) & MAX_INCREMENT;\n\n return res;\n }\n\n /**\n * Generates a Snowflake ID as a `Uint8Array` buffer.\n *\n * ⚠️ Returns a reference to the **same** internal `Uint8Array` instance.\n * Its contents may be overwritten on the next ID generation call.\n *\n * This method is intended for high-performance scenarios where you\n * immediately transform the buffer (e.g., to base62) before calling again.\n * Avoid storing or mutating the returned buffer directly.\n */\n public generateBufferUnsafe(\n timestamp: Date | number = Date.now(),\n ): Uint8Array {\n if (timestamp instanceof Date) timestamp = timestamp.getTime();\n if (!isNumber(timestamp)) {\n throw new Error(\n `\"timestamp\" argument must be a number or Date (received ${typeof timestamp})`,\n );\n }\n\n this._timestamp = timestamp - this._epoch;\n this._packBuffer(this as any);\n this._increment = (this._increment + 1) & MAX_INCREMENT;\n\n return this.__buf;\n }\n\n /**\n * Generates a snowflake given an epoch and optionally a timestamp\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake({ epoch }).generate();\n * ```\n * @returns A unique snowflake as Uint8Array\n */\n public generateBuffer(timestamp: Date | number = Date.now()): Uint8Array {\n if (timestamp instanceof Date) timestamp = timestamp.getTime();\n if (!isNumber(timestamp)) {\n throw new Error(\n `\"timestamp\" argument must be a number or Date (received ${typeof timestamp})`,\n );\n }\n\n this.__buf = new Uint8Array(8);\n this._timestamp = timestamp - this._epoch;\n this._packBuffer(this as any);\n this._increment = (this._increment + 1) & MAX_INCREMENT;\n\n return this.__buf;\n }\n\n /**\n * Deconstructs a snowflake given a snowflake ID\n * @param id the snowflake to deconstruct\n * @returns a deconstructed snowflake\n * @example\n * ```typescript\n * const epoch = new Date('2000-01-01T00:00:00.000Z');\n * const snowflake = new Snowflake(epoch).deconstruct('3971046231244935168');\n * ```\n */\n public deconstruct(id: string | bigint | Uint8Array): DeconstructedSnowflake {\n if (isString(id)) {\n id = BigInt(id);\n }\n\n let result: DeconstructedSnowflake;\n\n if (isBigInt(id)) {\n result = this._unpackBigInt(id) as DeconstructedSnowflake;\n result.id = id;\n } else {\n result = this._unpackBuffer(id) as DeconstructedSnowflake;\n result.id = bigIntFromBytes(id);\n }\n\n result.timestamp += this._epoch;\n result.epoch = this._epoch;\n\n return result;\n }\n\n /**\n * Retrieves the timestamp field's value from a snowflake.\n * @param id The snowflake to get the timestamp value from.\n * @returns The UNIX timestamp that is stored in `id`.\n */\n public timestampFrom(id: string | bigint | Uint8Array): number {\n return this.deconstruct(id).timestamp;\n }\n\n /**\n * Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given\n * snowflake in sort order.\n * @param a The first snowflake to compare.\n * @param b The second snowflake to compare.\n * @returns `-1` if `a` is older than `b`, `0` if `a` and `b` are equals, `1` if `a` is newer than `b`.\n */\n public static compare(\n a: string | bigint | Uint8Array,\n b: string | bigint | Uint8Array,\n ): -1 | 0 | 1 {\n if (isString(a)) {\n a = BigInt(a);\n } else if (a instanceof Uint8Array) {\n a = bigIntFromBytes(a);\n }\n\n if (isString(b)) {\n b = BigInt(b);\n } else if (b instanceof Uint8Array) {\n b = bigIntFromBytes(b);\n }\n\n return a === b ? 0 : a < b ? -1 : 1;\n }\n\n /**\n * Parse value as Uint8Array buffer\n */\n public static bufferFrom(value: bigint | string): Uint8Array {\n if (isString(value)) value = BigInt(value);\n\n return new Uint8Array(bigintToBuffer(value));\n }\n}\n\nfunction bigintToBuffer(value: bigint): Uint8Array {\n if (value < 0n) {\n value = value * -1n;\n }\n for (var i = 0; i < 8; i++) {\n ENCODE_BIGINT_BUFFER[i] = Number(\n (value >> BigInt((8 - i - 1) * 8)) & 0xffn,\n );\n }\n return ENCODE_BIGINT_BUFFER;\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andrew_l/snowflake",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "Another implementation of snowflake id generator.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dist"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@andrew_l/toolkit": "0.3.
|
|
31
|
+
"@andrew_l/toolkit": "0.3.5"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@sapphire/snowflake": "^3.5.5",
|