lunibee 0.3.0 → 0.3.2

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.
Files changed (87) hide show
  1. package/dist/builders/attachment.d.ts +1 -0
  2. package/dist/builders/clone.d.ts +10 -0
  3. package/dist/builders/commands.d.ts +1 -1
  4. package/dist/builders/components.d.ts +24 -5
  5. package/dist/builders/embed.d.ts +1 -0
  6. package/dist/builders/index.js +68 -17
  7. package/dist/builders/index.js.map +10 -9
  8. package/dist/collection/index.d.ts +1 -0
  9. package/dist/collection/index.js +297 -19
  10. package/dist/collection/index.js.map +5 -4
  11. package/dist/collection/redis.d.ts +98 -0
  12. package/dist/core/collector.d.ts +8 -0
  13. package/dist/core/events.d.ts +1 -0
  14. package/dist/core/index.d.ts +3 -0
  15. package/dist/core/index.js +6252 -4704
  16. package/dist/core/index.js.map +47 -40
  17. package/dist/core/permissions.d.ts +3 -402
  18. package/dist/core/redis-cache.d.ts +85 -0
  19. package/dist/formatters/index.d.ts +5 -1
  20. package/dist/formatters/index.js +7 -3
  21. package/dist/formatters/index.js.map +3 -3
  22. package/dist/handlers/index.js +11 -2
  23. package/dist/handlers/index.js.map +3 -3
  24. package/dist/index.js +10481 -6148
  25. package/dist/index.js.map +70 -56
  26. package/dist/managers/application.d.ts +10 -6
  27. package/dist/managers/base.d.ts +4 -1
  28. package/dist/managers/guild.d.ts +3 -1
  29. package/dist/managers/index.d.ts +6 -1
  30. package/dist/managers/index.js +365 -103
  31. package/dist/managers/index.js.map +19 -22
  32. package/dist/managers/member.d.ts +3 -1
  33. package/dist/managers/message.d.ts +13 -4
  34. package/dist/managers/thread.d.ts +3 -3
  35. package/dist/rest/decoder.d.ts +2 -0
  36. package/dist/rest/errors.d.ts +13 -2
  37. package/dist/rest/headers.d.ts +31 -0
  38. package/dist/rest/identity.d.ts +31 -0
  39. package/dist/rest/index.d.ts +99 -6
  40. package/dist/rest/index.js +1412 -231
  41. package/dist/rest/index.js.map +16 -13
  42. package/dist/rest/limiter.d.ts +75 -10
  43. package/dist/rest/redis.d.ts +103 -22
  44. package/dist/rest/scheduler.d.ts +13 -0
  45. package/dist/rest/store.d.ts +135 -12
  46. package/dist/rest/telemetry.d.ts +151 -0
  47. package/dist/rest/transport.d.ts +9 -0
  48. package/dist/rest/webhook.d.ts +18 -6
  49. package/dist/sharding/bus.d.ts +12 -2
  50. package/dist/sharding/cluster.d.ts +225 -15
  51. package/dist/sharding/context.d.ts +41 -0
  52. package/dist/sharding/gateway-bot.d.ts +20 -0
  53. package/dist/sharding/health.d.ts +94 -0
  54. package/dist/sharding/host.d.ts +76 -0
  55. package/dist/sharding/identify.d.ts +64 -0
  56. package/dist/sharding/index.d.ts +62 -12
  57. package/dist/sharding/index.js +2459 -202
  58. package/dist/sharding/index.js.map +21 -13
  59. package/dist/sharding/protocol.d.ts +47 -0
  60. package/dist/sharding/remote-protocol.d.ts +100 -0
  61. package/dist/sharding/remote.d.ts +134 -0
  62. package/dist/sharding/requests.d.ts +54 -0
  63. package/dist/sharding/supervisor.d.ts +1 -1
  64. package/dist/sharding/transport.d.ts +6 -5
  65. package/dist/sharding/worker.d.ts +55 -0
  66. package/dist/structures/base.d.ts +16 -5
  67. package/dist/structures/index.d.ts +1 -1
  68. package/dist/structures/index.js +57 -91
  69. package/dist/structures/index.js.map +10 -18
  70. package/dist/structures/options.d.ts +3 -2
  71. package/dist/structures/permissions.d.ts +409 -0
  72. package/dist/structures/resources.d.ts +4 -1
  73. package/dist/types/gateway.d.ts +7 -0
  74. package/dist/types/index.d.ts +14 -4
  75. package/dist/types/index.js.map +3 -3
  76. package/dist/utils/args.d.ts +3 -1
  77. package/dist/utils/index.d.ts +6 -1
  78. package/dist/utils/index.js +17 -10
  79. package/dist/utils/index.js.map +4 -4
  80. package/dist/voice/index.d.ts +7 -1
  81. package/dist/voice/index.js +33 -10
  82. package/dist/voice/index.js.map +3 -3
  83. package/dist/ws/index.d.ts +3 -1
  84. package/dist/ws/index.js +33 -5
  85. package/dist/ws/index.js.map +6 -6
  86. package/dist/ws/send-budget.d.ts +1 -1
  87. package/package.json +22 -17
