seyfert 1.0.0 → 1.0.1

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/lib/api/api.d.ts CHANGED
@@ -4,12 +4,17 @@ import type { ProxyRequestMethod } from './Router';
4
4
  import { Bucket } from './bucket';
5
5
  import { type ApiHandlerInternalOptions, type ApiHandlerOptions, type ApiRequestOptions, type HttpMethods, type RawFile, type RequestHeaders } from './shared';
6
6
  export declare class ApiHandler {
7
+ #private;
7
8
  options: ApiHandlerInternalOptions;
8
9
  globalBlock: boolean;
9
10
  ratelimits: Map<string, Bucket>;
10
11
  readyQueue: (() => void)[];
11
12
  cdn: CDN;
12
13
  debugger?: Logger;
14
+ workerPromises?: Map<string, {
15
+ resolve: (value: any) => any;
16
+ reject: (error: any) => any;
17
+ }>;
13
18
  constructor(options: ApiHandlerOptions);
14
19
  globalUnblock(): void;
15
20
  request<T = any>(method: HttpMethods, url: `/${string}`, { auth, ...request }?: ApiRequestOptions): Promise<T>;
package/lib/api/api.js CHANGED
@@ -2,7 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ApiHandler = void 0;
4
4
  const magic_bytes_js_1 = require("magic-bytes.js");
5
+ const node_crypto_1 = require("node:crypto");
5
6
  const promises_1 = require("node:timers/promises");
7
+ const node_worker_threads_1 = require("node:worker_threads");
6
8
  const common_1 = require("../common");
7
9
  const functions_1 = require("../structures/extra/functions");
8
10
  const CDN_1 = require("./CDN");
@@ -16,8 +18,11 @@ class ApiHandler {
16
18
  readyQueue = [];
17
19
  cdn = new CDN_1.CDN();
18
20
  debugger;
21
+ workerPromises;
19
22
  constructor(options) {
20
23
  this.options = {
24
+ baseUrl: 'api/v10',
25
+ domain: 'https://discord.com',
21
26
  ...options,
22
27
  userAgent: shared_1.DefaultUserAgent,
23
28
  };
@@ -26,6 +31,10 @@ class ApiHandler {
26
31
  name: '[API]',
27
32
  });
28
33
  }
34
+ if (options.workerProxy && !node_worker_threads_1.parentPort)
35
+ throw new Error('Cannot use workerProxy without a parent.');
36
+ if (options.workerProxy)
37
+ this.workerPromises = new Map();
29
38
  }
30
39
  globalUnblock() {
31
40
  this.globalBlock = false;
@@ -34,7 +43,34 @@ class ApiHandler {
34
43
  cb();
35
44
  }
36
45
  }
