lunibee 0.3.3 → 0.4.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.
Files changed (125) hide show
  1. package/README.md +1 -1
  2. package/dist/builders/commands.d.ts +1 -1
  3. package/dist/builders/components.d.ts +9 -11
  4. package/dist/builders/embed.d.ts +1 -1
  5. package/dist/builders/index.d.ts +1 -1
  6. package/dist/builders/index.js +87 -1298
  7. package/dist/builders/index.js.map +3 -11
  8. package/dist/chunks/index-0wn81eng.js +2492 -0
  9. package/dist/chunks/index-0wn81eng.js.map +17 -0
  10. package/dist/chunks/index-2en489j6.js +40 -0
  11. package/dist/chunks/index-2en489j6.js.map +10 -0
  12. package/dist/chunks/index-3hyps48a.js +203 -0
  13. package/dist/chunks/index-3hyps48a.js.map +11 -0
  14. package/dist/chunks/index-57c5n3ms.js +2274 -0
  15. package/dist/chunks/index-57c5n3ms.js.map +19 -0
  16. package/dist/chunks/index-5yx92e36.js +1170 -0
  17. package/dist/chunks/index-5yx92e36.js.map +14 -0
  18. package/dist/chunks/index-690bp093.js +95 -0
  19. package/dist/chunks/index-690bp093.js.map +10 -0
  20. package/dist/chunks/index-7fp2hvmg.js +2155 -0
  21. package/dist/chunks/index-7fp2hvmg.js.map +24 -0
  22. package/dist/chunks/index-cnmsajvk.js +1119 -0
  23. package/dist/chunks/index-cnmsajvk.js.map +12 -0
  24. package/dist/chunks/index-fdvgk2sw.js +1310 -0
  25. package/dist/chunks/index-fdvgk2sw.js.map +21 -0
  26. package/dist/chunks/index-gyvps8b9.js +214 -0
  27. package/dist/chunks/index-gyvps8b9.js.map +12 -0
  28. package/dist/chunks/index-jzg4bh99.js +1533 -0
  29. package/dist/chunks/index-jzg4bh99.js.map +21 -0
  30. package/dist/chunks/index-mgw2yvrm.js +3547 -0
  31. package/dist/chunks/index-mgw2yvrm.js.map +25 -0
  32. package/dist/chunks/index-yh76b55h.js +3449 -0
  33. package/dist/chunks/index-yh76b55h.js.map +29 -0
  34. package/dist/collection/index.js +9 -1118
  35. package/dist/collection/index.js.map +3 -6
  36. package/dist/core/api.d.ts +3 -3
  37. package/dist/core/channel-create.d.ts +2 -2
  38. package/dist/core/commands.d.ts +3 -3
  39. package/dist/core/events.d.ts +4 -4
  40. package/dist/core/handles.d.ts +4 -4
  41. package/dist/core/index.d.ts +25 -20
  42. package/dist/core/index.js +68 -10130
  43. package/dist/core/index.js.map +3 -65
  44. package/dist/core/permissions.d.ts +1 -1
  45. package/dist/core/redis-cache.d.ts +1 -1
  46. package/dist/formatters/index.js +41 -110
  47. package/dist/formatters/index.js.map +3 -4
  48. package/dist/handlers/index.js +5 -37
  49. package/dist/handlers/index.js.map +3 -4
  50. package/dist/index.d.ts +21 -21
  51. package/dist/index.js +641 -16325
  52. package/dist/index.js.map +3 -92
  53. package/dist/managers/advanced.d.ts +3 -3
  54. package/dist/managers/application.d.ts +2 -2
  55. package/dist/managers/base.d.ts +1 -1
  56. package/dist/managers/emoji.d.ts +2 -2
  57. package/dist/managers/guild-resources.d.ts +6 -6
  58. package/dist/managers/guild.d.ts +3 -3
  59. package/dist/managers/index.d.ts +4 -8
  60. package/dist/managers/index.js +51 -4060
  61. package/dist/managers/index.js.map +3 -29
  62. package/dist/managers/member.d.ts +2 -2
  63. package/dist/managers/message.d.ts +14 -6
  64. package/dist/managers/role.d.ts +2 -2
  65. package/dist/managers/thread.d.ts +3 -3
  66. package/dist/managers/user.d.ts +7 -4
  67. package/dist/rest/index.d.ts +10 -35
  68. package/dist/rest/index.js +57 -2184
  69. package/dist/rest/index.js.map +3 -18
  70. package/dist/rest/limiter.d.ts +9 -1
  71. package/dist/rest/webhook.d.ts +2 -8
  72. package/dist/sharding/bus.d.ts +2 -2
  73. package/dist/sharding/cluster.d.ts +45 -5
  74. package/dist/sharding/context.d.ts +45 -3
  75. package/dist/sharding/gateway-bot.d.ts +2 -1
  76. package/dist/sharding/health.d.ts +1 -1
  77. package/dist/sharding/identify.d.ts +12 -0
  78. package/dist/sharding/index.d.ts +44 -11
  79. package/dist/sharding/index.js +60 -4620
  80. package/dist/sharding/index.js.map +3 -33
  81. package/dist/sharding/supervisor.d.ts +4 -2
  82. package/dist/structures/audit-log.d.ts +1 -1
  83. package/dist/structures/base.d.ts +6 -6
  84. package/dist/structures/channels.d.ts +1 -1
  85. package/dist/structures/embed.d.ts +1 -1
  86. package/dist/structures/index.d.ts +14 -14
  87. package/dist/structures/index.js +109 -2382
  88. package/dist/structures/index.js.map +3 -16
  89. package/dist/structures/interactions.d.ts +13 -9
  90. package/dist/structures/options.d.ts +1 -1
  91. package/dist/structures/permissions.d.ts +2 -2
  92. package/dist/structures/resources.d.ts +10 -10
  93. package/dist/structures/sticker.d.ts +1 -1
  94. package/dist/types/gateway.d.ts +2 -79
  95. package/dist/types/index.d.ts +0 -6
  96. package/dist/types/index.js +41 -272
  97. package/dist/types/index.js.map +3 -6
  98. package/dist/utils/index.js +23 -209
  99. package/dist/utils/index.js.map +3 -5
  100. package/dist/voice/connection.d.ts +200 -0
  101. package/dist/voice/crypto.d.ts +50 -0
  102. package/dist/voice/dave.d.ts +85 -0
  103. package/dist/voice/effects.d.ts +31 -0
  104. package/dist/voice/emitter.d.ts +14 -0
  105. package/dist/voice/gateway.d.ts +59 -0
  106. package/dist/voice/index.d.ts +25 -228
  107. package/dist/voice/index.js +111 -442
  108. package/dist/voice/index.js.map +3 -4
  109. package/dist/voice/libopus.d.ts +88 -0
  110. package/dist/voice/networking.d.ts +80 -0
  111. package/dist/voice/ogg.d.ts +24 -0
  112. package/dist/voice/opus.d.ts +18 -0
  113. package/dist/voice/player.d.ts +79 -0
  114. package/dist/voice/protocol.d.ts +76 -0
  115. package/dist/voice/receiver.d.ts +59 -0
  116. package/dist/voice/resource.d.ts +102 -0
  117. package/dist/voice/udp.d.ts +40 -0
  118. package/dist/ws/close-codes.d.ts +1 -1
  119. package/dist/ws/index.d.ts +25 -4
  120. package/dist/ws/index.js +47 -1336
  121. package/dist/ws/index.js.map +3 -17
  122. package/dist/ws/protocol.d.ts +1 -1
  123. package/dist/ws/send-budget.d.ts +0 -2
  124. package/dist/ws/state.d.ts +0 -10
  125. package/package.json +19 -16