@@ -1,6 +1,7 @@
1
1
  import { REST } from "@lunibee/rest";
2
2
  import { GuildMember, type ResourceContext } from "@lunibee/structures";
3
3
  import { ResourceManager } from "./base.js";
4
+ /** Fields that can change when editing a guild member (nickname, roles, voice state, timeout). */
4
5
  export interface MemberEditOptions {
5
6
  /** Audit-log reason. */
6
7
  reason?: string;
@@ -11,6 +12,7 @@ export interface MemberEditOptions {
11
12
  channel_id?: string | null;
12
13
  communication_disabled_until?: string | null;
13
14
  }
15
+ /** Options for banning a member: audit-log `reason` and how many seconds of their messages to delete. */
14
16
  export interface BanOptions {
15
17
  reason?: string;
16
18
  deleteMessageSeconds?: number;
@@ -20,7 +22,7 @@ export declare class GuildMemberManager extends ResourceManager<string, GuildMem
20
22
  #private;
21
23
  readonly guildId: string;
22
24
  /** @param context Gives fetched members their actions (`member.kick()`...). */
23
- constructor(guildId: string, rest: REST, context?: () => ResourceContext | undefined);
25
+ constructor(guildId: string, rest: REST, context?: () => ResourceContext | undefined, maxSize?: number);
24
26
  /** Finds members whose username or nickname starts with `query` (up to `limit`, 1-1000, default 1). */
25
27
  search(query: string, limit?: number): Promise<GuildMember[]>;
26
28
  /** Changes the bot's own nickname in this guild (`null` clears it). */
@@ -8,16 +8,25 @@ export interface MessageCacheOptions {
8
8
  ttl?: number;
9
9
  }
10
10
  import { REST, type RESTFileAttachment } from "@lunibee/rest";
11
- import type { AllowedMentions, MessageCreateOptions, MessageEditOptions, MessageFile } from "@lunibee/types";
11
+ import type { AllowedMentions, MessageCreateOptions, MessageEditOptions, MessageFile, MessageFileSource } from "@lunibee/types";
12
12
  import { Message, type ResourceContext } from "@lunibee/structures";
13
- export type { MessageCreateOptions, MessageEditOptions, MessageFile };
14
- /** Turns message files into REST uploads, encoding string data as UTF-8. */
15
- export declare function toAttachments(files: readonly MessageFile[]): RESTFileAttachment[];
13
+ export type { MessageCreateOptions, MessageEditOptions, MessageFile, MessageFileSource, };
14
+ /**
15
+ * Turns message files into REST uploads, encoding string data as UTF-8. A file
16
+ * with `toBuffer()` (such as a `CreateAttachment`) is read when the request is sent.
17
+ */
18
+ export declare function toAttachments(files: readonly (MessageFile | MessageFileSource)[]): RESTFileAttachment[];
16
19
  /**
17
20
  * Splits `files` out of a message payload into a REST upload, encoding string
18
21
  * data as UTF-8. `allowedMentions` is the client's default, applied only when
19
22
  * the payload has no `allowed_mentions` of its own.
20
23
  */
24
+ /**
25
+ * Refuses an `allowed_mentions` object Discord would answer with 400: a kind
26
+ * both in `parse` and listed by id, an unknown `parse` value, or non-string ids.
27
+ * @throws {TypeError} If the object is invalid.
28
+ */
29
+ export declare function assertAllowedMentions(mentions: AllowedMentions): void;
21
30
  export declare function toRequest(options: MessageCreateOptions, allowedMentions?: AllowedMentions): Omit<MessageCreateOptions, "files"> | {
22
31
  body: Omit<MessageCreateOptions, "files">;
23
32
  files: RESTFileAttachment[];
@@ -1,6 +1,6 @@
1
1
  import { REST } from "@lunibee/rest";
2
2
  import { Channel, type ResourceContext } from "@lunibee/structures";
3
- import type { APIGuildMember, APIThreadMember, MessageCreateOptions } from "@lunibee/types";
3
+ import type { AllowedMentions, APIGuildMember, APIThreadMember, MessageCreateOptions } from "@lunibee/types";
4
4
  /** Options shared by every way of starting a thread. */
5
5
  export interface ThreadCreateOptions {
6
6
  name: string;
@@ -26,8 +26,8 @@ export interface ArchivedThreads {
26
26
  /** Manages thread resources created from a parent channel. */
27
27
  export declare class ThreadManager {
28
28
  #private;
29
- /** Creates a thread manager. @param rest REST transport. @param context Structure resource context. @param channelId Parent channel identifier. @throws {TypeError} If channelId is empty. */
30
- constructor(rest: REST, context: ResourceContext, channelId: string);
29
+ /** Creates a thread manager. @param rest REST transport. @param context Structure resource context. @param channelId Parent channel identifier. @param allowedMentions Default `allowed_mentions` for a forum post's first message without its own. @throws {TypeError} If channelId is empty. */
30
+ constructor(rest: REST, context: ResourceContext, channelId: string, allowedMentions?: AllowedMentions);
31
31
  /** Creates a thread from a message. @param messageId Message identifier. @param options Thread creation options. @returns Created thread channel. @throws {Error} If REST rejects the request. */
32
32
  createFromMessage(messageId: string, options: {
33
33
  name: string;
@@ -7,6 +7,8 @@ export interface DecodedError {
7
7
  }
8
8
  /** Turns a raw {@link Response} into a payload and the error metadata retries need. */
9
9
  export declare class ResponseDecoder {
10
+ /** Creates an empty instance. */
11
+ constructor();
10
12
  /** Reads a Discord response payload as JSON, text, or nothing for 204. */
11
13
  read(response: Response): Promise<unknown>;
12
14
  /** Extracts Discord's error metadata from a decoded payload. */
@@ -19,13 +19,25 @@ export type RESTErrorKind =
19
19
  /** 5xx: Discord failed to handle the request. */
20
20
  | "server"
21
21
  /** Any other 4xx. */
22
- | "client";
22
+ | "client"
23
+ /** The rate-limit store failed or refused to coordinate; the request was not sent. */
24
+ | "coordination"
25
+ /** A local queue limit was reached; the request was not sent. */
26
+ | "overloaded";
23
27
  /**
24
28
  * Replaces the token segment of webhook and interaction paths with `:token`,
25
29
  * so request paths can appear in errors, hooks and logs without leaking a
26
30
  * credential.
27
31
  */
28
32
  export declare function redactPath(path: string): string;
33
+ /** Hides webhook and interaction tokens in free text. */
34
+ export declare function redactText(text: string): string;
35
+ /**
36
+ * A copy of a lower-level error that is safe to attach as a `cause`: the same
37
+ * name and code, with tokens removed from the message and stack. Runtimes put
38
+ * the request URL in network error messages, and the URL holds webhook tokens.
39
+ */
40
+ export declare function sanitizeCause(error: unknown): unknown;
29
41
  /** Error thrown when Discord rejects a REST request. */
30
42
  export declare class RESTError extends Error {
31
43
  /** Failure category. */
@@ -55,7 +67,6 @@ export declare class RESTError extends Error {
55
67
  }
56
68
  /** Creates the cancellation error shared by every stage of the request pipeline. */
57
69
  export declare function abortError(path: string, reason: unknown): RESTError;
58
- /** Waits for a delay, rejecting early if the signal aborts. */
59
70
  export declare function sleep(delay: number, signal: AbortSignal | undefined, path: string): Promise<void>;
60
71
  /** Awaits a promise, rejecting early if the signal aborts. */
61
72
  export declare function abortable(promise: Promise<void>, signal: AbortSignal | undefined, path: string): Promise<void>;
@@ -0,0 +1,31 @@
1
+ /** Which limit a 429 counts against, from `X-RateLimit-Scope`. */
2
+ export type RateLimitScope = "user" | "global" | "shared";
3
+ /** A response's rate-limit headers, each one validated on its own. */
4
+ export interface RateLimitHeaders {
5
+ /** `X-RateLimit-Limit`: requests per window. */
6
+ limit?: number;
7
+ /** `X-RateLimit-Remaining`: requests left in the window. */
8
+ remaining?: number;
9
+ /** `X-RateLimit-Reset-After`, in ms from now. */
10
+ resetAfterMs?: number;
11
+ /** `X-RateLimit-Reset`, as epoch ms: identifies the window. */
12
+ resetAtMs?: number;
13
+ /** `X-RateLimit-Bucket`: the server's bucket hash. */
14
+ bucket?: string;
15
+ /** `X-RateLimit-Scope`, when it is one Discord documents. */
16
+ scope?: RateLimitScope;
17
+ /** `X-RateLimit-Global: true`. */
18
+ global: boolean;
19
+ /** `Retry-After`, in ms. */
20
+ retryAfterMs?: number;
21
+ }
22
+ /**
23
+ * A non-negative finite number from a header, or `undefined`.
24
+ *
25
+ * `Number(null)` and `Number("")` are 0, which would read a missing header as
26
+ * "nothing remaining" or "reset now"; a negative or non-numeric value is a
27
+ * broken proxy, not information.
28
+ */
29
+ export declare function headerNumber(headers: Headers, name: string): number | undefined;
30
+ /** Reads every rate-limit header of a response defensively. */
31
+ export declare function parseRateLimitHeaders(headers: Headers): RateLimitHeaders;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Who a request's rate limits belong to.
3
+ *
4
+ * `bucket` prefixes the bucket key: Discord counts a bot's buckets per bot, so
5
+ * two bots sharing one Redis must not share counters. `global` is the scope of
6
+ * the global limit the request counts against, or `undefined` when it counts
7
+ * against none.
8
+ */
9
+ export interface RequestIdentity {
10
+ bucket: string;
11
+ global?: string;
12
+ }
13
+ /**
14
+ * A stable, non-reversible fingerprint of a token, identical in every process.
15
+ * The token itself never enters a key, a label or a log line.
16
+ */
17
+ export declare function tokenFingerprint(token: string): string;
18
+ /**
19
+ * Classifies a request.
20
+ *
21
+ * - Interaction callbacks (`/interactions/:id/:token/…`) and token webhooks
22
+ * (`/webhooks/:id/:token…`, which includes interaction follow-ups) are
23
+ * limited per webhook, whoever sends them: their buckets are shared
24
+ * (`"shared"`), so every bot and process agrees on one counter.
25
+ * Interaction callbacks are not bound to any global limit; a token webhook
26
+ * still counts against the sender's, conservatively, because a follow-up
27
+ * cannot be told from a plain webhook by its path.
28
+ * - A request sent without a bot token is limited per caller (`"anon"`).
29
+ * - Everything else belongs to the bot that sends it.
30
+ */
31
+ export declare function requestIdentity(path: string, fingerprint: string | undefined): RequestIdentity;
@@ -1,11 +1,13 @@
1
1
  import { type RateLimitStore } from "./store.js";
2
2
  import { RESTError } from "./errors.js";
3
3
  import { type RESTQuery } from "./route.js";
4
+ import { type CoordinationMode, type RESTTelemetry } from "./telemetry.js";
4
5
  import { HttpTransport } from "./transport.js";
5
6
  /** A file attachment sent as part of a multipart REST request. */
6
7
  export interface RESTFileAttachment {
7
8
  name: string;
8
- data: Blob | Uint8Array | ArrayBuffer;
9
+ /** The bytes, or a promise of them (read just before the request is sent). */
10
+ data: Blob | Uint8Array | ArrayBuffer | PromiseLike<Blob | Uint8Array | ArrayBuffer>;
9
11
  contentType?: string;
10
12
  }
11
13
  /**
@@ -26,6 +28,12 @@ export interface RESTRequestOptions {
26
28
  reason?: string;
27
29
  /** Set `false` to omit the `Authorization` header for this request. Defaults to `true`. */
28
30
  auth?: boolean;
31
+ /**
32
+ * Longest, in ms, this request may wait before it is sent: queued behind
33
+ * its bucket, for a rate limit, or between retries. Past it the request
34
+ * fails with kind `"overloaded"`. Overrides the client's `maxQueueWait`.
35
+ */
36
+ maxQueueWait?: number;
29
37
  }
30
38
  /**
31
39
  * Discord.js-familiar request payload. Superset of {@link RESTRequestOptions} that also
@@ -38,6 +46,18 @@ export interface RequestData extends RESTRequestOptions {
38
46
  /** File attachments; presence upgrades the request to `multipart/form-data`. */
39
47
  files?: RESTFileAttachment[];
40
48
  }
49
+ /**
50
+ * The single-object form of {@link REST.request}, matching `@discordjs/rest`:
51
+ * the route is `path` (or its Discord.js name, `fullRoute`).
52
+ */
53
+ export interface RequestOptionsObject extends RequestData {
54
+ /** HTTP method. */
55
+ method: string;
56
+ /** API path, starting with `/`. */
57
+ path?: string;
58
+ /** Alias of `path`, as `@discordjs/rest` names it. */
59
+ fullRoute?: string;
60
+ }
41
61
  /** Context passed to `RESTHooks.onRequest`. */
42
62
  export interface RESTRequestContext {
43
63
  method: string;
@@ -97,6 +117,26 @@ export interface RetryPolicy {
97
117
  }
98
118
  /** Creates the default conservative REST retry policy. @param maxRetries Maximum retries. @returns Retry policy that retries rate limits and idempotent transient failures. @throws {TypeError} If maxRetries is negative or not finite. */
99
119
  export declare function createRetryPolicy(maxRetries?: number): RetryPolicy;
120
+ /** A REST client's state, for health checks and diagnostics endpoints. */
121
+ export interface RESTDiagnostics {
122
+ /** How the store enforces limits right now. */
123
+ mode: CoordinationMode;
124
+ /** Requests waiting for a bucket slot. */
125
+ queued: number;
126
+ /** Requests started and not yet settled, queued ones included. */
127
+ inFlight: number;
128
+ /** Bucket keys holding a queue slot. */
129
+ buckets: number;
130
+ /** Whether `close()` was called. */
131
+ closed: boolean;
132
+ /**
133
+ * `401`, `403` and `429` responses (shared-scope 429s excepted) in the
134
+ * last ten minutes. Discord bans an IP for a while past 10,000.
135
+ */
136
+ invalidRequests: number;
137
+ /** Whether requests are refused because Discord rejected the token (see `stopOnInvalidToken`). */
138
+ tokenRejected: boolean;
139
+ }
100
140
  /** Bun-native REST transport with Discord bucket-aware rate limiting, retries, and cancellation. */
101
141
  export declare class REST {
102
142
  #private;
@@ -107,6 +147,8 @@ export declare class REST {
107
147
  retries?: number;
108
148
  retryPolicy?: RetryPolicy;
109
149
  baseURL?: string;
150
+ /** Allow a cleartext `http://` base URL on a network you trust (a REST proxy). Default false. */
151
+ allowInsecureBaseURL?: boolean;
110
152
  hooks?: RESTHooks;
111
153
  store?: RateLimitStore;
112
154
  /** Replaces the HTTP stage, e.g. with a recording transport in tests. */
@@ -115,9 +157,48 @@ export declare class REST {
115
157
  * Lets requests on a bucket whose limit is known run concurrently, up
116
158
  * to its `remaining` allowance, instead of one at a time. Requires a
117
159
  * store with `reserve`. Requests on one bucket may then complete out
118
- * of order (e.g. messages to one channel). Defaults to `false`.
160
+ * of order (e.g. messages to one channel). Defaults to `true`.
119
161
  */
120
162
  concurrentBuckets?: boolean;
163
+ /**
164
+ * The longest, in ms, that a rate-limit header from the server may
165
+ * make this client wait. A `Retry-After` beyond it fails the request
166
+ * with the 429 instead of sleeping, and stored limits are capped to it,
167
+ * so a proxy or an attacker cannot stall every request for hours.
168
+ * Default 600,000 (ten minutes).
169
+ */
170
+ maxBackoff?: number;
171
+ /**
172
+ * Receives telemetry events (latency, 429s by scope, waits,
173
+ * reservations, retries, cancellations, queue depth). See
174
+ * `RESTMetrics` for a ready-made aggregator.
175
+ */
176
+ telemetry?: RESTTelemetry;
177
+ /** Most requests waiting for a bucket slot; more fail with kind `"overloaded"`. Default unlimited. */
178
+ maxQueued?: number;
179
+ /** Most requests waiting on one bucket; more fail with kind `"overloaded"`. Default unlimited. */
180
+ maxQueuedPerBucket?: number;
181
+ /**
182
+ * Requests per second this bot may send across all buckets,
183
+ * enforced before Discord answers with a global 429 (shared through
184
+ * the store, so it holds for every process). Default 50, Discord's
185
+ * global limit; set what Discord granted a large bot, or `false`
186
+ * to rely on 429s alone.
187
+ */
188
+ globalLimit?: number | false;
189
+ /**
190
+ * After a `401` on a bot route, refuse every later request with
191
+ * this token without sending it, until `setToken()`: repeated 401s
192
+ * count towards Discord's invalid-request ban. Default `true`.
193
+ */
194
+ stopOnInvalidToken?: boolean;
195
+ /**
196
+ * Longest, in ms, a request may wait before it is sent (queue,
197
+ * rate limits, pauses between retries); past it the request fails
198
+ * with kind `"overloaded"`. Default unlimited. Per request:
199
+ * `maxQueueWait` in the request options.
200
+ */
201
+ maxQueueWait?: number;
121
202
  });
122
203
  /** The rate-limit store backing this transport. */
123
204
  get store(): RateLimitStore;
@@ -125,6 +206,14 @@ export declare class REST {
125
206
  setHooks(hooks: RESTHooks): this;
126
207
  /** Sets the authentication token. @param token Discord bot token. @returns Nothing. @throws {TypeError} If token is empty. */
127
208
  setToken(token: string): void;
209
+ /** The client's current state. */
210
+ diagnostics(): RESTDiagnostics;
211
+ /**
212
+ * Stops the client: new requests are refused, requests still queued or
213
+ * waiting for a limit fail with kind `"aborted"`, and attempts already
214
+ * sent are allowed to finish. Resolves when nothing is in flight.
215
+ */
216
+ close(): Promise<void>;
128
217
  /** Executes an HTTP request with Discord bucket/global rate limits, retry handling, and AbortSignal support.
129
218
  * Accepts a JSON body, a FormData body (for file uploads), or undefined.
130
219
  * @param method HTTP method.
@@ -135,6 +224,7 @@ export declare class REST {
135
224
  * @returns Decoded response body.
136
225
  * @throws {RESTError} If Discord or transport rejects the request.
137
226
  */
227
+ request<T>(options: RequestOptionsObject): Promise<T>;
138
228
  request<T>(method: string, path: string, body?: unknown, options?: RequestData): Promise<T>;
139
229
  /** Sends a GET request. @param path API path. @param options Request options (`query`, `headers`, `signal`, …). @returns Decoded response. @throws {RESTError} When the request fails. */
140
230
  get<T>(path: string, options?: RequestData): Promise<T>;
@@ -175,12 +265,15 @@ export { Routes } from "./routes.js";
175
265
  export { RESTError, abortError, redactPath, type RESTErrorKind, } from "./errors.js";
176
266
  export { RESTErrorCode } from "./error-codes.js";
177
267
  export { createRouteKey, normalizeRoutePath, majorParameter, scopeBucket, serializeQuery, type RouteKey, type RESTQuery, } from "./route.js";
178
- export { RequestScheduler } from "./scheduler.js";
179
- export { RateLimiter } from "./limiter.js";
268
+ export { RequestScheduler, type SchedulerOptions } from "./scheduler.js";
269
+ export { RateLimiter, DEFAULT_MAX_BACKOFF_MS, type Grant, type ApplyResponseOptions, } from "./limiter.js";
270
+ export { parseRateLimitHeaders, headerNumber, type RateLimitHeaders, type RateLimitScope, } from "./headers.js";
271
+ export { requestIdentity, tokenFingerprint, type RequestIdentity, } from "./identity.js";
272
+ export { RESTMetrics, type RESTMetricsSnapshot, type RESTTelemetry, type RESTTelemetryEvent, type CoordinationMode, } from "./telemetry.js";
180
273
  export { HttpTransport, TransportError, type TransportRequest, type FetchLike, } from "./transport.js";
181
274
  export { ResponseDecoder, type DecodedError } from "./decoder.js";
182
- export { type RateLimitStore, type BucketState, type Reservation, MemoryRateLimitStore, } from "./store.js";
183
- export { RedisRateLimitStore, type RedisRateLimitStoreOptions, type MinimalRedisClient, } from "./redis.js";
275
+ export { type RateLimitStore, type BucketState, type BucketUpdate, type Reservation, type ReserveOptions, MemoryRateLimitStore, } from "./store.js";
276
+ export { RedisRateLimitStore, fromBunRedis, type RedisRateLimitStoreOptions, type RedisFailurePolicy, type RedisStoreDiagnostics, type MinimalRedisClient, } from "./redis.js";
184
277
  export { WebhookClient, type WebhookClientOptions, type WebhookMessageOptions, } from "./webhook.js";
185
278
  /**
186
279
  * Discord.js-familiar alias for {@link RESTError}. `@discordjs/rest` throws `DiscordAPIError`