@sapphire/ratelimits 2.4.6-next.78a79ca.0 β†’ 2.4.6-next.7c98509.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
@@ -108,70 +108,14 @@ We accept donations through Open Collective, Ko-fi, PayPal, Patreon and GitHub S
108
108
  | Patreon | [Click Here](https://sapphirejs.dev/patreon) |
109
109
  | PayPal | [Click Here](https://sapphirejs.dev/paypal) |
110
110
 
111
- ## Contributors ✨
112
-
113
- Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
114
-
115
- <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
116
- <!-- prettier-ignore-start -->
117
- <!-- markdownlint-disable -->
118
- <table>
119
- <tr>
120
- <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>
121
- <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>
122
- <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>
123
- <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>
124
- <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>
125
- <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>
126
- <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>
127
- </tr>
128
- <tr>
129
- <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>
130
- <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>
131
- <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>
132
- <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>
133
- <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>
134
- <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>
135
- <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>
136
- </tr>
137
- <tr>
138
- <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>
139
- <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>
140
- <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>
141
- <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>
142
- <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>
143
- <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>
144
- <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>
145
- </tr>
146
- <tr>
147
- <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>
148
- <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>
149
- <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>
150
- <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>
151
- <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>
152
- <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>
153
- <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>
154
- </tr>
155
- <tr>
156
- <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>
157
- <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>
158
- <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>
159
- <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>
160
- <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>
161
- <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>
162
- <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>
163
- </tr>
164
- <tr>
165
- <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>
166
- <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>
167
- <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>
168
- <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>
169
- </tr>
170
- </table>
171
-
172
- <!-- markdownlint-restore -->
173
- <!-- prettier-ignore-end -->
174
-
175
- <!-- ALL-CONTRIBUTORS-LIST:END -->
176
-
177
- This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
111
+ ## Contributors
112
+
113
+ Please make sure to read the [Contributing Guide][contributing] before making a pull request.
114
+
115
+ Thank you to all the people who already contributed to Sapphire!
116
+
117
+ <a href="https://github.com/sapphiredev/utilities/graphs/contributors">
118
+ <img src="https://contrib.rocks/image?repo=sapphiredev/utilities" />
119
+ </a>
120
+
121
+ [contributing]: https://github.com/sapphiredev/.github/blob/main/.github/CONTRIBUTING.md
@@ -1,54 +1,56 @@
1
- "use strict";
2
- var SapphireRatelimits = (() => {
1
+ var SapphireRatelimits = (function (exports) {
2
+ 'use strict';
3
+
3
4
  var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
5
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
6
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
- var __export = (target, all) => {
10
- for (var name in all)
11
- __defProp(target, name, { get: all[name], enumerable: true });
12
- };
13
- var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from))
16
- if (!__hasOwnProp.call(to, key) && key !== except)
17
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
- }
19
- return to;
20
- };
21
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
7
  var __publicField = (obj, key, value) => {
23
8
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
24
9
  return value;
25
10
  };
26
11
 
27
- // src/index.ts
28
- var src_exports = {};
29
- __export(src_exports, {
30
- RateLimit: () => RateLimit,
31
- RateLimitManager: () => RateLimitManager
32
- });
33
-
34
12
  // src/lib/RateLimit.ts
35
13
  var RateLimit = class {
14
+ /**
15
+ * @param manager The manager for this entry.
16
+ */
36
17
  constructor(manager) {
18
+ /**
19
+ * The remaining amount of times this entry can be dripped before the bucket is empty.
20
+ */
37
21
  __publicField(this, "remaining");
22
+ /**
23
+ * The timestamp that represents when this entry will reset back to a available state.
24
+ */
38
25
  __publicField(this, "expires");
26
+ /**
27
+ * The {@link RateLimitManager} this entry is for.
28
+ */
39
29
  __publicField(this, "manager");
40
30
  this.manager = manager;
41
31
  this.reset();
42
32
  }
33
+ /**
34
+ * Whether this entry is expired or not, allowing the bucket to be reset.
35
+ */
43
36
  get expired() {
44
37
  return this.remainingTime === 0;
45
38
  }
39
+ /**
40
+ * Whether this entry is limited or not.
41
+ */
46
42
  get limited() {
47
43
  return this.remaining === 0 && !this.expired;
48
44
  }
45
+ /**
46
+ * The remaining time in milliseconds before resetting.
47
+ */
49
48
  get remainingTime() {
50
49
  return Math.max(this.expires - Date.now(), 0);
51
50
  }
51
+ /**
52
+ * Consumes {@link RateLimit.remaining} by one if it's not limited, calling {@link RateLimit.reset} first if {@link RateLimit.expired} is true.
53
+ */
52
54
  consume() {
53
55
  if (this.limited)
54
56
  throw new Error("Cannot consume a limited bucket");
@@ -57,13 +59,22 @@ var SapphireRatelimits = (() => {
57
59
  this.remaining--;
58
60
  return this;
59
61
  }
62
+ /**
63
+ * Resets the entry back to it's full state.
64
+ */
60
65
  reset() {
61
66
  return this.resetRemaining().resetTime();
62
67
  }
68
+ /**
69
+ * Resets the entry's {@link RateLimit.remaining} uses back to full state.
70
+ */
63
71
  resetRemaining() {
64
72
  this.remaining = this.manager.limit;
65
73
  return this;
66
74
  }
75
+ /**
76
+ * Resets the entry's {@link RateLimit.expires} to the current time plus {@link RateLimitManager.time}.
77
+ */
67
78
  resetTime() {
68
79
  this.expires = Date.now() + this.manager.time;
69
80
  return this;
@@ -80,6 +91,12 @@ var SapphireRatelimits = (() => {
80
91
  return value;
81
92
  }, "__publicField");
82
93
  var TimerManager = /* @__PURE__ */ __name(class extends null {
94
+ /**
95
+ * Creates a timeout gets cleared when destroyed
96
+ * @param fn callback function
97
+ * @param delay amount of time before running the callback
98
+ * @param args additional arguments to pass back to the callback
99
+ */
83
100
  static setTimeout(fn, delay, ...args) {
84
101
  const timeout = setTimeout(() => {
85
102
  this.storedTimeouts.delete(timeout);
@@ -88,19 +105,36 @@ var SapphireRatelimits = (() => {
88
105
  this.storedTimeouts.add(timeout);
89
106
  return timeout;
90
107
  }
108
+ /**
109
+ * Clears a timeout created through this class
110
+ * @param timeout The timeout to clear
111
+ */
91
112
  static clearTimeout(timeout) {
92
113
  clearTimeout(timeout);
93
114
  this.storedTimeouts.delete(timeout);
94
115
  }
116
+ /**
117
+ * Creates an interval gets cleared when destroyed
118
+ * @param fn callback function
119
+ * @param delay amount of time before running the callback
120
+ * @param args additional arguments to pass back to the callback
121
+ */
95
122
  static setInterval(fn, delay, ...args) {
96
123
  const interval = setInterval(fn, delay, ...args);
97
124
  this.storedIntervals.add(interval);
98
125
  return interval;
99
126
  }
127
+ /**
128
+ * Clears an internal created through this class
129
+ * @param interval The interval to clear
130
+ */
100
131
  static clearInterval(interval) {
101
132
  clearInterval(interval);
102
133
  this.storedIntervals.delete(interval);
103
134
  }
135
+ /**
136
+ * Clears running timeouts and intervals created through this class so NodeJS can gracefully exit
137
+ */
104
138
  static destroy() {
105
139
  for (const i of this.storedTimeouts)
106
140
  clearTimeout(i);
@@ -116,26 +150,55 @@ var SapphireRatelimits = (() => {
116
150
 
117
151
  // src/lib/RateLimitManager.ts
118
152
  var _RateLimitManager = class extends Map {
153
+ /**
154
+ * @param time The amount of milliseconds for the ratelimits from this manager to expire.
155
+ * @param limit The amount of times a {@link RateLimit} can drip before it's limited.
156
+ */
119
157
  constructor(time, limit = 1) {
120
158
  super();
159
+ /**
160
+ * The amount of milliseconds for the {@link RateLimit ratelimits} from this manager to expire.
161
+ */
121
162
  __publicField(this, "time");
163
+ /**
164
+ * The amount of times a {@link RateLimit} can drip before it's limited.
165
+ */
122
166
  __publicField(this, "limit");
167
+ /**
168
+ * The interval to sweep expired {@link RateLimit ratelimits}.
169
+ */
123
170
  __publicField(this, "sweepInterval");
124
171
  this.time = time;
125
172
  this.limit = limit;
126
173
  }
174
+ /**
175
+ * Gets a {@link RateLimit} from this manager or creates it if it does not exist.
176
+ * @param id The id for the {@link RateLimit}
177
+ */
127
178
  acquire(id) {
128
179
  return this.get(id) ?? this.create(id);
129
180
  }
181
+ /**
182
+ * Creates a {@link RateLimit} for this manager.
183
+ * @param id The id the {@link RateLimit} belongs to
184
+ */
130
185
  create(id) {
131
186
  const value = new RateLimit(this);
132
187
  this.set(id, value);
133
188
  return value;
134
189
  }
190
+ /**
191
+ * Wraps Collection's set method to set interval to sweep inactive {@link RateLimit}s.
192
+ * @param id The id the {@link RateLimit} belongs to
193
+ * @param value The {@link RateLimit} to set
194
+ */
135
195
  set(id, value) {
136
196
  this.sweepInterval ?? (this.sweepInterval = TimerManager.setInterval(this.sweep.bind(this), _RateLimitManager.sweepIntervalDuration));
137
197
  return super.set(id, value);
138
198
  }
199
+ /**
200
+ * Wraps Collection's sweep method to clear the interval when this manager is empty.
201
+ */
139
202
  sweep() {
140
203
  for (const [id, value] of this.entries()) {
141
204
  if (value.expired)
@@ -149,7 +212,16 @@ var SapphireRatelimits = (() => {
149
212
  };
150
213
  var RateLimitManager = _RateLimitManager;
151
214
  __name(RateLimitManager, "RateLimitManager");
215
+ /**
216
+ * The delay in milliseconds for {@link RateLimitManager.sweepInterval}.
217
+ */
152
218
  __publicField(RateLimitManager, "sweepIntervalDuration", 3e4);
153
- return __toCommonJS(src_exports);
154
- })();
219
+
220
+ exports.RateLimit = RateLimit;
221
+ exports.RateLimitManager = RateLimitManager;
222
+
223
+ return exports;
224
+
225
+ })({});
226
+ //# sourceMappingURL=out.js.map
155
227
  //# sourceMappingURL=index.global.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/lib/RateLimit.ts","../../timer-manager/src/lib/TimerManager.ts","../src/lib/RateLimitManager.ts"],"sourcesContent":["export * from './lib/RateLimit';\nexport * from './lib/RateLimitManager';\n","import type { RateLimitManager } from './RateLimitManager';\n\nexport class RateLimit<K = string> {\n\t/**\n\t * The remaining amount of times this entry can be dripped before the bucket is empty.\n\t */\n\tpublic remaining!: number;\n\n\t/**\n\t * The timestamp that represents when this entry will reset back to a available state.\n\t */\n\tpublic expires!: number;\n\n\t/**\n\t * The {@link RateLimitManager} this entry is for.\n\t */\n\tprivate manager: RateLimitManager<K>;\n\n\t/**\n\t * @param manager The manager for this entry.\n\t */\n\tpublic constructor(manager: RateLimitManager<K>) {\n\t\tthis.manager = manager;\n\t\tthis.reset();\n\t}\n\n\t/**\n\t * Whether this entry is expired or not, allowing the bucket to be reset.\n\t */\n\tpublic get expired(): boolean {\n\t\treturn this.remainingTime === 0;\n\t}\n\n\t/**\n\t * Whether this entry is limited or not.\n\t */\n\tpublic get limited(): boolean {\n\t\treturn this.remaining === 0 && !this.expired;\n\t}\n\n\t/**\n\t * The remaining time in milliseconds before resetting.\n\t */\n\tpublic get remainingTime(): number {\n\t\treturn Math.max(this.expires - Date.now(), 0);\n\t}\n\n\t/**\n\t * Consumes {@link RateLimit.remaining} by one if it's not limited, calling {@link RateLimit.reset} first if {@link RateLimit.expired} is true.\n\t */\n\tpublic consume(): this {\n\t\tif (this.limited) throw new Error('Cannot consume a limited bucket');\n\t\tif (this.expired) this.reset();\n\n\t\tthis.remaining--;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resets the entry back to it's full state.\n\t */\n\tpublic reset(): this {\n\t\treturn this.resetRemaining().resetTime();\n\t}\n\n\t/**\n\t * Resets the entry's {@link RateLimit.remaining} uses back to full state.\n\t */\n\tpublic resetRemaining(): this {\n\t\tthis.remaining = this.manager.limit;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resets the entry's {@link RateLimit.expires} to the current time plus {@link RateLimitManager.time}.\n\t */\n\tpublic resetTime(): this {\n\t\tthis.expires = Date.now() + this.manager.time;\n\t\treturn this;\n\t}\n}\n","/**\n * Manages timers so that this application can be cleanly exited\n */\nexport class TimerManager extends null {\n\t/**\n\t * A set of timeouts to clear on destroy\n\t */\n\tprivate static storedTimeouts = new Set<NodeJS.Timeout>();\n\n\t/**\n\t * A set of intervals to clear on destroy\n\t */\n\tprivate static storedIntervals = new Set<NodeJS.Timeout>();\n\n\t/**\n\t * Creates a timeout gets cleared when destroyed\n\t * @param fn callback function\n\t * @param delay amount of time before running the callback\n\t * @param args additional arguments to pass back to the callback\n\t */\n\tpublic static setTimeout<A = unknown>(fn: (...args: A[]) => void, delay: number, ...args: A[]): NodeJS.Timeout {\n\t\tconst timeout = setTimeout(() => {\n\t\t\tthis.storedTimeouts.delete(timeout);\n\t\t\tfn(...args);\n\t\t}, delay);\n\t\tthis.storedTimeouts.add(timeout);\n\t\treturn timeout;\n\t}\n\n\t/**\n\t * Clears a timeout created through this class\n\t * @param timeout The timeout to clear\n\t */\n\tpublic static clearTimeout(timeout: NodeJS.Timeout): void {\n\t\tclearTimeout(timeout);\n\t\tthis.storedTimeouts.delete(timeout);\n\t}\n\n\t/**\n\t * Creates an interval gets cleared when destroyed\n\t * @param fn callback function\n\t * @param delay amount of time before running the callback\n\t * @param args additional arguments to pass back to the callback\n\t */\n\tpublic static setInterval<A = unknown>(fn: (...args: A[]) => void, delay: number, ...args: A[]): NodeJS.Timeout {\n\t\tconst interval = setInterval(fn, delay, ...args);\n\t\tthis.storedIntervals.add(interval);\n\t\treturn interval;\n\t}\n\n\t/**\n\t * Clears an internal created through this class\n\t * @param interval The interval to clear\n\t */\n\tpublic static clearInterval(interval: NodeJS.Timeout): void {\n\t\tclearInterval(interval);\n\t\tthis.storedIntervals.delete(interval);\n\t}\n\n\t/**\n\t * Clears running timeouts and intervals created through this class so NodeJS can gracefully exit\n\t */\n\tpublic static destroy(): void {\n\t\tfor (const i of this.storedTimeouts) clearTimeout(i);\n\t\tfor (const i of this.storedIntervals) clearInterval(i);\n\t\tthis.storedTimeouts.clear();\n\t\tthis.storedIntervals.clear();\n\t}\n}\n","import { TimerManager } from '@sapphire/timer-manager';\nimport { RateLimit } from './RateLimit';\n\nexport class RateLimitManager<K = string> extends Map<K, RateLimit<K>> {\n\t/**\n\t * The amount of milliseconds for the {@link RateLimit ratelimits} from this manager to expire.\n\t */\n\tpublic readonly time: number;\n\n\t/**\n\t * The amount of times a {@link RateLimit} can drip before it's limited.\n\t */\n\tpublic readonly limit: number;\n\n\t/**\n\t * The interval to sweep expired {@link RateLimit ratelimits}.\n\t */\n\tprivate sweepInterval!: NodeJS.Timer | null;\n\n\t/**\n\t * @param time The amount of milliseconds for the ratelimits from this manager to expire.\n\t * @param limit The amount of times a {@link RateLimit} can drip before it's limited.\n\t */\n\tpublic constructor(time: number, limit = 1) {\n\t\tsuper();\n\n\t\tthis.time = time;\n\t\tthis.limit = limit;\n\t}\n\n\t/**\n\t * Gets a {@link RateLimit} from this manager or creates it if it does not exist.\n\t * @param id The id for the {@link RateLimit}\n\t */\n\tpublic acquire(id: K): RateLimit<K> {\n\t\treturn this.get(id) ?? this.create(id);\n\t}\n\n\t/**\n\t * Creates a {@link RateLimit} for this manager.\n\t * @param id The id the {@link RateLimit} belongs to\n\t */\n\tpublic create(id: K): RateLimit<K> {\n\t\tconst value = new RateLimit(this);\n\t\tthis.set(id, value);\n\t\treturn value;\n\t}\n\n\t/**\n\t * Wraps Collection's set method to set interval to sweep inactive {@link RateLimit}s.\n\t * @param id The id the {@link RateLimit} belongs to\n\t * @param value The {@link RateLimit} to set\n\t */\n\tpublic override set(id: K, value: RateLimit<K>): this {\n\t\tthis.sweepInterval ??= TimerManager.setInterval(this.sweep.bind(this), RateLimitManager.sweepIntervalDuration);\n\t\treturn super.set(id, value);\n\t}\n\n\t/**\n\t * Wraps Collection's sweep method to clear the interval when this manager is empty.\n\t */\n\tpublic sweep(): void {\n\t\tfor (const [id, value] of this.entries()) {\n\t\t\tif (value.expired) this.delete(id);\n\t\t}\n\n\t\tif (this.size === 0) {\n\t\t\tTimerManager.clearInterval(this.sweepInterval!);\n\t\t\tthis.sweepInterval = null;\n\t\t}\n\t}\n\n\t/**\n\t * The delay in milliseconds for {@link RateLimitManager.sweepInterval}.\n\t */\n\tpublic static sweepIntervalDuration = 30_000;\n}\n"],"mappings":"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","names":["__name","__publicField"]}
1
+ {"version":3,"sources":["../src/lib/RateLimit.ts","../../timer-manager/src/lib/TimerManager.ts","../src/lib/RateLimitManager.ts"],"names":["__name","__publicField"],"mappings":"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","sourcesContent":["import type { RateLimitManager } from './RateLimitManager';\n\nexport class RateLimit<K = string> {\n\t/**\n\t * The remaining amount of times this entry can be dripped before the bucket is empty.\n\t */\n\tpublic remaining!: number;\n\n\t/**\n\t * The timestamp that represents when this entry will reset back to a available state.\n\t */\n\tpublic expires!: number;\n\n\t/**\n\t * The {@link RateLimitManager} this entry is for.\n\t */\n\tprivate manager: RateLimitManager<K>;\n\n\t/**\n\t * @param manager The manager for this entry.\n\t */\n\tpublic constructor(manager: RateLimitManager<K>) {\n\t\tthis.manager = manager;\n\t\tthis.reset();\n\t}\n\n\t/**\n\t * Whether this entry is expired or not, allowing the bucket to be reset.\n\t */\n\tpublic get expired(): boolean {\n\t\treturn this.remainingTime === 0;\n\t}\n\n\t/**\n\t * Whether this entry is limited or not.\n\t */\n\tpublic get limited(): boolean {\n\t\treturn this.remaining === 0 && !this.expired;\n\t}\n\n\t/**\n\t * The remaining time in milliseconds before resetting.\n\t */\n\tpublic get remainingTime(): number {\n\t\treturn Math.max(this.expires - Date.now(), 0);\n\t}\n\n\t/**\n\t * Consumes {@link RateLimit.remaining} by one if it's not limited, calling {@link RateLimit.reset} first if {@link RateLimit.expired} is true.\n\t */\n\tpublic consume(): this {\n\t\tif (this.limited) throw new Error('Cannot consume a limited bucket');\n\t\tif (this.expired) this.reset();\n\n\t\tthis.remaining--;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resets the entry back to it's full state.\n\t */\n\tpublic reset(): this {\n\t\treturn this.resetRemaining().resetTime();\n\t}\n\n\t/**\n\t * Resets the entry's {@link RateLimit.remaining} uses back to full state.\n\t */\n\tpublic resetRemaining(): this {\n\t\tthis.remaining = this.manager.limit;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resets the entry's {@link RateLimit.expires} to the current time plus {@link RateLimitManager.time}.\n\t */\n\tpublic resetTime(): this {\n\t\tthis.expires = Date.now() + this.manager.time;\n\t\treturn this;\n\t}\n}\n","/**\n * Manages timers so that this application can be cleanly exited\n */\nexport class TimerManager extends null {\n\t/**\n\t * A set of timeouts to clear on destroy\n\t */\n\tprivate static storedTimeouts = new Set<NodeJS.Timeout>();\n\n\t/**\n\t * A set of intervals to clear on destroy\n\t */\n\tprivate static storedIntervals = new Set<NodeJS.Timeout>();\n\n\t/**\n\t * Creates a timeout gets cleared when destroyed\n\t * @param fn callback function\n\t * @param delay amount of time before running the callback\n\t * @param args additional arguments to pass back to the callback\n\t */\n\tpublic static setTimeout<A = unknown>(fn: (...args: A[]) => void, delay: number, ...args: A[]): NodeJS.Timeout {\n\t\tconst timeout = setTimeout(() => {\n\t\t\tthis.storedTimeouts.delete(timeout);\n\t\t\tfn(...args);\n\t\t}, delay);\n\t\tthis.storedTimeouts.add(timeout);\n\t\treturn timeout;\n\t}\n\n\t/**\n\t * Clears a timeout created through this class\n\t * @param timeout The timeout to clear\n\t */\n\tpublic static clearTimeout(timeout: NodeJS.Timeout): void {\n\t\tclearTimeout(timeout);\n\t\tthis.storedTimeouts.delete(timeout);\n\t}\n\n\t/**\n\t * Creates an interval gets cleared when destroyed\n\t * @param fn callback function\n\t * @param delay amount of time before running the callback\n\t * @param args additional arguments to pass back to the callback\n\t */\n\tpublic static setInterval<A = unknown>(fn: (...args: A[]) => void, delay: number, ...args: A[]): NodeJS.Timeout {\n\t\tconst interval = setInterval(fn, delay, ...args);\n\t\tthis.storedIntervals.add(interval);\n\t\treturn interval;\n\t}\n\n\t/**\n\t * Clears an internal created through this class\n\t * @param interval The interval to clear\n\t */\n\tpublic static clearInterval(interval: NodeJS.Timeout): void {\n\t\tclearInterval(interval);\n\t\tthis.storedIntervals.delete(interval);\n\t}\n\n\t/**\n\t * Clears running timeouts and intervals created through this class so NodeJS can gracefully exit\n\t */\n\tpublic static destroy(): void {\n\t\tfor (const i of this.storedTimeouts) clearTimeout(i);\n\t\tfor (const i of this.storedIntervals) clearInterval(i);\n\t\tthis.storedTimeouts.clear();\n\t\tthis.storedIntervals.clear();\n\t}\n}\n","import { TimerManager } from '@sapphire/timer-manager';\nimport { RateLimit } from './RateLimit';\n\nexport class RateLimitManager<K = string> extends Map<K, RateLimit<K>> {\n\t/**\n\t * The amount of milliseconds for the {@link RateLimit ratelimits} from this manager to expire.\n\t */\n\tpublic readonly time: number;\n\n\t/**\n\t * The amount of times a {@link RateLimit} can drip before it's limited.\n\t */\n\tpublic readonly limit: number;\n\n\t/**\n\t * The interval to sweep expired {@link RateLimit ratelimits}.\n\t */\n\tprivate sweepInterval!: NodeJS.Timer | null;\n\n\t/**\n\t * @param time The amount of milliseconds for the ratelimits from this manager to expire.\n\t * @param limit The amount of times a {@link RateLimit} can drip before it's limited.\n\t */\n\tpublic constructor(time: number, limit = 1) {\n\t\tsuper();\n\n\t\tthis.time = time;\n\t\tthis.limit = limit;\n\t}\n\n\t/**\n\t * Gets a {@link RateLimit} from this manager or creates it if it does not exist.\n\t * @param id The id for the {@link RateLimit}\n\t */\n\tpublic acquire(id: K): RateLimit<K> {\n\t\treturn this.get(id) ?? this.create(id);\n\t}\n\n\t/**\n\t * Creates a {@link RateLimit} for this manager.\n\t * @param id The id the {@link RateLimit} belongs to\n\t */\n\tpublic create(id: K): RateLimit<K> {\n\t\tconst value = new RateLimit(this);\n\t\tthis.set(id, value);\n\t\treturn value;\n\t}\n\n\t/**\n\t * Wraps Collection's set method to set interval to sweep inactive {@link RateLimit}s.\n\t * @param id The id the {@link RateLimit} belongs to\n\t * @param value The {@link RateLimit} to set\n\t */\n\tpublic override set(id: K, value: RateLimit<K>): this {\n\t\tthis.sweepInterval ??= TimerManager.setInterval(this.sweep.bind(this), RateLimitManager.sweepIntervalDuration);\n\t\treturn super.set(id, value);\n\t}\n\n\t/**\n\t * Wraps Collection's sweep method to clear the interval when this manager is empty.\n\t */\n\tpublic sweep(): void {\n\t\tfor (const [id, value] of this.entries()) {\n\t\t\tif (value.expired) this.delete(id);\n\t\t}\n\n\t\tif (this.size === 0) {\n\t\t\tTimerManager.clearInterval(this.sweepInterval!);\n\t\t\tthis.sweepInterval = null;\n\t\t}\n\t}\n\n\t/**\n\t * The delay in milliseconds for {@link RateLimitManager.sweepInterval}.\n\t */\n\tpublic static sweepIntervalDuration = 30_000;\n}\n"]}
package/dist/index.js CHANGED
@@ -1,55 +1,57 @@
1
- "use strict";
2
- "use strict";
1
+ 'use strict';
2
+
3
+ var timerManager = require('@sapphire/timer-manager');
4
+
3
5
  var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
6
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
7
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
- var __export = (target, all) => {
10
- for (var name in all)
11
- __defProp(target, name, { get: all[name], enumerable: true });
12
- };
13
- var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from))
16
- if (!__hasOwnProp.call(to, key) && key !== except)
17
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
- }
19
- return to;
20
- };
21
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
8
  var __publicField = (obj, key, value) => {
23
9
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
24
10
  return value;
25
11
  };
26
12
 
27
- // src/index.ts
28
- var src_exports = {};
29
- __export(src_exports, {
30
- RateLimit: () => RateLimit,
31
- RateLimitManager: () => RateLimitManager
32
- });
33
- module.exports = __toCommonJS(src_exports);
34
-
35
13
  // src/lib/RateLimit.ts
36
14
  var RateLimit = class {
15
+ /**
16
+ * @param manager The manager for this entry.
17
+ */
37
18
  constructor(manager) {
19
+ /**
20
+ * The remaining amount of times this entry can be dripped before the bucket is empty.
21
+ */
38
22
  __publicField(this, "remaining");
23
+ /**
24
+ * The timestamp that represents when this entry will reset back to a available state.
25
+ */
39
26
  __publicField(this, "expires");
27
+ /**
28
+ * The {@link RateLimitManager} this entry is for.
29
+ */
40
30
  __publicField(this, "manager");
41
31
  this.manager = manager;
42
32
  this.reset();
43
33
  }
34
+ /**
35
+ * Whether this entry is expired or not, allowing the bucket to be reset.
36
+ */
44
37
  get expired() {
45
38
  return this.remainingTime === 0;
46
39
  }
40
+ /**
41
+ * Whether this entry is limited or not.
42
+ */
47
43
  get limited() {
48
44
  return this.remaining === 0 && !this.expired;
49
45
  }
46
+ /**
47
+ * The remaining time in milliseconds before resetting.
48
+ */
50
49
  get remainingTime() {
51
50
  return Math.max(this.expires - Date.now(), 0);
52
51
  }
52
+ /**
53
+ * Consumes {@link RateLimit.remaining} by one if it's not limited, calling {@link RateLimit.reset} first if {@link RateLimit.expired} is true.
54
+ */
53
55
  consume() {
54
56
  if (this.limited)
55
57
  throw new Error("Cannot consume a limited bucket");
@@ -58,60 +60,97 @@ var RateLimit = class {
58
60
  this.remaining--;
59
61
  return this;
60
62
  }
63
+ /**
64
+ * Resets the entry back to it's full state.
65
+ */
61
66
  reset() {
62
67
  return this.resetRemaining().resetTime();
63
68
  }
69
+ /**
70
+ * Resets the entry's {@link RateLimit.remaining} uses back to full state.
71
+ */
64
72
  resetRemaining() {
65
73
  this.remaining = this.manager.limit;
66
74
  return this;
67
75
  }
76
+ /**
77
+ * Resets the entry's {@link RateLimit.expires} to the current time plus {@link RateLimitManager.time}.
78
+ */
68
79
  resetTime() {
69
80
  this.expires = Date.now() + this.manager.time;
70
81
  return this;
71
82
  }
72
83
  };
73
84
  __name(RateLimit, "RateLimit");
74
-
75
- // src/lib/RateLimitManager.ts
76
- var import_timer_manager = require("@sapphire/timer-manager");
77
85
  var _RateLimitManager = class extends Map {
86
+ /**
87
+ * @param time The amount of milliseconds for the ratelimits from this manager to expire.
88
+ * @param limit The amount of times a {@link RateLimit} can drip before it's limited.
89
+ */
78
90
  constructor(time, limit = 1) {
79
91
  super();
92
+ /**
93
+ * The amount of milliseconds for the {@link RateLimit ratelimits} from this manager to expire.
94
+ */
80
95
  __publicField(this, "time");
96
+ /**
97
+ * The amount of times a {@link RateLimit} can drip before it's limited.
98
+ */
81
99
  __publicField(this, "limit");
100
+ /**
101
+ * The interval to sweep expired {@link RateLimit ratelimits}.
102
+ */
82
103
  __publicField(this, "sweepInterval");
83
104
  this.time = time;
84
105
  this.limit = limit;
85
106
  }
107
+ /**
108
+ * Gets a {@link RateLimit} from this manager or creates it if it does not exist.
109
+ * @param id The id for the {@link RateLimit}
110
+ */
86
111
  acquire(id) {
87
112
  return this.get(id) ?? this.create(id);
88
113
  }
114
+ /**
115
+ * Creates a {@link RateLimit} for this manager.
116
+ * @param id The id the {@link RateLimit} belongs to
117
+ */
89
118
  create(id) {
90
119
  const value = new RateLimit(this);
91
120
  this.set(id, value);
92
121
  return value;
93
122
  }
123
+ /**
124
+ * Wraps Collection's set method to set interval to sweep inactive {@link RateLimit}s.
125
+ * @param id The id the {@link RateLimit} belongs to
126
+ * @param value The {@link RateLimit} to set
127
+ */
94
128
  set(id, value) {
95
- this.sweepInterval ?? (this.sweepInterval = import_timer_manager.TimerManager.setInterval(this.sweep.bind(this), _RateLimitManager.sweepIntervalDuration));
129
+ this.sweepInterval ?? (this.sweepInterval = timerManager.TimerManager.setInterval(this.sweep.bind(this), _RateLimitManager.sweepIntervalDuration));
96
130
  return super.set(id, value);
97
131
  }
132
+ /**
133
+ * Wraps Collection's sweep method to clear the interval when this manager is empty.
134
+ */
98
135
  sweep() {
99
136
  for (const [id, value] of this.entries()) {
100
137
  if (value.expired)
101
138
  this.delete(id);
102
139
  }
103
140
  if (this.size === 0) {
104
- import_timer_manager.TimerManager.clearInterval(this.sweepInterval);
141
+ timerManager.TimerManager.clearInterval(this.sweepInterval);
105
142
  this.sweepInterval = null;
106
143
  }
107
144
  }
108
145
  };
109
146
  var RateLimitManager = _RateLimitManager;
110
147
  __name(RateLimitManager, "RateLimitManager");
148
+ /**
149
+ * The delay in milliseconds for {@link RateLimitManager.sweepInterval}.
150
+ */
111
151
  __publicField(RateLimitManager, "sweepIntervalDuration", 3e4);
112
- // Annotate the CommonJS export names for ESM import in node:
113
- 0 && (module.exports = {
114
- RateLimit,
115
- RateLimitManager
116
- });
152
+
153
+ exports.RateLimit = RateLimit;
154
+ exports.RateLimitManager = RateLimitManager;
155
+ //# sourceMappingURL=out.js.map
117
156
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/lib/RateLimit.ts","../src/lib/RateLimitManager.ts"],"sourcesContent":["export * from './lib/RateLimit';\nexport * from './lib/RateLimitManager';\n","import type { RateLimitManager } from './RateLimitManager';\n\nexport class RateLimit<K = string> {\n\t/**\n\t * The remaining amount of times this entry can be dripped before the bucket is empty.\n\t */\n\tpublic remaining!: number;\n\n\t/**\n\t * The timestamp that represents when this entry will reset back to a available state.\n\t */\n\tpublic expires!: number;\n\n\t/**\n\t * The {@link RateLimitManager} this entry is for.\n\t */\n\tprivate manager: RateLimitManager<K>;\n\n\t/**\n\t * @param manager The manager for this entry.\n\t */\n\tpublic constructor(manager: RateLimitManager<K>) {\n\t\tthis.manager = manager;\n\t\tthis.reset();\n\t}\n\n\t/**\n\t * Whether this entry is expired or not, allowing the bucket to be reset.\n\t */\n\tpublic get expired(): boolean {\n\t\treturn this.remainingTime === 0;\n\t}\n\n\t/**\n\t * Whether this entry is limited or not.\n\t */\n\tpublic get limited(): boolean {\n\t\treturn this.remaining === 0 && !this.expired;\n\t}\n\n\t/**\n\t * The remaining time in milliseconds before resetting.\n\t */\n\tpublic get remainingTime(): number {\n\t\treturn Math.max(this.expires - Date.now(), 0);\n\t}\n\n\t/**\n\t * Consumes {@link RateLimit.remaining} by one if it's not limited, calling {@link RateLimit.reset} first if {@link RateLimit.expired} is true.\n\t */\n\tpublic consume(): this {\n\t\tif (this.limited) throw new Error('Cannot consume a limited bucket');\n\t\tif (this.expired) this.reset();\n\n\t\tthis.remaining--;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resets the entry back to it's full state.\n\t */\n\tpublic reset(): this {\n\t\treturn this.resetRemaining().resetTime();\n\t}\n\n\t/**\n\t * Resets the entry's {@link RateLimit.remaining} uses back to full state.\n\t */\n\tpublic resetRemaining(): this {\n\t\tthis.remaining = this.manager.limit;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resets the entry's {@link RateLimit.expires} to the current time plus {@link RateLimitManager.time}.\n\t */\n\tpublic resetTime(): this {\n\t\tthis.expires = Date.now() + this.manager.time;\n\t\treturn this;\n\t}\n}\n","import { TimerManager } from '@sapphire/timer-manager';\nimport { RateLimit } from './RateLimit';\n\nexport class RateLimitManager<K = string> extends Map<K, RateLimit<K>> {\n\t/**\n\t * The amount of milliseconds for the {@link RateLimit ratelimits} from this manager to expire.\n\t */\n\tpublic readonly time: number;\n\n\t/**\n\t * The amount of times a {@link RateLimit} can drip before it's limited.\n\t */\n\tpublic readonly limit: number;\n\n\t/**\n\t * The interval to sweep expired {@link RateLimit ratelimits}.\n\t */\n\tprivate sweepInterval!: NodeJS.Timer | null;\n\n\t/**\n\t * @param time The amount of milliseconds for the ratelimits from this manager to expire.\n\t * @param limit The amount of times a {@link RateLimit} can drip before it's limited.\n\t */\n\tpublic constructor(time: number, limit = 1) {\n\t\tsuper();\n\n\t\tthis.time = time;\n\t\tthis.limit = limit;\n\t}\n\n\t/**\n\t * Gets a {@link RateLimit} from this manager or creates it if it does not exist.\n\t * @param id The id for the {@link RateLimit}\n\t */\n\tpublic acquire(id: K): RateLimit<K> {\n\t\treturn this.get(id) ?? this.create(id);\n\t}\n\n\t/**\n\t * Creates a {@link RateLimit} for this manager.\n\t * @param id The id the {@link RateLimit} belongs to\n\t */\n\tpublic create(id: K): RateLimit<K> {\n\t\tconst value = new RateLimit(this);\n\t\tthis.set(id, value);\n\t\treturn value;\n\t}\n\n\t/**\n\t * Wraps Collection's set method to set interval to sweep inactive {@link RateLimit}s.\n\t * @param id The id the {@link RateLimit} belongs to\n\t * @param value The {@link RateLimit} to set\n\t */\n\tpublic override set(id: K, value: RateLimit<K>): this {\n\t\tthis.sweepInterval ??= TimerManager.setInterval(this.sweep.bind(this), RateLimitManager.sweepIntervalDuration);\n\t\treturn super.set(id, value);\n\t}\n\n\t/**\n\t * Wraps Collection's sweep method to clear the interval when this manager is empty.\n\t */\n\tpublic sweep(): void {\n\t\tfor (const [id, value] of this.entries()) {\n\t\t\tif (value.expired) this.delete(id);\n\t\t}\n\n\t\tif (this.size === 0) {\n\t\t\tTimerManager.clearInterval(this.sweepInterval!);\n\t\t\tthis.sweepInterval = null;\n\t\t}\n\t}\n\n\t/**\n\t * The delay in milliseconds for {@link RateLimitManager.sweepInterval}.\n\t */\n\tpublic static sweepIntervalDuration = 30_000;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,YAAN,MAA4B;AAAA,EAmB3B,YAAY,SAA8B;AAfjD,wBAAO;AAKP,wBAAO;AAKP,wBAAQ;AAMP,SAAK,UAAU;AACf,SAAK,MAAM;AAAA,EACZ;AAAA,EAKA,IAAW,UAAmB;AAC7B,WAAO,KAAK,kBAAkB;AAAA,EAC/B;AAAA,EAKA,IAAW,UAAmB;AAC7B,WAAO,KAAK,cAAc,KAAK,CAAC,KAAK;AAAA,EACtC;AAAA,EAKA,IAAW,gBAAwB;AAClC,WAAO,KAAK,IAAI,KAAK,UAAU,KAAK,IAAI,GAAG,CAAC;AAAA,EAC7C;AAAA,EAKO,UAAgB;AACtB,QAAI,KAAK;AAAS,YAAM,IAAI,MAAM,iCAAiC;AACnE,QAAI,KAAK;AAAS,WAAK,MAAM;AAE7B,SAAK;AACL,WAAO;AAAA,EACR;AAAA,EAKO,QAAc;AACpB,WAAO,KAAK,eAAe,EAAE,UAAU;AAAA,EACxC;AAAA,EAKO,iBAAuB;AAC7B,SAAK,YAAY,KAAK,QAAQ;AAC9B,WAAO;AAAA,EACR;AAAA,EAKO,YAAkB;AACxB,SAAK,UAAU,KAAK,IAAI,IAAI,KAAK,QAAQ;AACzC,WAAO;AAAA,EACR;AACD;AA9Ea;;;ACFb,2BAA6B;AAGtB,IAAM,oBAAN,cAA2C,IAAqB;AAAA,EAoB/D,YAAY,MAAc,QAAQ,GAAG;AAC3C,UAAM;AAjBP,wBAAgB;AAKhB,wBAAgB;AAKhB,wBAAQ;AASP,SAAK,OAAO;AACZ,SAAK,QAAQ;AAAA,EACd;AAAA,EAMO,QAAQ,IAAqB;AACnC,WAAO,KAAK,IAAI,EAAE,KAAK,KAAK,OAAO,EAAE;AAAA,EACtC;AAAA,EAMO,OAAO,IAAqB;AAClC,UAAM,QAAQ,IAAI,UAAU,IAAI;AAChC,SAAK,IAAI,IAAI,KAAK;AAClB,WAAO;AAAA,EACR;AAAA,EAOgB,IAAI,IAAO,OAA2B;AACrD,SAAK,kBAAL,KAAK,gBAAkB,kCAAa,YAAY,KAAK,MAAM,KAAK,IAAI,GAAG,kBAAiB,qBAAqB;AAC7G,WAAO,MAAM,IAAI,IAAI,KAAK;AAAA,EAC3B;AAAA,EAKO,QAAc;AACpB,eAAW,CAAC,IAAI,KAAK,KAAK,KAAK,QAAQ,GAAG;AACzC,UAAI,MAAM;AAAS,aAAK,OAAO,EAAE;AAAA,IAClC;AAEA,QAAI,KAAK,SAAS,GAAG;AACpB,wCAAa,cAAc,KAAK,aAAc;AAC9C,WAAK,gBAAgB;AAAA,IACtB;AAAA,EACD;AAMD;AAzEO,IAAM,mBAAN;AAAM;AAwEZ,cAxEY,kBAwEE,yBAAwB;","names":[]}
1
+ {"version":3,"sources":["../src/lib/RateLimit.ts","../src/lib/RateLimitManager.ts"],"names":[],"mappings":";;;;;;;;;AAEO,IAAM,YAAN,MAA4B;AAAA;AAAA;AAAA;AAAA,EAmB3B,YAAY,SAA8B;AAfjD;AAAA;AAAA;AAAA,wBAAO;AAKP;AAAA;AAAA;AAAA,wBAAO;AAKP;AAAA;AAAA;AAAA,wBAAQ;AAMP,SAAK,UAAU;AACf,SAAK,MAAM;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAKA,IAAW,UAAmB;AAC7B,WAAO,KAAK,kBAAkB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAW,UAAmB;AAC7B,WAAO,KAAK,cAAc,KAAK,CAAC,KAAK;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAW,gBAAwB;AAClC,WAAO,KAAK,IAAI,KAAK,UAAU,KAAK,IAAI,GAAG,CAAC;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKO,UAAgB;AACtB,QAAI,KAAK;AAAS,YAAM,IAAI,MAAM,iCAAiC;AACnE,QAAI,KAAK;AAAS,WAAK,MAAM;AAE7B,SAAK;AACL,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAKO,QAAc;AACpB,WAAO,KAAK,eAAe,EAAE,UAAU;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKO,iBAAuB;AAC7B,SAAK,YAAY,KAAK,QAAQ;AAC9B,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAKO,YAAkB;AACxB,SAAK,UAAU,KAAK,IAAI,IAAI,KAAK,QAAQ;AACzC,WAAO;AAAA,EACR;AACD;AA9Ea;;;ACFb,SAAS,oBAAoB;AAGtB,IAAM,oBAAN,cAA2C,IAAqB;AAAA;AAAA;AAAA;AAAA;AAAA,EAoB/D,YAAY,MAAc,QAAQ,GAAG;AAC3C,UAAM;AAjBP;AAAA;AAAA;AAAA,wBAAgB;AAKhB;AAAA;AAAA;AAAA,wBAAgB;AAKhB;AAAA;AAAA;AAAA,wBAAQ;AASP,SAAK,OAAO;AACZ,SAAK,QAAQ;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,QAAQ,IAAqB;AACnC,WAAO,KAAK,IAAI,EAAE,KAAK,KAAK,OAAO,EAAE;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,OAAO,IAAqB;AAClC,UAAM,QAAQ,IAAI,UAAU,IAAI;AAChC,SAAK,IAAI,IAAI,KAAK;AAClB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOgB,IAAI,IAAO,OAA2B;AACrD,SAAK,kBAAL,KAAK,gBAAkB,aAAa,YAAY,KAAK,MAAM,KAAK,IAAI,GAAG,kBAAiB,qBAAqB;AAC7G,WAAO,MAAM,IAAI,IAAI,KAAK;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKO,QAAc;AACpB,eAAW,CAAC,IAAI,KAAK,KAAK,KAAK,QAAQ,GAAG;AACzC,UAAI,MAAM;AAAS,aAAK,OAAO,EAAE;AAAA,IAClC;AAEA,QAAI,KAAK,SAAS,GAAG;AACpB,mBAAa,cAAc,KAAK,aAAc;AAC9C,WAAK,gBAAgB;AAAA,IACtB;AAAA,EACD;AAMD;AAzEO,IAAM,mBAAN;AAAM;AAAA;AAAA;AAAA;AAwEZ,cAxEY,kBAwEE,yBAAwB","sourcesContent":["import type { RateLimitManager } from './RateLimitManager';\n\nexport class RateLimit<K = string> {\n\t/**\n\t * The remaining amount of times this entry can be dripped before the bucket is empty.\n\t */\n\tpublic remaining!: number;\n\n\t/**\n\t * The timestamp that represents when this entry will reset back to a available state.\n\t */\n\tpublic expires!: number;\n\n\t/**\n\t * The {@link RateLimitManager} this entry is for.\n\t */\n\tprivate manager: RateLimitManager<K>;\n\n\t/**\n\t * @param manager The manager for this entry.\n\t */\n\tpublic constructor(manager: RateLimitManager<K>) {\n\t\tthis.manager = manager;\n\t\tthis.reset();\n\t}\n\n\t/**\n\t * Whether this entry is expired or not, allowing the bucket to be reset.\n\t */\n\tpublic get expired(): boolean {\n\t\treturn this.remainingTime === 0;\n\t}\n\n\t/**\n\t * Whether this entry is limited or not.\n\t */\n\tpublic get limited(): boolean {\n\t\treturn this.remaining === 0 && !this.expired;\n\t}\n\n\t/**\n\t * The remaining time in milliseconds before resetting.\n\t */\n\tpublic get remainingTime(): number {\n\t\treturn Math.max(this.expires - Date.now(), 0);\n\t}\n\n\t/**\n\t * Consumes {@link RateLimit.remaining} by one if it's not limited, calling {@link RateLimit.reset} first if {@link RateLimit.expired} is true.\n\t */\n\tpublic consume(): this {\n\t\tif (this.limited) throw new Error('Cannot consume a limited bucket');\n\t\tif (this.expired) this.reset();\n\n\t\tthis.remaining--;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resets the entry back to it's full state.\n\t */\n\tpublic reset(): this {\n\t\treturn this.resetRemaining().resetTime();\n\t}\n\n\t/**\n\t * Resets the entry's {@link RateLimit.remaining} uses back to full state.\n\t */\n\tpublic resetRemaining(): this {\n\t\tthis.remaining = this.manager.limit;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resets the entry's {@link RateLimit.expires} to the current time plus {@link RateLimitManager.time}.\n\t */\n\tpublic resetTime(): this {\n\t\tthis.expires = Date.now() + this.manager.time;\n\t\treturn this;\n\t}\n}\n","import { TimerManager } from '@sapphire/timer-manager';\nimport { RateLimit } from './RateLimit';\n\nexport class RateLimitManager<K = string> extends Map<K, RateLimit<K>> {\n\t/**\n\t * The amount of milliseconds for the {@link RateLimit ratelimits} from this manager to expire.\n\t */\n\tpublic readonly time: number;\n\n\t/**\n\t * The amount of times a {@link RateLimit} can drip before it's limited.\n\t */\n\tpublic readonly limit: number;\n\n\t/**\n\t * The interval to sweep expired {@link RateLimit ratelimits}.\n\t */\n\tprivate sweepInterval!: NodeJS.Timer | null;\n\n\t/**\n\t * @param time The amount of milliseconds for the ratelimits from this manager to expire.\n\t * @param limit The amount of times a {@link RateLimit} can drip before it's limited.\n\t */\n\tpublic constructor(time: number, limit = 1) {\n\t\tsuper();\n\n\t\tthis.time = time;\n\t\tthis.limit = limit;\n\t}\n\n\t/**\n\t * Gets a {@link RateLimit} from this manager or creates it if it does not exist.\n\t * @param id The id for the {@link RateLimit}\n\t */\n\tpublic acquire(id: K): RateLimit<K> {\n\t\treturn this.get(id) ?? this.create(id);\n\t}\n\n\t/**\n\t * Creates a {@link RateLimit} for this manager.\n\t * @param id The id the {@link RateLimit} belongs to\n\t */\n\tpublic create(id: K): RateLimit<K> {\n\t\tconst value = new RateLimit(this);\n\t\tthis.set(id, value);\n\t\treturn value;\n\t}\n\n\t/**\n\t * Wraps Collection's set method to set interval to sweep inactive {@link RateLimit}s.\n\t * @param id The id the {@link RateLimit} belongs to\n\t * @param value The {@link RateLimit} to set\n\t */\n\tpublic override set(id: K, value: RateLimit<K>): this {\n\t\tthis.sweepInterval ??= TimerManager.setInterval(this.sweep.bind(this), RateLimitManager.sweepIntervalDuration);\n\t\treturn super.set(id, value);\n\t}\n\n\t/**\n\t * Wraps Collection's sweep method to clear the interval when this manager is empty.\n\t */\n\tpublic sweep(): void {\n\t\tfor (const [id, value] of this.entries()) {\n\t\t\tif (value.expired) this.delete(id);\n\t\t}\n\n\t\tif (this.size === 0) {\n\t\t\tTimerManager.clearInterval(this.sweepInterval!);\n\t\t\tthis.sweepInterval = null;\n\t\t}\n\t}\n\n\t/**\n\t * The delay in milliseconds for {@link RateLimitManager.sweepInterval}.\n\t */\n\tpublic static sweepIntervalDuration = 30_000;\n}\n"]}
package/dist/index.mjs CHANGED
@@ -1,3 +1,5 @@
1
+ import { TimerManager } from '@sapphire/timer-manager';
2
+
1
3
  var __defProp = Object.defineProperty;
2
4
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
5
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
@@ -8,22 +10,46 @@ var __publicField = (obj, key, value) => {
8
10
 
9
11
  // src/lib/RateLimit.ts
10
12
  var RateLimit = class {
13
+ /**
14
+ * @param manager The manager for this entry.
15
+ */
11
16
  constructor(manager) {
17
+ /**
18
+ * The remaining amount of times this entry can be dripped before the bucket is empty.
19
+ */
12
20
  __publicField(this, "remaining");
21
+ /**
22
+ * The timestamp that represents when this entry will reset back to a available state.
23
+ */
13
24
  __publicField(this, "expires");
25
+ /**
26
+ * The {@link RateLimitManager} this entry is for.
27
+ */
14
28
  __publicField(this, "manager");
15
29
  this.manager = manager;
16
30
  this.reset();
17
31
  }
32
+ /**
33
+ * Whether this entry is expired or not, allowing the bucket to be reset.
34
+ */
18
35
  get expired() {
19
36
  return this.remainingTime === 0;
20
37
  }
38
+ /**
39
+ * Whether this entry is limited or not.
40
+ */
21
41
  get limited() {
22
42
  return this.remaining === 0 && !this.expired;
23
43
  }
44
+ /**
45
+ * The remaining time in milliseconds before resetting.
46
+ */
24
47
  get remainingTime() {
25
48
  return Math.max(this.expires - Date.now(), 0);
26
49
  }
50
+ /**
51
+ * Consumes {@link RateLimit.remaining} by one if it's not limited, calling {@link RateLimit.reset} first if {@link RateLimit.expired} is true.
52
+ */
27
53
  consume() {
28
54
  if (this.limited)
29
55
  throw new Error("Cannot consume a limited bucket");
@@ -32,43 +58,78 @@ var RateLimit = class {
32
58
  this.remaining--;
33
59
  return this;
34
60
  }
61
+ /**
62
+ * Resets the entry back to it's full state.
63
+ */
35
64
  reset() {
36
65
  return this.resetRemaining().resetTime();
37
66
  }
67
+ /**
68
+ * Resets the entry's {@link RateLimit.remaining} uses back to full state.
69
+ */
38
70
  resetRemaining() {
39
71
  this.remaining = this.manager.limit;
40
72
  return this;
41
73
  }
74
+ /**
75
+ * Resets the entry's {@link RateLimit.expires} to the current time plus {@link RateLimitManager.time}.
76
+ */
42
77
  resetTime() {
43
78
  this.expires = Date.now() + this.manager.time;
44
79
  return this;
45
80
  }
46
81
  };
47
82
  __name(RateLimit, "RateLimit");
48
-
49
- // src/lib/RateLimitManager.ts
50
- import { TimerManager } from "@sapphire/timer-manager";
51
83
  var _RateLimitManager = class extends Map {
84
+ /**
85
+ * @param time The amount of milliseconds for the ratelimits from this manager to expire.
86
+ * @param limit The amount of times a {@link RateLimit} can drip before it's limited.
87
+ */
52
88
  constructor(time, limit = 1) {
53
89
  super();
90
+ /**
91
+ * The amount of milliseconds for the {@link RateLimit ratelimits} from this manager to expire.
92
+ */
54
93
  __publicField(this, "time");
94
+ /**
95
+ * The amount of times a {@link RateLimit} can drip before it's limited.
96
+ */
55
97
  __publicField(this, "limit");
98
+ /**
99
+ * The interval to sweep expired {@link RateLimit ratelimits}.
100
+ */
56
101
  __publicField(this, "sweepInterval");
57
102
  this.time = time;
58
103
  this.limit = limit;
59
104
  }
105
+ /**
106
+ * Gets a {@link RateLimit} from this manager or creates it if it does not exist.
107
+ * @param id The id for the {@link RateLimit}
108
+ */
60
109
  acquire(id) {
61
110
  return this.get(id) ?? this.create(id);
62
111
  }
112
+ /**
113
+ * Creates a {@link RateLimit} for this manager.
114
+ * @param id The id the {@link RateLimit} belongs to
115
+ */
63
116
  create(id) {
64
117
  const value = new RateLimit(this);
65
118
  this.set(id, value);
66
119
  return value;
67
120
  }
121
+ /**
122
+ * Wraps Collection's set method to set interval to sweep inactive {@link RateLimit}s.
123
+ * @param id The id the {@link RateLimit} belongs to
124
+ * @param value The {@link RateLimit} to set
125
+ */
68
126
  set(id, value) {
69
127
  this.sweepInterval ?? (this.sweepInterval = TimerManager.setInterval(this.sweep.bind(this), _RateLimitManager.sweepIntervalDuration));
70
128
  return super.set(id, value);
71
129
  }
130
+ /**
131
+ * Wraps Collection's sweep method to clear the interval when this manager is empty.
132
+ */
72
133
  sweep() {
73
134
  for (const [id, value] of this.entries()) {
74
135
  if (value.expired)
@@ -82,9 +143,11 @@ var _RateLimitManager = class extends Map {
82
143
  };
83
144
  var RateLimitManager = _RateLimitManager;
84
145
  __name(RateLimitManager, "RateLimitManager");
146
+ /**
147
+ * The delay in milliseconds for {@link RateLimitManager.sweepInterval}.
148
+ */
85
149
  __publicField(RateLimitManager, "sweepIntervalDuration", 3e4);
86
- export {
87
- RateLimit,
88
- RateLimitManager
89
- };
150
+
151
+ export { RateLimit, RateLimitManager };
152
+ //# sourceMappingURL=out.js.map
90
153
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/RateLimit.ts","../src/lib/RateLimitManager.ts"],"sourcesContent":["import type { RateLimitManager } from './RateLimitManager';\n\nexport class RateLimit<K = string> {\n\t/**\n\t * The remaining amount of times this entry can be dripped before the bucket is empty.\n\t */\n\tpublic remaining!: number;\n\n\t/**\n\t * The timestamp that represents when this entry will reset back to a available state.\n\t */\n\tpublic expires!: number;\n\n\t/**\n\t * The {@link RateLimitManager} this entry is for.\n\t */\n\tprivate manager: RateLimitManager<K>;\n\n\t/**\n\t * @param manager The manager for this entry.\n\t */\n\tpublic constructor(manager: RateLimitManager<K>) {\n\t\tthis.manager = manager;\n\t\tthis.reset();\n\t}\n\n\t/**\n\t * Whether this entry is expired or not, allowing the bucket to be reset.\n\t */\n\tpublic get expired(): boolean {\n\t\treturn this.remainingTime === 0;\n\t}\n\n\t/**\n\t * Whether this entry is limited or not.\n\t */\n\tpublic get limited(): boolean {\n\t\treturn this.remaining === 0 && !this.expired;\n\t}\n\n\t/**\n\t * The remaining time in milliseconds before resetting.\n\t */\n\tpublic get remainingTime(): number {\n\t\treturn Math.max(this.expires - Date.now(), 0);\n\t}\n\n\t/**\n\t * Consumes {@link RateLimit.remaining} by one if it's not limited, calling {@link RateLimit.reset} first if {@link RateLimit.expired} is true.\n\t */\n\tpublic consume(): this {\n\t\tif (this.limited) throw new Error('Cannot consume a limited bucket');\n\t\tif (this.expired) this.reset();\n\n\t\tthis.remaining--;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resets the entry back to it's full state.\n\t */\n\tpublic reset(): this {\n\t\treturn this.resetRemaining().resetTime();\n\t}\n\n\t/**\n\t * Resets the entry's {@link RateLimit.remaining} uses back to full state.\n\t */\n\tpublic resetRemaining(): this {\n\t\tthis.remaining = this.manager.limit;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resets the entry's {@link RateLimit.expires} to the current time plus {@link RateLimitManager.time}.\n\t */\n\tpublic resetTime(): this {\n\t\tthis.expires = Date.now() + this.manager.time;\n\t\treturn this;\n\t}\n}\n","import { TimerManager } from '@sapphire/timer-manager';\nimport { RateLimit } from './RateLimit';\n\nexport class RateLimitManager<K = string> extends Map<K, RateLimit<K>> {\n\t/**\n\t * The amount of milliseconds for the {@link RateLimit ratelimits} from this manager to expire.\n\t */\n\tpublic readonly time: number;\n\n\t/**\n\t * The amount of times a {@link RateLimit} can drip before it's limited.\n\t */\n\tpublic readonly limit: number;\n\n\t/**\n\t * The interval to sweep expired {@link RateLimit ratelimits}.\n\t */\n\tprivate sweepInterval!: NodeJS.Timer | null;\n\n\t/**\n\t * @param time The amount of milliseconds for the ratelimits from this manager to expire.\n\t * @param limit The amount of times a {@link RateLimit} can drip before it's limited.\n\t */\n\tpublic constructor(time: number, limit = 1) {\n\t\tsuper();\n\n\t\tthis.time = time;\n\t\tthis.limit = limit;\n\t}\n\n\t/**\n\t * Gets a {@link RateLimit} from this manager or creates it if it does not exist.\n\t * @param id The id for the {@link RateLimit}\n\t */\n\tpublic acquire(id: K): RateLimit<K> {\n\t\treturn this.get(id) ?? this.create(id);\n\t}\n\n\t/**\n\t * Creates a {@link RateLimit} for this manager.\n\t * @param id The id the {@link RateLimit} belongs to\n\t */\n\tpublic create(id: K): RateLimit<K> {\n\t\tconst value = new RateLimit(this);\n\t\tthis.set(id, value);\n\t\treturn value;\n\t}\n\n\t/**\n\t * Wraps Collection's set method to set interval to sweep inactive {@link RateLimit}s.\n\t * @param id The id the {@link RateLimit} belongs to\n\t * @param value The {@link RateLimit} to set\n\t */\n\tpublic override set(id: K, value: RateLimit<K>): this {\n\t\tthis.sweepInterval ??= TimerManager.setInterval(this.sweep.bind(this), RateLimitManager.sweepIntervalDuration);\n\t\treturn super.set(id, value);\n\t}\n\n\t/**\n\t * Wraps Collection's sweep method to clear the interval when this manager is empty.\n\t */\n\tpublic sweep(): void {\n\t\tfor (const [id, value] of this.entries()) {\n\t\t\tif (value.expired) this.delete(id);\n\t\t}\n\n\t\tif (this.size === 0) {\n\t\t\tTimerManager.clearInterval(this.sweepInterval!);\n\t\t\tthis.sweepInterval = null;\n\t\t}\n\t}\n\n\t/**\n\t * The delay in milliseconds for {@link RateLimitManager.sweepInterval}.\n\t */\n\tpublic static sweepIntervalDuration = 30_000;\n}\n"],"mappings":";;;;;;;;;AAEO,IAAM,YAAN,MAA4B;AAAA,EAmB3B,YAAY,SAA8B;AAfjD,wBAAO;AAKP,wBAAO;AAKP,wBAAQ;AAMP,SAAK,UAAU;AACf,SAAK,MAAM;AAAA,EACZ;AAAA,EAKA,IAAW,UAAmB;AAC7B,WAAO,KAAK,kBAAkB;AAAA,EAC/B;AAAA,EAKA,IAAW,UAAmB;AAC7B,WAAO,KAAK,cAAc,KAAK,CAAC,KAAK;AAAA,EACtC;AAAA,EAKA,IAAW,gBAAwB;AAClC,WAAO,KAAK,IAAI,KAAK,UAAU,KAAK,IAAI,GAAG,CAAC;AAAA,EAC7C;AAAA,EAKO,UAAgB;AACtB,QAAI,KAAK;AAAS,YAAM,IAAI,MAAM,iCAAiC;AACnE,QAAI,KAAK;AAAS,WAAK,MAAM;AAE7B,SAAK;AACL,WAAO;AAAA,EACR;AAAA,EAKO,QAAc;AACpB,WAAO,KAAK,eAAe,EAAE,UAAU;AAAA,EACxC;AAAA,EAKO,iBAAuB;AAC7B,SAAK,YAAY,KAAK,QAAQ;AAC9B,WAAO;AAAA,EACR;AAAA,EAKO,YAAkB;AACxB,SAAK,UAAU,KAAK,IAAI,IAAI,KAAK,QAAQ;AACzC,WAAO;AAAA,EACR;AACD;AA9Ea;;;ACFb,SAAS,oBAAoB;AAGtB,IAAM,oBAAN,cAA2C,IAAqB;AAAA,EAoB/D,YAAY,MAAc,QAAQ,GAAG;AAC3C,UAAM;AAjBP,wBAAgB;AAKhB,wBAAgB;AAKhB,wBAAQ;AASP,SAAK,OAAO;AACZ,SAAK,QAAQ;AAAA,EACd;AAAA,EAMO,QAAQ,IAAqB;AACnC,WAAO,KAAK,IAAI,EAAE,KAAK,KAAK,OAAO,EAAE;AAAA,EACtC;AAAA,EAMO,OAAO,IAAqB;AAClC,UAAM,QAAQ,IAAI,UAAU,IAAI;AAChC,SAAK,IAAI,IAAI,KAAK;AAClB,WAAO;AAAA,EACR;AAAA,EAOgB,IAAI,IAAO,OAA2B;AACrD,SAAK,kBAAL,KAAK,gBAAkB,aAAa,YAAY,KAAK,MAAM,KAAK,IAAI,GAAG,kBAAiB,qBAAqB;AAC7G,WAAO,MAAM,IAAI,IAAI,KAAK;AAAA,EAC3B;AAAA,EAKO,QAAc;AACpB,eAAW,CAAC,IAAI,KAAK,KAAK,KAAK,QAAQ,GAAG;AACzC,UAAI,MAAM;AAAS,aAAK,OAAO,EAAE;AAAA,IAClC;AAEA,QAAI,KAAK,SAAS,GAAG;AACpB,mBAAa,cAAc,KAAK,aAAc;AAC9C,WAAK,gBAAgB;AAAA,IACtB;AAAA,EACD;AAMD;AAzEO,IAAM,mBAAN;AAAM;AAwEZ,cAxEY,kBAwEE,yBAAwB;","names":[]}
1
+ {"version":3,"sources":["../src/lib/RateLimit.ts","../src/lib/RateLimitManager.ts"],"names":[],"mappings":";;;;;;;;;AAEO,IAAM,YAAN,MAA4B;AAAA;AAAA;AAAA;AAAA,EAmB3B,YAAY,SAA8B;AAfjD;AAAA;AAAA;AAAA,wBAAO;AAKP;AAAA;AAAA;AAAA,wBAAO;AAKP;AAAA;AAAA;AAAA,wBAAQ;AAMP,SAAK,UAAU;AACf,SAAK,MAAM;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAKA,IAAW,UAAmB;AAC7B,WAAO,KAAK,kBAAkB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAW,UAAmB;AAC7B,WAAO,KAAK,cAAc,KAAK,CAAC,KAAK;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAW,gBAAwB;AAClC,WAAO,KAAK,IAAI,KAAK,UAAU,KAAK,IAAI,GAAG,CAAC;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKO,UAAgB;AACtB,QAAI,KAAK;AAAS,YAAM,IAAI,MAAM,iCAAiC;AACnE,QAAI,KAAK;AAAS,WAAK,MAAM;AAE7B,SAAK;AACL,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAKO,QAAc;AACpB,WAAO,KAAK,eAAe,EAAE,UAAU;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKO,iBAAuB;AAC7B,SAAK,YAAY,KAAK,QAAQ;AAC9B,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAKO,YAAkB;AACxB,SAAK,UAAU,KAAK,IAAI,IAAI,KAAK,QAAQ;AACzC,WAAO;AAAA,EACR;AACD;AA9Ea;;;ACFb,SAAS,oBAAoB;AAGtB,IAAM,oBAAN,cAA2C,IAAqB;AAAA;AAAA;AAAA;AAAA;AAAA,EAoB/D,YAAY,MAAc,QAAQ,GAAG;AAC3C,UAAM;AAjBP;AAAA;AAAA;AAAA,wBAAgB;AAKhB;AAAA;AAAA;AAAA,wBAAgB;AAKhB;AAAA;AAAA;AAAA,wBAAQ;AASP,SAAK,OAAO;AACZ,SAAK,QAAQ;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,QAAQ,IAAqB;AACnC,WAAO,KAAK,IAAI,EAAE,KAAK,KAAK,OAAO,EAAE;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,OAAO,IAAqB;AAClC,UAAM,QAAQ,IAAI,UAAU,IAAI;AAChC,SAAK,IAAI,IAAI,KAAK;AAClB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOgB,IAAI,IAAO,OAA2B;AACrD,SAAK,kBAAL,KAAK,gBAAkB,aAAa,YAAY,KAAK,MAAM,KAAK,IAAI,GAAG,kBAAiB,qBAAqB;AAC7G,WAAO,MAAM,IAAI,IAAI,KAAK;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKO,QAAc;AACpB,eAAW,CAAC,IAAI,KAAK,KAAK,KAAK,QAAQ,GAAG;AACzC,UAAI,MAAM;AAAS,aAAK,OAAO,EAAE;AAAA,IAClC;AAEA,QAAI,KAAK,SAAS,GAAG;AACpB,mBAAa,cAAc,KAAK,aAAc;AAC9C,WAAK,gBAAgB;AAAA,IACtB;AAAA,EACD;AAMD;AAzEO,IAAM,mBAAN;AAAM;AAAA;AAAA;AAAA;AAwEZ,cAxEY,kBAwEE,yBAAwB","sourcesContent":["import type { RateLimitManager } from './RateLimitManager';\n\nexport class RateLimit<K = string> {\n\t/**\n\t * The remaining amount of times this entry can be dripped before the bucket is empty.\n\t */\n\tpublic remaining!: number;\n\n\t/**\n\t * The timestamp that represents when this entry will reset back to a available state.\n\t */\n\tpublic expires!: number;\n\n\t/**\n\t * The {@link RateLimitManager} this entry is for.\n\t */\n\tprivate manager: RateLimitManager<K>;\n\n\t/**\n\t * @param manager The manager for this entry.\n\t */\n\tpublic constructor(manager: RateLimitManager<K>) {\n\t\tthis.manager = manager;\n\t\tthis.reset();\n\t}\n\n\t/**\n\t * Whether this entry is expired or not, allowing the bucket to be reset.\n\t */\n\tpublic get expired(): boolean {\n\t\treturn this.remainingTime === 0;\n\t}\n\n\t/**\n\t * Whether this entry is limited or not.\n\t */\n\tpublic get limited(): boolean {\n\t\treturn this.remaining === 0 && !this.expired;\n\t}\n\n\t/**\n\t * The remaining time in milliseconds before resetting.\n\t */\n\tpublic get remainingTime(): number {\n\t\treturn Math.max(this.expires - Date.now(), 0);\n\t}\n\n\t/**\n\t * Consumes {@link RateLimit.remaining} by one if it's not limited, calling {@link RateLimit.reset} first if {@link RateLimit.expired} is true.\n\t */\n\tpublic consume(): this {\n\t\tif (this.limited) throw new Error('Cannot consume a limited bucket');\n\t\tif (this.expired) this.reset();\n\n\t\tthis.remaining--;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resets the entry back to it's full state.\n\t */\n\tpublic reset(): this {\n\t\treturn this.resetRemaining().resetTime();\n\t}\n\n\t/**\n\t * Resets the entry's {@link RateLimit.remaining} uses back to full state.\n\t */\n\tpublic resetRemaining(): this {\n\t\tthis.remaining = this.manager.limit;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resets the entry's {@link RateLimit.expires} to the current time plus {@link RateLimitManager.time}.\n\t */\n\tpublic resetTime(): this {\n\t\tthis.expires = Date.now() + this.manager.time;\n\t\treturn this;\n\t}\n}\n","import { TimerManager } from '@sapphire/timer-manager';\nimport { RateLimit } from './RateLimit';\n\nexport class RateLimitManager<K = string> extends Map<K, RateLimit<K>> {\n\t/**\n\t * The amount of milliseconds for the {@link RateLimit ratelimits} from this manager to expire.\n\t */\n\tpublic readonly time: number;\n\n\t/**\n\t * The amount of times a {@link RateLimit} can drip before it's limited.\n\t */\n\tpublic readonly limit: number;\n\n\t/**\n\t * The interval to sweep expired {@link RateLimit ratelimits}.\n\t */\n\tprivate sweepInterval!: NodeJS.Timer | null;\n\n\t/**\n\t * @param time The amount of milliseconds for the ratelimits from this manager to expire.\n\t * @param limit The amount of times a {@link RateLimit} can drip before it's limited.\n\t */\n\tpublic constructor(time: number, limit = 1) {\n\t\tsuper();\n\n\t\tthis.time = time;\n\t\tthis.limit = limit;\n\t}\n\n\t/**\n\t * Gets a {@link RateLimit} from this manager or creates it if it does not exist.\n\t * @param id The id for the {@link RateLimit}\n\t */\n\tpublic acquire(id: K): RateLimit<K> {\n\t\treturn this.get(id) ?? this.create(id);\n\t}\n\n\t/**\n\t * Creates a {@link RateLimit} for this manager.\n\t * @param id The id the {@link RateLimit} belongs to\n\t */\n\tpublic create(id: K): RateLimit<K> {\n\t\tconst value = new RateLimit(this);\n\t\tthis.set(id, value);\n\t\treturn value;\n\t}\n\n\t/**\n\t * Wraps Collection's set method to set interval to sweep inactive {@link RateLimit}s.\n\t * @param id The id the {@link RateLimit} belongs to\n\t * @param value The {@link RateLimit} to set\n\t */\n\tpublic override set(id: K, value: RateLimit<K>): this {\n\t\tthis.sweepInterval ??= TimerManager.setInterval(this.sweep.bind(this), RateLimitManager.sweepIntervalDuration);\n\t\treturn super.set(id, value);\n\t}\n\n\t/**\n\t * Wraps Collection's sweep method to clear the interval when this manager is empty.\n\t */\n\tpublic sweep(): void {\n\t\tfor (const [id, value] of this.entries()) {\n\t\t\tif (value.expired) this.delete(id);\n\t\t}\n\n\t\tif (this.size === 0) {\n\t\t\tTimerManager.clearInterval(this.sweepInterval!);\n\t\t\tthis.sweepInterval = null;\n\t\t}\n\t}\n\n\t/**\n\t * The delay in milliseconds for {@link RateLimitManager.sweepInterval}.\n\t */\n\tpublic static sweepIntervalDuration = 30_000;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sapphire/ratelimits",
3
- "version": "2.4.6-next.78a79ca.0",
3
+ "version": "2.4.6-next.7c98509.0",
4
4
  "description": "Bucket implementation for Ratelimits.",
5
5
  "author": "@sapphire",
6
6
  "license": "MIT",
@@ -59,12 +59,12 @@
59
59
  "@sapphire/timer-manager": "^1.0.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@favware/cliff-jumper": "^1.8.7",
63
- "@vitest/coverage-c8": "^0.23.4",
64
- "tsup": "^6.2.3",
65
- "typedoc": "^0.23.14",
66
- "typedoc-json-parser": "^4.0.0",
67
- "typescript": "^4.8.3",
68
- "vitest": "^0.23.4"
62
+ "@favware/cliff-jumper": "^1.10.0",
63
+ "@vitest/coverage-c8": "^0.28.4",
64
+ "tsup": "^6.6.0",
65
+ "typedoc": "^0.23.25",
66
+ "typedoc-json-parser": "^7.1.0",
67
+ "typescript": "^4.9.5",
68
+ "vitest": "^0.28.4"
69
69
  }
70
70
  }