162 lines
6.9 KiB
JavaScript
162 lines
6.9 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
|
/*! *****************************************************************************
|
|
Copyright (c) Microsoft Corporation.
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
purpose with or without fee is hereby granted.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|
***************************************************************************** */
|
|
|
|
function __classPrivateFieldGet(receiver, state, kind, f) {
|
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
}
|
|
|
|
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
}
|
|
|
|
var _Snowflake_increment, _Snowflake_epoch;
|
|
const ProcessId = 1n;
|
|
const WorkerId = 0n;
|
|
/**
|
|
* A class for generating and deconstructing Twitter snowflakes.
|
|
*
|
|
* A {@link https://developer.twitter.com/en/docs/twitter-ids Twitter snowflake}
|
|
* is a 64-bit unsigned integer with 4 fields that have a fixed epoch value.
|
|
*
|
|
* If we have a snowflake `266241948824764416` we can represent it as binary:
|
|
* ```
|
|
* 64 22 17 12 0
|
|
* 000000111011000111100001101001000101000000 00001 00000 000000000000
|
|
* number of ms since epoch worker pid increment
|
|
* ```
|
|
*/
|
|
class Snowflake {
|
|
/**
|
|
* @param epoch the epoch to use
|
|
*/
|
|
constructor(epoch) {
|
|
/**
|
|
* Internal incrementor for generating snowflakes
|
|
* @internal
|
|
*/
|
|
_Snowflake_increment.set(this, 0n);
|
|
/**
|
|
* Internal reference of the epoch passed in the constructor
|
|
* @internal
|
|
*/
|
|
_Snowflake_epoch.set(this, void 0);
|
|
/**
|
|
* Alias for {@link deconstruct}
|
|
*/
|
|
// eslint-disable-next-line @typescript-eslint/unbound-method, @typescript-eslint/no-invalid-this
|
|
Object.defineProperty(this, "decode", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: this.deconstruct
|
|
});
|
|
__classPrivateFieldSet(this, _Snowflake_epoch, BigInt(epoch instanceof Date ? epoch.getTime() : epoch), "f");
|
|
}
|
|
/**
|
|
* The epoch for this snowflake.
|
|
*/
|
|
get epoch() {
|
|
return __classPrivateFieldGet(this, _Snowflake_epoch, "f");
|
|
}
|
|
/**
|
|
* Generates a snowflake given an epoch and optionally a timestamp
|
|
* @param options options to pass into the generator, see {@link SnowflakeGenerateOptions}
|
|
*
|
|
* **note** when `increment` is not provided it defaults to the private `increment` of the instance
|
|
* @example
|
|
* ```typescript
|
|
* const epoch = new Date('2000-01-01T00:00:00.000Z');
|
|
* const snowflake = new Snowflake(epoch).generate();
|
|
* ```
|
|
* @returns A unique snowflake
|
|
*/
|
|
generate({ increment, timestamp = Date.now(), workerId = WorkerId, processId = ProcessId } = {}) {
|
|
var _a, _b;
|
|
if (timestamp instanceof Date)
|
|
timestamp = BigInt(timestamp.getTime());
|
|
else if (typeof timestamp === 'number')
|
|
timestamp = BigInt(timestamp);
|
|
else if (typeof timestamp !== 'bigint') {
|
|
throw new TypeError(`"timestamp" argument must be a number, bigint, or Date (received ${typeof timestamp})`);
|
|
}
|
|
if (typeof increment === 'bigint' && increment >= 4095n)
|
|
increment = 0n;
|
|
else {
|
|
increment = (__classPrivateFieldSet(this, _Snowflake_increment, (_b = __classPrivateFieldGet(this, _Snowflake_increment, "f"), _a = _b++, _b), "f"), _a);
|
|
if (__classPrivateFieldGet(this, _Snowflake_increment, "f") >= 4095n)
|
|
__classPrivateFieldSet(this, _Snowflake_increment, 0n, "f");
|
|
}
|
|
// timestamp, workerId, processId, increment
|
|
return ((timestamp - __classPrivateFieldGet(this, _Snowflake_epoch, "f")) << 22n) | ((workerId & 31n) << 17n) | ((processId & 31n) << 12n) | increment;
|
|
}
|
|
/**
|
|
* Deconstructs a snowflake given a snowflake ID
|
|
* @param id the snowflake to deconstruct
|
|
* @returns a deconstructed snowflake
|
|
* @example
|
|
* ```typescript
|
|
* const epoch = new Date('2000-01-01T00:00:00.000Z');
|
|
* const snowflake = new Snowflake(epoch).deconstruct('3971046231244935168');
|
|
* ```
|
|
*/
|
|
deconstruct(id) {
|
|
const bigIntId = BigInt(id);
|
|
return {
|
|
id: bigIntId,
|
|
timestamp: (bigIntId >> 22n) + __classPrivateFieldGet(this, _Snowflake_epoch, "f"),
|
|
workerId: (bigIntId >> 17n) & 31n,
|
|
processId: (bigIntId >> 12n) & 31n,
|
|
increment: bigIntId & 4095n,
|
|
epoch: __classPrivateFieldGet(this, _Snowflake_epoch, "f")
|
|
};
|
|
}
|
|
/**
|
|
* Retrieves the timestamp field's value from a snowflake.
|
|
* @param id The snowflake to get the timestamp value from.
|
|
* @returns The UNIX timestamp that is stored in `id`.
|
|
*/
|
|
timestampFrom(id) {
|
|
return Number((BigInt(id) >> 22n) + __classPrivateFieldGet(this, _Snowflake_epoch, "f"));
|
|
}
|
|
}
|
|
_Snowflake_increment = new WeakMap(), _Snowflake_epoch = new WeakMap();
|
|
|
|
/**
|
|
* A class for parsing snowflake ids using Discord's snowflake epoch
|
|
*
|
|
* Which is 2015-01-01 at 00:00:00.000 UTC+0, {@linkplain https://discord.com/developers/docs/reference#snowflakes}
|
|
*/
|
|
const DiscordSnowflake = new Snowflake(1420070400000n);
|
|
|
|
/**
|
|
* A class for parsing snowflake ids using Twitter's snowflake epoch
|
|
*
|
|
* Which is 2006-03-21 at 20:50:14.000 UTC+0, the time and date of the first tweet ever made {@linkplain https://twitter.com/jack/status/20}
|
|
*/
|
|
const TwitterSnowflake = new Snowflake(1142974214000n);
|
|
|
|
exports.DiscordSnowflake = DiscordSnowflake;
|
|
exports.Snowflake = Snowflake;
|
|
exports.TwitterSnowflake = TwitterSnowflake;
|
|
//# sourceMappingURL=index.js.map
|