@sapphire/snowflake 3.4.3 → 3.5.0
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/CHANGELOG.md +6 -0
- package/dist/index.d.ts +43 -2
- package/dist/index.global.js +62 -45
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +62 -45
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +62 -45
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
# [@sapphire/snowflake@3.5.0](https://github.com/sapphiredev/utilities/compare/@sapphire/snowflake@3.4.3...@sapphire/snowflake@3.5.0) - (2023-05-10)
|
|
6
|
+
|
|
7
|
+
## 🚀 Features
|
|
8
|
+
|
|
9
|
+
- **snowflake:** Expose `processId` and `workerId` (#595) ([b873c1c](https://github.com/sapphiredev/utilities/commit/b873c1cc3b30cb54d710a49f7618e125ac1132ad))
|
|
10
|
+
|
|
5
11
|
# [@sapphire/snowflake@3.4.2](https://github.com/sapphiredev/utilities/compare/@sapphire/snowflake@3.4.1...@sapphire/snowflake@3.4.2) - (2023-04-12)
|
|
6
12
|
|
|
7
13
|
## 🏠 Refactor
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
declare const IncrementSymbol: unique symbol;
|
|
2
|
+
declare const EpochSymbol: unique symbol;
|
|
3
|
+
declare const ProcessIdSymbol: unique symbol;
|
|
4
|
+
declare const WorkerIdSymbol: unique symbol;
|
|
1
5
|
/**
|
|
2
6
|
* A class for generating and deconstructing Twitter snowflakes.
|
|
3
7
|
*
|
|
@@ -12,19 +16,56 @@
|
|
|
12
16
|
* ```
|
|
13
17
|
*/
|
|
14
18
|
declare class Snowflake {
|
|
15
|
-
#private;
|
|
16
19
|
/**
|
|
17
20
|
* Alias for {@link deconstruct}
|
|
18
21
|
*/
|
|
19
22
|
decode: (id: string | bigint) => DeconstructedSnowflake;
|
|
23
|
+
/**
|
|
24
|
+
* Internal reference of the epoch passed in the constructor
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
private readonly [EpochSymbol];
|
|
28
|
+
/**
|
|
29
|
+
* Internal incrementor for generating snowflakes
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
32
|
+
private [IncrementSymbol];
|
|
33
|
+
/**
|
|
34
|
+
* The process ID that will be used by default in the generate method
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
private [ProcessIdSymbol];
|
|
38
|
+
/**
|
|
39
|
+
* The worker ID that will be used by default in the generate method
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
private [WorkerIdSymbol];
|
|
20
43
|
/**
|
|
21
44
|
* @param epoch the epoch to use
|
|
22
45
|
*/
|
|
23
46
|
constructor(epoch: number | bigint | Date);
|
|
24
47
|
/**
|
|
25
|
-
* The epoch for this snowflake
|
|
48
|
+
* The epoch for this snowflake
|
|
26
49
|
*/
|
|
27
50
|
get epoch(): bigint;
|
|
51
|
+
/**
|
|
52
|
+
* Gets the configured process ID
|
|
53
|
+
*/
|
|
54
|
+
get processId(): bigint;
|
|
55
|
+
/**
|
|
56
|
+
* Sets the process ID that will be used by default for the {@link generate} method
|
|
57
|
+
* @param value The new value, will be coerced to BigInt and masked with `0b11111n`
|
|
58
|
+
*/
|
|
59
|
+
set processId(value: number | bigint);
|
|
60
|
+
/**
|
|
61
|
+
* Gets the configured worker ID
|
|
62
|
+
*/
|
|
63
|
+
get workerId(): bigint;
|
|
64
|
+
/**
|
|
65
|
+
* Sets the worker ID that will be used by default for the {@link generate} method
|
|
66
|
+
* @param value The new value, will be coerced to BigInt and masked with `0b11111n`
|
|
67
|
+
*/
|
|
68
|
+
set workerId(value: number | bigint);
|
|
28
69
|
/**
|
|
29
70
|
* Generates a snowflake given an epoch and optionally a timestamp
|
|
30
71
|
* @param options options to pass into the generator, see {@link SnowflakeGenerateOptions}
|
package/dist/index.global.js
CHANGED
|
@@ -8,37 +8,13 @@ var SapphireSnowflake = (function (exports) {
|
|
|
8
8
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
9
9
|
return value;
|
|
10
10
|
};
|
|
11
|
-
var __accessCheck = (obj, member, msg) => {
|
|
12
|
-
if (!member.has(obj))
|
|
13
|
-
throw TypeError("Cannot " + msg);
|
|
14
|
-
};
|
|
15
|
-
var __privateGet = (obj, member, getter) => {
|
|
16
|
-
__accessCheck(obj, member, "read from private field");
|
|
17
|
-
return getter ? getter.call(obj) : member.get(obj);
|
|
18
|
-
};
|
|
19
|
-
var __privateAdd = (obj, member, value) => {
|
|
20
|
-
if (member.has(obj))
|
|
21
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
22
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
23
|
-
};
|
|
24
|
-
var __privateSet = (obj, member, value, setter) => {
|
|
25
|
-
__accessCheck(obj, member, "write to private field");
|
|
26
|
-
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
27
|
-
return value;
|
|
28
|
-
};
|
|
29
|
-
var __privateWrapper = (obj, member, setter, getter) => ({
|
|
30
|
-
set _(value) {
|
|
31
|
-
__privateSet(obj, member, value, setter);
|
|
32
|
-
},
|
|
33
|
-
get _() {
|
|
34
|
-
return __privateGet(obj, member, getter);
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
11
|
|
|
38
12
|
// src/lib/Snowflake.ts
|
|
39
|
-
var
|
|
40
|
-
var
|
|
41
|
-
var
|
|
13
|
+
var IncrementSymbol = Symbol("@sapphire/snowflake.increment");
|
|
14
|
+
var EpochSymbol = Symbol("@sapphire/snowflake.epoch");
|
|
15
|
+
var ProcessIdSymbol = Symbol("@sapphire/snowflake.processId");
|
|
16
|
+
var WorkerIdSymbol = Symbol("@sapphire/snowflake.workerId");
|
|
17
|
+
var _a, _b, _c, _d;
|
|
42
18
|
var Snowflake = class {
|
|
43
19
|
/**
|
|
44
20
|
* @param epoch the epoch to use
|
|
@@ -49,23 +25,59 @@ var SapphireSnowflake = (function (exports) {
|
|
|
49
25
|
*/
|
|
50
26
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
51
27
|
__publicField(this, "decode", this.deconstruct);
|
|
28
|
+
/**
|
|
29
|
+
* Internal reference of the epoch passed in the constructor
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
32
|
+
__publicField(this, _a);
|
|
52
33
|
/**
|
|
53
34
|
* Internal incrementor for generating snowflakes
|
|
54
35
|
* @internal
|
|
55
36
|
*/
|
|
56
|
-
|
|
37
|
+
__publicField(this, _b, 0n);
|
|
57
38
|
/**
|
|
58
|
-
*
|
|
39
|
+
* The process ID that will be used by default in the generate method
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
__publicField(this, _c, 1n);
|
|
43
|
+
/**
|
|
44
|
+
* The worker ID that will be used by default in the generate method
|
|
59
45
|
* @internal
|
|
60
46
|
*/
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
__publicField(this, _d, 0n);
|
|
48
|
+
this[EpochSymbol] = BigInt(epoch instanceof Date ? epoch.getTime() : epoch);
|
|
63
49
|
}
|
|
64
50
|
/**
|
|
65
|
-
* The epoch for this snowflake
|
|
51
|
+
* The epoch for this snowflake
|
|
66
52
|
*/
|
|
67
53
|
get epoch() {
|
|
68
|
-
return
|
|
54
|
+
return this[EpochSymbol];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Gets the configured process ID
|
|
58
|
+
*/
|
|
59
|
+
get processId() {
|
|
60
|
+
return this[ProcessIdSymbol];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Sets the process ID that will be used by default for the {@link generate} method
|
|
64
|
+
* @param value The new value, will be coerced to BigInt and masked with `0b11111n`
|
|
65
|
+
*/
|
|
66
|
+
set processId(value) {
|
|
67
|
+
this[ProcessIdSymbol] = BigInt(value) & 0b11111n;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Gets the configured worker ID
|
|
71
|
+
*/
|
|
72
|
+
get workerId() {
|
|
73
|
+
return this[WorkerIdSymbol];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Sets the worker ID that will be used by default for the {@link generate} method
|
|
77
|
+
* @param value The new value, will be coerced to BigInt and masked with `0b11111n`
|
|
78
|
+
*/
|
|
79
|
+
set workerId(value) {
|
|
80
|
+
this[WorkerIdSymbol] = BigInt(value) & 0b11111n;
|
|
69
81
|
}
|
|
70
82
|
/**
|
|
71
83
|
* Generates a snowflake given an epoch and optionally a timestamp
|
|
@@ -79,7 +91,12 @@ var SapphireSnowflake = (function (exports) {
|
|
|
79
91
|
* ```
|
|
80
92
|
* @returns A unique snowflake
|
|
81
93
|
*/
|
|
82
|
-
generate({
|
|
94
|
+
generate({
|
|
95
|
+
increment,
|
|
96
|
+
timestamp = Date.now(),
|
|
97
|
+
workerId = this[WorkerIdSymbol],
|
|
98
|
+
processId = this[ProcessIdSymbol]
|
|
99
|
+
} = {}) {
|
|
83
100
|
if (timestamp instanceof Date)
|
|
84
101
|
timestamp = BigInt(timestamp.getTime());
|
|
85
102
|
else if (typeof timestamp === "number")
|
|
@@ -90,11 +107,11 @@ var SapphireSnowflake = (function (exports) {
|
|
|
90
107
|
if (typeof increment === "bigint" && increment >= 4095n)
|
|
91
108
|
increment = 0n;
|
|
92
109
|
else {
|
|
93
|
-
increment =
|
|
94
|
-
if (
|
|
95
|
-
|
|
110
|
+
increment = this[IncrementSymbol]++;
|
|
111
|
+
if (this[IncrementSymbol] >= 4095n)
|
|
112
|
+
this[IncrementSymbol] = 0n;
|
|
96
113
|
}
|
|
97
|
-
return timestamp -
|
|
114
|
+
return timestamp - this[EpochSymbol] << 22n | (workerId & 0b11111n) << 17n | (processId & 0b11111n) << 12n | increment;
|
|
98
115
|
}
|
|
99
116
|
/**
|
|
100
117
|
* Deconstructs a snowflake given a snowflake ID
|
|
@@ -108,13 +125,14 @@ var SapphireSnowflake = (function (exports) {
|
|
|
108
125
|
*/
|
|
109
126
|
deconstruct(id) {
|
|
110
127
|
const bigIntId = BigInt(id);
|
|
128
|
+
const epoch = this[EpochSymbol];
|
|
111
129
|
return {
|
|
112
130
|
id: bigIntId,
|
|
113
|
-
timestamp: (bigIntId >> 22n) +
|
|
131
|
+
timestamp: (bigIntId >> 22n) + epoch,
|
|
114
132
|
workerId: bigIntId >> 17n & 0b11111n,
|
|
115
133
|
processId: bigIntId >> 12n & 0b11111n,
|
|
116
134
|
increment: bigIntId & 0b111111111111n,
|
|
117
|
-
epoch
|
|
135
|
+
epoch
|
|
118
136
|
};
|
|
119
137
|
}
|
|
120
138
|
/**
|
|
@@ -123,7 +141,7 @@ var SapphireSnowflake = (function (exports) {
|
|
|
123
141
|
* @returns The UNIX timestamp that is stored in `id`.
|
|
124
142
|
*/
|
|
125
143
|
timestampFrom(id) {
|
|
126
|
-
return Number((BigInt(id) >> 22n) +
|
|
144
|
+
return Number((BigInt(id) >> 22n) + this[EpochSymbol]);
|
|
127
145
|
}
|
|
128
146
|
/**
|
|
129
147
|
* Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given
|
|
@@ -150,8 +168,7 @@ var SapphireSnowflake = (function (exports) {
|
|
|
150
168
|
}
|
|
151
169
|
};
|
|
152
170
|
__name(Snowflake, "Snowflake");
|
|
153
|
-
|
|
154
|
-
_epoch = new WeakMap();
|
|
171
|
+
_a = EpochSymbol, _b = IncrementSymbol, _c = ProcessIdSymbol, _d = WorkerIdSymbol;
|
|
155
172
|
function cmpBigInt(a, b) {
|
|
156
173
|
return a === b ? 0 : a < b ? -1 : 1;
|
|
157
174
|
}
|
package/dist/index.global.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/Snowflake.ts","../src/lib/DiscordSnowflake.ts","../src/lib/TwitterSnowflake.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAM,YAAY;AAClB,IAAM,WAAW;AADjB;AAgBO,IAAM,YAAN,MAAgB;AAAA;AAAA;AAAA;AAAA,EAsBf,YAAY,OAA+B;AAjBlD;AAAA;AAAA;AAAA;AAAA,wBAAO,UAAS,KAAK;AAMrB;AAAA;AAAA;AAAA;AAAA,mCAAa;AAMb;AAAA;AAAA;AAAA;AAAA;AAMC,uBAAK,QAAS,OAAO,iBAAiB,OAAO,MAAM,QAAQ,IAAI,KAAK;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,IAAW,QAAgB;AAC1B,WAAO,mBAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcO,SAAS,EAAE,WAAW,YAAY,KAAK,IAAI,GAAG,WAAW,UAAU,YAAY,UAAU,IAA8B,CAAC,GAAG;AACjI,QAAI,qBAAqB;AAAM,kBAAY,OAAO,UAAU,QAAQ,CAAC;AAAA,aAC5D,OAAO,cAAc;AAAU,kBAAY,OAAO,SAAS;AAAA,aAC3D,OAAO,cAAc,UAAU;AACvC,YAAM,IAAI,UAAU,oEAAoE,OAAO,YAAY;AAAA,IAC5G;AAEA,QAAI,OAAO,cAAc,YAAY,aAAa;AAAO,kBAAY;AAAA,SAChE;AACJ,kBAAY,uBAAK,YAAL;AACZ,UAAI,mBAAK,eAAc;AAAO,2BAAK,YAAa;AAAA,IACjD;AAGA,WAAS,YAAY,mBAAK,WAAW,OAAS,WAAW,aAAa,OAAS,YAAY,aAAa,MAAO;AAAA,EAChH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYO,YAAY,IAA6C;AAC/D,UAAM,WAAW,OAAO,EAAE;AAC1B,WAAO;AAAA,MACN,IAAI;AAAA,MACJ,YAAY,YAAY,OAAO,mBAAK;AAAA,MACpC,UAAW,YAAY,MAAO;AAAA,MAC9B,WAAY,YAAY,MAAO;AAAA,MAC/B,WAAW,WAAW;AAAA,MACtB,OAAO,mBAAK;AAAA,IACb;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,cAAc,IAA6B;AACjD,WAAO,QAAQ,OAAO,EAAE,KAAK,OAAO,mBAAK,OAAM;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,OAAc,QAAQ,GAAoB,GAAgC;AACzE,UAAM,QAAQ,OAAO;AACrB,WAAO,UAAU,OAAO,IACrB,UAAU,WACT,UAAU,GAAa,CAAW,IAClC,UAAU,GAAa,CAAW,IACnC,UAAU,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,EAClC;AACD;AAxHa;AAWZ;AAMA;AA0GD,SAAS,UAAU,GAAW,GAAW;AACxC,SAAO,MAAM,IAAI,IAAI,IAAI,IAAI,KAAK;AACnC;AAFS;AAKT,SAAS,UAAU,GAAW,GAAW;AACxC,SAAO,MAAM,IAAI,IAAI,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,IAAI,KAAK;AACxF;AAFS;;;ACzIF,IAAM,mBAAmB,IAAI,UAAU,cAAc;;;ACArD,IAAM,mBAAmB,IAAI,UAAU,cAAc","sourcesContent":["const ProcessId = 1n;\nconst WorkerId = 0n;\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 */\nexport class Snowflake {\n\t/**\n\t * Alias for {@link deconstruct}\n\t */\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tpublic decode = this.deconstruct;\n\n\t/**\n\t * Internal incrementor for generating snowflakes\n\t * @internal\n\t */\n\t#increment = 0n;\n\n\t/**\n\t * Internal reference of the epoch passed in the constructor\n\t * @internal\n\t */\n\t#epoch: bigint;\n\n\t/**\n\t * @param epoch the epoch to use\n\t */\n\tpublic constructor(epoch: number | bigint | Date) {\n\t\tthis.#epoch = BigInt(epoch instanceof Date ? epoch.getTime() : epoch);\n\t}\n\n\t/**\n\t * The epoch for this snowflake.\n\t */\n\tpublic get epoch(): bigint {\n\t\treturn this.#epoch;\n\t}\n\n\t/**\n\t * Generates a snowflake given an epoch and optionally a timestamp\n\t * @param options options to pass into the generator, see {@link SnowflakeGenerateOptions}\n\t *\n\t * **note** when `increment` is not provided it defaults to the private `increment` of the instance\n\t * @example\n\t * ```typescript\n\t * const epoch = new Date('2000-01-01T00:00:00.000Z');\n\t * const snowflake = new Snowflake(epoch).generate();\n\t * ```\n\t * @returns A unique snowflake\n\t */\n\tpublic generate({ increment, timestamp = Date.now(), workerId = WorkerId, processId = ProcessId }: SnowflakeGenerateOptions = {}) {\n\t\tif (timestamp instanceof Date) timestamp = BigInt(timestamp.getTime());\n\t\telse if (typeof timestamp === 'number') timestamp = BigInt(timestamp);\n\t\telse if (typeof timestamp !== 'bigint') {\n\t\t\tthrow new TypeError(`\"timestamp\" argument must be a number, bigint, or Date (received ${typeof timestamp})`);\n\t\t}\n\n\t\tif (typeof increment === 'bigint' && increment >= 4095n) increment = 0n;\n\t\telse {\n\t\t\tincrement = this.#increment++;\n\t\t\tif (this.#increment >= 4095n) this.#increment = 0n;\n\t\t}\n\n\t\t// timestamp, workerId, processId, increment\n\t\treturn ((timestamp - this.#epoch) << 22n) | ((workerId & 0b11111n) << 17n) | ((processId & 0b11111n) << 12n) | increment;\n\t}\n\n\t/**\n\t * Deconstructs a snowflake given a snowflake ID\n\t * @param id the snowflake to deconstruct\n\t * @returns a deconstructed snowflake\n\t * @example\n\t * ```typescript\n\t * const epoch = new Date('2000-01-01T00:00:00.000Z');\n\t * const snowflake = new Snowflake(epoch).deconstruct('3971046231244935168');\n\t * ```\n\t */\n\tpublic deconstruct(id: string | bigint): DeconstructedSnowflake {\n\t\tconst bigIntId = BigInt(id);\n\t\treturn {\n\t\t\tid: bigIntId,\n\t\t\ttimestamp: (bigIntId >> 22n) + this.#epoch,\n\t\t\tworkerId: (bigIntId >> 17n) & 0b11111n,\n\t\t\tprocessId: (bigIntId >> 12n) & 0b11111n,\n\t\t\tincrement: bigIntId & 0b111111111111n,\n\t\t\tepoch: this.#epoch\n\t\t};\n\t}\n\n\t/**\n\t * Retrieves the timestamp field's value from a snowflake.\n\t * @param id The snowflake to get the timestamp value from.\n\t * @returns The UNIX timestamp that is stored in `id`.\n\t */\n\tpublic timestampFrom(id: string | bigint): number {\n\t\treturn Number((BigInt(id) >> 22n) + this.#epoch);\n\t}\n\n\t/**\n\t * Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given\n\t * snowflake in sort order.\n\t * @param a The first snowflake to compare.\n\t * @param b The second snowflake to compare.\n\t * @returns `-1` if `a` is older than `b`, `0` if `a` and `b` are equals, `1` if `a` is newer than `b`.\n\t * @example Sort snowflakes in ascending order\n\t * ```typescript\n\t * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];\n\t * console.log(ids.sort((a, b) => Snowflake.compare(a, b)));\n\t * // → ['254360814063058944', '737141877803057244', '1056191128120082432'];\n\t * ```\n\t * @example Sort snowflakes in descending order\n\t * ```typescript\n\t * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];\n\t * console.log(ids.sort((a, b) => -Snowflake.compare(a, b)));\n\t * // → ['1056191128120082432', '737141877803057244', '254360814063058944'];\n\t * ```\n\t */\n\tpublic static compare(a: string | bigint, b: string | bigint): -1 | 0 | 1 {\n\t\tconst typeA = typeof a;\n\t\treturn typeA === typeof b\n\t\t\t? typeA === 'string'\n\t\t\t\t? cmpString(a as string, b as string)\n\t\t\t\t: cmpBigInt(a as bigint, b as bigint)\n\t\t\t: cmpBigInt(BigInt(a), BigInt(b));\n\t}\n}\n\n/** @internal */\nfunction cmpBigInt(a: bigint, b: bigint) {\n\treturn a === b ? 0 : a < b ? -1 : 1;\n}\n\n/** @internal */\nfunction cmpString(a: string, b: string) {\n\treturn a === b ? 0 : a.length < b.length ? -1 : a.length > b.length ? 1 : a < b ? -1 : 1;\n}\n\n/**\n * Options for Snowflake#generate\n */\nexport interface SnowflakeGenerateOptions {\n\t/**\n\t * Timestamp or date of the snowflake to generate\n\t * @default Date.now()\n\t */\n\ttimestamp?: number | bigint | Date;\n\n\t/**\n\t * The increment to use\n\t * @default 0n\n\t * @remark keep in mind that this bigint is auto-incremented between generate calls\n\t */\n\tincrement?: bigint;\n\n\t/**\n\t * The worker ID to use, will be truncated to 5 bits (0-31)\n\t * @default 0n\n\t */\n\tworkerId?: bigint;\n\n\t/**\n\t * The process ID to use, will be truncated to 5 bits (0-31)\n\t * @default 1n\n\t */\n\tprocessId?: bigint;\n}\n\n/**\n * Object returned by Snowflake#deconstruct\n */\nexport interface DeconstructedSnowflake {\n\t/**\n\t * The id in BigInt form\n\t */\n\tid: bigint;\n\n\t/**\n\t * The timestamp stored in the snowflake\n\t */\n\ttimestamp: bigint;\n\n\t/**\n\t * The worker id stored in the snowflake\n\t */\n\tworkerId: bigint;\n\n\t/**\n\t * The process id stored in the snowflake\n\t */\n\tprocessId: bigint;\n\n\t/**\n\t * The increment stored in the snowflake\n\t */\n\tincrement: bigint;\n\n\t/**\n\t * The epoch to use in the snowflake\n\t */\n\tepoch: bigint;\n}\n","import { Snowflake } from './Snowflake';\n\n/**\n * A class for parsing snowflake ids using Discord's snowflake epoch\n *\n * Which is 2015-01-01 at 00:00:00.000 UTC+0, {@linkplain https://discord.com/developers/docs/reference#snowflakes}\n */\nexport const DiscordSnowflake = new Snowflake(1420070400000n);\n","import { Snowflake } from './Snowflake';\n\n/**\n * A class for parsing snowflake ids using Twitter's snowflake epoch\n *\n * Which is 2010-11-04 at 01:42:54.657 UTC+0, found in the archived snowflake repository {@linkplain https://github.com/twitter-archive/snowflake/blob/b3f6a3c6ca8e1b6847baa6ff42bf72201e2c2231/src/main/scala/com/twitter/service/snowflake/IdWorker.scala#L25}\n */\nexport const TwitterSnowflake = new Snowflake(1288834974657n);\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/Snowflake.ts","../src/lib/DiscordSnowflake.ts","../src/lib/TwitterSnowflake.ts"],"names":[],"mappings":";;;;;;;;;AAAA,IAAM,kBAAkB,OAAO,+BAA+B;AAC9D,IAAM,cAAc,OAAO,2BAA2B;AACtD,IAAM,kBAAkB,OAAO,+BAA+B;AAC9D,IAAM,iBAAiB,OAAO,8BAA8B;AAH5D;AAkBO,IAAM,YAAN,MAAgB;AAAA;AAAA;AAAA;AAAA,EAkCf,YAAY,OAA+B;AA7BlD;AAAA;AAAA;AAAA;AAAA,wBAAO,UAAS,KAAK;AAMrB;AAAA;AAAA;AAAA;AAAA,wBAAkB;AAMlB;AAAA;AAAA;AAAA;AAAA,wBAAS,IAAmB;AAM5B;AAAA;AAAA;AAAA;AAAA,wBAAS,IAAmB;AAM5B;AAAA;AAAA;AAAA;AAAA,wBAAS,IAAkB;AAM1B,SAAK,WAAW,IAAI,OAAO,iBAAiB,OAAO,MAAM,QAAQ,IAAI,KAAK;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKA,IAAW,QAAgB;AAC1B,WAAO,KAAK,WAAW;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAW,YAAoB;AAC9B,WAAO,KAAK,eAAe;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,UAAU,OAAwB;AAC5C,SAAK,eAAe,IAAI,OAAO,KAAK,IAAI;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAW,WAAmB;AAC7B,WAAO,KAAK,cAAc;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,SAAS,OAAwB;AAC3C,SAAK,cAAc,IAAI,OAAO,KAAK,IAAI;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcO,SAAS;AAAA,IACf;AAAA,IACA,YAAY,KAAK,IAAI;AAAA,IACrB,WAAW,KAAK,cAAc;AAAA,IAC9B,YAAY,KAAK,eAAe;AAAA,EACjC,IAA8B,CAAC,GAAG;AACjC,QAAI,qBAAqB;AAAM,kBAAY,OAAO,UAAU,QAAQ,CAAC;AAAA,aAC5D,OAAO,cAAc;AAAU,kBAAY,OAAO,SAAS;AAAA,aAC3D,OAAO,cAAc,UAAU;AACvC,YAAM,IAAI,UAAU,oEAAoE,OAAO,YAAY;AAAA,IAC5G;AAEA,QAAI,OAAO,cAAc,YAAY,aAAa;AAAO,kBAAY;AAAA,SAChE;AACJ,kBAAY,KAAK,eAAe;AAChC,UAAI,KAAK,eAAe,KAAK;AAAO,aAAK,eAAe,IAAI;AAAA,IAC7D;AAGA,WAAS,YAAY,KAAK,WAAW,KAAM,OAAS,WAAW,aAAa,OAAS,YAAY,aAAa,MAAO;AAAA,EACtH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYO,YAAY,IAA6C;AAC/D,UAAM,WAAW,OAAO,EAAE;AAC1B,UAAM,QAAQ,KAAK,WAAW;AAC9B,WAAO;AAAA,MACN,IAAI;AAAA,MACJ,YAAY,YAAY,OAAO;AAAA,MAC/B,UAAW,YAAY,MAAO;AAAA,MAC9B,WAAY,YAAY,MAAO;AAAA,MAC/B,WAAW,WAAW;AAAA,MACtB;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,cAAc,IAA6B;AACjD,WAAO,QAAQ,OAAO,EAAE,KAAK,OAAO,KAAK,WAAW,CAAC;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,OAAc,QAAQ,GAAoB,GAAgC;AACzE,UAAM,QAAQ,OAAO;AACrB,WAAO,UAAU,OAAO,IACrB,UAAU,WACT,UAAU,GAAa,CAAW,IAClC,UAAU,GAAa,CAAW,IACnC,UAAU,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,EAClC;AACD;AAxKa;AAWM,kBAMT,sBAMA,sBAMA;AA8IV,SAAS,UAAU,GAAW,GAAW;AACxC,SAAO,MAAM,IAAI,IAAI,IAAI,IAAI,KAAK;AACnC;AAFS;AAKT,SAAS,UAAU,GAAW,GAAW;AACxC,SAAO,MAAM,IAAI,IAAI,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,IAAI,KAAK;AACxF;AAFS;;;AC3LF,IAAM,mBAAmB,IAAI,UAAU,cAAc;;;ACArD,IAAM,mBAAmB,IAAI,UAAU,cAAc","sourcesContent":["const IncrementSymbol = Symbol('@sapphire/snowflake.increment');\nconst EpochSymbol = Symbol('@sapphire/snowflake.epoch');\nconst ProcessIdSymbol = Symbol('@sapphire/snowflake.processId');\nconst WorkerIdSymbol = Symbol('@sapphire/snowflake.workerId');\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 */\nexport class Snowflake {\n\t/**\n\t * Alias for {@link deconstruct}\n\t */\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tpublic decode = this.deconstruct;\n\n\t/**\n\t * Internal reference of the epoch passed in the constructor\n\t * @internal\n\t */\n\tprivate readonly [EpochSymbol]: bigint;\n\n\t/**\n\t * Internal incrementor for generating snowflakes\n\t * @internal\n\t */\n\tprivate [IncrementSymbol] = 0n;\n\n\t/**\n\t * The process ID that will be used by default in the generate method\n\t * @internal\n\t */\n\tprivate [ProcessIdSymbol] = 1n;\n\n\t/**\n\t * The worker ID that will be used by default in the generate method\n\t * @internal\n\t */\n\tprivate [WorkerIdSymbol] = 0n;\n\n\t/**\n\t * @param epoch the epoch to use\n\t */\n\tpublic constructor(epoch: number | bigint | Date) {\n\t\tthis[EpochSymbol] = BigInt(epoch instanceof Date ? epoch.getTime() : epoch);\n\t}\n\n\t/**\n\t * The epoch for this snowflake\n\t */\n\tpublic get epoch(): bigint {\n\t\treturn this[EpochSymbol];\n\t}\n\n\t/**\n\t * Gets the configured process ID\n\t */\n\tpublic get processId(): bigint {\n\t\treturn this[ProcessIdSymbol];\n\t}\n\n\t/**\n\t * Sets the process ID that will be used by default for the {@link generate} method\n\t * @param value The new value, will be coerced to BigInt and masked with `0b11111n`\n\t */\n\tpublic set processId(value: number | bigint) {\n\t\tthis[ProcessIdSymbol] = BigInt(value) & 0b11111n;\n\t}\n\n\t/**\n\t * Gets the configured worker ID\n\t */\n\tpublic get workerId(): bigint {\n\t\treturn this[WorkerIdSymbol];\n\t}\n\n\t/**\n\t * Sets the worker ID that will be used by default for the {@link generate} method\n\t * @param value The new value, will be coerced to BigInt and masked with `0b11111n`\n\t */\n\tpublic set workerId(value: number | bigint) {\n\t\tthis[WorkerIdSymbol] = BigInt(value) & 0b11111n;\n\t}\n\n\t/**\n\t * Generates a snowflake given an epoch and optionally a timestamp\n\t * @param options options to pass into the generator, see {@link SnowflakeGenerateOptions}\n\t *\n\t * **note** when `increment` is not provided it defaults to the private `increment` of the instance\n\t * @example\n\t * ```typescript\n\t * const epoch = new Date('2000-01-01T00:00:00.000Z');\n\t * const snowflake = new Snowflake(epoch).generate();\n\t * ```\n\t * @returns A unique snowflake\n\t */\n\tpublic generate({\n\t\tincrement,\n\t\ttimestamp = Date.now(),\n\t\tworkerId = this[WorkerIdSymbol],\n\t\tprocessId = this[ProcessIdSymbol]\n\t}: SnowflakeGenerateOptions = {}) {\n\t\tif (timestamp instanceof Date) timestamp = BigInt(timestamp.getTime());\n\t\telse if (typeof timestamp === 'number') timestamp = BigInt(timestamp);\n\t\telse if (typeof timestamp !== 'bigint') {\n\t\t\tthrow new TypeError(`\"timestamp\" argument must be a number, bigint, or Date (received ${typeof timestamp})`);\n\t\t}\n\n\t\tif (typeof increment === 'bigint' && increment >= 4095n) increment = 0n;\n\t\telse {\n\t\t\tincrement = this[IncrementSymbol]++;\n\t\t\tif (this[IncrementSymbol] >= 4095n) this[IncrementSymbol] = 0n;\n\t\t}\n\n\t\t// timestamp, workerId, processId, increment\n\t\treturn ((timestamp - this[EpochSymbol]) << 22n) | ((workerId & 0b11111n) << 17n) | ((processId & 0b11111n) << 12n) | increment;\n\t}\n\n\t/**\n\t * Deconstructs a snowflake given a snowflake ID\n\t * @param id the snowflake to deconstruct\n\t * @returns a deconstructed snowflake\n\t * @example\n\t * ```typescript\n\t * const epoch = new Date('2000-01-01T00:00:00.000Z');\n\t * const snowflake = new Snowflake(epoch).deconstruct('3971046231244935168');\n\t * ```\n\t */\n\tpublic deconstruct(id: string | bigint): DeconstructedSnowflake {\n\t\tconst bigIntId = BigInt(id);\n\t\tconst epoch = this[EpochSymbol];\n\t\treturn {\n\t\t\tid: bigIntId,\n\t\t\ttimestamp: (bigIntId >> 22n) + epoch,\n\t\t\tworkerId: (bigIntId >> 17n) & 0b11111n,\n\t\t\tprocessId: (bigIntId >> 12n) & 0b11111n,\n\t\t\tincrement: bigIntId & 0b111111111111n,\n\t\t\tepoch\n\t\t};\n\t}\n\n\t/**\n\t * Retrieves the timestamp field's value from a snowflake.\n\t * @param id The snowflake to get the timestamp value from.\n\t * @returns The UNIX timestamp that is stored in `id`.\n\t */\n\tpublic timestampFrom(id: string | bigint): number {\n\t\treturn Number((BigInt(id) >> 22n) + this[EpochSymbol]);\n\t}\n\n\t/**\n\t * Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given\n\t * snowflake in sort order.\n\t * @param a The first snowflake to compare.\n\t * @param b The second snowflake to compare.\n\t * @returns `-1` if `a` is older than `b`, `0` if `a` and `b` are equals, `1` if `a` is newer than `b`.\n\t * @example Sort snowflakes in ascending order\n\t * ```typescript\n\t * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];\n\t * console.log(ids.sort((a, b) => Snowflake.compare(a, b)));\n\t * // → ['254360814063058944', '737141877803057244', '1056191128120082432'];\n\t * ```\n\t * @example Sort snowflakes in descending order\n\t * ```typescript\n\t * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];\n\t * console.log(ids.sort((a, b) => -Snowflake.compare(a, b)));\n\t * // → ['1056191128120082432', '737141877803057244', '254360814063058944'];\n\t * ```\n\t */\n\tpublic static compare(a: string | bigint, b: string | bigint): -1 | 0 | 1 {\n\t\tconst typeA = typeof a;\n\t\treturn typeA === typeof b\n\t\t\t? typeA === 'string'\n\t\t\t\t? cmpString(a as string, b as string)\n\t\t\t\t: cmpBigInt(a as bigint, b as bigint)\n\t\t\t: cmpBigInt(BigInt(a), BigInt(b));\n\t}\n}\n\n/** @internal */\nfunction cmpBigInt(a: bigint, b: bigint) {\n\treturn a === b ? 0 : a < b ? -1 : 1;\n}\n\n/** @internal */\nfunction cmpString(a: string, b: string) {\n\treturn a === b ? 0 : a.length < b.length ? -1 : a.length > b.length ? 1 : a < b ? -1 : 1;\n}\n\n/**\n * Options for Snowflake#generate\n */\nexport interface SnowflakeGenerateOptions {\n\t/**\n\t * Timestamp or date of the snowflake to generate\n\t * @default Date.now()\n\t */\n\ttimestamp?: number | bigint | Date;\n\n\t/**\n\t * The increment to use\n\t * @default 0n\n\t * @remark keep in mind that this bigint is auto-incremented between generate calls\n\t */\n\tincrement?: bigint;\n\n\t/**\n\t * The worker ID to use, will be truncated to 5 bits (0-31)\n\t * @default 0n\n\t */\n\tworkerId?: bigint;\n\n\t/**\n\t * The process ID to use, will be truncated to 5 bits (0-31)\n\t * @default 1n\n\t */\n\tprocessId?: bigint;\n}\n\n/**\n * Object returned by Snowflake#deconstruct\n */\nexport interface DeconstructedSnowflake {\n\t/**\n\t * The id in BigInt form\n\t */\n\tid: bigint;\n\n\t/**\n\t * The timestamp stored in the snowflake\n\t */\n\ttimestamp: bigint;\n\n\t/**\n\t * The worker id stored in the snowflake\n\t */\n\tworkerId: bigint;\n\n\t/**\n\t * The process id stored in the snowflake\n\t */\n\tprocessId: bigint;\n\n\t/**\n\t * The increment stored in the snowflake\n\t */\n\tincrement: bigint;\n\n\t/**\n\t * The epoch to use in the snowflake\n\t */\n\tepoch: bigint;\n}\n","import { Snowflake } from './Snowflake';\n\n/**\n * A class for parsing snowflake ids using Discord's snowflake epoch\n *\n * Which is 2015-01-01 at 00:00:00.000 UTC+0, {@linkplain https://discord.com/developers/docs/reference#snowflakes}\n */\nexport const DiscordSnowflake = new Snowflake(1420070400000n);\n","import { Snowflake } from './Snowflake';\n\n/**\n * A class for parsing snowflake ids using Twitter's snowflake epoch\n *\n * Which is 2010-11-04 at 01:42:54.657 UTC+0, found in the archived snowflake repository {@linkplain https://github.com/twitter-archive/snowflake/blob/b3f6a3c6ca8e1b6847baa6ff42bf72201e2c2231/src/main/scala/com/twitter/service/snowflake/IdWorker.scala#L25}\n */\nexport const TwitterSnowflake = new Snowflake(1288834974657n);\n"]}
|
package/dist/index.js
CHANGED
|
@@ -7,37 +7,13 @@ var __publicField = (obj, key, value) => {
|
|
|
7
7
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
8
8
|
return value;
|
|
9
9
|
};
|
|
10
|
-
var __accessCheck = (obj, member, msg) => {
|
|
11
|
-
if (!member.has(obj))
|
|
12
|
-
throw TypeError("Cannot " + msg);
|
|
13
|
-
};
|
|
14
|
-
var __privateGet = (obj, member, getter) => {
|
|
15
|
-
__accessCheck(obj, member, "read from private field");
|
|
16
|
-
return getter ? getter.call(obj) : member.get(obj);
|
|
17
|
-
};
|
|
18
|
-
var __privateAdd = (obj, member, value) => {
|
|
19
|
-
if (member.has(obj))
|
|
20
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
21
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
22
|
-
};
|
|
23
|
-
var __privateSet = (obj, member, value, setter) => {
|
|
24
|
-
__accessCheck(obj, member, "write to private field");
|
|
25
|
-
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
26
|
-
return value;
|
|
27
|
-
};
|
|
28
|
-
var __privateWrapper = (obj, member, setter, getter) => ({
|
|
29
|
-
set _(value) {
|
|
30
|
-
__privateSet(obj, member, value, setter);
|
|
31
|
-
},
|
|
32
|
-
get _() {
|
|
33
|
-
return __privateGet(obj, member, getter);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
10
|
|
|
37
11
|
// src/lib/Snowflake.ts
|
|
38
|
-
var
|
|
39
|
-
var
|
|
40
|
-
var
|
|
12
|
+
var IncrementSymbol = Symbol("@sapphire/snowflake.increment");
|
|
13
|
+
var EpochSymbol = Symbol("@sapphire/snowflake.epoch");
|
|
14
|
+
var ProcessIdSymbol = Symbol("@sapphire/snowflake.processId");
|
|
15
|
+
var WorkerIdSymbol = Symbol("@sapphire/snowflake.workerId");
|
|
16
|
+
var _a, _b, _c, _d;
|
|
41
17
|
var Snowflake = class {
|
|
42
18
|
/**
|
|
43
19
|
* @param epoch the epoch to use
|
|
@@ -48,23 +24,59 @@ var Snowflake = class {
|
|
|
48
24
|
*/
|
|
49
25
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
50
26
|
__publicField(this, "decode", this.deconstruct);
|
|
27
|
+
/**
|
|
28
|
+
* Internal reference of the epoch passed in the constructor
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
__publicField(this, _a);
|
|
51
32
|
/**
|
|
52
33
|
* Internal incrementor for generating snowflakes
|
|
53
34
|
* @internal
|
|
54
35
|
*/
|
|
55
|
-
|
|
36
|
+
__publicField(this, _b, 0n);
|
|
56
37
|
/**
|
|
57
|
-
*
|
|
38
|
+
* The process ID that will be used by default in the generate method
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
__publicField(this, _c, 1n);
|
|
42
|
+
/**
|
|
43
|
+
* The worker ID that will be used by default in the generate method
|
|
58
44
|
* @internal
|
|
59
45
|
*/
|
|
60
|
-
|
|
61
|
-
|
|
46
|
+
__publicField(this, _d, 0n);
|
|
47
|
+
this[EpochSymbol] = BigInt(epoch instanceof Date ? epoch.getTime() : epoch);
|
|
62
48
|
}
|
|
63
49
|
/**
|
|
64
|
-
* The epoch for this snowflake
|
|
50
|
+
* The epoch for this snowflake
|
|
65
51
|
*/
|
|
66
52
|
get epoch() {
|
|
67
|
-
return
|
|
53
|
+
return this[EpochSymbol];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Gets the configured process ID
|
|
57
|
+
*/
|
|
58
|
+
get processId() {
|
|
59
|
+
return this[ProcessIdSymbol];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Sets the process ID that will be used by default for the {@link generate} method
|
|
63
|
+
* @param value The new value, will be coerced to BigInt and masked with `0b11111n`
|
|
64
|
+
*/
|
|
65
|
+
set processId(value) {
|
|
66
|
+
this[ProcessIdSymbol] = BigInt(value) & 0b11111n;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Gets the configured worker ID
|
|
70
|
+
*/
|
|
71
|
+
get workerId() {
|
|
72
|
+
return this[WorkerIdSymbol];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Sets the worker ID that will be used by default for the {@link generate} method
|
|
76
|
+
* @param value The new value, will be coerced to BigInt and masked with `0b11111n`
|
|
77
|
+
*/
|
|
78
|
+
set workerId(value) {
|
|
79
|
+
this[WorkerIdSymbol] = BigInt(value) & 0b11111n;
|
|
68
80
|
}
|
|
69
81
|
/**
|
|
70
82
|
* Generates a snowflake given an epoch and optionally a timestamp
|
|
@@ -78,7 +90,12 @@ var Snowflake = class {
|
|
|
78
90
|
* ```
|
|
79
91
|
* @returns A unique snowflake
|
|
80
92
|
*/
|
|
81
|
-
generate({
|
|
93
|
+
generate({
|
|
94
|
+
increment,
|
|
95
|
+
timestamp = Date.now(),
|
|
96
|
+
workerId = this[WorkerIdSymbol],
|
|
97
|
+
processId = this[ProcessIdSymbol]
|
|
98
|
+
} = {}) {
|
|
82
99
|
if (timestamp instanceof Date)
|
|
83
100
|
timestamp = BigInt(timestamp.getTime());
|
|
84
101
|
else if (typeof timestamp === "number")
|
|
@@ -89,11 +106,11 @@ var Snowflake = class {
|
|
|
89
106
|
if (typeof increment === "bigint" && increment >= 4095n)
|
|
90
107
|
increment = 0n;
|
|
91
108
|
else {
|
|
92
|
-
increment =
|
|
93
|
-
if (
|
|
94
|
-
|
|
109
|
+
increment = this[IncrementSymbol]++;
|
|
110
|
+
if (this[IncrementSymbol] >= 4095n)
|
|
111
|
+
this[IncrementSymbol] = 0n;
|
|
95
112
|
}
|
|
96
|
-
return timestamp -
|
|
113
|
+
return timestamp - this[EpochSymbol] << 22n | (workerId & 0b11111n) << 17n | (processId & 0b11111n) << 12n | increment;
|
|
97
114
|
}
|
|
98
115
|
/**
|
|
99
116
|
* Deconstructs a snowflake given a snowflake ID
|
|
@@ -107,13 +124,14 @@ var Snowflake = class {
|
|
|
107
124
|
*/
|
|
108
125
|
deconstruct(id) {
|
|
109
126
|
const bigIntId = BigInt(id);
|
|
127
|
+
const epoch = this[EpochSymbol];
|
|
110
128
|
return {
|
|
111
129
|
id: bigIntId,
|
|
112
|
-
timestamp: (bigIntId >> 22n) +
|
|
130
|
+
timestamp: (bigIntId >> 22n) + epoch,
|
|
113
131
|
workerId: bigIntId >> 17n & 0b11111n,
|
|
114
132
|
processId: bigIntId >> 12n & 0b11111n,
|
|
115
133
|
increment: bigIntId & 0b111111111111n,
|
|
116
|
-
epoch
|
|
134
|
+
epoch
|
|
117
135
|
};
|
|
118
136
|
}
|
|
119
137
|
/**
|
|
@@ -122,7 +140,7 @@ var Snowflake = class {
|
|
|
122
140
|
* @returns The UNIX timestamp that is stored in `id`.
|
|
123
141
|
*/
|
|
124
142
|
timestampFrom(id) {
|
|
125
|
-
return Number((BigInt(id) >> 22n) +
|
|
143
|
+
return Number((BigInt(id) >> 22n) + this[EpochSymbol]);
|
|
126
144
|
}
|
|
127
145
|
/**
|
|
128
146
|
* Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given
|
|
@@ -149,8 +167,7 @@ var Snowflake = class {
|
|
|
149
167
|
}
|
|
150
168
|
};
|
|
151
169
|
__name(Snowflake, "Snowflake");
|
|
152
|
-
|
|
153
|
-
_epoch = new WeakMap();
|
|
170
|
+
_a = EpochSymbol, _b = IncrementSymbol, _c = ProcessIdSymbol, _d = WorkerIdSymbol;
|
|
154
171
|
function cmpBigInt(a, b) {
|
|
155
172
|
return a === b ? 0 : a < b ? -1 : 1;
|
|
156
173
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/Snowflake.ts","../src/lib/DiscordSnowflake.ts","../src/lib/TwitterSnowflake.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAM,YAAY;AAClB,IAAM,WAAW;AADjB;AAgBO,IAAM,YAAN,MAAgB;AAAA;AAAA;AAAA;AAAA,EAsBf,YAAY,OAA+B;AAjBlD;AAAA;AAAA;AAAA;AAAA,wBAAO,UAAS,KAAK;AAMrB;AAAA;AAAA;AAAA;AAAA,mCAAa;AAMb;AAAA;AAAA;AAAA;AAAA;AAMC,uBAAK,QAAS,OAAO,iBAAiB,OAAO,MAAM,QAAQ,IAAI,KAAK;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,IAAW,QAAgB;AAC1B,WAAO,mBAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcO,SAAS,EAAE,WAAW,YAAY,KAAK,IAAI,GAAG,WAAW,UAAU,YAAY,UAAU,IAA8B,CAAC,GAAG;AACjI,QAAI,qBAAqB;AAAM,kBAAY,OAAO,UAAU,QAAQ,CAAC;AAAA,aAC5D,OAAO,cAAc;AAAU,kBAAY,OAAO,SAAS;AAAA,aAC3D,OAAO,cAAc,UAAU;AACvC,YAAM,IAAI,UAAU,oEAAoE,OAAO,YAAY;AAAA,IAC5G;AAEA,QAAI,OAAO,cAAc,YAAY,aAAa;AAAO,kBAAY;AAAA,SAChE;AACJ,kBAAY,uBAAK,YAAL;AACZ,UAAI,mBAAK,eAAc;AAAO,2BAAK,YAAa;AAAA,IACjD;AAGA,WAAS,YAAY,mBAAK,WAAW,OAAS,WAAW,aAAa,OAAS,YAAY,aAAa,MAAO;AAAA,EAChH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYO,YAAY,IAA6C;AAC/D,UAAM,WAAW,OAAO,EAAE;AAC1B,WAAO;AAAA,MACN,IAAI;AAAA,MACJ,YAAY,YAAY,OAAO,mBAAK;AAAA,MACpC,UAAW,YAAY,MAAO;AAAA,MAC9B,WAAY,YAAY,MAAO;AAAA,MAC/B,WAAW,WAAW;AAAA,MACtB,OAAO,mBAAK;AAAA,IACb;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,cAAc,IAA6B;AACjD,WAAO,QAAQ,OAAO,EAAE,KAAK,OAAO,mBAAK,OAAM;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,OAAc,QAAQ,GAAoB,GAAgC;AACzE,UAAM,QAAQ,OAAO;AACrB,WAAO,UAAU,OAAO,IACrB,UAAU,WACT,UAAU,GAAa,CAAW,IAClC,UAAU,GAAa,CAAW,IACnC,UAAU,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,EAClC;AACD;AAxHa;AAWZ;AAMA;AA0GD,SAAS,UAAU,GAAW,GAAW;AACxC,SAAO,MAAM,IAAI,IAAI,IAAI,IAAI,KAAK;AACnC;AAFS;AAKT,SAAS,UAAU,GAAW,GAAW;AACxC,SAAO,MAAM,IAAI,IAAI,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,IAAI,KAAK;AACxF;AAFS;;;ACzIF,IAAM,mBAAmB,IAAI,UAAU,cAAc;;;ACArD,IAAM,mBAAmB,IAAI,UAAU,cAAc","sourcesContent":["const ProcessId = 1n;\nconst WorkerId = 0n;\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 */\nexport class Snowflake {\n\t/**\n\t * Alias for {@link deconstruct}\n\t */\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tpublic decode = this.deconstruct;\n\n\t/**\n\t * Internal incrementor for generating snowflakes\n\t * @internal\n\t */\n\t#increment = 0n;\n\n\t/**\n\t * Internal reference of the epoch passed in the constructor\n\t * @internal\n\t */\n\t#epoch: bigint;\n\n\t/**\n\t * @param epoch the epoch to use\n\t */\n\tpublic constructor(epoch: number | bigint | Date) {\n\t\tthis.#epoch = BigInt(epoch instanceof Date ? epoch.getTime() : epoch);\n\t}\n\n\t/**\n\t * The epoch for this snowflake.\n\t */\n\tpublic get epoch(): bigint {\n\t\treturn this.#epoch;\n\t}\n\n\t/**\n\t * Generates a snowflake given an epoch and optionally a timestamp\n\t * @param options options to pass into the generator, see {@link SnowflakeGenerateOptions}\n\t *\n\t * **note** when `increment` is not provided it defaults to the private `increment` of the instance\n\t * @example\n\t * ```typescript\n\t * const epoch = new Date('2000-01-01T00:00:00.000Z');\n\t * const snowflake = new Snowflake(epoch).generate();\n\t * ```\n\t * @returns A unique snowflake\n\t */\n\tpublic generate({ increment, timestamp = Date.now(), workerId = WorkerId, processId = ProcessId }: SnowflakeGenerateOptions = {}) {\n\t\tif (timestamp instanceof Date) timestamp = BigInt(timestamp.getTime());\n\t\telse if (typeof timestamp === 'number') timestamp = BigInt(timestamp);\n\t\telse if (typeof timestamp !== 'bigint') {\n\t\t\tthrow new TypeError(`\"timestamp\" argument must be a number, bigint, or Date (received ${typeof timestamp})`);\n\t\t}\n\n\t\tif (typeof increment === 'bigint' && increment >= 4095n) increment = 0n;\n\t\telse {\n\t\t\tincrement = this.#increment++;\n\t\t\tif (this.#increment >= 4095n) this.#increment = 0n;\n\t\t}\n\n\t\t// timestamp, workerId, processId, increment\n\t\treturn ((timestamp - this.#epoch) << 22n) | ((workerId & 0b11111n) << 17n) | ((processId & 0b11111n) << 12n) | increment;\n\t}\n\n\t/**\n\t * Deconstructs a snowflake given a snowflake ID\n\t * @param id the snowflake to deconstruct\n\t * @returns a deconstructed snowflake\n\t * @example\n\t * ```typescript\n\t * const epoch = new Date('2000-01-01T00:00:00.000Z');\n\t * const snowflake = new Snowflake(epoch).deconstruct('3971046231244935168');\n\t * ```\n\t */\n\tpublic deconstruct(id: string | bigint): DeconstructedSnowflake {\n\t\tconst bigIntId = BigInt(id);\n\t\treturn {\n\t\t\tid: bigIntId,\n\t\t\ttimestamp: (bigIntId >> 22n) + this.#epoch,\n\t\t\tworkerId: (bigIntId >> 17n) & 0b11111n,\n\t\t\tprocessId: (bigIntId >> 12n) & 0b11111n,\n\t\t\tincrement: bigIntId & 0b111111111111n,\n\t\t\tepoch: this.#epoch\n\t\t};\n\t}\n\n\t/**\n\t * Retrieves the timestamp field's value from a snowflake.\n\t * @param id The snowflake to get the timestamp value from.\n\t * @returns The UNIX timestamp that is stored in `id`.\n\t */\n\tpublic timestampFrom(id: string | bigint): number {\n\t\treturn Number((BigInt(id) >> 22n) + this.#epoch);\n\t}\n\n\t/**\n\t * Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given\n\t * snowflake in sort order.\n\t * @param a The first snowflake to compare.\n\t * @param b The second snowflake to compare.\n\t * @returns `-1` if `a` is older than `b`, `0` if `a` and `b` are equals, `1` if `a` is newer than `b`.\n\t * @example Sort snowflakes in ascending order\n\t * ```typescript\n\t * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];\n\t * console.log(ids.sort((a, b) => Snowflake.compare(a, b)));\n\t * // → ['254360814063058944', '737141877803057244', '1056191128120082432'];\n\t * ```\n\t * @example Sort snowflakes in descending order\n\t * ```typescript\n\t * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];\n\t * console.log(ids.sort((a, b) => -Snowflake.compare(a, b)));\n\t * // → ['1056191128120082432', '737141877803057244', '254360814063058944'];\n\t * ```\n\t */\n\tpublic static compare(a: string | bigint, b: string | bigint): -1 | 0 | 1 {\n\t\tconst typeA = typeof a;\n\t\treturn typeA === typeof b\n\t\t\t? typeA === 'string'\n\t\t\t\t? cmpString(a as string, b as string)\n\t\t\t\t: cmpBigInt(a as bigint, b as bigint)\n\t\t\t: cmpBigInt(BigInt(a), BigInt(b));\n\t}\n}\n\n/** @internal */\nfunction cmpBigInt(a: bigint, b: bigint) {\n\treturn a === b ? 0 : a < b ? -1 : 1;\n}\n\n/** @internal */\nfunction cmpString(a: string, b: string) {\n\treturn a === b ? 0 : a.length < b.length ? -1 : a.length > b.length ? 1 : a < b ? -1 : 1;\n}\n\n/**\n * Options for Snowflake#generate\n */\nexport interface SnowflakeGenerateOptions {\n\t/**\n\t * Timestamp or date of the snowflake to generate\n\t * @default Date.now()\n\t */\n\ttimestamp?: number | bigint | Date;\n\n\t/**\n\t * The increment to use\n\t * @default 0n\n\t * @remark keep in mind that this bigint is auto-incremented between generate calls\n\t */\n\tincrement?: bigint;\n\n\t/**\n\t * The worker ID to use, will be truncated to 5 bits (0-31)\n\t * @default 0n\n\t */\n\tworkerId?: bigint;\n\n\t/**\n\t * The process ID to use, will be truncated to 5 bits (0-31)\n\t * @default 1n\n\t */\n\tprocessId?: bigint;\n}\n\n/**\n * Object returned by Snowflake#deconstruct\n */\nexport interface DeconstructedSnowflake {\n\t/**\n\t * The id in BigInt form\n\t */\n\tid: bigint;\n\n\t/**\n\t * The timestamp stored in the snowflake\n\t */\n\ttimestamp: bigint;\n\n\t/**\n\t * The worker id stored in the snowflake\n\t */\n\tworkerId: bigint;\n\n\t/**\n\t * The process id stored in the snowflake\n\t */\n\tprocessId: bigint;\n\n\t/**\n\t * The increment stored in the snowflake\n\t */\n\tincrement: bigint;\n\n\t/**\n\t * The epoch to use in the snowflake\n\t */\n\tepoch: bigint;\n}\n","import { Snowflake } from './Snowflake';\n\n/**\n * A class for parsing snowflake ids using Discord's snowflake epoch\n *\n * Which is 2015-01-01 at 00:00:00.000 UTC+0, {@linkplain https://discord.com/developers/docs/reference#snowflakes}\n */\nexport const DiscordSnowflake = new Snowflake(1420070400000n);\n","import { Snowflake } from './Snowflake';\n\n/**\n * A class for parsing snowflake ids using Twitter's snowflake epoch\n *\n * Which is 2010-11-04 at 01:42:54.657 UTC+0, found in the archived snowflake repository {@linkplain https://github.com/twitter-archive/snowflake/blob/b3f6a3c6ca8e1b6847baa6ff42bf72201e2c2231/src/main/scala/com/twitter/service/snowflake/IdWorker.scala#L25}\n */\nexport const TwitterSnowflake = new Snowflake(1288834974657n);\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/Snowflake.ts","../src/lib/DiscordSnowflake.ts","../src/lib/TwitterSnowflake.ts"],"names":[],"mappings":"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","sourcesContent":["const IncrementSymbol = Symbol('@sapphire/snowflake.increment');\nconst EpochSymbol = Symbol('@sapphire/snowflake.epoch');\nconst ProcessIdSymbol = Symbol('@sapphire/snowflake.processId');\nconst WorkerIdSymbol = Symbol('@sapphire/snowflake.workerId');\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 */\nexport class Snowflake {\n\t/**\n\t * Alias for {@link deconstruct}\n\t */\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tpublic decode = this.deconstruct;\n\n\t/**\n\t * Internal reference of the epoch passed in the constructor\n\t * @internal\n\t */\n\tprivate readonly [EpochSymbol]: bigint;\n\n\t/**\n\t * Internal incrementor for generating snowflakes\n\t * @internal\n\t */\n\tprivate [IncrementSymbol] = 0n;\n\n\t/**\n\t * The process ID that will be used by default in the generate method\n\t * @internal\n\t */\n\tprivate [ProcessIdSymbol] = 1n;\n\n\t/**\n\t * The worker ID that will be used by default in the generate method\n\t * @internal\n\t */\n\tprivate [WorkerIdSymbol] = 0n;\n\n\t/**\n\t * @param epoch the epoch to use\n\t */\n\tpublic constructor(epoch: number | bigint | Date) {\n\t\tthis[EpochSymbol] = BigInt(epoch instanceof Date ? epoch.getTime() : epoch);\n\t}\n\n\t/**\n\t * The epoch for this snowflake\n\t */\n\tpublic get epoch(): bigint {\n\t\treturn this[EpochSymbol];\n\t}\n\n\t/**\n\t * Gets the configured process ID\n\t */\n\tpublic get processId(): bigint {\n\t\treturn this[ProcessIdSymbol];\n\t}\n\n\t/**\n\t * Sets the process ID that will be used by default for the {@link generate} method\n\t * @param value The new value, will be coerced to BigInt and masked with `0b11111n`\n\t */\n\tpublic set processId(value: number | bigint) {\n\t\tthis[ProcessIdSymbol] = BigInt(value) & 0b11111n;\n\t}\n\n\t/**\n\t * Gets the configured worker ID\n\t */\n\tpublic get workerId(): bigint {\n\t\treturn this[WorkerIdSymbol];\n\t}\n\n\t/**\n\t * Sets the worker ID that will be used by default for the {@link generate} method\n\t * @param value The new value, will be coerced to BigInt and masked with `0b11111n`\n\t */\n\tpublic set workerId(value: number | bigint) {\n\t\tthis[WorkerIdSymbol] = BigInt(value) & 0b11111n;\n\t}\n\n\t/**\n\t * Generates a snowflake given an epoch and optionally a timestamp\n\t * @param options options to pass into the generator, see {@link SnowflakeGenerateOptions}\n\t *\n\t * **note** when `increment` is not provided it defaults to the private `increment` of the instance\n\t * @example\n\t * ```typescript\n\t * const epoch = new Date('2000-01-01T00:00:00.000Z');\n\t * const snowflake = new Snowflake(epoch).generate();\n\t * ```\n\t * @returns A unique snowflake\n\t */\n\tpublic generate({\n\t\tincrement,\n\t\ttimestamp = Date.now(),\n\t\tworkerId = this[WorkerIdSymbol],\n\t\tprocessId = this[ProcessIdSymbol]\n\t}: SnowflakeGenerateOptions = {}) {\n\t\tif (timestamp instanceof Date) timestamp = BigInt(timestamp.getTime());\n\t\telse if (typeof timestamp === 'number') timestamp = BigInt(timestamp);\n\t\telse if (typeof timestamp !== 'bigint') {\n\t\t\tthrow new TypeError(`\"timestamp\" argument must be a number, bigint, or Date (received ${typeof timestamp})`);\n\t\t}\n\n\t\tif (typeof increment === 'bigint' && increment >= 4095n) increment = 0n;\n\t\telse {\n\t\t\tincrement = this[IncrementSymbol]++;\n\t\t\tif (this[IncrementSymbol] >= 4095n) this[IncrementSymbol] = 0n;\n\t\t}\n\n\t\t// timestamp, workerId, processId, increment\n\t\treturn ((timestamp - this[EpochSymbol]) << 22n) | ((workerId & 0b11111n) << 17n) | ((processId & 0b11111n) << 12n) | increment;\n\t}\n\n\t/**\n\t * Deconstructs a snowflake given a snowflake ID\n\t * @param id the snowflake to deconstruct\n\t * @returns a deconstructed snowflake\n\t * @example\n\t * ```typescript\n\t * const epoch = new Date('2000-01-01T00:00:00.000Z');\n\t * const snowflake = new Snowflake(epoch).deconstruct('3971046231244935168');\n\t * ```\n\t */\n\tpublic deconstruct(id: string | bigint): DeconstructedSnowflake {\n\t\tconst bigIntId = BigInt(id);\n\t\tconst epoch = this[EpochSymbol];\n\t\treturn {\n\t\t\tid: bigIntId,\n\t\t\ttimestamp: (bigIntId >> 22n) + epoch,\n\t\t\tworkerId: (bigIntId >> 17n) & 0b11111n,\n\t\t\tprocessId: (bigIntId >> 12n) & 0b11111n,\n\t\t\tincrement: bigIntId & 0b111111111111n,\n\t\t\tepoch\n\t\t};\n\t}\n\n\t/**\n\t * Retrieves the timestamp field's value from a snowflake.\n\t * @param id The snowflake to get the timestamp value from.\n\t * @returns The UNIX timestamp that is stored in `id`.\n\t */\n\tpublic timestampFrom(id: string | bigint): number {\n\t\treturn Number((BigInt(id) >> 22n) + this[EpochSymbol]);\n\t}\n\n\t/**\n\t * Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given\n\t * snowflake in sort order.\n\t * @param a The first snowflake to compare.\n\t * @param b The second snowflake to compare.\n\t * @returns `-1` if `a` is older than `b`, `0` if `a` and `b` are equals, `1` if `a` is newer than `b`.\n\t * @example Sort snowflakes in ascending order\n\t * ```typescript\n\t * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];\n\t * console.log(ids.sort((a, b) => Snowflake.compare(a, b)));\n\t * // → ['254360814063058944', '737141877803057244', '1056191128120082432'];\n\t * ```\n\t * @example Sort snowflakes in descending order\n\t * ```typescript\n\t * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];\n\t * console.log(ids.sort((a, b) => -Snowflake.compare(a, b)));\n\t * // → ['1056191128120082432', '737141877803057244', '254360814063058944'];\n\t * ```\n\t */\n\tpublic static compare(a: string | bigint, b: string | bigint): -1 | 0 | 1 {\n\t\tconst typeA = typeof a;\n\t\treturn typeA === typeof b\n\t\t\t? typeA === 'string'\n\t\t\t\t? cmpString(a as string, b as string)\n\t\t\t\t: cmpBigInt(a as bigint, b as bigint)\n\t\t\t: cmpBigInt(BigInt(a), BigInt(b));\n\t}\n}\n\n/** @internal */\nfunction cmpBigInt(a: bigint, b: bigint) {\n\treturn a === b ? 0 : a < b ? -1 : 1;\n}\n\n/** @internal */\nfunction cmpString(a: string, b: string) {\n\treturn a === b ? 0 : a.length < b.length ? -1 : a.length > b.length ? 1 : a < b ? -1 : 1;\n}\n\n/**\n * Options for Snowflake#generate\n */\nexport interface SnowflakeGenerateOptions {\n\t/**\n\t * Timestamp or date of the snowflake to generate\n\t * @default Date.now()\n\t */\n\ttimestamp?: number | bigint | Date;\n\n\t/**\n\t * The increment to use\n\t * @default 0n\n\t * @remark keep in mind that this bigint is auto-incremented between generate calls\n\t */\n\tincrement?: bigint;\n\n\t/**\n\t * The worker ID to use, will be truncated to 5 bits (0-31)\n\t * @default 0n\n\t */\n\tworkerId?: bigint;\n\n\t/**\n\t * The process ID to use, will be truncated to 5 bits (0-31)\n\t * @default 1n\n\t */\n\tprocessId?: bigint;\n}\n\n/**\n * Object returned by Snowflake#deconstruct\n */\nexport interface DeconstructedSnowflake {\n\t/**\n\t * The id in BigInt form\n\t */\n\tid: bigint;\n\n\t/**\n\t * The timestamp stored in the snowflake\n\t */\n\ttimestamp: bigint;\n\n\t/**\n\t * The worker id stored in the snowflake\n\t */\n\tworkerId: bigint;\n\n\t/**\n\t * The process id stored in the snowflake\n\t */\n\tprocessId: bigint;\n\n\t/**\n\t * The increment stored in the snowflake\n\t */\n\tincrement: bigint;\n\n\t/**\n\t * The epoch to use in the snowflake\n\t */\n\tepoch: bigint;\n}\n","import { Snowflake } from './Snowflake';\n\n/**\n * A class for parsing snowflake ids using Discord's snowflake epoch\n *\n * Which is 2015-01-01 at 00:00:00.000 UTC+0, {@linkplain https://discord.com/developers/docs/reference#snowflakes}\n */\nexport const DiscordSnowflake = new Snowflake(1420070400000n);\n","import { Snowflake } from './Snowflake';\n\n/**\n * A class for parsing snowflake ids using Twitter's snowflake epoch\n *\n * Which is 2010-11-04 at 01:42:54.657 UTC+0, found in the archived snowflake repository {@linkplain https://github.com/twitter-archive/snowflake/blob/b3f6a3c6ca8e1b6847baa6ff42bf72201e2c2231/src/main/scala/com/twitter/service/snowflake/IdWorker.scala#L25}\n */\nexport const TwitterSnowflake = new Snowflake(1288834974657n);\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -5,37 +5,13 @@ var __publicField = (obj, key, value) => {
|
|
|
5
5
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
6
6
|
return value;
|
|
7
7
|
};
|
|
8
|
-
var __accessCheck = (obj, member, msg) => {
|
|
9
|
-
if (!member.has(obj))
|
|
10
|
-
throw TypeError("Cannot " + msg);
|
|
11
|
-
};
|
|
12
|
-
var __privateGet = (obj, member, getter) => {
|
|
13
|
-
__accessCheck(obj, member, "read from private field");
|
|
14
|
-
return getter ? getter.call(obj) : member.get(obj);
|
|
15
|
-
};
|
|
16
|
-
var __privateAdd = (obj, member, value) => {
|
|
17
|
-
if (member.has(obj))
|
|
18
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
19
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
20
|
-
};
|
|
21
|
-
var __privateSet = (obj, member, value, setter) => {
|
|
22
|
-
__accessCheck(obj, member, "write to private field");
|
|
23
|
-
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
24
|
-
return value;
|
|
25
|
-
};
|
|
26
|
-
var __privateWrapper = (obj, member, setter, getter) => ({
|
|
27
|
-
set _(value) {
|
|
28
|
-
__privateSet(obj, member, value, setter);
|
|
29
|
-
},
|
|
30
|
-
get _() {
|
|
31
|
-
return __privateGet(obj, member, getter);
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
8
|
|
|
35
9
|
// src/lib/Snowflake.ts
|
|
36
|
-
var
|
|
37
|
-
var
|
|
38
|
-
var
|
|
10
|
+
var IncrementSymbol = Symbol("@sapphire/snowflake.increment");
|
|
11
|
+
var EpochSymbol = Symbol("@sapphire/snowflake.epoch");
|
|
12
|
+
var ProcessIdSymbol = Symbol("@sapphire/snowflake.processId");
|
|
13
|
+
var WorkerIdSymbol = Symbol("@sapphire/snowflake.workerId");
|
|
14
|
+
var _a, _b, _c, _d;
|
|
39
15
|
var Snowflake = class {
|
|
40
16
|
/**
|
|
41
17
|
* @param epoch the epoch to use
|
|
@@ -46,23 +22,59 @@ var Snowflake = class {
|
|
|
46
22
|
*/
|
|
47
23
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
48
24
|
__publicField(this, "decode", this.deconstruct);
|
|
25
|
+
/**
|
|
26
|
+
* Internal reference of the epoch passed in the constructor
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
__publicField(this, _a);
|
|
49
30
|
/**
|
|
50
31
|
* Internal incrementor for generating snowflakes
|
|
51
32
|
* @internal
|
|
52
33
|
*/
|
|
53
|
-
|
|
34
|
+
__publicField(this, _b, 0n);
|
|
54
35
|
/**
|
|
55
|
-
*
|
|
36
|
+
* The process ID that will be used by default in the generate method
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
__publicField(this, _c, 1n);
|
|
40
|
+
/**
|
|
41
|
+
* The worker ID that will be used by default in the generate method
|
|
56
42
|
* @internal
|
|
57
43
|
*/
|
|
58
|
-
|
|
59
|
-
|
|
44
|
+
__publicField(this, _d, 0n);
|
|
45
|
+
this[EpochSymbol] = BigInt(epoch instanceof Date ? epoch.getTime() : epoch);
|
|
60
46
|
}
|
|
61
47
|
/**
|
|
62
|
-
* The epoch for this snowflake
|
|
48
|
+
* The epoch for this snowflake
|
|
63
49
|
*/
|
|
64
50
|
get epoch() {
|
|
65
|
-
return
|
|
51
|
+
return this[EpochSymbol];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Gets the configured process ID
|
|
55
|
+
*/
|
|
56
|
+
get processId() {
|
|
57
|
+
return this[ProcessIdSymbol];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Sets the process ID that will be used by default for the {@link generate} method
|
|
61
|
+
* @param value The new value, will be coerced to BigInt and masked with `0b11111n`
|
|
62
|
+
*/
|
|
63
|
+
set processId(value) {
|
|
64
|
+
this[ProcessIdSymbol] = BigInt(value) & 0b11111n;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Gets the configured worker ID
|
|
68
|
+
*/
|
|
69
|
+
get workerId() {
|
|
70
|
+
return this[WorkerIdSymbol];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Sets the worker ID that will be used by default for the {@link generate} method
|
|
74
|
+
* @param value The new value, will be coerced to BigInt and masked with `0b11111n`
|
|
75
|
+
*/
|
|
76
|
+
set workerId(value) {
|
|
77
|
+
this[WorkerIdSymbol] = BigInt(value) & 0b11111n;
|
|
66
78
|
}
|
|
67
79
|
/**
|
|
68
80
|
* Generates a snowflake given an epoch and optionally a timestamp
|
|
@@ -76,7 +88,12 @@ var Snowflake = class {
|
|
|
76
88
|
* ```
|
|
77
89
|
* @returns A unique snowflake
|
|
78
90
|
*/
|
|
79
|
-
generate({
|
|
91
|
+
generate({
|
|
92
|
+
increment,
|
|
93
|
+
timestamp = Date.now(),
|
|
94
|
+
workerId = this[WorkerIdSymbol],
|
|
95
|
+
processId = this[ProcessIdSymbol]
|
|
96
|
+
} = {}) {
|
|
80
97
|
if (timestamp instanceof Date)
|
|
81
98
|
timestamp = BigInt(timestamp.getTime());
|
|
82
99
|
else if (typeof timestamp === "number")
|
|
@@ -87,11 +104,11 @@ var Snowflake = class {
|
|
|
87
104
|
if (typeof increment === "bigint" && increment >= 4095n)
|
|
88
105
|
increment = 0n;
|
|
89
106
|
else {
|
|
90
|
-
increment =
|
|
91
|
-
if (
|
|
92
|
-
|
|
107
|
+
increment = this[IncrementSymbol]++;
|
|
108
|
+
if (this[IncrementSymbol] >= 4095n)
|
|
109
|
+
this[IncrementSymbol] = 0n;
|
|
93
110
|
}
|
|
94
|
-
return timestamp -
|
|
111
|
+
return timestamp - this[EpochSymbol] << 22n | (workerId & 0b11111n) << 17n | (processId & 0b11111n) << 12n | increment;
|
|
95
112
|
}
|
|
96
113
|
/**
|
|
97
114
|
* Deconstructs a snowflake given a snowflake ID
|
|
@@ -105,13 +122,14 @@ var Snowflake = class {
|
|
|
105
122
|
*/
|
|
106
123
|
deconstruct(id) {
|
|
107
124
|
const bigIntId = BigInt(id);
|
|
125
|
+
const epoch = this[EpochSymbol];
|
|
108
126
|
return {
|
|
109
127
|
id: bigIntId,
|
|
110
|
-
timestamp: (bigIntId >> 22n) +
|
|
128
|
+
timestamp: (bigIntId >> 22n) + epoch,
|
|
111
129
|
workerId: bigIntId >> 17n & 0b11111n,
|
|
112
130
|
processId: bigIntId >> 12n & 0b11111n,
|
|
113
131
|
increment: bigIntId & 0b111111111111n,
|
|
114
|
-
epoch
|
|
132
|
+
epoch
|
|
115
133
|
};
|
|
116
134
|
}
|
|
117
135
|
/**
|
|
@@ -120,7 +138,7 @@ var Snowflake = class {
|
|
|
120
138
|
* @returns The UNIX timestamp that is stored in `id`.
|
|
121
139
|
*/
|
|
122
140
|
timestampFrom(id) {
|
|
123
|
-
return Number((BigInt(id) >> 22n) +
|
|
141
|
+
return Number((BigInt(id) >> 22n) + this[EpochSymbol]);
|
|
124
142
|
}
|
|
125
143
|
/**
|
|
126
144
|
* Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given
|
|
@@ -147,8 +165,7 @@ var Snowflake = class {
|
|
|
147
165
|
}
|
|
148
166
|
};
|
|
149
167
|
__name(Snowflake, "Snowflake");
|
|
150
|
-
|
|
151
|
-
_epoch = new WeakMap();
|
|
168
|
+
_a = EpochSymbol, _b = IncrementSymbol, _c = ProcessIdSymbol, _d = WorkerIdSymbol;
|
|
152
169
|
function cmpBigInt(a, b) {
|
|
153
170
|
return a === b ? 0 : a < b ? -1 : 1;
|
|
154
171
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/Snowflake.ts","../src/lib/DiscordSnowflake.ts","../src/lib/TwitterSnowflake.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAM,YAAY;AAClB,IAAM,WAAW;AADjB;AAgBO,IAAM,YAAN,MAAgB;AAAA;AAAA;AAAA;AAAA,EAsBf,YAAY,OAA+B;AAjBlD;AAAA;AAAA;AAAA;AAAA,wBAAO,UAAS,KAAK;AAMrB;AAAA;AAAA;AAAA;AAAA,mCAAa;AAMb;AAAA;AAAA;AAAA;AAAA;AAMC,uBAAK,QAAS,OAAO,iBAAiB,OAAO,MAAM,QAAQ,IAAI,KAAK;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,IAAW,QAAgB;AAC1B,WAAO,mBAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcO,SAAS,EAAE,WAAW,YAAY,KAAK,IAAI,GAAG,WAAW,UAAU,YAAY,UAAU,IAA8B,CAAC,GAAG;AACjI,QAAI,qBAAqB;AAAM,kBAAY,OAAO,UAAU,QAAQ,CAAC;AAAA,aAC5D,OAAO,cAAc;AAAU,kBAAY,OAAO,SAAS;AAAA,aAC3D,OAAO,cAAc,UAAU;AACvC,YAAM,IAAI,UAAU,oEAAoE,OAAO,YAAY;AAAA,IAC5G;AAEA,QAAI,OAAO,cAAc,YAAY,aAAa;AAAO,kBAAY;AAAA,SAChE;AACJ,kBAAY,uBAAK,YAAL;AACZ,UAAI,mBAAK,eAAc;AAAO,2BAAK,YAAa;AAAA,IACjD;AAGA,WAAS,YAAY,mBAAK,WAAW,OAAS,WAAW,aAAa,OAAS,YAAY,aAAa,MAAO;AAAA,EAChH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYO,YAAY,IAA6C;AAC/D,UAAM,WAAW,OAAO,EAAE;AAC1B,WAAO;AAAA,MACN,IAAI;AAAA,MACJ,YAAY,YAAY,OAAO,mBAAK;AAAA,MACpC,UAAW,YAAY,MAAO;AAAA,MAC9B,WAAY,YAAY,MAAO;AAAA,MAC/B,WAAW,WAAW;AAAA,MACtB,OAAO,mBAAK;AAAA,IACb;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,cAAc,IAA6B;AACjD,WAAO,QAAQ,OAAO,EAAE,KAAK,OAAO,mBAAK,OAAM;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,OAAc,QAAQ,GAAoB,GAAgC;AACzE,UAAM,QAAQ,OAAO;AACrB,WAAO,UAAU,OAAO,IACrB,UAAU,WACT,UAAU,GAAa,CAAW,IAClC,UAAU,GAAa,CAAW,IACnC,UAAU,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,EAClC;AACD;AAxHa;AAWZ;AAMA;AA0GD,SAAS,UAAU,GAAW,GAAW;AACxC,SAAO,MAAM,IAAI,IAAI,IAAI,IAAI,KAAK;AACnC;AAFS;AAKT,SAAS,UAAU,GAAW,GAAW;AACxC,SAAO,MAAM,IAAI,IAAI,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,IAAI,KAAK;AACxF;AAFS;;;ACzIF,IAAM,mBAAmB,IAAI,UAAU,cAAc;;;ACArD,IAAM,mBAAmB,IAAI,UAAU,cAAc","sourcesContent":["const ProcessId = 1n;\nconst WorkerId = 0n;\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 */\nexport class Snowflake {\n\t/**\n\t * Alias for {@link deconstruct}\n\t */\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tpublic decode = this.deconstruct;\n\n\t/**\n\t * Internal incrementor for generating snowflakes\n\t * @internal\n\t */\n\t#increment = 0n;\n\n\t/**\n\t * Internal reference of the epoch passed in the constructor\n\t * @internal\n\t */\n\t#epoch: bigint;\n\n\t/**\n\t * @param epoch the epoch to use\n\t */\n\tpublic constructor(epoch: number | bigint | Date) {\n\t\tthis.#epoch = BigInt(epoch instanceof Date ? epoch.getTime() : epoch);\n\t}\n\n\t/**\n\t * The epoch for this snowflake.\n\t */\n\tpublic get epoch(): bigint {\n\t\treturn this.#epoch;\n\t}\n\n\t/**\n\t * Generates a snowflake given an epoch and optionally a timestamp\n\t * @param options options to pass into the generator, see {@link SnowflakeGenerateOptions}\n\t *\n\t * **note** when `increment` is not provided it defaults to the private `increment` of the instance\n\t * @example\n\t * ```typescript\n\t * const epoch = new Date('2000-01-01T00:00:00.000Z');\n\t * const snowflake = new Snowflake(epoch).generate();\n\t * ```\n\t * @returns A unique snowflake\n\t */\n\tpublic generate({ increment, timestamp = Date.now(), workerId = WorkerId, processId = ProcessId }: SnowflakeGenerateOptions = {}) {\n\t\tif (timestamp instanceof Date) timestamp = BigInt(timestamp.getTime());\n\t\telse if (typeof timestamp === 'number') timestamp = BigInt(timestamp);\n\t\telse if (typeof timestamp !== 'bigint') {\n\t\t\tthrow new TypeError(`\"timestamp\" argument must be a number, bigint, or Date (received ${typeof timestamp})`);\n\t\t}\n\n\t\tif (typeof increment === 'bigint' && increment >= 4095n) increment = 0n;\n\t\telse {\n\t\t\tincrement = this.#increment++;\n\t\t\tif (this.#increment >= 4095n) this.#increment = 0n;\n\t\t}\n\n\t\t// timestamp, workerId, processId, increment\n\t\treturn ((timestamp - this.#epoch) << 22n) | ((workerId & 0b11111n) << 17n) | ((processId & 0b11111n) << 12n) | increment;\n\t}\n\n\t/**\n\t * Deconstructs a snowflake given a snowflake ID\n\t * @param id the snowflake to deconstruct\n\t * @returns a deconstructed snowflake\n\t * @example\n\t * ```typescript\n\t * const epoch = new Date('2000-01-01T00:00:00.000Z');\n\t * const snowflake = new Snowflake(epoch).deconstruct('3971046231244935168');\n\t * ```\n\t */\n\tpublic deconstruct(id: string | bigint): DeconstructedSnowflake {\n\t\tconst bigIntId = BigInt(id);\n\t\treturn {\n\t\t\tid: bigIntId,\n\t\t\ttimestamp: (bigIntId >> 22n) + this.#epoch,\n\t\t\tworkerId: (bigIntId >> 17n) & 0b11111n,\n\t\t\tprocessId: (bigIntId >> 12n) & 0b11111n,\n\t\t\tincrement: bigIntId & 0b111111111111n,\n\t\t\tepoch: this.#epoch\n\t\t};\n\t}\n\n\t/**\n\t * Retrieves the timestamp field's value from a snowflake.\n\t * @param id The snowflake to get the timestamp value from.\n\t * @returns The UNIX timestamp that is stored in `id`.\n\t */\n\tpublic timestampFrom(id: string | bigint): number {\n\t\treturn Number((BigInt(id) >> 22n) + this.#epoch);\n\t}\n\n\t/**\n\t * Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given\n\t * snowflake in sort order.\n\t * @param a The first snowflake to compare.\n\t * @param b The second snowflake to compare.\n\t * @returns `-1` if `a` is older than `b`, `0` if `a` and `b` are equals, `1` if `a` is newer than `b`.\n\t * @example Sort snowflakes in ascending order\n\t * ```typescript\n\t * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];\n\t * console.log(ids.sort((a, b) => Snowflake.compare(a, b)));\n\t * // → ['254360814063058944', '737141877803057244', '1056191128120082432'];\n\t * ```\n\t * @example Sort snowflakes in descending order\n\t * ```typescript\n\t * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];\n\t * console.log(ids.sort((a, b) => -Snowflake.compare(a, b)));\n\t * // → ['1056191128120082432', '737141877803057244', '254360814063058944'];\n\t * ```\n\t */\n\tpublic static compare(a: string | bigint, b: string | bigint): -1 | 0 | 1 {\n\t\tconst typeA = typeof a;\n\t\treturn typeA === typeof b\n\t\t\t? typeA === 'string'\n\t\t\t\t? cmpString(a as string, b as string)\n\t\t\t\t: cmpBigInt(a as bigint, b as bigint)\n\t\t\t: cmpBigInt(BigInt(a), BigInt(b));\n\t}\n}\n\n/** @internal */\nfunction cmpBigInt(a: bigint, b: bigint) {\n\treturn a === b ? 0 : a < b ? -1 : 1;\n}\n\n/** @internal */\nfunction cmpString(a: string, b: string) {\n\treturn a === b ? 0 : a.length < b.length ? -1 : a.length > b.length ? 1 : a < b ? -1 : 1;\n}\n\n/**\n * Options for Snowflake#generate\n */\nexport interface SnowflakeGenerateOptions {\n\t/**\n\t * Timestamp or date of the snowflake to generate\n\t * @default Date.now()\n\t */\n\ttimestamp?: number | bigint | Date;\n\n\t/**\n\t * The increment to use\n\t * @default 0n\n\t * @remark keep in mind that this bigint is auto-incremented between generate calls\n\t */\n\tincrement?: bigint;\n\n\t/**\n\t * The worker ID to use, will be truncated to 5 bits (0-31)\n\t * @default 0n\n\t */\n\tworkerId?: bigint;\n\n\t/**\n\t * The process ID to use, will be truncated to 5 bits (0-31)\n\t * @default 1n\n\t */\n\tprocessId?: bigint;\n}\n\n/**\n * Object returned by Snowflake#deconstruct\n */\nexport interface DeconstructedSnowflake {\n\t/**\n\t * The id in BigInt form\n\t */\n\tid: bigint;\n\n\t/**\n\t * The timestamp stored in the snowflake\n\t */\n\ttimestamp: bigint;\n\n\t/**\n\t * The worker id stored in the snowflake\n\t */\n\tworkerId: bigint;\n\n\t/**\n\t * The process id stored in the snowflake\n\t */\n\tprocessId: bigint;\n\n\t/**\n\t * The increment stored in the snowflake\n\t */\n\tincrement: bigint;\n\n\t/**\n\t * The epoch to use in the snowflake\n\t */\n\tepoch: bigint;\n}\n","import { Snowflake } from './Snowflake';\n\n/**\n * A class for parsing snowflake ids using Discord's snowflake epoch\n *\n * Which is 2015-01-01 at 00:00:00.000 UTC+0, {@linkplain https://discord.com/developers/docs/reference#snowflakes}\n */\nexport const DiscordSnowflake = new Snowflake(1420070400000n);\n","import { Snowflake } from './Snowflake';\n\n/**\n * A class for parsing snowflake ids using Twitter's snowflake epoch\n *\n * Which is 2010-11-04 at 01:42:54.657 UTC+0, found in the archived snowflake repository {@linkplain https://github.com/twitter-archive/snowflake/blob/b3f6a3c6ca8e1b6847baa6ff42bf72201e2c2231/src/main/scala/com/twitter/service/snowflake/IdWorker.scala#L25}\n */\nexport const TwitterSnowflake = new Snowflake(1288834974657n);\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/Snowflake.ts","../src/lib/DiscordSnowflake.ts","../src/lib/TwitterSnowflake.ts"],"names":[],"mappings":"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","sourcesContent":["const IncrementSymbol = Symbol('@sapphire/snowflake.increment');\nconst EpochSymbol = Symbol('@sapphire/snowflake.epoch');\nconst ProcessIdSymbol = Symbol('@sapphire/snowflake.processId');\nconst WorkerIdSymbol = Symbol('@sapphire/snowflake.workerId');\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 */\nexport class Snowflake {\n\t/**\n\t * Alias for {@link deconstruct}\n\t */\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tpublic decode = this.deconstruct;\n\n\t/**\n\t * Internal reference of the epoch passed in the constructor\n\t * @internal\n\t */\n\tprivate readonly [EpochSymbol]: bigint;\n\n\t/**\n\t * Internal incrementor for generating snowflakes\n\t * @internal\n\t */\n\tprivate [IncrementSymbol] = 0n;\n\n\t/**\n\t * The process ID that will be used by default in the generate method\n\t * @internal\n\t */\n\tprivate [ProcessIdSymbol] = 1n;\n\n\t/**\n\t * The worker ID that will be used by default in the generate method\n\t * @internal\n\t */\n\tprivate [WorkerIdSymbol] = 0n;\n\n\t/**\n\t * @param epoch the epoch to use\n\t */\n\tpublic constructor(epoch: number | bigint | Date) {\n\t\tthis[EpochSymbol] = BigInt(epoch instanceof Date ? epoch.getTime() : epoch);\n\t}\n\n\t/**\n\t * The epoch for this snowflake\n\t */\n\tpublic get epoch(): bigint {\n\t\treturn this[EpochSymbol];\n\t}\n\n\t/**\n\t * Gets the configured process ID\n\t */\n\tpublic get processId(): bigint {\n\t\treturn this[ProcessIdSymbol];\n\t}\n\n\t/**\n\t * Sets the process ID that will be used by default for the {@link generate} method\n\t * @param value The new value, will be coerced to BigInt and masked with `0b11111n`\n\t */\n\tpublic set processId(value: number | bigint) {\n\t\tthis[ProcessIdSymbol] = BigInt(value) & 0b11111n;\n\t}\n\n\t/**\n\t * Gets the configured worker ID\n\t */\n\tpublic get workerId(): bigint {\n\t\treturn this[WorkerIdSymbol];\n\t}\n\n\t/**\n\t * Sets the worker ID that will be used by default for the {@link generate} method\n\t * @param value The new value, will be coerced to BigInt and masked with `0b11111n`\n\t */\n\tpublic set workerId(value: number | bigint) {\n\t\tthis[WorkerIdSymbol] = BigInt(value) & 0b11111n;\n\t}\n\n\t/**\n\t * Generates a snowflake given an epoch and optionally a timestamp\n\t * @param options options to pass into the generator, see {@link SnowflakeGenerateOptions}\n\t *\n\t * **note** when `increment` is not provided it defaults to the private `increment` of the instance\n\t * @example\n\t * ```typescript\n\t * const epoch = new Date('2000-01-01T00:00:00.000Z');\n\t * const snowflake = new Snowflake(epoch).generate();\n\t * ```\n\t * @returns A unique snowflake\n\t */\n\tpublic generate({\n\t\tincrement,\n\t\ttimestamp = Date.now(),\n\t\tworkerId = this[WorkerIdSymbol],\n\t\tprocessId = this[ProcessIdSymbol]\n\t}: SnowflakeGenerateOptions = {}) {\n\t\tif (timestamp instanceof Date) timestamp = BigInt(timestamp.getTime());\n\t\telse if (typeof timestamp === 'number') timestamp = BigInt(timestamp);\n\t\telse if (typeof timestamp !== 'bigint') {\n\t\t\tthrow new TypeError(`\"timestamp\" argument must be a number, bigint, or Date (received ${typeof timestamp})`);\n\t\t}\n\n\t\tif (typeof increment === 'bigint' && increment >= 4095n) increment = 0n;\n\t\telse {\n\t\t\tincrement = this[IncrementSymbol]++;\n\t\t\tif (this[IncrementSymbol] >= 4095n) this[IncrementSymbol] = 0n;\n\t\t}\n\n\t\t// timestamp, workerId, processId, increment\n\t\treturn ((timestamp - this[EpochSymbol]) << 22n) | ((workerId & 0b11111n) << 17n) | ((processId & 0b11111n) << 12n) | increment;\n\t}\n\n\t/**\n\t * Deconstructs a snowflake given a snowflake ID\n\t * @param id the snowflake to deconstruct\n\t * @returns a deconstructed snowflake\n\t * @example\n\t * ```typescript\n\t * const epoch = new Date('2000-01-01T00:00:00.000Z');\n\t * const snowflake = new Snowflake(epoch).deconstruct('3971046231244935168');\n\t * ```\n\t */\n\tpublic deconstruct(id: string | bigint): DeconstructedSnowflake {\n\t\tconst bigIntId = BigInt(id);\n\t\tconst epoch = this[EpochSymbol];\n\t\treturn {\n\t\t\tid: bigIntId,\n\t\t\ttimestamp: (bigIntId >> 22n) + epoch,\n\t\t\tworkerId: (bigIntId >> 17n) & 0b11111n,\n\t\t\tprocessId: (bigIntId >> 12n) & 0b11111n,\n\t\t\tincrement: bigIntId & 0b111111111111n,\n\t\t\tepoch\n\t\t};\n\t}\n\n\t/**\n\t * Retrieves the timestamp field's value from a snowflake.\n\t * @param id The snowflake to get the timestamp value from.\n\t * @returns The UNIX timestamp that is stored in `id`.\n\t */\n\tpublic timestampFrom(id: string | bigint): number {\n\t\treturn Number((BigInt(id) >> 22n) + this[EpochSymbol]);\n\t}\n\n\t/**\n\t * Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given\n\t * snowflake in sort order.\n\t * @param a The first snowflake to compare.\n\t * @param b The second snowflake to compare.\n\t * @returns `-1` if `a` is older than `b`, `0` if `a` and `b` are equals, `1` if `a` is newer than `b`.\n\t * @example Sort snowflakes in ascending order\n\t * ```typescript\n\t * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];\n\t * console.log(ids.sort((a, b) => Snowflake.compare(a, b)));\n\t * // → ['254360814063058944', '737141877803057244', '1056191128120082432'];\n\t * ```\n\t * @example Sort snowflakes in descending order\n\t * ```typescript\n\t * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];\n\t * console.log(ids.sort((a, b) => -Snowflake.compare(a, b)));\n\t * // → ['1056191128120082432', '737141877803057244', '254360814063058944'];\n\t * ```\n\t */\n\tpublic static compare(a: string | bigint, b: string | bigint): -1 | 0 | 1 {\n\t\tconst typeA = typeof a;\n\t\treturn typeA === typeof b\n\t\t\t? typeA === 'string'\n\t\t\t\t? cmpString(a as string, b as string)\n\t\t\t\t: cmpBigInt(a as bigint, b as bigint)\n\t\t\t: cmpBigInt(BigInt(a), BigInt(b));\n\t}\n}\n\n/** @internal */\nfunction cmpBigInt(a: bigint, b: bigint) {\n\treturn a === b ? 0 : a < b ? -1 : 1;\n}\n\n/** @internal */\nfunction cmpString(a: string, b: string) {\n\treturn a === b ? 0 : a.length < b.length ? -1 : a.length > b.length ? 1 : a < b ? -1 : 1;\n}\n\n/**\n * Options for Snowflake#generate\n */\nexport interface SnowflakeGenerateOptions {\n\t/**\n\t * Timestamp or date of the snowflake to generate\n\t * @default Date.now()\n\t */\n\ttimestamp?: number | bigint | Date;\n\n\t/**\n\t * The increment to use\n\t * @default 0n\n\t * @remark keep in mind that this bigint is auto-incremented between generate calls\n\t */\n\tincrement?: bigint;\n\n\t/**\n\t * The worker ID to use, will be truncated to 5 bits (0-31)\n\t * @default 0n\n\t */\n\tworkerId?: bigint;\n\n\t/**\n\t * The process ID to use, will be truncated to 5 bits (0-31)\n\t * @default 1n\n\t */\n\tprocessId?: bigint;\n}\n\n/**\n * Object returned by Snowflake#deconstruct\n */\nexport interface DeconstructedSnowflake {\n\t/**\n\t * The id in BigInt form\n\t */\n\tid: bigint;\n\n\t/**\n\t * The timestamp stored in the snowflake\n\t */\n\ttimestamp: bigint;\n\n\t/**\n\t * The worker id stored in the snowflake\n\t */\n\tworkerId: bigint;\n\n\t/**\n\t * The process id stored in the snowflake\n\t */\n\tprocessId: bigint;\n\n\t/**\n\t * The increment stored in the snowflake\n\t */\n\tincrement: bigint;\n\n\t/**\n\t * The epoch to use in the snowflake\n\t */\n\tepoch: bigint;\n}\n","import { Snowflake } from './Snowflake';\n\n/**\n * A class for parsing snowflake ids using Discord's snowflake epoch\n *\n * Which is 2015-01-01 at 00:00:00.000 UTC+0, {@linkplain https://discord.com/developers/docs/reference#snowflakes}\n */\nexport const DiscordSnowflake = new Snowflake(1420070400000n);\n","import { Snowflake } from './Snowflake';\n\n/**\n * A class for parsing snowflake ids using Twitter's snowflake epoch\n *\n * Which is 2010-11-04 at 01:42:54.657 UTC+0, found in the archived snowflake repository {@linkplain https://github.com/twitter-archive/snowflake/blob/b3f6a3c6ca8e1b6847baa6ff42bf72201e2c2231/src/main/scala/com/twitter/service/snowflake/IdWorker.scala#L25}\n */\nexport const TwitterSnowflake = new Snowflake(1288834974657n);\n"]}
|