@sapphire/snowflake 3.4.0 β†’ 3.4.1-next.04a16e3.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/README.md CHANGED
@@ -157,78 +157,14 @@ We accept donations through Open Collective, Ko-fi, PayPal, Patreon and GitHub S
157
157
  | Patreon | [Click Here](https://sapphirejs.dev/patreon) |
158
158
  | PayPal | [Click Here](https://sapphirejs.dev/paypal) |
159
159
 
160
- ## Contributors ✨
161
-
162
- Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
163
-
164
- <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
165
- <!-- prettier-ignore-start -->
166
- <!-- markdownlint-disable -->
167
- <table>
168
- <tr>
169
- <td align="center"><a href="https://favware.tech/"><img src="https://avatars3.githubusercontent.com/u/4019718?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jeroen Claassens</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=favna" title="Code">πŸ’»</a> <a href="#infra-favna" title="Infrastructure (Hosting, Build-Tools, etc)">πŸš‡</a> <a href="#projectManagement-favna" title="Project Management">πŸ“†</a> <a href="https://github.com/sapphiredev/utilities/commits?author=favna" title="Documentation">πŸ“–</a> <a href="https://github.com/sapphiredev/utilities/commits?author=favna" title="Tests">⚠️</a></td>
170
- <td align="center"><a href="https://github.com/kyranet"><img src="https://avatars0.githubusercontent.com/u/24852502?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aura RomΓ‘n</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=kyranet" title="Code">πŸ’»</a> <a href="#projectManagement-kyranet" title="Project Management">πŸ“†</a> <a href="https://github.com/sapphiredev/utilities/pulls?q=is%3Apr+reviewed-by%3Akyranet" title="Reviewed Pull Requests">πŸ‘€</a> <a href="https://github.com/sapphiredev/utilities/commits?author=kyranet" title="Tests">⚠️</a></td>
171
- <td align="center"><a href="https://github.com/PyroTechniac"><img src="https://avatars2.githubusercontent.com/u/39341355?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gryffon Bellish</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=PyroTechniac" title="Code">πŸ’»</a> <a href="https://github.com/sapphiredev/utilities/pulls?q=is%3Apr+reviewed-by%3APyroTechniac" title="Reviewed Pull Requests">πŸ‘€</a> <a href="https://github.com/sapphiredev/utilities/commits?author=PyroTechniac" title="Tests">⚠️</a></td>
172
- <td align="center"><a href="https://github.com/vladfrangu"><img src="https://avatars3.githubusercontent.com/u/17960496?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vlad Frangu</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=vladfrangu" title="Code">πŸ’»</a> <a href="https://github.com/sapphiredev/utilities/issues?q=author%3Avladfrangu" title="Bug reports">πŸ›</a> <a href="https://github.com/sapphiredev/utilities/pulls?q=is%3Apr+reviewed-by%3Avladfrangu" title="Reviewed Pull Requests">πŸ‘€</a> <a href="#userTesting-vladfrangu" title="User Testing">πŸ““</a> <a href="https://github.com/sapphiredev/utilities/commits?author=vladfrangu" title="Tests">⚠️</a></td>
173
- <td align="center"><a href="https://github.com/Stitch07"><img src="https://avatars0.githubusercontent.com/u/29275227?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Stitch07</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=Stitch07" title="Code">πŸ’»</a> <a href="#projectManagement-Stitch07" title="Project Management">πŸ“†</a> <a href="https://github.com/sapphiredev/utilities/commits?author=Stitch07" title="Tests">⚠️</a></td>
174
- <td align="center"><a href="https://github.com/apps/depfu"><img src="https://avatars3.githubusercontent.com/in/715?v=4?s=100" width="100px;" alt=""/><br /><sub><b>depfu[bot]</b></sub></a><br /><a href="#maintenance-depfu[bot]" title="Maintenance">🚧</a></td>
175
- <td align="center"><a href="https://github.com/apps/allcontributors"><img src="https://avatars0.githubusercontent.com/in/23186?v=4?s=100" width="100px;" alt=""/><br /><sub><b>allcontributors[bot]</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=allcontributors[bot]" title="Documentation">πŸ“–</a></td>
176
- </tr>
177
- <tr>
178
- <td align="center"><a href="https://github.com/Nytelife26"><img src="https://avatars1.githubusercontent.com/u/22531310?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tyler J Russell</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=Nytelife26" title="Documentation">πŸ“–</a></td>
179
- <td align="center"><a href="https://github.com/Alcremie"><img src="https://avatars0.githubusercontent.com/u/54785334?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ivan Lieder</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=Alcremie" title="Code">πŸ’»</a> <a href="https://github.com/sapphiredev/utilities/issues?q=author%3AAlcremie" title="Bug reports">πŸ›</a></td>
180
- <td align="center"><a href="https://github.com/RealShadowNova"><img src="https://avatars3.githubusercontent.com/u/46537907?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hezekiah Hendry</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=RealShadowNova" title="Code">πŸ’»</a> <a href="#tool-RealShadowNova" title="Tools">πŸ”§</a></td>
181
- <td align="center"><a href="https://github.com/Vetlix"><img src="https://avatars.githubusercontent.com/u/31412314?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vetlix</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=Vetlix" title="Code">πŸ’»</a></td>
182
- <td align="center"><a href="https://github.com/ethamitc"><img src="https://avatars.githubusercontent.com/u/27776796?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ethan Mitchell</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=ethamitc" title="Documentation">πŸ“–</a></td>
183
- <td align="center"><a href="https://github.com/noftaly"><img src="https://avatars.githubusercontent.com/u/34779161?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Elliot</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=noftaly" title="Code">πŸ’»</a></td>
184
- <td align="center"><a href="https://jurien.dev"><img src="https://avatars.githubusercontent.com/u/5418114?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jurien Hamaker</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=jurienhamaker" title="Code">πŸ’»</a></td>
185
- </tr>
186
- <tr>
187
- <td align="center"><a href="https://fanoulis.dev/"><img src="https://avatars.githubusercontent.com/u/38255093?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Charalampos Fanoulis</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=cfanoulis" title="Documentation">πŸ“–</a></td>
188
- <td align="center"><a href="https://github.com/apps/dependabot"><img src="https://avatars.githubusercontent.com/in/29110?v=4?s=100" width="100px;" alt=""/><br /><sub><b>dependabot[bot]</b></sub></a><br /><a href="#maintenance-dependabot[bot]" title="Maintenance">🚧</a></td>
189
- <td align="center"><a href="https://kaname.netlify.app/"><img src="https://avatars.githubusercontent.com/u/56084970?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kaname</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=kaname-png" title="Code">πŸ’»</a></td>
190
- <td align="center"><a href="https://github.com/nandhagk"><img src="https://avatars.githubusercontent.com/u/62976649?v=4?s=100" width="100px;" alt=""/><br /><sub><b>nandhagk</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/issues?q=author%3Anandhagk" title="Bug reports">πŸ›</a></td>
191
- <td align="center"><a href="https://megatank58.me/"><img src="https://avatars.githubusercontent.com/u/51410502?v=4?s=100" width="100px;" alt=""/><br /><sub><b>megatank58</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=megatank58" title="Code">πŸ’»</a></td>
192
- <td align="center"><a href="https://github.com/UndiedGamer"><img src="https://avatars.githubusercontent.com/u/84702365?v=4?s=100" width="100px;" alt=""/><br /><sub><b>UndiedGamer</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=UndiedGamer" title="Code">πŸ’»</a></td>
193
- <td align="center"><a href="https://github.com/Lioness100"><img src="https://avatars.githubusercontent.com/u/65814829?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lioness100</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=Lioness100" title="Documentation">πŸ“–</a> <a href="https://github.com/sapphiredev/utilities/commits?author=Lioness100" title="Code">πŸ’»</a></td>
194
- </tr>
195
- <tr>
196
- <td align="center"><a href="https://gitlab.com/DavidPH/"><img src="https://avatars.githubusercontent.com/u/44669930?v=4?s=100" width="100px;" alt=""/><br /><sub><b>David</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=DavidPHH" title="Code">πŸ’»</a></td>
197
- <td align="center"><a href="https://github.com/apps/renovate"><img src="https://avatars.githubusercontent.com/in/2740?v=4?s=100" width="100px;" alt=""/><br /><sub><b>renovate[bot]</b></sub></a><br /><a href="#maintenance-renovate[bot]" title="Maintenance">🚧</a></td>
198
- <td align="center"><a href="https://renovate.whitesourcesoftware.com/"><img src="https://avatars.githubusercontent.com/u/25180681?v=4?s=100" width="100px;" alt=""/><br /><sub><b>WhiteSource Renovate</b></sub></a><br /><a href="#maintenance-renovate-bot" title="Maintenance">🚧</a></td>
199
- <td align="center"><a href="https://fc5570.me/"><img src="https://avatars.githubusercontent.com/u/68158483?v=4?s=100" width="100px;" alt=""/><br /><sub><b>FC</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=FC5570" title="Code">πŸ’»</a></td>
200
- <td align="center"><a href="https://github.com/Tokipudi"><img src="https://avatars.githubusercontent.com/u/29551076?v=4?s=100" width="100px;" alt=""/><br /><sub><b>JΓ©rΓ©my de Saint Denis</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=Tokipudi" title="Code">πŸ’»</a></td>
201
- <td align="center"><a href="https://github.com/ItsMrCube"><img src="https://avatars.githubusercontent.com/u/25201357?v=4?s=100" width="100px;" alt=""/><br /><sub><b>MrCube</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=ItsMrCube" title="Code">πŸ’»</a></td>
202
- <td align="center"><a href="https://github.com/bitomic"><img src="https://avatars.githubusercontent.com/u/35199700?v=4?s=100" width="100px;" alt=""/><br /><sub><b>bitomic</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=bitomic" title="Code">πŸ’»</a></td>
203
- </tr>
204
- <tr>
205
- <td align="center"><a href="https://c43721.dev/"><img src="https://avatars.githubusercontent.com/u/55610086?v=4?s=100" width="100px;" alt=""/><br /><sub><b>c43721</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=c43721" title="Code">πŸ’»</a></td>
206
- <td align="center"><a href="https://commandtechno.com/"><img src="https://avatars.githubusercontent.com/u/68407783?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Commandtechno</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=Commandtechno" title="Code">πŸ’»</a></td>
207
- <td align="center"><a href="https://github.com/dhruv-kaushikk"><img src="https://avatars.githubusercontent.com/u/73697546?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aura</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=dhruv-kaushikk" title="Code">πŸ’»</a></td>
208
- <td align="center"><a href="https://axis.moe/"><img src="https://avatars.githubusercontent.com/u/54381371?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jonathan</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=axisiscool" title="Code">πŸ’»</a></td>
209
- <td align="center"><a href="https://github.com/imranbarbhuiya"><img src="https://avatars.githubusercontent.com/u/74945038?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Parbez</b></sub></a><br /><a href="#maintenance-imranbarbhuiya" title="Maintenance">🚧</a></td>
210
- <td align="center"><a href="https://github.com/NotKaskus"><img src="https://avatars.githubusercontent.com/u/75168528?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Paul Andrew</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=NotKaskus" title="Documentation">πŸ“–</a></td>
211
- <td align="center"><a href="https://linktr.ee/mzato0001"><img src="https://avatars.githubusercontent.com/u/62367547?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mzato</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=Mzato0001" title="Code">πŸ’»</a> <a href="https://github.com/sapphiredev/utilities/issues?q=author%3AMzato0001" title="Bug reports">πŸ›</a></td>
212
- </tr>
213
- <tr>
214
- <td align="center"><a href="https://github.com/MajesticString"><img src="https://avatars.githubusercontent.com/u/66224939?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Harry Allen</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=MajesticString" title="Documentation">πŸ“–</a></td>
215
- <td align="center"><a href="https://github.com/EvolutionX-10"><img src="https://avatars.githubusercontent.com/u/85353424?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Evo</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=EvolutionX-10" title="Code">πŸ’»</a></td>
216
- <td align="center"><a href="https://enes.ovh/"><img src="https://avatars.githubusercontent.com/u/61084101?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Enes GenΓ§</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=enxg" title="Code">πŸ’»</a></td>
217
- <td align="center"><a href="https://github.com/muchnameless"><img src="https://avatars.githubusercontent.com/u/12682826?v=4?s=100" width="100px;" alt=""/><br /><sub><b>muchnameless</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=muchnameless" title="Code">πŸ’»</a></td>
218
- <td align="center"><a href="https://github.com/r-priyam"><img src="https://avatars.githubusercontent.com/u/50884372?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Priyam</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=r-priyam" title="Code">πŸ’»</a></td>
219
- <td align="center"><a href="https://github.com/legendhimslef"><img src="https://avatars.githubusercontent.com/u/69213593?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Voxelli</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=legendhimslef" title="Code">πŸ’»</a></td>
220
- <td align="center"><a href="https://github.com/CitTheDev"><img src="https://avatars.githubusercontent.com/u/94020875?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Cit The Dev</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=CitTheDev" title="Code">πŸ’»</a></td>
221
- </tr>
222
- <tr>
223
- <td align="center"><a href="https://www.goestav.com/"><img src="https://avatars.githubusercontent.com/u/27970303?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Goestav</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=goestav" title="Code">πŸ’»</a></td>
224
- <td align="center"><a href="https://github.com/didinele"><img src="https://avatars.githubusercontent.com/u/27137376?v=4?s=100" width="100px;" alt=""/><br /><sub><b>DD</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=didinele" title="Code">πŸ’»</a></td>
225
- <td align="center"><a href="https://steamcommunity.com/id/06000208"><img src="https://avatars.githubusercontent.com/u/52764066?v=4?s=100" width="100px;" alt=""/><br /><sub><b>amber</b></sub></a><br /><a href="https://github.com/sapphiredev/utilities/commits?author=06000208" title="Code">πŸ’»</a></td>
226
- </tr>
227
- </table>
228
-
229
- <!-- markdownlint-restore -->
230
- <!-- prettier-ignore-end -->
231
-
232
- <!-- ALL-CONTRIBUTORS-LIST:END -->
233
-
234
- This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
160
+ ## Contributors
161
+
162
+ Please make sure to read the [Contributing Guide][contributing] before making a pull request.
163
+
164
+ Thank you to all the people who already contributed to Sapphire!
165
+
166
+ <a href="https://github.com/sapphiredev/utilities/graphs/contributors">
167
+ <img src="https://contrib.rocks/image?repo=sapphiredev/utilities" />
168
+ </a>
169
+
170
+ [contributing]: https://github.com/sapphiredev/.github/blob/main/.github/CONTRIBUTING.md
@@ -40,15 +40,45 @@ var SapphireSnowflake = (function (exports) {
40
40
  var WorkerId = 0n;
41
41
  var _increment, _epoch;
42
42
  var Snowflake = class {
43
+ /**
44
+ * @param epoch the epoch to use
45
+ */
43
46
  constructor(epoch) {
47
+ /**
48
+ * Alias for {@link deconstruct}
49
+ */
50
+ // eslint-disable-next-line @typescript-eslint/unbound-method
44
51
  __publicField(this, "decode", this.deconstruct);
52
+ /**
53
+ * Internal incrementor for generating snowflakes
54
+ * @internal
55
+ */
45
56
  __privateAdd(this, _increment, 0n);
57
+ /**
58
+ * Internal reference of the epoch passed in the constructor
59
+ * @internal
60
+ */
46
61
  __privateAdd(this, _epoch, void 0);
47
62
  __privateSet(this, _epoch, BigInt(epoch instanceof Date ? epoch.getTime() : epoch));
48
63
  }
64
+ /**
65
+ * The epoch for this snowflake.
66
+ */
49
67
  get epoch() {
50
68
  return __privateGet(this, _epoch);
51
69
  }
70
+ /**
71
+ * Generates a snowflake given an epoch and optionally a timestamp
72
+ * @param options options to pass into the generator, see {@link SnowflakeGenerateOptions}
73
+ *
74
+ * **note** when `increment` is not provided it defaults to the private `increment` of the instance
75
+ * @example
76
+ * ```typescript
77
+ * const epoch = new Date('2000-01-01T00:00:00.000Z');
78
+ * const snowflake = new Snowflake(epoch).generate();
79
+ * ```
80
+ * @returns A unique snowflake
81
+ */
52
82
  generate({ increment, timestamp = Date.now(), workerId = WorkerId, processId = ProcessId } = {}) {
53
83
  if (timestamp instanceof Date)
54
84
  timestamp = BigInt(timestamp.getTime());
@@ -66,6 +96,16 @@ var SapphireSnowflake = (function (exports) {
66
96
  }
67
97
  return timestamp - __privateGet(this, _epoch) << 22n | (workerId & 0b11111n) << 17n | (processId & 0b11111n) << 12n | increment;
68
98
  }
99
+ /**
100
+ * Deconstructs a snowflake given a snowflake ID
101
+ * @param id the snowflake to deconstruct
102
+ * @returns a deconstructed snowflake
103
+ * @example
104
+ * ```typescript
105
+ * const epoch = new Date('2000-01-01T00:00:00.000Z');
106
+ * const snowflake = new Snowflake(epoch).deconstruct('3971046231244935168');
107
+ * ```
108
+ */
69
109
  deconstruct(id) {
70
110
  const bigIntId = BigInt(id);
71
111
  return {
@@ -77,9 +117,33 @@ var SapphireSnowflake = (function (exports) {
77
117
  epoch: __privateGet(this, _epoch)
78
118
  };
79
119
  }
120
+ /**
121
+ * Retrieves the timestamp field's value from a snowflake.
122
+ * @param id The snowflake to get the timestamp value from.
123
+ * @returns The UNIX timestamp that is stored in `id`.
124
+ */
80
125
  timestampFrom(id) {
81
126
  return Number((BigInt(id) >> 22n) + __privateGet(this, _epoch));
82
127
  }
128
+ /**
129
+ * Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given
130
+ * snowflake in sort order.
131
+ * @param a The first snowflake to compare.
132
+ * @param b The second snowflake to compare.
133
+ * @returns `-1` if `a` is older than `b`, `0` if `a` and `b` are equals, `1` if `a` is newer than `b`.
134
+ * @example Sort snowflakes in ascending order
135
+ * ```typescript
136
+ * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];
137
+ * console.log(ids.sort((a, b) => Snowflake.compare(a, b)));
138
+ * // β†’ ['254360814063058944', '737141877803057244', '1056191128120082432'];
139
+ * ```
140
+ * @example Sort snowflakes in descending order
141
+ * ```typescript
142
+ * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];
143
+ * console.log(ids.sort((a, b) => -Snowflake.compare(a, b)));
144
+ * // β†’ ['1056191128120082432', '737141877803057244', '254360814063058944'];
145
+ * ```
146
+ */
83
147
  static compare(a, b) {
84
148
  if (typeof a === "bigint" || typeof b === "bigint") {
85
149
  if (typeof a === "string")
@@ -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,EAsBf,YAAY,OAA+B;AAjBlD,wBAAO,UAAS,KAAK;AAMrB,mCAAa;AAMb;AAMC,uBAAK,QAAS,OAAO,iBAAiB,OAAO,MAAM,QAAQ,IAAI,KAAK;AAAA,EACrE;AAAA,EAKA,IAAW,QAAgB;AAC1B,WAAO,mBAAK;AAAA,EACb;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,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,EAOO,cAAc,IAA6B;AACjD,WAAO,QAAQ,OAAO,EAAE,KAAK,OAAO,mBAAK,OAAM;AAAA,EAChD;AAAA,EAqBA,OAAc,QAAQ,GAAoB,GAAgC;AACzE,QAAI,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AACnD,UAAI,OAAO,MAAM;AAAU,YAAI,OAAO,CAAC;AAAA,eAC9B,OAAO,MAAM;AAAU,YAAI,OAAO,CAAC;AAC5C,aAAO,MAAM,IAAI,IAAI,IAAI,IAAI,KAAK;AAAA,IACnC;AAEA,WAAO,MAAM,IAAI,IAAI,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,IAAI,KAAK;AAAA,EACxF;AACD;AAzHa;AAWZ;AAMA;;;AC1BM,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\tif (typeof a === 'bigint' || typeof b === 'bigint') {\n\t\t\tif (typeof a === 'string') a = BigInt(a);\n\t\t\telse if (typeof b === 'string') b = BigInt(b);\n\t\t\treturn a === b ? 0 : a < b ? -1 : 1;\n\t\t}\n\n\t\treturn a === b ? 0 : a.length < b.length ? -1 : a.length > b.length ? 1 : a < b ? -1 : 1;\n\t}\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,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,QAAI,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AACnD,UAAI,OAAO,MAAM;AAAU,YAAI,OAAO,CAAC;AAAA,eAC9B,OAAO,MAAM;AAAU,YAAI,OAAO,CAAC;AAC5C,aAAO,MAAM,IAAI,IAAI,IAAI,IAAI,KAAK;AAAA,IACnC;AAEA,WAAO,MAAM,IAAI,IAAI,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,IAAI,KAAK;AAAA,EACxF;AACD;AAzHa;AAWZ;AAMA;;;AC1BM,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\tif (typeof a === 'bigint' || typeof b === 'bigint') {\n\t\t\tif (typeof a === 'string') a = BigInt(a);\n\t\t\telse if (typeof b === 'string') b = BigInt(b);\n\t\t\treturn a === b ? 0 : a < b ? -1 : 1;\n\t\t}\n\n\t\treturn a === b ? 0 : a.length < b.length ? -1 : a.length > b.length ? 1 : a < b ? -1 : 1;\n\t}\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
@@ -39,15 +39,45 @@ var ProcessId = 1n;
39
39
  var WorkerId = 0n;
40
40
  var _increment, _epoch;
41
41
  var Snowflake = class {
42
+ /**
43
+ * @param epoch the epoch to use
44
+ */
42
45
  constructor(epoch) {
46
+ /**
47
+ * Alias for {@link deconstruct}
48
+ */
49
+ // eslint-disable-next-line @typescript-eslint/unbound-method
43
50
  __publicField(this, "decode", this.deconstruct);
51
+ /**
52
+ * Internal incrementor for generating snowflakes
53
+ * @internal
54
+ */
44
55
  __privateAdd(this, _increment, 0n);
56
+ /**
57
+ * Internal reference of the epoch passed in the constructor
58
+ * @internal
59
+ */
45
60
  __privateAdd(this, _epoch, void 0);
46
61
  __privateSet(this, _epoch, BigInt(epoch instanceof Date ? epoch.getTime() : epoch));
47
62
  }
63
+ /**
64
+ * The epoch for this snowflake.
65
+ */
48
66
  get epoch() {
49
67
  return __privateGet(this, _epoch);
50
68
  }
69
+ /**
70
+ * Generates a snowflake given an epoch and optionally a timestamp
71
+ * @param options options to pass into the generator, see {@link SnowflakeGenerateOptions}
72
+ *
73
+ * **note** when `increment` is not provided it defaults to the private `increment` of the instance
74
+ * @example
75
+ * ```typescript
76
+ * const epoch = new Date('2000-01-01T00:00:00.000Z');
77
+ * const snowflake = new Snowflake(epoch).generate();
78
+ * ```
79
+ * @returns A unique snowflake
80
+ */
51
81
  generate({ increment, timestamp = Date.now(), workerId = WorkerId, processId = ProcessId } = {}) {
52
82
  if (timestamp instanceof Date)
53
83
  timestamp = BigInt(timestamp.getTime());
@@ -65,6 +95,16 @@ var Snowflake = class {
65
95
  }
66
96
  return timestamp - __privateGet(this, _epoch) << 22n | (workerId & 0b11111n) << 17n | (processId & 0b11111n) << 12n | increment;
67
97
  }
98
+ /**
99
+ * Deconstructs a snowflake given a snowflake ID
100
+ * @param id the snowflake to deconstruct
101
+ * @returns a deconstructed snowflake
102
+ * @example
103
+ * ```typescript
104
+ * const epoch = new Date('2000-01-01T00:00:00.000Z');
105
+ * const snowflake = new Snowflake(epoch).deconstruct('3971046231244935168');
106
+ * ```
107
+ */
68
108
  deconstruct(id) {
69
109
  const bigIntId = BigInt(id);
70
110
  return {
@@ -76,9 +116,33 @@ var Snowflake = class {
76
116
  epoch: __privateGet(this, _epoch)
77
117
  };
78
118
  }
119
+ /**
120
+ * Retrieves the timestamp field's value from a snowflake.
121
+ * @param id The snowflake to get the timestamp value from.
122
+ * @returns The UNIX timestamp that is stored in `id`.
123
+ */
79
124
  timestampFrom(id) {
80
125
  return Number((BigInt(id) >> 22n) + __privateGet(this, _epoch));
81
126
  }
127
+ /**
128
+ * Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given
129
+ * snowflake in sort order.
130
+ * @param a The first snowflake to compare.
131
+ * @param b The second snowflake to compare.
132
+ * @returns `-1` if `a` is older than `b`, `0` if `a` and `b` are equals, `1` if `a` is newer than `b`.
133
+ * @example Sort snowflakes in ascending order
134
+ * ```typescript
135
+ * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];
136
+ * console.log(ids.sort((a, b) => Snowflake.compare(a, b)));
137
+ * // β†’ ['254360814063058944', '737141877803057244', '1056191128120082432'];
138
+ * ```
139
+ * @example Sort snowflakes in descending order
140
+ * ```typescript
141
+ * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];
142
+ * console.log(ids.sort((a, b) => -Snowflake.compare(a, b)));
143
+ * // β†’ ['1056191128120082432', '737141877803057244', '254360814063058944'];
144
+ * ```
145
+ */
82
146
  static compare(a, b) {
83
147
  if (typeof a === "bigint" || typeof b === "bigint") {
84
148
  if (typeof a === "string")
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,EAsBf,YAAY,OAA+B;AAjBlD,wBAAO,UAAS,KAAK;AAMrB,mCAAa;AAMb;AAMC,uBAAK,QAAS,OAAO,iBAAiB,OAAO,MAAM,QAAQ,IAAI,KAAK;AAAA,EACrE;AAAA,EAKA,IAAW,QAAgB;AAC1B,WAAO,mBAAK;AAAA,EACb;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,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,EAOO,cAAc,IAA6B;AACjD,WAAO,QAAQ,OAAO,EAAE,KAAK,OAAO,mBAAK,OAAM;AAAA,EAChD;AAAA,EAqBA,OAAc,QAAQ,GAAoB,GAAgC;AACzE,QAAI,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AACnD,UAAI,OAAO,MAAM;AAAU,YAAI,OAAO,CAAC;AAAA,eAC9B,OAAO,MAAM;AAAU,YAAI,OAAO,CAAC;AAC5C,aAAO,MAAM,IAAI,IAAI,IAAI,IAAI,KAAK;AAAA,IACnC;AAEA,WAAO,MAAM,IAAI,IAAI,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,IAAI,KAAK;AAAA,EACxF;AACD;AAzHa;AAWZ;AAMA;;;AC1BM,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\tif (typeof a === 'bigint' || typeof b === 'bigint') {\n\t\t\tif (typeof a === 'string') a = BigInt(a);\n\t\t\telse if (typeof b === 'string') b = BigInt(b);\n\t\t\treturn a === b ? 0 : a < b ? -1 : 1;\n\t\t}\n\n\t\treturn a === b ? 0 : a.length < b.length ? -1 : a.length > b.length ? 1 : a < b ? -1 : 1;\n\t}\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,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,QAAI,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AACnD,UAAI,OAAO,MAAM;AAAU,YAAI,OAAO,CAAC;AAAA,eAC9B,OAAO,MAAM;AAAU,YAAI,OAAO,CAAC;AAC5C,aAAO,MAAM,IAAI,IAAI,IAAI,IAAI,KAAK;AAAA,IACnC;AAEA,WAAO,MAAM,IAAI,IAAI,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,IAAI,KAAK;AAAA,EACxF;AACD;AAzHa;AAWZ;AAMA;;;AC1BM,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\tif (typeof a === 'bigint' || typeof b === 'bigint') {\n\t\t\tif (typeof a === 'string') a = BigInt(a);\n\t\t\telse if (typeof b === 'string') b = BigInt(b);\n\t\t\treturn a === b ? 0 : a < b ? -1 : 1;\n\t\t}\n\n\t\treturn a === b ? 0 : a.length < b.length ? -1 : a.length > b.length ? 1 : a < b ? -1 : 1;\n\t}\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
@@ -37,15 +37,45 @@ var ProcessId = 1n;
37
37
  var WorkerId = 0n;
38
38
  var _increment, _epoch;
39
39
  var Snowflake = class {
40
+ /**
41
+ * @param epoch the epoch to use
42
+ */
40
43
  constructor(epoch) {
44
+ /**
45
+ * Alias for {@link deconstruct}
46
+ */
47
+ // eslint-disable-next-line @typescript-eslint/unbound-method
41
48
  __publicField(this, "decode", this.deconstruct);
49
+ /**
50
+ * Internal incrementor for generating snowflakes
51
+ * @internal
52
+ */
42
53
  __privateAdd(this, _increment, 0n);
54
+ /**
55
+ * Internal reference of the epoch passed in the constructor
56
+ * @internal
57
+ */
43
58
  __privateAdd(this, _epoch, void 0);
44
59
  __privateSet(this, _epoch, BigInt(epoch instanceof Date ? epoch.getTime() : epoch));
45
60
  }
61
+ /**
62
+ * The epoch for this snowflake.
63
+ */
46
64
  get epoch() {
47
65
  return __privateGet(this, _epoch);
48
66
  }
67
+ /**
68
+ * Generates a snowflake given an epoch and optionally a timestamp
69
+ * @param options options to pass into the generator, see {@link SnowflakeGenerateOptions}
70
+ *
71
+ * **note** when `increment` is not provided it defaults to the private `increment` of the instance
72
+ * @example
73
+ * ```typescript
74
+ * const epoch = new Date('2000-01-01T00:00:00.000Z');
75
+ * const snowflake = new Snowflake(epoch).generate();
76
+ * ```
77
+ * @returns A unique snowflake
78
+ */
49
79
  generate({ increment, timestamp = Date.now(), workerId = WorkerId, processId = ProcessId } = {}) {
50
80
  if (timestamp instanceof Date)
51
81
  timestamp = BigInt(timestamp.getTime());
@@ -63,6 +93,16 @@ var Snowflake = class {
63
93
  }
64
94
  return timestamp - __privateGet(this, _epoch) << 22n | (workerId & 0b11111n) << 17n | (processId & 0b11111n) << 12n | increment;
65
95
  }
96
+ /**
97
+ * Deconstructs a snowflake given a snowflake ID
98
+ * @param id the snowflake to deconstruct
99
+ * @returns a deconstructed snowflake
100
+ * @example
101
+ * ```typescript
102
+ * const epoch = new Date('2000-01-01T00:00:00.000Z');
103
+ * const snowflake = new Snowflake(epoch).deconstruct('3971046231244935168');
104
+ * ```
105
+ */
66
106
  deconstruct(id) {
67
107
  const bigIntId = BigInt(id);
68
108
  return {
@@ -74,9 +114,33 @@ var Snowflake = class {
74
114
  epoch: __privateGet(this, _epoch)
75
115
  };
76
116
  }
117
+ /**
118
+ * Retrieves the timestamp field's value from a snowflake.
119
+ * @param id The snowflake to get the timestamp value from.
120
+ * @returns The UNIX timestamp that is stored in `id`.
121
+ */
77
122
  timestampFrom(id) {
78
123
  return Number((BigInt(id) >> 22n) + __privateGet(this, _epoch));
79
124
  }
125
+ /**
126
+ * Returns a number indicating whether a reference snowflake comes before, or after, or is same as the given
127
+ * snowflake in sort order.
128
+ * @param a The first snowflake to compare.
129
+ * @param b The second snowflake to compare.
130
+ * @returns `-1` if `a` is older than `b`, `0` if `a` and `b` are equals, `1` if `a` is newer than `b`.
131
+ * @example Sort snowflakes in ascending order
132
+ * ```typescript
133
+ * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];
134
+ * console.log(ids.sort((a, b) => Snowflake.compare(a, b)));
135
+ * // β†’ ['254360814063058944', '737141877803057244', '1056191128120082432'];
136
+ * ```
137
+ * @example Sort snowflakes in descending order
138
+ * ```typescript
139
+ * const ids = ['737141877803057244', '1056191128120082432', '254360814063058944'];
140
+ * console.log(ids.sort((a, b) => -Snowflake.compare(a, b)));
141
+ * // β†’ ['1056191128120082432', '737141877803057244', '254360814063058944'];
142
+ * ```
143
+ */
80
144
  static compare(a, b) {
81
145
  if (typeof a === "bigint" || typeof b === "bigint") {
82
146
  if (typeof a === "string")
@@ -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,EAsBf,YAAY,OAA+B;AAjBlD,wBAAO,UAAS,KAAK;AAMrB,mCAAa;AAMb;AAMC,uBAAK,QAAS,OAAO,iBAAiB,OAAO,MAAM,QAAQ,IAAI,KAAK;AAAA,EACrE;AAAA,EAKA,IAAW,QAAgB;AAC1B,WAAO,mBAAK;AAAA,EACb;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,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,EAOO,cAAc,IAA6B;AACjD,WAAO,QAAQ,OAAO,EAAE,KAAK,OAAO,mBAAK,OAAM;AAAA,EAChD;AAAA,EAqBA,OAAc,QAAQ,GAAoB,GAAgC;AACzE,QAAI,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AACnD,UAAI,OAAO,MAAM;AAAU,YAAI,OAAO,CAAC;AAAA,eAC9B,OAAO,MAAM;AAAU,YAAI,OAAO,CAAC;AAC5C,aAAO,MAAM,IAAI,IAAI,IAAI,IAAI,KAAK;AAAA,IACnC;AAEA,WAAO,MAAM,IAAI,IAAI,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,IAAI,KAAK;AAAA,EACxF;AACD;AAzHa;AAWZ;AAMA;;;AC1BM,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\tif (typeof a === 'bigint' || typeof b === 'bigint') {\n\t\t\tif (typeof a === 'string') a = BigInt(a);\n\t\t\telse if (typeof b === 'string') b = BigInt(b);\n\t\t\treturn a === b ? 0 : a < b ? -1 : 1;\n\t\t}\n\n\t\treturn a === b ? 0 : a.length < b.length ? -1 : a.length > b.length ? 1 : a < b ? -1 : 1;\n\t}\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,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,QAAI,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AACnD,UAAI,OAAO,MAAM;AAAU,YAAI,OAAO,CAAC;AAAA,eAC9B,OAAO,MAAM;AAAU,YAAI,OAAO,CAAC;AAC5C,aAAO,MAAM,IAAI,IAAI,IAAI,IAAI,KAAK;AAAA,IACnC;AAEA,WAAO,MAAM,IAAI,IAAI,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,IAAI,KAAK;AAAA,EACxF;AACD;AAzHa;AAWZ;AAMA;;;AC1BM,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\tif (typeof a === 'bigint' || typeof b === 'bigint') {\n\t\t\tif (typeof a === 'string') a = BigInt(a);\n\t\t\telse if (typeof b === 'string') b = BigInt(b);\n\t\t\treturn a === b ? 0 : a < b ? -1 : 1;\n\t\t}\n\n\t\treturn a === b ? 0 : a.length < b.length ? -1 : a.length > b.length ? 1 : a < b ? -1 : 1;\n\t}\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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sapphire/snowflake",
3
- "version": "3.4.0",
3
+ "version": "3.4.1-next.04a16e3.0",
4
4
  "description": "Deconstructs and generates snowflake IDs using BigInts",
5
5
  "author": "@sapphire",
6
6
  "license": "MIT",
@@ -56,12 +56,12 @@
56
56
  "access": "public"
57
57
  },
58
58
  "devDependencies": {
59
- "@favware/cliff-jumper": "^1.9.0",
60
- "@vitest/coverage-c8": "^0.26.2",
61
- "tsup": "^6.5.0",
62
- "typedoc": "^0.23.23",
63
- "typedoc-json-parser": "^7.0.2",
64
- "typescript": "^4.9.4",
65
- "vitest": "^0.26.2"
59
+ "@favware/cliff-jumper": "^1.10.0",
60
+ "@vitest/coverage-c8": "^0.29.1",
61
+ "tsup": "^6.6.3",
62
+ "typedoc": "^0.23.25",
63
+ "typedoc-json-parser": "^7.1.0",
64
+ "typescript": "^4.9.5",
65
+ "vitest": "^0.29.1"
66
66
  }
67
67
  }