@sapphire/ratelimits 2.1.0-next.a3e5cf0b.0 → 2.1.0-next.a4e5a567.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
@@ -20,15 +20,15 @@
20
20
  - [Features](#features)
21
21
  - [Installation](#installation)
22
22
  - [Usage](#usage)
23
- - [Token Bucket](#token-bucket)
24
- - [Leaky Bucket](#leaky-bucket)
23
+ - [Token RateLimitManager](#token-ratelimitmanager)
24
+ - [Leaky RateLimitManager](#leaky-ratelimitmanager)
25
25
  - [API Documentation](#api-documentation)
26
26
  - [Buy us some doughnuts](#buy-us-some-doughnuts)
27
27
  - [Contributors ✨](#contributors-%E2%9C%A8)
28
28
 
29
29
  ## Description
30
30
 
31
- There is often a need to apply ratelimits to protect a network from excessive traffic levels on connections routed through it. This package offers two different techniques in the same implementation: the simple [Token Bucket](https://en.wikipedia.org/wiki/Token_bucket), and the more complex [Leaky Bucket](https://en.wikipedia.org/wiki/Leaky_bucket).
31
+ There is often a need to apply ratelimits to protect a network from excessive traffic levels on connections routed through it, or limit bot command usages in your Discord bot, or similar things. This package offers two different techniques in the same implementation: the [Token Bucket](https://en.wikipedia.org/wiki/Token_bucket), and the [Leaky Bucket](https://en.wikipedia.org/wiki/Leaky_bucket).
32
32
 
33
33
  ## Features
34
34
 
@@ -47,33 +47,52 @@ npm install @sapphire/ratelimits
47
47
 
48
48
  ## Usage
49
49
 
50
- **Note:** While this section uses `require`, the imports match 1:1 with ESM imports. For example `const { Bucket } = require('@sapphire/ratelimits')` equals `import { Bucket } from '@sapphire/ratelimits'`.
50
+ **Note:** While this section uses `require`, the imports match 1:1 with ESM imports. For example `const { RateLimitManager } = require('@sapphire/ratelimits')` equals `import { RateLimitManager } from '@sapphire/ratelimits'`.
51
51
 
52
- ### Token Bucket
52
+ ### Token RateLimitManager
53
53
 
54
54
  ```ts
55
55
  // Import the Bucket class
56
- const { Bucket } = require('@sapphire/ratelimits');
56
+ const { RateLimitManager } = require('@sapphire/ratelimits');
57
57
 
58
58
  // Define a bucket with 1 usage every 5 seconds
59
- const bucket = new Bucket().setDelay(5000);
59
+ const rateLimitManager = new RateLimitManager(5000);
60
60
 
61
- console.log(bucket.take(420)); // -> 0
62
- console.log(bucket.take(420)); // -> 5000
61
+ // Acquire the rate limit. The ID can be something like `'global'`, a Discord channel/server/user ID, or anything else.
62
+ const ratelimit = rateLimitManager.acquire('some-unique-id-here');
63
+
64
+ // Check if there is a rate limit right now
65
+ if (ratelimit.limited) {
66
+ // Do something when limited, such as throwing an error
67
+ }
68
+
69
+ // We're not rate limited so we drip the bucket. After consuming once, the second run through we'll be rate limited.
70
+ ratelimit.consume();
71
+
72
+ // And now we can finish the flow by returning some form of "success" state.
63
73
  ```
64
74
 
65
- ### Leaky Bucket
75
+ ### Leaky RateLimitManager
66
76
 
67
77
  ```ts
68
78
  // Import the Bucket class
69
- const { Bucket } = require('@sapphire/ratelimits');
79
+ const { RateLimitManager } = require('@sapphire/ratelimits');
70
80
 
71
81
  // Define a bucket with 2 usages every 5 seconds
72
- const bucket = new Bucket().setLimit({ timespan: 5000, maximum: 2 });
82
+ const rateLimitManager = new RateLimitManager(5000, 2);
83
+
84
+ // Acquire the rate limit. The ID can be something like `'global'`, a Discord channel/server/user ID, or anything else.
85
+ const ratelimit = rateLimitManager.acquire('some-unique-id-here');
86
+
87
+ // Check if there is a rate limit right now
88
+ if (ratelimit.limited) {
89
+ // Do something when limited, such as throwing an error
90
+ }
91
+
92
+ // We're not rate limited so we drip the bucket. After consuming twice, the third run through we'll be rate limited.
93
+ ratelimit.consume();
73
94
 
74
- console.log(bucket.take(420)); // -> 0
75
- console.log(bucket.take(420)); // -> 0
76
- console.log(bucket.take(420)); // -> 5000
95
+ // And now we can finish the flow by returning some form of "success" state.
77
96
  ```
78
97
 
79
98
  ---
package/dist/index.js CHANGED
@@ -92,8 +92,8 @@ class RateLimit {
92
92
 
93
93
  class RateLimitManager extends Map {
94
94
  /**
95
- * @param limit The amount of times a {@link RateLimit} can drip before it's limited.
96
95
  * @param time The amount of milliseconds for the ratelimits from this manager to expire.
96
+ * @param limit The amount of times a {@link RateLimit} can drip before it's limited.
97
97
  */
98
98
  constructor(time, limit = 1) {
99
99
  super();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/lib/RateLimit.ts","../src/lib/RateLimitManager.ts"],"sourcesContent":["import type { RateLimitManager } from './RateLimitManager';\n\nexport class RateLimit<K> {\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/time-utilities';\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 limit The amount of times a {@link RateLimit} can drip before it's limited.\n\t * @param time The amount of milliseconds for the ratelimits from this manager to expire.\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 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"],"names":["TimerManager"],"mappings":";;;;;;MAEa,SAAS;;;;IAmBrB,YAAmB,OAA4B;;;;QAf/C;;;;;WAA0B;;;;QAK1B;;;;;WAAwB;;;;QAKxB;;;;;WAAqC;QAMpC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,KAAK,EAAE,CAAC;KACb;;;;IAKD,IAAW,OAAO;QACjB,OAAO,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC;KAChC;;;;IAKD,IAAW,OAAO;QACjB,OAAO,IAAI,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;KAC7C;;;;IAKD,IAAW,aAAa;QACvB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;KAC9C;;;;IAKM,OAAO;QACb,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrE,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QAE/B,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;KACZ;;;;IAKM,KAAK;QACX,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE,CAAC;KACzC;;;;IAKM,cAAc;QACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACpC,OAAO,IAAI,CAAC;KACZ;;;;IAKM,SAAS;QACf,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QAC9C,OAAO,IAAI,CAAC;KACZ;;;MC5EW,gBAA6B,SAAQ,GAAoB;;;;;IAoBrE,YAAmB,IAAY,EAAE,KAAK,GAAG,CAAC;QACzC,KAAK,EAAE,CAAC;;;;QAjBT;;;;;WAA6B;;;;QAK7B;;;;;WAA8B;;;;QAK9B;;;;;WAA4C;QAS3C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;KACnB;;;;;IAMM,OAAO,CAAC,EAAK;QACnB,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;KACvC;;;;;IAMM,MAAM,CAAC,EAAK;QAClB,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACpB,OAAO,KAAK,CAAC;KACb;;;;;;IAOM,GAAG,CAAC,EAAK,EAAE,KAAmB;QACpC,IAAI,CAAC,aAAa,KAAlB,IAAI,CAAC,aAAa,GAAKA,0BAAY,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC,qBAAqB,CAAC,EAAC;QAC/G,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;KAC5B;;;;IAKM,KAAK;QACX,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;YACzC,IAAI,KAAK,CAAC,OAAO;gBAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;SACnC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE;YACpBA,0BAAY,CAAC,aAAa,CAAC,IAAI,CAAC,aAAc,CAAC,CAAC;YAChD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;SAC1B;KACD;;AAED;;;AAGA;;;;WAAsC,KAAM;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../src/lib/RateLimit.ts","../src/lib/RateLimitManager.ts"],"sourcesContent":["import type { RateLimitManager } from './RateLimitManager';\n\nexport class RateLimit<K> {\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/time-utilities';\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 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"],"names":["TimerManager"],"mappings":";;;;;;MAEa,SAAS;;;;IAmBrB,YAAmB,OAA4B;;;;QAf/C;;;;;WAA0B;;;;QAK1B;;;;;WAAwB;;;;QAKxB;;;;;WAAqC;QAMpC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,KAAK,EAAE,CAAC;KACb;;;;IAKD,IAAW,OAAO;QACjB,OAAO,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC;KAChC;;;;IAKD,IAAW,OAAO;QACjB,OAAO,IAAI,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;KAC7C;;;;IAKD,IAAW,aAAa;QACvB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;KAC9C;;;;IAKM,OAAO;QACb,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrE,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QAE/B,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;KACZ;;;;IAKM,KAAK;QACX,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE,CAAC;KACzC;;;;IAKM,cAAc;QACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACpC,OAAO,IAAI,CAAC;KACZ;;;;IAKM,SAAS;QACf,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QAC9C,OAAO,IAAI,CAAC;KACZ;;;MC5EW,gBAA6B,SAAQ,GAAoB;;;;;IAoBrE,YAAmB,IAAY,EAAE,KAAK,GAAG,CAAC;QACzC,KAAK,EAAE,CAAC;;;;QAjBT;;;;;WAA6B;;;;QAK7B;;;;;WAA8B;;;;QAK9B;;;;;WAA4C;QAS3C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;KACnB;;;;;IAMM,OAAO,CAAC,EAAK;QACnB,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;KACvC;;;;;IAMM,MAAM,CAAC,EAAK;QAClB,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACpB,OAAO,KAAK,CAAC;KACb;;;;;;IAOM,GAAG,CAAC,EAAK,EAAE,KAAmB;QACpC,IAAI,CAAC,aAAa,KAAlB,IAAI,CAAC,aAAa,GAAKA,0BAAY,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC,qBAAqB,CAAC,EAAC;QAC/G,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;KAC5B;;;;IAKM,KAAK;QACX,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;YACzC,IAAI,KAAK,CAAC,OAAO;gBAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;SACnC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE;YACpBA,0BAAY,CAAC,aAAa,CAAC,IAAI,CAAC,aAAc,CAAC,CAAC;YAChD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;SAC1B;KACD;;AAED;;;AAGA;;;;WAAsC,KAAM;;;;;;"}
package/dist/index.mjs CHANGED
@@ -88,8 +88,8 @@ class RateLimit {
88
88
 
89
89
  class RateLimitManager extends Map {
90
90
  /**
91
- * @param limit The amount of times a {@link RateLimit} can drip before it's limited.
92
91
  * @param time The amount of milliseconds for the ratelimits from this manager to expire.
92
+ * @param limit The amount of times a {@link RateLimit} can drip before it's limited.
93
93
  */
94
94
  constructor(time, limit = 1) {
95
95
  super();
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/lib/RateLimit.ts","../src/lib/RateLimitManager.ts"],"sourcesContent":["import type { RateLimitManager } from './RateLimitManager';\n\nexport class RateLimit<K> {\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/time-utilities';\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 limit The amount of times a {@link RateLimit} can drip before it's limited.\n\t * @param time The amount of milliseconds for the ratelimits from this manager to expire.\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 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"],"names":[],"mappings":";;MAEa,SAAS;;;;IAmBrB,YAAmB,OAA4B;;;;QAf/C;;;;;WAA0B;;;;QAK1B;;;;;WAAwB;;;;QAKxB;;;;;WAAqC;QAMpC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,KAAK,EAAE,CAAC;KACb;;;;IAKD,IAAW,OAAO;QACjB,OAAO,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC;KAChC;;;;IAKD,IAAW,OAAO;QACjB,OAAO,IAAI,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;KAC7C;;;;IAKD,IAAW,aAAa;QACvB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;KAC9C;;;;IAKM,OAAO;QACb,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrE,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QAE/B,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;KACZ;;;;IAKM,KAAK;QACX,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE,CAAC;KACzC;;;;IAKM,cAAc;QACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACpC,OAAO,IAAI,CAAC;KACZ;;;;IAKM,SAAS;QACf,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QAC9C,OAAO,IAAI,CAAC;KACZ;;;MC5EW,gBAA6B,SAAQ,GAAoB;;;;;IAoBrE,YAAmB,IAAY,EAAE,KAAK,GAAG,CAAC;QACzC,KAAK,EAAE,CAAC;;;;QAjBT;;;;;WAA6B;;;;QAK7B;;;;;WAA8B;;;;QAK9B;;;;;WAA4C;QAS3C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;KACnB;;;;;IAMM,OAAO,CAAC,EAAK;QACnB,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;KACvC;;;;;IAMM,MAAM,CAAC,EAAK;QAClB,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACpB,OAAO,KAAK,CAAC;KACb;;;;;;IAOM,GAAG,CAAC,EAAK,EAAE,KAAmB;QACpC,IAAI,CAAC,aAAa,KAAlB,IAAI,CAAC,aAAa,GAAK,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC,qBAAqB,CAAC,EAAC;QAC/G,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;KAC5B;;;;IAKM,KAAK;QACX,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;YACzC,IAAI,KAAK,CAAC,OAAO;gBAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;SACnC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE;YACpB,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,aAAc,CAAC,CAAC;YAChD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;SAC1B;KACD;;AAED;;;AAGA;;;;WAAsC,KAAM;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/lib/RateLimit.ts","../src/lib/RateLimitManager.ts"],"sourcesContent":["import type { RateLimitManager } from './RateLimitManager';\n\nexport class RateLimit<K> {\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/time-utilities';\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 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"],"names":[],"mappings":";;MAEa,SAAS;;;;IAmBrB,YAAmB,OAA4B;;;;QAf/C;;;;;WAA0B;;;;QAK1B;;;;;WAAwB;;;;QAKxB;;;;;WAAqC;QAMpC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,KAAK,EAAE,CAAC;KACb;;;;IAKD,IAAW,OAAO;QACjB,OAAO,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC;KAChC;;;;IAKD,IAAW,OAAO;QACjB,OAAO,IAAI,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;KAC7C;;;;IAKD,IAAW,aAAa;QACvB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;KAC9C;;;;IAKM,OAAO;QACb,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrE,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QAE/B,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;KACZ;;;;IAKM,KAAK;QACX,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE,CAAC;KACzC;;;;IAKM,cAAc;QACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACpC,OAAO,IAAI,CAAC;KACZ;;;;IAKM,SAAS;QACf,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QAC9C,OAAO,IAAI,CAAC;KACZ;;;MC5EW,gBAA6B,SAAQ,GAAoB;;;;;IAoBrE,YAAmB,IAAY,EAAE,KAAK,GAAG,CAAC;QACzC,KAAK,EAAE,CAAC;;;;QAjBT;;;;;WAA6B;;;;QAK7B;;;;;WAA8B;;;;QAK9B;;;;;WAA4C;QAS3C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;KACnB;;;;;IAMM,OAAO,CAAC,EAAK;QACnB,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;KACvC;;;;;IAMM,MAAM,CAAC,EAAK;QAClB,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACpB,OAAO,KAAK,CAAC;KACb;;;;;;IAOM,GAAG,CAAC,EAAK,EAAE,KAAmB;QACpC,IAAI,CAAC,aAAa,KAAlB,IAAI,CAAC,aAAa,GAAK,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC,qBAAqB,CAAC,EAAC;QAC/G,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;KAC5B;;;;IAKM,KAAK;QACX,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;YACzC,IAAI,KAAK,CAAC,OAAO;gBAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;SACnC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE;YACpB,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,aAAc,CAAC,CAAC;YAChD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;SAC1B;KACD;;AAED;;;AAGA;;;;WAAsC,KAAM;;;;;"}
package/dist/index.umd.js CHANGED
@@ -92,8 +92,8 @@
92
92
 
93
93
  class RateLimitManager extends Map {
94
94
  /**
95
- * @param limit The amount of times a {@link RateLimit} can drip before it's limited.
96
95
  * @param time The amount of milliseconds for the ratelimits from this manager to expire.
96
+ * @param limit The amount of times a {@link RateLimit} can drip before it's limited.
97
97
  */
98
98
  constructor(time, limit = 1) {
99
99
  super();
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/lib/RateLimit.ts","../src/lib/RateLimitManager.ts"],"sourcesContent":["import type { RateLimitManager } from './RateLimitManager';\n\nexport class RateLimit<K> {\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/time-utilities';\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 limit The amount of times a {@link RateLimit} can drip before it's limited.\n\t * @param time The amount of milliseconds for the ratelimits from this manager to expire.\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 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"],"names":["TimerManager"],"mappings":";;;;;;OAEa,SAAS;;;;KAmBrB,YAAmB,OAA4B;;;;SAf/C;;;;;YAA0B;;;;SAK1B;;;;;YAAwB;;;;SAKxB;;;;;YAAqC;SAMpC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;SACvB,IAAI,CAAC,KAAK,EAAE,CAAC;MACb;;;;KAKD,IAAW,OAAO;SACjB,OAAO,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC;MAChC;;;;KAKD,IAAW,OAAO;SACjB,OAAO,IAAI,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;MAC7C;;;;KAKD,IAAW,aAAa;SACvB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;MAC9C;;;;KAKM,OAAO;SACb,IAAI,IAAI,CAAC,OAAO;aAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;SACrE,IAAI,IAAI,CAAC,OAAO;aAAE,IAAI,CAAC,KAAK,EAAE,CAAC;SAE/B,IAAI,CAAC,SAAS,EAAE,CAAC;SACjB,OAAO,IAAI,CAAC;MACZ;;;;KAKM,KAAK;SACX,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE,CAAC;MACzC;;;;KAKM,cAAc;SACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;SACpC,OAAO,IAAI,CAAC;MACZ;;;;KAKM,SAAS;SACf,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;SAC9C,OAAO,IAAI,CAAC;MACZ;;;OC5EW,gBAA6B,SAAQ,GAAoB;;;;;KAoBrE,YAAmB,IAAY,EAAE,KAAK,GAAG,CAAC;SACzC,KAAK,EAAE,CAAC;;;;SAjBT;;;;;YAA6B;;;;SAK7B;;;;;YAA8B;;;;SAK9B;;;;;YAA4C;SAS3C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;SACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;MACnB;;;;;KAMM,OAAO,CAAC,EAAK;SACnB,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;MACvC;;;;;KAMM,MAAM,CAAC,EAAK;SAClB,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;SAClC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;SACpB,OAAO,KAAK,CAAC;MACb;;;;;;KAOM,GAAG,CAAC,EAAK,EAAE,KAAmB;SACpC,IAAI,CAAC,aAAa,KAAlB,IAAI,CAAC,aAAa,GAAKA,0BAAY,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC,qBAAqB,CAAC,EAAC;SAC/G,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;MAC5B;;;;KAKM,KAAK;SACX,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;aACzC,IAAI,KAAK,CAAC,OAAO;iBAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;UACnC;SAED,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE;aACpBA,0BAAY,CAAC,aAAa,CAAC,IAAI,CAAC,aAAc,CAAC,CAAC;aAChD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;UAC1B;MACD;;CAED;;;CAGA;;;;YAAsC,KAAM;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/lib/RateLimit.ts","../src/lib/RateLimitManager.ts"],"sourcesContent":["import type { RateLimitManager } from './RateLimitManager';\n\nexport class RateLimit<K> {\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/time-utilities';\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 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"],"names":["TimerManager"],"mappings":";;;;;;OAEa,SAAS;;;;KAmBrB,YAAmB,OAA4B;;;;SAf/C;;;;;YAA0B;;;;SAK1B;;;;;YAAwB;;;;SAKxB;;;;;YAAqC;SAMpC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;SACvB,IAAI,CAAC,KAAK,EAAE,CAAC;MACb;;;;KAKD,IAAW,OAAO;SACjB,OAAO,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC;MAChC;;;;KAKD,IAAW,OAAO;SACjB,OAAO,IAAI,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;MAC7C;;;;KAKD,IAAW,aAAa;SACvB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;MAC9C;;;;KAKM,OAAO;SACb,IAAI,IAAI,CAAC,OAAO;aAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;SACrE,IAAI,IAAI,CAAC,OAAO;aAAE,IAAI,CAAC,KAAK,EAAE,CAAC;SAE/B,IAAI,CAAC,SAAS,EAAE,CAAC;SACjB,OAAO,IAAI,CAAC;MACZ;;;;KAKM,KAAK;SACX,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE,CAAC;MACzC;;;;KAKM,cAAc;SACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;SACpC,OAAO,IAAI,CAAC;MACZ;;;;KAKM,SAAS;SACf,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;SAC9C,OAAO,IAAI,CAAC;MACZ;;;OC5EW,gBAA6B,SAAQ,GAAoB;;;;;KAoBrE,YAAmB,IAAY,EAAE,KAAK,GAAG,CAAC;SACzC,KAAK,EAAE,CAAC;;;;SAjBT;;;;;YAA6B;;;;SAK7B;;;;;YAA8B;;;;SAK9B;;;;;YAA4C;SAS3C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;SACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;MACnB;;;;;KAMM,OAAO,CAAC,EAAK;SACnB,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;MACvC;;;;;KAMM,MAAM,CAAC,EAAK;SAClB,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;SAClC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;SACpB,OAAO,KAAK,CAAC;MACb;;;;;;KAOM,GAAG,CAAC,EAAK,EAAE,KAAmB;SACpC,IAAI,CAAC,aAAa,KAAlB,IAAI,CAAC,aAAa,GAAKA,0BAAY,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC,qBAAqB,CAAC,EAAC;SAC/G,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;MAC5B;;;;KAKM,KAAK;SACX,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;aACzC,IAAI,KAAK,CAAC,OAAO;iBAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;UACnC;SAED,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE;aACpBA,0BAAY,CAAC,aAAa,CAAC,IAAI,CAAC,aAAc,CAAC,CAAC;aAChD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;UAC1B;MACD;;CAED;;;CAGA;;;;YAAsC,KAAM;;;;;;;;;;;;"}
@@ -13,8 +13,8 @@ export declare class RateLimitManager<K = string> extends Map<K, RateLimit<K>> {
13
13
  */
14
14
  private sweepInterval;
15
15
  /**
16
- * @param limit The amount of times a {@link RateLimit} can drip before it's limited.
17
16
  * @param time The amount of milliseconds for the ratelimits from this manager to expire.
17
+ * @param limit The amount of times a {@link RateLimit} can drip before it's limited.
18
18
  */
19
19
  constructor(time: number, limit?: number);
20
20
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sapphire/ratelimits",
3
- "version": "2.1.0-next.a3e5cf0b.0",
3
+ "version": "2.1.0-next.a4e5a567.0",
4
4
  "description": "Bucket implementation for Ratelimits.",
5
5
  "author": "@sapphire",
6
6
  "license": "MIT",
@@ -52,7 +52,7 @@
52
52
  "access": "public"
53
53
  },
54
54
  "dependencies": {
55
- "@sapphire/time-utilities": "^1.4.0-next.a3e5cf0b.0"
55
+ "@sapphire/time-utilities": "^1.4.0-next.a4e5a567.0"
56
56
  },
57
- "gitHead": "a3e5cf0bbe28eb36e46274bfe54a5f9c8ebe2703"
57
+ "gitHead": "a4e5a567a4d75dbba57df6774664ebaff55c24f4"
58
58
  }