@@ -10,6 +10,8 @@ export interface Grant {
10
10
  known: boolean;
11
11
  /** The window the unit came from (store clock), when the store reports it. */
12
12
  resetAt?: number;
13
+ /** The bucket key the unit came from, when `acquire` moved to another one (see `resolve`). */
14
+ key?: string;
13
15
  }
14
16
  /** Context for {@link RateLimiter.applyResponse} beyond the response itself. */
15
17
  export interface ApplyResponseOptions {
@@ -75,8 +77,14 @@ export declare class RateLimiter {
75
77
  * @throws {RESTError} `"aborted"` on cancellation, `"coordination"` on a
76
78
  * broken store, `"rateLimited"` when waiting would exceed `maxBackoff`.
77
79
  */
78
- acquire(bucketKey: string, signal: AbortSignal | undefined, path: string, options?: {
80
+ acquire(initialKey: string, signal: AbortSignal | undefined, path: string, options?: {
79
81
  global?: string;
82
+ /**
83
+ * Resolves the request's bucket key again. Called after waiting on
84
+ * another worker's probe: its response may have revealed the shared
85
+ * bucket, whose key differs from the route-derived one.
86
+ */
87
+ resolve?: () => Promise<string>;
80
88
  }): Promise<Grant>;
81
89
  /**
82
90
  * Extends the global limit (of `scope`), never shortening a longer one
@@ -1,12 +1,12 @@
1
1
  import { type RESTFileAttachment } from "./index.js";
2
- import type { AllowedMentions, APIEmbed, APIMessage, APIMessageComponent } from "@lunibee/types";
2
+ import type { AllowedMentions, APIEmbed, APIMessage, APIMessageComponent } from "../types/index.js";
3
3
  /** Where a `WebhookClient` sends: a Discord webhook `url`, or its `id` and `token`. */
4
4
  export interface WebhookClientOptions {
5
5
  id?: string;
6
6
  token?: string;
7
7
  url?: string;
8
8
  }
9
- /** A webhook message for `send()` and `editMessage()`; camelCase aliases (`avatarURL`, `threadId`, `allowedMentions`) are accepted beside the wire names. */
9
+ /** A webhook message for `send()` and `editMessage()`, in Discord's wire names. */
10
10
  export interface WebhookMessageOptions {
11
11
  content?: string;
12
12
  username?: string;
@@ -22,12 +22,6 @@ export interface WebhookMessageOptions {
22
22
  files?: RESTFileAttachment[];
23
23
  flags?: number;
24
24
  thread_id?: string;
25
- /** Discord.js-familiar alias of `avatar_url`. */
26
- avatarURL?: string;
27
- /** Discord.js-familiar alias of `thread_id`. */
28
- threadId?: string;
29
- /** Discord.js-familiar alias of `allowed_mentions`. */
30
- allowedMentions?: AllowedMentions;
31
25
  allowed_mentions?: AllowedMentions;
32
26
  }
33
27
  /** Standalone client for sending Discord webhooks. */
@@ -66,8 +66,8 @@ export declare class ShardBus {
66
66
  broadcast<T>(type: string, data: T): string;
67
67
  /**
68
68
  * Registers a handler that answers requests of `type`. Its return value (or
69
- * thrown error) is sent back to the requesting shard. Discord.js-familiar
70
- * replacement for `broadcastEval` that never evaluates received code.
69
+ * thrown error) is sent back to the requesting shard. Received code is
70
+ * never evaluated.
71
71
  * @returns This bus.
72
72
  */
73
73
  respond<T, R>(type: string, handler: (data: T, message: ShardMessage<T>) => R | Promise<R>): this;
@@ -1,9 +1,28 @@
1
1
  import { type ChildProcess } from "node:child_process";
2
2
  import { type ShardReply } from "./bus.js";
3
+ import { type ClusterCountSource } from "./context.js";
3
4
  import type { ClusterManagerHealth, ClusterState, WorkerReport } from "./health.js";
5
+ import { type IdentifyEvent } from "./identify.js";
4
6
  import type { LeaderLock } from "./leader.js";
5
7
  import { type HostStatus, type RemoteOptions } from "./remote.js";
6
8
  import { type SupervisorOptions } from "./supervisor.js";
9
+ /** What the `plan` event reports. */
10
+ export interface ClusterPlanInfo {
11
+ /** The deployment's shard count (Discord's `num_shards`), the same in every worker. */
12
+ totalShards: number;
13
+ clusterCount: number;
14
+ /** `"clusterCount"`, `"shardsPerCluster"` or `"default"` (the number of CPUs). */
15
+ clusterCountSource: ClusterCountSource;
16
+ /** The count asked for; larger than `clusterCount` when there were more clusters than shards. */
17
+ requestedClusterCount: number;
18
+ clusters: {
19
+ id: number;
20
+ shards: number[];
21
+ }[];
22
+ maxConcurrency: number;
23
+ startup: "safe" | "sequential";
24
+ identifyCoordinated: boolean;
25
+ }
7
26
  /** Configuration for managing multiple shard clusters. */
8
27
  export interface ClusterManagerOptions {
9
28
  /** Discord bot token. */
@@ -13,11 +32,12 @@ export interface ClusterManagerOptions {
13
32
  /** Total number of shards. Use "auto" to request Discord's recommended count. */
14
33
  shardCount?: number | "auto";
15
34
  /**
16
- * With `shardCount: "auto"`, size the deployment by guilds instead of
17
- * Discord's recommendation: `ceil(guilds / guildsPerShard)` shards, at
18
- * least one. 1 to 2500 (Discord's limit); Discord recommends about 1000.
19
- * Guilds are assigned to shards by their ID, so this sets the average,
20
- * not an exact split.
35
+ * A sizing hint for `shardCount: "auto"`: run at least
36
+ * `ceil(guildCount / guildsPerShard)` shards, and never fewer than Discord
37
+ * recommends. 1 to 2500 (Discord's limit); Discord recommends about 1000.
38
+ * It only picks the shard count: Discord puts each guild on shard
39
+ * `(guild_id >> 22) % shardCount`, so shards get about this many guilds,
40
+ * not exactly, and ownership never follows from it.
21
41
  */
22
42
  guildsPerShard?: number;
23
43
  /** The bot's guild count for `guildsPerShard`, instead of asking Discord for it. */
@@ -39,6 +59,17 @@ export interface ClusterManagerOptions {
39
59
  maxConcurrency?: number;
40
60
  /** Ask `/gateway/bot` for `max_concurrency` and the session budget even with a fixed `shardCount`. */
41
61
  fetchLimits?: boolean;
62
+ /**
63
+ * How shards start across the whole deployment.
64
+ * - `"safe"` (default): as fast as Discord allows. One IDENTIFY per
65
+ * rate-limit key (`shard_id % max_concurrency`) every `identify.interval`,
66
+ * keys in parallel; a slot is freed as soon as the IDENTIFY is sent.
67
+ * - `"sequential"`: one shard at a time across all clusters, in the order
68
+ * they ask (cluster by cluster, as they spawn). Each slot is held until that shard is READY (or
69
+ * `identify.holdTimeout` passes; workers wait that long for READY), then the next shard waits the interval.
70
+ * Slow, for debugging and small bots. Needs IDENTIFY coordination.
71
+ */
72
+ startup?: "safe" | "sequential";
42
73
  /** IDENTIFY coordination across clusters. On by default. */
43
74
  identify?: {
44
75
  /** Set `false` to let every cluster pace its own IDENTIFYs. */
@@ -210,6 +241,15 @@ export interface ClusterManagerEvents {
210
241
  shardId: number;
211
242
  waitMs: number;
212
243
  }];
244
+ /** The allocation of a start: total shards, the cluster count and where it came from, each cluster's shards. */
245
+ plan: [plan: ClusterPlanInfo];
246
+ /** The IDENTIFY queue: a shard asked for a slot, got it, or gave it back. */
247
+ identify: [event: IdentifyEvent];
248
+ /** `shutdownAll()` finished: every cluster process has exited (or was killed after the timeout). */
249
+ shutdown: [info: {
250
+ clusters: number;
251
+ durationMs: number;
252
+ }];
213
253
  /** Something went wrong that did not stop the deployment (a bad frame, a failed recovery). */
214
254
  error: [error: Error];
215
255
  }
@@ -13,6 +13,14 @@ export interface ClusterContext {
13
13
  shardIds: number[];
14
14
  /** Whether the parent hands out IDENTIFY slots for this cluster. */
15
15
  coordinatedIdentify: boolean;
16
+ /**
17
+ * `"sequential"`: hold each IDENTIFY slot until the shard is READY, so the
18
+ * deployment starts one shard at a time. `"safe"` (default): release it once
19
+ * the IDENTIFY is sent.
20
+ */
21
+ startup?: "safe" | "sequential";
22
+ /** Sequential startup: ms a shard may take to become READY (`LUNIBEE_READY_TIMEOUT`, the parent's `identify.holdTimeout`). */
23
+ readyTimeout?: number;
16
24
  }
17
25
  /** Set to `1` in every process `ClusterManager` forks, so a worker can tell it is one. */
18
26
  export declare const WORKER_MARKER = "LUNIBEE_CLUSTER_WORKER";
@@ -21,12 +29,46 @@ export declare function isClusterWorker(env?: Record<string, string | undefined>
21
29
  /** Checks that shard IDs are unique integers in `[0, total)`. @throws {RangeError} Otherwise. */
22
30
  export declare function validateShardIds(shardIds: readonly number[], total: number): void;
23
31
  /**
24
- * Splits shard IDs across clusters round-robin: the i-th ID goes to cluster
25
- * `i % clusterCount`. The same input always gives the same output.
26
- * @returns One list per cluster (some may be empty when there are more clusters than shards).
32
+ * Splits shard IDs across clusters in contiguous blocks, in order. When they do
33
+ * not divide evenly the first clusters get one more: 10 shards over 3 clusters
34
+ * are `[0-3] [4-6] [7-9]`. The same input always gives the same output.
35
+ * @returns One list per cluster (empty ones at the end when there are more clusters than shards).
27
36
  * @throws {RangeError} If `clusterCount` is not a positive integer.
28
37
  */
29
38
  export declare function allocateShards(shardIds: readonly number[], clusterCount: number): number[][];
39
+ /** How {@link planClusters} chose the cluster count. */
40
+ export type ClusterCountSource = "clusterCount" | "shardsPerCluster" | "default";
41
+ /** Options for {@link planClusters}; set `clusterCount` or `shardsPerCluster`, not both. */
42
+ export interface ClusterPlanOptions {
43
+ /** The deployment's shards, in order. */
44
+ shardIds: readonly number[];
45
+ /** Split the shards over this many clusters (Mode A). */
46
+ clusterCount?: number;
47
+ /** Fill clusters with this many shards each; the last may have fewer (Mode B). */
48
+ shardsPerCluster?: number;
49
+ /** Cluster count when neither is set (Mode C), e.g. the number of CPUs. */
50
+ defaultClusterCount: number;
51
+ }
52
+ /** The result of {@link planClusters}. */
53
+ export interface ClusterPlan {
54
+ /** Shards of each cluster, by cluster ID. Never empty: there are at most as many clusters as shards. */
55
+ clusters: number[][];
56
+ /** Where the cluster count came from. */
57
+ source: ClusterCountSource;
58
+ /** The count asked for, before capping at the number of shards. */
59
+ requested: number;
60
+ }
61
+ /**
62
+ * Decides which cluster runs which shard, without starting anything:
63
+ * - `clusterCount`: every shard, split in contiguous blocks over that many clusters;
64
+ * - `shardsPerCluster`: `ceil(shards / shardsPerCluster)` clusters of that size, the last one partial;
65
+ * - neither: `defaultClusterCount` clusters.
66
+ *
67
+ * There are never more clusters than shards: a larger count is capped (an
68
+ * empty cluster would hold a process for nothing). Every shard is in exactly one cluster.
69
+ * @throws {RangeError} For both options at once, or a count that is not a positive integer.
70
+ */
71
+ export declare function planClusters(options: ClusterPlanOptions): ClusterPlan;
30
72
  /**
31
73
  * Proves an allocation covers `expected` exactly once.
32
74
  * @throws {Error} Naming the missing, duplicate or unexpected shard IDs.
@@ -30,7 +30,8 @@ export declare function fetchGuildCount(token: string): Promise<number>;
30
30
  /**
31
31
  * The shard count to use for `"auto"`: Discord's recommendation, or, with
32
32
  * `guildsPerShard`, enough shards for the bot's guild count (`guildCount`, or
33
- * what Discord reports).
33
+ * what Discord reports), but never fewer than the recommendation: a stale or
34
+ * low guild count must not leave shards over Discord's 2,500-guild limit.
34
35
  */
35
36
  export declare function resolveShardCount(token: string, info: GatewayBotInfo, options: {
36
37
  guildsPerShard?: number;
@@ -1,4 +1,4 @@
1
- import type { Gateway } from "@lunibee/ws";
1
+ import type { Gateway } from "../ws/index.js";
2
2
  /** Where a shard is in its life, apart from the state of its Gateway socket. */
3
3
  export type ShardStatus =
4
4
  /** Created, never connected. */
@@ -29,6 +29,18 @@ export interface IdentifyCoordinatorOptions {
29
29
  shardId: number;
30
30
  waitMs: number;
31
31
  }) => void;
32
+ /** Called for every queue change, for logs and metrics. */
33
+ onEvent?: (event: IdentifyEvent) => void;
34
+ }
35
+ /** One change in the IDENTIFY queue. `bucket` is the rate-limit key, `shardId % maxConcurrency`. */
36
+ export interface IdentifyEvent {
37
+ type: "queued" | "granted" | "released" | "expired" | "dropped";
38
+ /** The cluster that asked. */
39
+ owner: number;
40
+ shardId: number;
41
+ bucket: number;
42
+ /** `granted`: how long the request waited. */
43
+ waitedMs?: number;
32
44
  }
33
45
  /**
34
46
  * Hands out IDENTIFY slots for a whole deployment. Every cluster asks the
@@ -1,5 +1,5 @@
1
1
  import { type GatewayBotInfo } from "./gateway-bot.js";
2
- import { Gateway } from "@lunibee/ws";
2
+ import { Gateway } from "../ws/index.js";
3
3
  import { type ClusterContext } from "./context.js";
4
4
  import type { ShardHealth, WorkerReport } from "./health.js";
5
5
  import { ClusterWorker, type IdentifyGate } from "./worker.js";
@@ -9,17 +9,38 @@ export { BroadcastChannelTransport, IpcTransport, type IpcEndpoint, type ShardBu
9
9
  export { ShardSupervisor, type SupervisorOptions } from "./supervisor.js";
10
10
  export type { ShardBusErrorHandler, ShardBusOptions, ShardMessage, ShardMessageHandler, ShardReply, } from "./bus.js";
11
11
  export { ClusterManager } from "./cluster.js";
12
- export type { ClusterManagerOptions, ClusterManagerEvents, ClusterInfo, BroadcastResult, RequestOptions, } from "./cluster.js";
13
- export { allocateShards, assertCompleteAllocation, isClusterWorker, readClusterContext, validateShardIds, type ClusterContext, } from "./context.js";
12
+ export type { ClusterManagerOptions, ClusterManagerEvents, ClusterInfo, BroadcastResult, RequestOptions, ClusterPlanInfo, } from "./cluster.js";
13
+ export { allocateShards, planClusters, type ClusterPlan, type ClusterPlanOptions, type ClusterCountSource, assertCompleteAllocation, isClusterWorker, readClusterContext, validateShardIds, type ClusterContext, } from "./context.js";
14
14
  export { ClusterWorker, type IdentifyGate } from "./worker.js";
15
15
  export { threadEndpoint, threadFork, type ThreadEndpoint, type ThreadForkOptions, } from "./thread.js";
16
16
  export { ClusterHost, type ClusterHostEvents, type ClusterHostOptions, } from "./host.js";
17
17
  export type { HostStatus, RemoteOptions } from "./remote.js";
18
18
  export { RedisLeaderLock, type LeaderLock, type LeaderRedisClient, type RedisLeaderLockOptions, } from "./leader.js";
19
19
  export { RemoteClose, REMOTE_PROTOCOL_VERSION } from "./remote-protocol.js";
20
- export { IdentifyCoordinator, IDENTIFY_INTERVAL, type IdentifyBudget, type IdentifyCoordinatorOptions, } from "./identify.js";
20
+ export { IdentifyCoordinator, IDENTIFY_INTERVAL, type IdentifyBudget, type IdentifyCoordinatorOptions, type IdentifyEvent, } from "./identify.js";
21
21
  export { RequestTracker } from "./requests.js";
22
22
  export type { ClusterHealth, ClusterManagerHealth, ClusterState, ShardHealth, ShardStatus, WorkerMetrics, WorkerReport, } from "./health.js";
23
+ /** How long sequential startup waits for a shard's READY before moving on, by default. */
24
+ export declare const SEQUENTIAL_READY_TIMEOUT = 60000;
25
+ /** An IDENTIFY slot source: a cluster worker's `identifyGate`. */
26
+ export interface IdentifySlotGate {
27
+ acquire(shardId: number): Promise<void>;
28
+ release(shardId: number): void;
29
+ }
30
+ /**
31
+ * Connects one shard inside the IDENTIFY queue: takes a slot, connects, and
32
+ * gives the slot back once the IDENTIFY is sent, or, with `waitForReady`
33
+ * (sequential startup), once the shard is READY. The slot is always released,
34
+ * also when connecting fails.
35
+ * @returns Whether the shard became READY in time (`true` without `waitForReady`).
36
+ */
37
+ export declare function connectInQueue(gateway: Gateway, shardId: number, gate: IdentifySlotGate, options?: {
38
+ handshakeTimeout?: number;
39
+ waitForReady?: boolean;
40
+ readyTimeout?: number;
41
+ /** Checked after the slot is granted: true skips connecting (a stale start). */
42
+ cancelled?: () => boolean;
43
+ }): Promise<boolean>;
23
44
  /** Configuration for a sharded Gateway client. */
24
45
  export interface ShardManagerOptions {
25
46
  /** Bot token. */
@@ -29,11 +50,12 @@ export interface ShardManagerOptions {
29
50
  /** Number of shards. Use `"auto"` to request Discord's recommended count. */
30
51
  shardCount?: number | "auto";
31
52
  /**
32
- * With `shardCount: "auto"`, size the deployment by guilds instead of
33
- * Discord's recommendation: `ceil(guilds / guildsPerShard)` shards, at
34
- * least one. 1 to 2500 (Discord's limit); Discord recommends about 1000.
35
- * Guilds are assigned to shards by their ID, so this sets the average,
36
- * not an exact split.
53
+ * A sizing hint for `shardCount: "auto"`: run at least
54
+ * `ceil(guildCount / guildsPerShard)` shards, and never fewer than Discord
55
+ * recommends. 1 to 2500 (Discord's limit); Discord recommends about 1000.
56
+ * It only picks the shard count: Discord puts each guild on shard
57
+ * `(guild_id >> 22) % shardCount`, so shards get about this many guilds,
58
+ * not exactly, and ownership never follows from it.
37
59
  */
38
60
  guildsPerShard?: number;
39
61
  /** The bot's guild count for `guildsPerShard`, instead of asking Discord for it. */
@@ -54,6 +76,19 @@ export interface ShardManagerOptions {
54
76
  * How long a startup round waits for its shards to send IDENTIFY/RESUME
55
77
  * before the next round's `spawnDelay` starts. Defaults to 15000 ms.
56
78
  */ handshakeTimeout?: number;
79
+ /**
80
+ * `"safe"` (default): start shards as fast as Discord's IDENTIFY limits
81
+ * allow. `"sequential"`: one shard at a time, each waiting for the previous
82
+ * one's READY (up to `readyTimeout`) and then `spawnDelay`. In a cluster
83
+ * worker this follows the `ClusterManager`'s `startup` option.
84
+ */
85
+ startup?: "safe" | "sequential";
86
+ /**
87
+ * Sequential startup: how long a shard may take to become READY before the
88
+ * next one starts (a `shardError` reports it), in ms. Default 60000; in a
89
+ * cluster worker, the parent's `identify.holdTimeout`.
90
+ */
91
+ readyTimeout?: number;
57
92
  /** Interval in milliseconds to automatically check for recommended shard count and re-scale if needed. Must be an integer >= 1000. */
58
93
  autoScaleInterval?: number;
59
94
  /** Optional handler invoked when a background auto-scale check fails. Receives the thrown error. */
@@ -166,5 +201,3 @@ export declare class ShardManager {
166
201
  /** Returns information for all managed shards. @returns Shard information snapshots. */
167
202
  values(): ShardInfo[];
168
203
  }
169
- /** Discord.js-familiar alias for {@link ShardManager}. */
170
- export { ShardManager as ShardingManager };