46
+ #randomUUID() {
47
+ const uuid = (0, node_crypto_1.randomUUID)();
48
+ if (this.workerPromises.has(uuid))
49
+ return this.#randomUUID();
50
+ return uuid;
51
+ }
37
52
  async request(method, url, { auth = true, ...request } = {}) {
53
+ if (this.options.workerProxy) {
54
+ const nonce = this.#randomUUID();
55
+ node_worker_threads_1.parentPort.postMessage({
56
+ method,
57
+ url,
58
+ type: 'WORKER_API_REQUEST',
59
+ workerId: node_worker_threads_1.workerData.workerId,
60
+ nonce,
61
+ requestOptions: { auth, ...request },
62
+ }, request.files
63
+ ?.filter(x => !['string', 'boolean', 'number'].includes(typeof x.data))
64
+ .map(x => x.data));
65
+ let resolve = (_value) => { };
66
+ let reject = () => { };
67
+ const promise = new Promise((res, rej) => {
68
+ resolve = res;
69
+ reject = rej;
70
+ });
71
+ this.workerPromises.set(nonce, { reject, resolve });
72
+ return promise;
73
+ }
38
74
  const route = request.route || this.routefy(url, method);
39
75
  let attempts = 0;
40
76
  const callback = async (next, resolve, reject) => {
@@ -1,17 +1,19 @@
1
1
  /// <reference types="node" />
2
+ import type { MakeRequired } from '../common';
2
3
  export * from './api';
3
4
  export * from './utils/constants';
4
5
  export * from './utils/types';
5
6
  export { calculateUserDefaultAvatarIndex } from './utils/utils';
6
7
  export interface ApiHandlerOptions {
7
- baseUrl: string;
8
- domain: string;
8
+ baseUrl?: string;
9
+ domain?: string;
9
10
  token: string;
10
11
  debug?: boolean;
11
12
  agent?: string;
12
13
  smartBucket?: boolean;
14
+ workerProxy?: boolean;
13
15
  }
14
- export interface ApiHandlerInternalOptions extends ApiHandlerOptions {
16
+ export interface ApiHandlerInternalOptions extends MakeRequired<ApiHandlerOptions, 'baseUrl' | 'domain'> {
15
17
  userAgent: string;
16
18
  }
17
19
  export interface RawFile {
@@ -1,4 +1,4 @@
1
- import { type APIButtonComponent, type APIButtonComponentWithCustomId, type APIButtonComponentWithURL, type ButtonStyle, type EmojiResolvable, type When } from '../common';
1
+ import { type APIButtonComponentWithCustomId, type APIButtonComponentWithURL, type ButtonStyle, type EmojiResolvable, type When } from '../common';
2
2
  export type ButtonStylesForID = Exclude<ButtonStyle, ButtonStyle.Link>;
3
3
  /**
4
4
  * Represents a button component.
@@ -46,5 +46,5 @@ export declare class Button<Type extends boolean = boolean> {
46
46
  * Converts the Button instance to its JSON representation.
47
47
  * @returns The JSON representation of the Button instance.
48
48
  */
49
- toJSON(): APIButtonComponent;
49
+ toJSON(): When<Type, APIButtonComponentWithCustomId, APIButtonComponentWithURL>;
50
50
  }
@@ -1,5 +1,6 @@
1
1
  import type { Adapter } from './types';
2
2
  export declare class MemoryAdapter implements Adapter {
3
+ isAsync: boolean;
3
4
  readonly storage: Map<string, string>;
4
5
  readonly relationships: Map<string, string[]>;
5
6
  scan(query: string, keys?: false): any[];
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MemoryAdapter = void 0;
4
4
  class MemoryAdapter {
5
+ isAsync = false;
5
6
  storage = new Map();
6
7
  relationships = new Map();
7
8
  scan(query, keys = false) {
@@ -4,6 +4,7 @@ interface RedisAdapterOptions {
4
4
  namespace?: string;
5
5
  }
6
6
  export declare class RedisAdapter implements Adapter {
7
+ isAsync: boolean;
7
8
  client: import('ioredis').Redis;
8
9
  namespace: string;
9
10
  constructor(data: ({
@@ -9,6 +9,7 @@ catch {
9
9
  // potocuit > seyfert
10
10
  }
11
11
  class RedisAdapter {
12
+ isAsync = true;
12
13
  client;
13
14
  namespace;
14
15
  constructor(data) {
@@ -1,4 +1,5 @@
1
1
  export interface Adapter {
2
+ isAsync: boolean;
2
3
  scan(query: string, keys?: false): RPV<any[]>;
3
4
  scan(query: string, keys: true): RPV<string[]>;
4
5
  scan(query: string, keys?: boolean): RPV<(any | string)[]>;
@@ -9,6 +9,7 @@ import type { WorkerSendCacheRequest } from '../../websocket/discord/worker';
9
9
  import type { Adapter } from './types';
10
10
  export declare class WorkerAdapter implements Adapter {
11
11
  readonly parent: MessagePort;
12
+ isAsync: boolean;
12
13
  promises: Map<string, {
13
14
  resolve: (value: unknown) => void;
14
15
  timeout: NodeJS.Timeout;
@@ -5,6 +5,7 @@ const node_crypto_1 = require("node:crypto");
5
5
  const node_worker_threads_1 = require("node:worker_threads");
6
6
  class WorkerAdapter {
7
7
  parent;
8
+ isAsync = true;
8
9
  promises = new Map();
9
10
  constructor(parent) {
10
11
  this.parent = parent;
@@ -27,7 +27,6 @@ export type CachedEvents = 'READY' | 'GUILD_CREATE' | 'GUILD_UPDATE' | 'GUILD_DE
27
27
  export declare class Cache {
28
28
  intents: number;
29
29
  adapter: Adapter;
30
- asyncCache: boolean;
31
30
  readonly disabledCache: (NonGuildBased | GuildBased | GuildRelated)[];
32
31
  users?: Users;
33
32
  guilds?: Guilds;
@@ -41,7 +40,7 @@ export declare class Cache {
41
40
  presences?: Presences;
42
41
  voiceStates?: VoiceStates;
43
42
  stageInstances?: StageInstances;
44
- constructor(intents: number, adapter: Adapter, asyncCache?: boolean, disabledCache?: (NonGuildBased | GuildBased | GuildRelated)[], client?: BaseClient);
43
+ constructor(intents: number, adapter: Adapter, disabledCache?: (NonGuildBased | GuildBased | GuildRelated)[], client?: BaseClient);
45
44
  hasIntent(intent: keyof typeof GatewayIntentBits): boolean;
46
45
  get hasGuildsIntent(): boolean;
47
46
  get hasRolesIntent(): boolean;
@@ -32,7 +32,6 @@ __exportStar(require("./adapters/index"), exports);
32
32
  class Cache {
33
33
  intents;
34
34
  adapter;
35
- asyncCache;
36
35
  disabledCache;
37
36
  // non-guild based
38
37
  users;
@@ -49,10 +48,9 @@ class Cache {
49
48
  presences;
50
49
  voiceStates;
51
50
  stageInstances;
52
- constructor(intents, adapter, asyncCache = false, disabledCache = [], client) {
51
+ constructor(intents, adapter, disabledCache = [], client) {
53
52
  this.intents = intents;
54
53
  this.adapter = adapter;
55
- this.asyncCache = asyncCache;
56
54
  this.disabledCache = disabledCache;
57
55
  // non-guild based
58
56
  if (!this.disabledCache.includes('users')) {
@@ -266,7 +266,6 @@ export type ServicesOptions = {
266
266
  cache?: {
267
267
  adapter: Adapter;
268
268
  disabledCache?: Cache['disabledCache'];
269
- asyncCache?: boolean;
270
269
  };
271
270
  langs?: {
272
271
  default?: string;
@@ -66,7 +66,7 @@ class BaseClient {
66
66
  this.rest = rest;
67
67
  }
68
68
  if (cache) {
69
- this.cache = new cache_1.Cache(this.cache?.intents ?? 0, cache.adapter, cache.asyncCache ?? this.cache?.asyncCache, cache.disabledCache ?? this.cache?.disabledCache, this);
69
+ this.cache = new cache_1.Cache(this.cache?.intents ?? 0, cache.adapter, cache.disabledCache ?? this.cache?.disabledCache, this);
70
70
  }
71
71
  if (langs) {
72
72
  if (langs.default)
@@ -108,7 +108,7 @@ class BaseClient {
108
108
  });
109
109
  }
110
110
  if (!this.cache) {
111
- this.cache = new cache_1.Cache(0, new cache_1.MemoryAdapter(), false, [], this);
111
+ this.cache = new cache_1.Cache(0, new cache_1.MemoryAdapter(), [], this);
112
112
  }
113
113
  else {
114
114
  this.cache.__setClient(this);
@@ -1,5 +1,5 @@
1
1
  import type { Command, CommandContext, Message, SubCommand } from '..';
2
- import type { DeepPartial, GatewayDispatchPayload, GatewayPresenceUpdateData, If } from '../common';
2
+ import { type DeepPartial, type GatewayDispatchPayload, type GatewayPresenceUpdateData, type If } from '../common';
3
3
  import { EventHandler } from '../events';
4
4
  import { ClientUser } from '../structures';
5
5
  import { ShardManager, type ShardManagerOptions } from '../websocket';
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Client = void 0;
4
4
  const node_worker_threads_1 = require("node:worker_threads");
5
+ const common_1 = require("../common");
5
6
  const events_1 = require("../events");
6
7
  const structures_1 = require("../structures");
7
8
  const websocket_1 = require("../websocket");
@@ -11,7 +12,7 @@ const base_1 = require("./base");
11
12
  const oninteractioncreate_1 = require("./oninteractioncreate");
12
13
  const onmessagecreate_1 = require("./onmessagecreate");
13
14
  class Client extends base_1.BaseClient {
14
- __handleGuilds;
15
+ __handleGuilds = new Set();
15
16
  gateway;
16
17
  events = new events_1.EventHandler(this.logger);
17
18
  me;
@@ -21,7 +22,6 @@ class Client extends base_1.BaseClient {
21
22
  super(options);
22
23
  }
23
24
  setServices({ gateway, ...rest }) {
24
- this.__handleGuilds = new Set();
25
25
  super.setServices(rest);
26
26
  if (gateway) {
27
27
  const onPacket = this.onPacket.bind(this);
@@ -123,25 +123,23 @@ class Client extends base_1.BaseClient {
123
123
  this.botId = packet.d.user.id;
124
124
  this.applicationId = packet.d.application.id;
125
125
  this.me = new structures_1.ClientUser(this, packet.d.user, packet.d.application);
126
- if (!this.__handleGuilds?.size) {
127
- if ([...this.gateway.values()].every(shard => shard.data.session_id) &&
128
- this.events.values.BOT_READY &&
129
- (this.events.values.BOT_READY.fired ? !this.events.values.BOT_READY.data.once : true)) {
126
+ if (!this.__handleGuilds?.size ||
127
+ !((this.gateway.options.intents & common_1.GatewayIntentBits.Guilds) === common_1.GatewayIntentBits.Guilds)) {
128
+ if ([...this.gateway.values()].every(shard => shard.data.session_id)) {
130
129
  await this.events.runEvent('BOT_READY', this, this.me, -1);
131
- delete this.__handleGuilds;
132
130
  }
131
+ delete this.__handleGuilds;
133
132
  }
134
133
  this.debugger?.debug(`#${shardId}[${packet.d.user.username}](${this.botId}) is online...`);
135
134
  break;
136
135
  case 'GUILD_CREATE': {
137
136
  if (this.__handleGuilds?.has(packet.d.id)) {
138
137
  this.__handleGuilds.delete(packet.d.id);
139
- if (!this.__handleGuilds.size &&
140
- [...this.gateway.values()].every(shard => shard.data.session_id) &&
141
- this.events.values.BOT_READY &&
142
- (this.events.values.BOT_READY.fired ? !this.events.values.BOT_READY.data.once : true)) {
138
+ if (!this.__handleGuilds.size && [...this.gateway.values()].every(shard => shard.data.session_id)) {
143
139
  await this.events.runEvent('BOT_READY', this, this.me, -1);
144
140
  }
141
+ if (!this.__handleGuilds.size)
142
+ delete this.__handleGuilds;
145
143
  return;
146
144
  }
147
145
  break;
@@ -178,8 +178,8 @@ async function onInteractionCreate(self, body, shardId, __reply) {
178
178
  case v10_1.InteractionType.MessageComponent:
179
179
  {
180
180
  const interaction = structures_1.BaseInteraction.from(self, body, __reply);
181
- if (self.components.hasComponent([body.message.id, body.id], interaction.customId)) {
182
- await self.components.onComponent([body.message.id, body.id], interaction);
181
+ if (self.components.hasComponent(body.message.id, interaction.customId)) {
182
+ await self.components.onComponent(body.message.id, interaction);
183
183
  }
184
184
  else {
185
185
  await self.components.executeComponent(interaction);
@@ -1,3 +1,8 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ /// <reference types="node" />
5
+ /// <reference types="node" />
1
6
  import type { Cache } from '../cache';
2
7
  import type { GatewayDispatchPayload, When } from '../common';
3
8
  import { Logger, type DeepPartial } from '../common';
@@ -14,13 +19,21 @@ export declare class WorkerClient<Ready extends boolean = boolean> extends BaseC
14
19
  logger: Logger;
15
20
  events: EventHandler;
16
21
  me: When<Ready, ClientUser>;
22
+ promises: Map<string, {
23
+ resolve: (value: any) => void;
24
+ timeout: NodeJS.Timeout;
25
+ }>;
17
26
  shards: Map<number, Shard>;
18
27
  options: WorkerClientOptions | undefined;
19
28
  constructor(options?: WorkerClientOptions);
20
29
  get workerId(): number;
30
+ get latency(): number;
21
31
  start(options?: Omit<DeepPartial<StartOptions>, 'httpConnection' | 'token' | 'connection'>): Promise<void>;
22
32
  loadEvents(dir?: string): Promise<void>;
23
- protected handleManagerMessages(data: ManagerMessages): Promise<void>;
33
+ protected handleManagerMessages(data: ManagerMessages): Promise<any>;
34
+ private generateNonce;
35
+ private generateSendPromise;
36
+ tellWorker(workerId: number, func: (_: this) => {}): Promise<unknown>;
24
37
  protected onPacket(packet: GatewayDispatchPayload, shardId: number): Promise<void>;
25
38
  }
26
39
  export declare function generateShardInfo(shard: Shard): WorkerShardInfo;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateShardInfo = exports.WorkerClient = void 0;
4
+ const node_crypto_1 = require("node:crypto");
4
5
  const node_worker_threads_1 = require("node:worker_threads");
6
+ const __1 = require("..");
5
7
  const cache_1 = require("../cache");
6
8
  const common_1 = require("../common");
7
9
  const events_1 = require("../events");
@@ -12,16 +14,16 @@ const oninteractioncreate_1 = require("./oninteractioncreate");
12
14
  const onmessagecreate_1 = require("./onmessagecreate");
13
15
  const workerData = node_worker_threads_1.workerData;
14
16
  class WorkerClient extends base_1.BaseClient {
15
- __handleGuilds;
17
+ __handleGuilds = new Set();
16
18
  logger = new common_1.Logger({
17
19
  name: `[Worker #${workerData.workerId}]`,
18
20
  });
19
21
  events = new events_1.EventHandler(this.logger);
20
22
  me;
23
+ promises = new Map();
21
24
  shards = new Map();
22
25
  constructor(options) {
23
26
  super(options);
24
- this.__handleGuilds = new Set();
25
27
  if (!node_worker_threads_1.parentPort) {
26
28
  throw new Error('WorkerClient cannot spawn without manager');
27
29
  }
@@ -38,10 +40,24 @@ class WorkerClient extends base_1.BaseClient {
38
40
  logLevel: common_1.LogLevels.Debug,
39
41
  });
40
42
  }
43
+ if (workerData.workerProxy) {
44
+ this.setServices({
45
+ rest: new __1.ApiHandler({
46
+ token: workerData.token,
47
+ workerProxy: true,
48
+ debug: workerData.debug,
49
+ }),
50
+ });
51
+ }
41
52
  }
42
53
  get workerId() {
43
54
  return workerData.workerId;
44
55
  }
56
+ get latency() {
57
+ let acc = 0;
58
+ this.shards.forEach(s => (acc += s.latency));
59
+ return acc / this.shards.size;
60
+ }
45
61
  async start(options = {}) {
46
62
  await super.start(options);
47
63
  await this.loadEvents(options.eventsDir);
@@ -77,6 +93,7 @@ class WorkerClient extends base_1.BaseClient {
77
93
  node_worker_threads_1.parentPort.postMessage({
78
94
  type: 'RESULT_PAYLOAD',
79
95
  nonce: data.nonce,
96
+ workerId: this.workerId,
80
97
  });
81
98
  }
82
99
  break;
@@ -138,6 +155,7 @@ class WorkerClient extends base_1.BaseClient {
138
155
  ...generateShardInfo(shard),
139
156
  nonce: data.nonce,
140
157
  type: 'SHARD_INFO',
158
+ workerId: this.workerId,
141
159
  });
142
160
  }
143
161
  break;
@@ -152,13 +170,84 @@ class WorkerClient extends base_1.BaseClient {
152
170
  }
153
171
  break;
154
172
  case 'BOT_READY':
155
- if (this.events.values.BOT_READY &&
156
- (this.events.values.BOT_READY.fired ? !this.events.values.BOT_READY.data.once : true)) {
157
- await this.events.runEvent('BOT_READY', this, this.me, -1);
173
+ await this.events.runEvent('BOT_READY', this, this.me, -1);
174
+ break;
175
+ case 'API_RESPONSE':
176
+ {
177
+ const promise = this.rest.workerPromises.get(data.nonce);
178
+ if (!promise)
179
+ return;
180
+ this.rest.workerPromises.delete(data.nonce);
181
+ if (data.error)
182
+ return promise.reject(data.error);
183
+ promise.resolve(data.response);
184
+ }
185
+ break;
186
+ case 'EXECUTE_EVAL':
187
+ {
188
+ let result;
189
+ try {
190
+ // biome-ignore lint/security/noGlobalEval: yes
191
+ result = await eval(`
192
+ (${data.func})(this)
193
+ `);
194
+ }
195
+ catch (e) {
196
+ result = e;
197
+ }
198
+ node_worker_threads_1.parentPort.postMessage({
199
+ type: 'EVAL_RESPONSE',
200
+ response: result,
201
+ workerId: workerData.workerId,
202
+ nonce: data.nonce,
203
+ });
204
+ }
205
+ break;
206
+ case 'EVAL_RESPONSE':
207
+ {
208
+ const evalResponse = this.promises.get(data.nonce);
209
+ if (!evalResponse)
210
+ return;
211
+ this.promises.delete(data.nonce);
212
+ clearTimeout(evalResponse.timeout);
213
+ evalResponse.resolve(data.response);
158
214
  }
159
215
  break;
160
216
  }
161
217
  }
218
+ generateNonce(large = true) {
219
+ const uuid = (0, node_crypto_1.randomUUID)();
220
+ const nonce = large ? uuid : uuid.split('-')[0];
221
+ if (this.promises.has(nonce))
222
+ return this.generateNonce(large);
223
+ return nonce;
224
+ }
225
+ generateSendPromise(nonce, message = 'Timeout') {
226
+ let resolve = (_) => {
227
+ /**/
228
+ };
229
+ let timeout = -1;
230
+ const promise = new Promise((res, rej) => {
231
+ resolve = res;
232
+ timeout = setTimeout(() => {
233
+ this.promises.delete(nonce);
234
+ rej(new Error(message));
235
+ }, 60e3);
236
+ });
237
+ this.promises.set(nonce, { resolve, timeout });
238
+ return promise;
239
+ }
240
+ tellWorker(workerId, func) {
241
+ const nonce = this.generateNonce();
242
+ node_worker_threads_1.parentPort.postMessage({
243
+ type: 'EVAL',
244
+ func: func.toString(),
245
+ toWorkerId: workerId,
246
+ workerId: workerData.workerId,
247
+ nonce,
248
+ });
249
+ return this.generateSendPromise(nonce);
250
+ }
162
251
  async onPacket(packet, shardId) {
163
252
  await this.events.execute('RAW', packet, this, shardId);
164
253
  switch (packet.t) {
@@ -181,17 +270,16 @@ class WorkerClient extends base_1.BaseClient {
181
270
  this.botId = packet.d.user.id;
182
271
  this.applicationId = packet.d.application.id;
183
272
  this.me = new structures_1.ClientUser(this, packet.d.user, packet.d.application);
184
- if (!this.__handleGuilds?.size) {
185
- if ([...this.shards.values()].every(shard => shard.data.session_id) &&
186
- this.events.values.WORKER_READY &&
187
- (this.events.values.WORKER_READY.fired ? !this.events.values.WORKER_READY.data.once : true)) {
273
+ if (!this.__handleGuilds?.size ||
274
+ !((workerData.intents & common_1.GatewayIntentBits.Guilds) === common_1.GatewayIntentBits.Guilds)) {
275
+ if ([...this.shards.values()].every(shard => shard.data.session_id)) {
188
276
  node_worker_threads_1.parentPort.postMessage({
189
277
  type: 'WORKER_READY',
190
278
  workerId: this.workerId,
191
279
  });
192
280
  await this.events.runEvent('WORKER_READY', this, this.me, -1);
193
- delete this.__handleGuilds;
194
281
  }
282
+ delete this.__handleGuilds;
195
283
  }
196
284
  this.debugger?.debug(`#${shardId} [${packet.d.user.username}](${this.botId}) is online...`);
197
285
  break;
@@ -204,16 +292,15 @@ class WorkerClient extends base_1.BaseClient {
204
292
  case 'GUILD_CREATE': {
205
293
  if (this.__handleGuilds?.has(packet.d.id)) {
206
294
  this.__handleGuilds.delete(packet.d.id);
207
- if (!this.__handleGuilds.size &&
208
- [...this.shards.values()].every(shard => shard.data.session_id) &&
209
- this.events.values.WORKER_READY &&
210
- (this.events.values.WORKER_READY.fired ? !this.events.values.WORKER_READY.data.once : true)) {
295
+ if (!this.__handleGuilds.size && [...this.shards.values()].every(shard => shard.data.session_id)) {
211
296
  node_worker_threads_1.parentPort.postMessage({
212
297
  type: 'WORKER_READY',
213
298
  workerId: this.workerId,
214
299
  });
215
300
  await this.events.runEvent('WORKER_READY', this, this.me, -1);
216
301
  }
302
+ if (!this.__handleGuilds.size)
303
+ delete this.__handleGuilds;
217
304
  return;
218
305
  }
219
306
  }
@@ -1,5 +1,5 @@
1
1
  import { MenuCommandContext, User, type AllChannels, type Guild, type InferWithPrefix, type MessageCommandInteraction, type ReturnCache, type UserCommandInteraction, type WebhookMessage } from '../..';
2
- import { type When, type If, type UnionToTuple } from '../../common';
2
+ import { type If, type UnionToTuple, type When } from '../../common';
3
3
  import type { InteractionCreateBodyRequest, InteractionMessageUpdateBodyRequest } from '../../common/types/write';
4
4
  import { Message, type ChatInputCommandInteraction, type GuildMember, type InteractionGuildMember } from '../../structures';
5
5
  import type { RegisteredMiddlewares } from '../decorators';
@@ -69,22 +69,22 @@ class CommandContext {
69
69
  }
70
70
  channel(mode = 'cache') {
71
71
  if (this.interaction?.channel && mode === 'cache')
72
- return this.client.cache.asyncCache ? Promise.resolve(this.interaction.channel) : this.interaction.channel;
72
+ return this.client.cache.adapter.isAsync ? Promise.resolve(this.interaction.channel) : this.interaction.channel;
73
73
  switch (mode) {
74
74
  case 'cache':
75
75
  return (this.client.cache.channels?.get(this.channelId) ||
76
- (this.client.cache.asyncCache ? Promise.resolve() : undefined));
76
+ (this.client.cache.adapter.isAsync ? Promise.resolve() : undefined));
77
77
  default:
78
78
  return this.client.channels.fetch(this.channelId, mode === 'rest');
79
79
  }
80
80
  }
81
81
  me(mode = 'cache') {
82
82
  if (!this.guildId)
83
- return mode === 'cache' ? (this.client.cache.asyncCache ? Promise.resolve() : undefined) : Promise.resolve();
83
+ return mode === 'cache' ? (this.client.cache.adapter.isAsync ? Promise.resolve() : undefined) : Promise.resolve();
84
84
  switch (mode) {
85
85
  case 'cache':
86
86
  return (this.client.cache.members?.get(this.client.botId, this.guildId) ||
87
- (this.client.cache.asyncCache ? Promise.resolve() : undefined));
87
+ (this.client.cache.adapter.isAsync ? Promise.resolve() : undefined));
88
88
  default:
89
89
  return this.client.members.fetch(this.guildId, this.client.botId, mode === 'rest');
90
90
  }
@@ -92,14 +92,14 @@ class CommandContext {
92
92
  guild(mode = 'cache') {
93
93
  if (!this.guildId)
94
94
  return (mode === 'cache'
95
- ? this.client.cache.asyncCache
95
+ ? this.client.cache.adapter.isAsync
96
96
  ? Promise.resolve()
97
97
  : undefined
98
98
  : Promise.resolve());
99
99
  switch (mode) {
100
100
  case 'cache':
101
101
  return (this.client.cache.guilds?.get(this.guildId) ||
102
- (this.client.cache.asyncCache ? Promise.resolve() : undefined));
102
+ (this.client.cache.adapter.isAsync ? Promise.resolve() : undefined));
103
103
  default:
104
104
  return this.client.guilds.fetch(this.guildId, mode === 'rest');
105
105
  }
@@ -1,5 +1,5 @@
1
- import { CommandContext, type WebhookMessage, type ReturnCache } from '../..';
2
- import { type When, type InteractionCreateBodyRequest, type InteractionMessageUpdateBodyRequest, type UnionToTuple } from '../../common';
1
+ import { CommandContext, type ReturnCache, type WebhookMessage } from '../..';
2
+ import { type InteractionCreateBodyRequest, type InteractionMessageUpdateBodyRequest, type UnionToTuple, type When } from '../../common';
3
3
  import { Message, User, type AllChannels, type Guild, type GuildMember, type MessageCommandInteraction, type UserCommandInteraction } from '../../structures';
4
4
  import type { RegisteredMiddlewares } from '../decorators';
5
5
  import type { CommandMetadata, ExtendContext, GlobalMetadata, UsingClient } from './shared';
@@ -57,12 +57,12 @@ class MenuCommandContext {
57
57
  }
58
58
  channel(mode = 'cache') {
59
59
  if (this.interaction?.channel && mode === 'cache')
60
- return this.client.cache.asyncCache ? Promise.resolve(this.interaction.channel) : this.interaction.channel;
60
+ return this.client.cache.adapter.isAsync ? Promise.resolve(this.interaction.channel) : this.interaction.channel;
61
61
  return this.client.channels.fetch(this.channelId, mode === 'rest');
62
62
  }
63
63
  me(mode = 'cache') {
64
64
  if (!this.guildId)
65
- return mode === 'cache' ? (this.client.cache.asyncCache ? Promise.resolve() : undefined) : Promise.resolve();
65
+ return mode === 'cache' ? (this.client.cache.adapter.isAsync ? Promise.resolve() : undefined) : Promise.resolve();
66
66
  switch (mode) {
67
67
  case 'cache':
68
68
  return this.client.cache.members?.get(this.client.botId, this.guildId);
@@ -72,7 +72,7 @@ class MenuCommandContext {
72
72
  }
73
73
  guild(mode = 'cache') {
74
74
  if (!this.guildId)
75
- return (mode === 'cache' ? (this.client.cache.asyncCache ? Promise.resolve() : undefined) : Promise.resolve());
75
+ return (mode === 'cache' ? (this.client.cache.adapter.isAsync ? Promise.resolve() : undefined) : Promise.resolve());
76
76
  switch (mode) {
77
77
  case 'cache':
78
78
  return this.client.cache.guilds?.get(this.guildId);
@@ -3,7 +3,7 @@ export type ToClass<T, This> = new (...args: any[]) => {
3
3
  [K in keyof T]: T[K] extends (...args: any[]) => any ? ReturnType<T[K]> extends Promise<T> ? (...args: Parameters<T[K]>) => Promise<This> : ReturnType<T[K]> extends T ? (...args: Parameters<T[K]>) => This : T[K] : T[K];
4
4
  };
5
5
  export type StringToNumber<T extends string> = T extends `${infer N extends number}` ? N : never;
6
- export type MakePartial<T, K extends keyof T> = T & {
6
+ export type MakePartial<T, K extends keyof T> = Omit<T, K> & {
7
7
  [P in K]?: T[P];
8
8
  };
9
9
  export type DeepPartial<T> = {
@@ -26,8 +26,8 @@ export declare class ComponentHandler extends BaseHandler {
26
26
  run: (customId: string, callback: ComponentCallback) => any;
27
27
  stop: (reason?: string) => void;
28
28
  };
29
- onComponent(ids: [string, string], interaction: ComponentInteraction): Promise<void>;
30
- hasComponent(ids: [string, string], customId: string): boolean;
29
+ onComponent(id: string, interaction: ComponentInteraction): Promise<void>;
30
+ hasComponent(id: string, customId: string): ComponentCallback | undefined;
31
31
  resetTimeouts(id: string): void;
32
32
  hasModal(interaction: ModalSubmitInteraction): boolean;
33
33
  onModalSubmit(interaction: ModalSubmitInteraction): any;
@@ -55,28 +55,25 @@ class ComponentHandler extends common_1.BaseHandler {
55
55
  },
56
56
  };
57
57
  }
58
- async onComponent(ids, interaction) {
59
- for (const id of ids) {
60
- const row = this.values.get(id);
61
- const component = row?.components?.[interaction.customId];
62
- if (!component)
63
- continue;
64
- if (row.options?.filter) {
65
- if (!(await row.options.filter(interaction)))
66
- return;
67
- }
68
- row.idle?.refresh();
69
- await component(interaction, reason => {
70
- row.options?.onStop?.(reason ?? 'stop');
71
- this.deleteValue(id);
72
- }, () => {
73
- this.resetTimeouts(id);
74
- });
75
- break;
58
+ async onComponent(id, interaction) {
59
+ const row = this.values.get(id);
60
+ const component = row?.components?.[interaction.customId];
61
+ if (!component)
62
+ return;
63
+ if (row.options?.filter) {
64
+ if (!(await row.options.filter(interaction)))
65
+ return;
76
66
  }
67
+ row.idle?.refresh();
68
+ await component(interaction, reason => {
69
+ row.options?.onStop?.(reason ?? 'stop');
70
+ this.deleteValue(id);
71
+ }, () => {
72
+ this.resetTimeouts(id);
73
+ });
77
74
  }
78
- hasComponent(ids, customId) {
79
- return ids.some(id => this.values.get(id)?.components?.[customId]);
75
+ hasComponent(id, customId) {
76
+ return this.values.get(id)?.components?.[customId];
80
77
  }
81
78
  resetTimeouts(id) {
82
79
  const listener = this.values.get(id);
@@ -24,8 +24,6 @@ exports.ShardManagerDefaults = ShardManagerDefaults;
24
24
  const WorkerManagerDefaults = {
25
25
  ...ShardManagerDefaults,
26
26
  shardsPerWorker: 32,
27
- handlePayload: (shardId, workerId, packet) => {
28
- console.info(`Packet ${packet.t} on shard ${shardId} worker ${workerId}`);
29
- },
27
+ handlePayload: (_shardId, _workerId, _packet) => { },
30
28
  };
31
29
  exports.WorkerManagerDefaults = WorkerManagerDefaults;
@@ -35,6 +35,7 @@ export interface WorkerManagerOptions extends Omit<ShardManagerOptions, 'handleP
35
35
  * @default 32
36
36
  */
37
37
  shardsPerWorker?: number;
38
+ workerProxy?: boolean;
38
39
  path: string;
39
40
  handlePayload(shardId: number, workerId: number, packet: GatewayDispatchPayload): unknown;
40
41
  }
@@ -96,4 +97,5 @@ export interface WorkerData {
96
97
  shards: number[];
97
98
  workerId: number;
98
99
  debug: boolean;
100
+ workerProxy: boolean;
99
101
  }
@@ -1,3 +1,4 @@
1
+ import type { ApiRequestOptions, HttpMethods } from '../..';
1
2
  import type { GatewayDispatchPayload } from '../../common';
2
3
  export interface WorkerShardInfo {
3
4
  open: boolean;
@@ -7,18 +8,16 @@ export interface WorkerShardInfo {
7
8
  }
8
9
  export type WorkerInfo = {
9
10
  shards: WorkerShardInfo[];
10
- workerId: number;
11
11
  };
12
12
  type CreateWorkerMessage<T extends string, D extends object = {}> = {
13
13
  type: T;
14
+ workerId: number;
14
15
  } & D;
15
16
  export type WorkerRequestConnect = CreateWorkerMessage<'CONNECT_QUEUE', {
16
17
  shardId: number;
17
- workerId: number;
18
18
  }>;
19
19
  export type WorkerReceivePayload = CreateWorkerMessage<'RECEIVE_PAYLOAD', {
20
20
  shardId: number;
21
- workerId: number;
22
21
  payload: GatewayDispatchPayload;
23
22
  }>;
24
23
  export type WorkerSendResultPayload = CreateWorkerMessage<'RESULT_PAYLOAD', {
@@ -28,7 +27,6 @@ export type WorkerSendCacheRequest = CreateWorkerMessage<'CACHE_REQUEST', {
28
27
  nonce: string;
29
28
  method: 'scan' | 'get' | 'set' | 'patch' | 'values' | 'keys' | 'count' | 'remove' | 'contains' | 'getToRelationship' | 'bulkAddToRelationShip' | 'addToRelationship' | 'removeRelationship' | 'removeToRelationship';
30
29
  args: any[];
31
- workerId: number;
32
30
  }>;
33
31
  export type WorkerSendShardInfo = CreateWorkerMessage<'SHARD_INFO', WorkerShardInfo & {
34
32
  nonce: string;
@@ -36,8 +34,26 @@ export type WorkerSendShardInfo = CreateWorkerMessage<'SHARD_INFO', WorkerShardI
36
34
  export type WorkerSendInfo = CreateWorkerMessage<'WORKER_INFO', WorkerInfo & {
37
35
  nonce: string;
38
36
  }>;
39
- export type WorkerReady = CreateWorkerMessage<'WORKER_READY', {
40
- workerId: number;
37
+ export type WorkerReady = CreateWorkerMessage<'WORKER_READY'>;
38
+ export type WorkerSendApiRequest = CreateWorkerMessage<'WORKER_API_REQUEST', {
39
+ method: HttpMethods;
40
+ url: `/${string}`;
41
+ requestOptions: ApiRequestOptions;
42
+ nonce: string;
43
+ }>;
44
+ export type WorkerExecuteEval = CreateWorkerMessage<'EXECUTE_EVAL', {
45
+ func: string;
46
+ nonce: string;
47
+ toWorkerId: number;
48
+ }>;
49
+ export type WorkerSendEvalResponse = CreateWorkerMessage<'EVAL_RESPONSE', {
50
+ response: any;
51
+ nonce: string;
52
+ }>;
53
+ export type WorkerSendEval = CreateWorkerMessage<'EVAL', {
54
+ func: string;
55
+ nonce: string;
56
+ toWorkerId: number;
41
57
  }>;
42
- export type WorkerMessage = WorkerRequestConnect | WorkerReceivePayload | WorkerSendResultPayload | WorkerSendCacheRequest | WorkerSendShardInfo | WorkerSendInfo | WorkerReady;
58
+ export type WorkerMessage = WorkerRequestConnect | WorkerReceivePayload | WorkerSendResultPayload | WorkerSendCacheRequest | WorkerSendShardInfo | WorkerSendInfo | WorkerReady | WorkerSendApiRequest | WorkerExecuteEval | WorkerSendEvalResponse | WorkerSendEval;
43
59
  export {};
@@ -5,14 +5,17 @@
5
5
  /// <reference types="node" />
6
6
  /// <reference types="node" />
7
7
  import { Worker } from 'node:worker_threads';
8
+ import { ApiHandler } from '../..';
8
9
  import { type Adapter } from '../../cache';
9
- import { Logger, type GatewayPresenceUpdateData, type GatewaySendPayload } from '../../common';
10
+ import { Logger, type GatewayPresenceUpdateData, type GatewaySendPayload, type MakePartial } from '../../common';
10
11
  import { ConnectQueue } from '../structures/timeout';
11
12
  import { MemberUpdateHandler } from './events/memberUpdate';
12
13
  import { PresenceUpdateHandler } from './events/presenceUpdate';
13
14
  import type { ShardOptions, WorkerData, WorkerManagerOptions } from './shared';
14
15
  import type { WorkerInfo, WorkerMessage, WorkerShardInfo } from './worker';
15
- export declare class WorkerManager extends Map<number, Worker> {
16
+ export declare class WorkerManager extends Map<number, Worker & {
17
+ ready?: boolean;
18
+ }> {
16
19
  options: Required<WorkerManagerOptions>;
17
20
  debugger?: Logger;
18
21
  connectQueue: ConnectQueue;
@@ -23,8 +26,10 @@ export declare class WorkerManager extends Map<number, Worker> {
23
26
  }>;
24
27
  memberUpdateHandler: MemberUpdateHandler;
25
28
  presenceUpdateHandler: PresenceUpdateHandler;
26
- constructor(options: WorkerManagerOptions);
29
+ rest: ApiHandler;
30
+ constructor(options: MakePartial<WorkerManagerOptions, 'token' | 'intents' | 'info' | 'handlePayload'>);
27
31
  setCache(adapter: Adapter): void;
32
+ setRest(rest: ApiHandler): void;
28
33
  get remaining(): number;
29
34
  get concurrency(): number;
30
35
  get totalWorkers(): number;
@@ -73,5 +78,19 @@ export type ManagerSendCacheResult = CreateManagerMessage<'CACHE_RESULT', {
73
78
  result: any;
74
79
  }>;
75
80
  export type ManagerSendBotReady = CreateManagerMessage<'BOT_READY'>;
76
- export type ManagerMessages = ManagerAllowConnect | ManagerSpawnShards | ManagerSendPayload | ManagerRequestShardInfo | ManagerRequestWorkerInfo | ManagerSendCacheResult | ManagerSendBotReady;
81
+ export type ManagerSendApiResponse = CreateManagerMessage<'API_RESPONSE', {
82
+ response: any;
83
+ error?: any;
84
+ nonce: string;
85
+ }>;
86
+ export type ManagerExecuteEval = CreateManagerMessage<'EXECUTE_EVAL', {
87
+ func: string;
88
+ nonce: string;
89
+ toWorkerId: number;
90
+ }>;
91
+ export type ManagerSendEvalResponse = CreateManagerMessage<'EVAL_RESPONSE', {
92
+ response: any;
93
+ nonce: string;
94
+ }>;
95
+ export type ManagerMessages = ManagerAllowConnect | ManagerSpawnShards | ManagerSendPayload | ManagerRequestShardInfo | ManagerRequestWorkerInfo | ManagerSendCacheResult | ManagerSendBotReady | ManagerSendApiResponse | ManagerSendEvalResponse | ManagerExecuteEval;
77
96
  export {};
@@ -3,7 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.WorkerManager = void 0;
4
4
  const node_crypto_1 = require("node:crypto");
5
5
  const node_worker_threads_1 = require("node:worker_threads");
6
+ const __1 = require("../..");
6
7
  const cache_1 = require("../../cache");
8
+ const base_1 = require("../../client/base");
7
9
  const common_1 = require("../../common");
8
10
  const constants_1 = require("../constants");
9
11
  const structures_1 = require("../structures");
@@ -18,28 +20,18 @@ class WorkerManager extends Map {
18
20
  promises = new Map();
19
21
  memberUpdateHandler = new memberUpdate_1.MemberUpdateHandler();
20
22
  presenceUpdateHandler = new presenceUpdate_1.PresenceUpdateHandler();
23
+ rest;
21
24
  constructor(options) {
22
25
  super();
23
- options.totalShards ??= options.info.shards;
24
26
  this.options = (0, common_1.MergeOptions)(constants_1.WorkerManagerDefaults, options);
25
- this.options.workers ??= Math.ceil(this.options.totalShards / this.options.shardsPerWorker);
26
- this.options.info.shards = options.totalShards;
27
- options.shardEnd ??= options.totalShards;
28
- options.shardStart ??= 0;
29
- this.connectQueue = new timeout_1.ConnectQueue(5.5e3, this.concurrency);
30
- if (this.options.debug) {
31
- this.debugger = new common_1.Logger({
32
- name: '[WorkerManager]',
33
- });
34
- }
35
- if (this.totalShards / this.shardsPerWorker > this.workers) {
36
- throw new Error(`Cannot create enough shards in the specified workers, minimum: ${Math.ceil(this.totalShards / this.shardsPerWorker)}`);
37
- }
38
27
  this.cacheAdapter = new cache_1.MemoryAdapter();
39
28
  }
40
29
  setCache(adapter) {
41
30
  this.cacheAdapter = adapter;
42
31
  }
32
+ setRest(rest) {
33
+ this.rest = rest;
34
+ }
43
35
  get remaining() {
44
36
  return this.options.info.session_start_limit.remaining;
45
37
  }
@@ -104,6 +96,7 @@ class WorkerManager extends Map {
104
96
  shards: shards[i],
105
97
  intents: this.options.intents,
106
98
  workerId: i,
99
+ workerProxy: this.options.workerProxy,
107
100
  });
108
101
  this.set(i, worker);
109
102
  }
@@ -173,46 +166,88 @@ class WorkerManager extends Map {
173
166
  break;
174
167
  case 'RESULT_PAYLOAD':
175
168
  {
176
- const cacheData = this.promises.get(message.nonce);
177
- if (!cacheData) {
169
+ const resultPayload = this.promises.get(message.nonce);
170
+ if (!resultPayload) {
178
171
  return;
179
172
  }
180
173
  this.promises.delete(message.nonce);
181
- clearTimeout(cacheData.timeout);
182
- cacheData.resolve(true);
174
+ clearTimeout(resultPayload.timeout);
175
+ resultPayload.resolve(true);
183
176
  }
184
177
  break;
185
178
  case 'SHARD_INFO':
186
179
  {
187
180
  const { nonce, type, ...data } = message;
188
- const cacheData = this.promises.get(nonce);
189
- if (!cacheData) {
181
+ const shardInfo = this.promises.get(nonce);
182
+ if (!shardInfo) {
190
183
  return;
191
184
  }
192
185
  this.promises.delete(nonce);
193
- clearTimeout(cacheData.timeout);
194
- cacheData.resolve(data);
186
+ clearTimeout(shardInfo.timeout);
187
+ shardInfo.resolve(data);
195
188
  }
196
189
  break;
197
190
  case 'WORKER_INFO':
198
191
  {
199
192
  const { nonce, type, ...data } = message;
200
- const cacheData = this.promises.get(nonce);
201
- if (!cacheData) {
193
+ const workerInfo = this.promises.get(nonce);
194
+ if (!workerInfo) {
202
195
  return;
203
196
  }
204
197
  this.promises.delete(nonce);
205
- clearTimeout(cacheData.timeout);
206
- cacheData.resolve(data);
198
+ clearTimeout(workerInfo.timeout);
199
+ workerInfo.resolve(data);
207
200
  }
208
201
  break;
209
202
  case 'WORKER_READY':
210
203
  {
211
- if (message.workerId === [...this.keys()].at(-1)) {
204
+ this.get(message.workerId).ready = true;
205
+ if ([...this.values()].every(w => w.ready)) {
212
206
  this.get(this.keys().next().value)?.postMessage({
213
207
  type: 'BOT_READY',
214
208
  });
209
+ this.forEach(w => {
210
+ delete w.ready;
211
+ });
212
+ }
213
+ }
214
+ break;
215
+ case 'WORKER_API_REQUEST':
216
+ {
217
+ const response = await this.rest.request(message.method, message.url, message.requestOptions);
218
+ this.get(message.workerId).postMessage({
219
+ nonce: message.nonce,
220
+ response,
221
+ type: 'API_RESPONSE',
222
+ });
223
+ }
224
+ break;
225
+ case 'EVAL_RESPONSE':
226
+ {
227
+ const { nonce, type, ...data } = message;
228
+ const evalResponse = this.promises.get(nonce);
229
+ if (!evalResponse) {
230
+ return;
215
231
  }
232
+ this.promises.delete(nonce);
233
+ clearTimeout(evalResponse.timeout);
234
+ evalResponse.resolve(data.response);
235
+ }
236
+ break;
237
+ case 'EVAL':
238
+ {
239
+ const nonce = this.generateNonce();
240
+ this.get(message.toWorkerId).postMessage({
241
+ nonce,
242
+ func: message.func,
243
+ type: 'EXECUTE_EVAL',
244
+ toWorkerId: message.toWorkerId,
245
+ });
246
+ this.generateSendPromise(nonce, 'Eval timeout').then(val => this.get(message.workerId).postMessage({
247
+ nonce: message.nonce,
248
+ response: val,
249
+ type: 'EVAL_RESPONSE',
250
+ }));
216
251
  }
217
252
  break;
218
253
  }
@@ -234,7 +269,7 @@ class WorkerManager extends Map {
234
269
  timeout = setTimeout(() => {
235
270
  this.promises.delete(nonce);
236
271
  rej(new Error(message));
237
- }, 3e3);
272
+ }, 60e3);
238
273
  });
239
274
  this.promises.set(nonce, { resolve, timeout });
240
275
  return promise;
@@ -274,6 +309,32 @@ class WorkerManager extends Map {
274
309
  return this.generateSendPromise(nonce, 'Get worker info timeout');
275
310
  }
276
311
  async start() {
312
+ const rc = await base_1.BaseClient.prototype.getRC();
313
+ this.options.debug ||= rc.debug;
314
+ this.options.intents ||= rc.intents ?? 0;
315
+ this.options.token ??= rc.token;
316
+ this.rest ??= new __1.ApiHandler({
317
+ token: this.options.token,
318
+ baseUrl: 'api/v10',
319
+ domain: 'https://discord.com',
320
+ debug: this.options.debug,
321
+ });
322
+ this.options.info ??= await new __1.Router(this.rest).createProxy().gateway.bot.get();
323
+ this.options.totalShards ??= this.options.info.shards;
324
+ this.options = (0, common_1.MergeOptions)(constants_1.WorkerManagerDefaults, this.options);
325
+ this.options.workers ??= Math.ceil(this.options.totalShards / this.options.shardsPerWorker);
326
+ this.options.info.shards = this.options.totalShards;
327
+ this.options.shardEnd ??= this.options.totalShards;
328
+ this.options.shardStart ??= 0;
329
+ this.connectQueue = new timeout_1.ConnectQueue(5.5e3, this.concurrency);
330
+ if (this.options.debug) {
331
+ this.debugger = new common_1.Logger({
332
+ name: '[WorkerManager]',
333
+ });
334
+ }
335
+ if (this.totalShards / this.shardsPerWorker > this.workers) {
336
+ throw new Error(`Cannot create enough shards in the specified workers, minimum: ${Math.ceil(this.totalShards / this.shardsPerWorker)}`);
337
+ }
277
338
  const spaces = this.prepareSpaces();
278
339
  await this.prepareWorkers(spaces);
279
340
  }
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "seyfert",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
+ "description": "The most advanced framework for discord bots",
4
5
  "main": "./lib/index.js",
5
6
  "module": "./lib/index.js",
6
7
  "types": "./lib/index.d.ts",
@@ -68,4 +69,4 @@
68
69
  "url": "https://github.com/socram03"
69
70
  }
70
71
  ]
71
- }
72
+ }