seyfert 1.0.0 → 1.1.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 (112) hide show
  1. package/lib/api/CDN.d.ts +1 -1
  2. package/lib/api/CDN.js +0 -2
  3. package/lib/api/Router.js +2 -2
  4. package/lib/api/Routes/applications.d.ts +29 -33
  5. package/lib/api/Routes/channels.d.ts +11 -17
  6. package/lib/api/Routes/interactions.d.ts +3 -7
  7. package/lib/api/Routes/webhooks.d.ts +4 -6
  8. package/lib/api/api.d.ts +5 -0
  9. package/lib/api/api.js +36 -0
  10. package/lib/api/shared.d.ts +5 -3
  11. package/lib/builders/Attachment.d.ts +2 -3
  12. package/lib/builders/Button.d.ts +2 -2
  13. package/lib/cache/adapters/default.d.ts +1 -0
  14. package/lib/cache/adapters/default.js +1 -0
  15. package/lib/cache/adapters/redis.d.ts +1 -0
  16. package/lib/cache/adapters/redis.js +7 -0
  17. package/lib/cache/adapters/types.d.ts +1 -0
  18. package/lib/cache/adapters/workeradapter.d.ts +5 -4
  19. package/lib/cache/adapters/workeradapter.js +11 -5
  20. package/lib/cache/index.d.ts +4 -6
  21. package/lib/cache/index.js +5 -6
  22. package/lib/cache/resources/default/base.d.ts +2 -1
  23. package/lib/cache/resources/default/guild-based.d.ts +2 -1
  24. package/lib/cache/resources/default/guild-based.js +6 -6
  25. package/lib/cache/resources/default/guild-related.d.ts +2 -1
  26. package/lib/cache/resources/default/guild-related.js +1 -1
  27. package/lib/cache/resources/guilds.js +2 -1
  28. package/lib/cache/resources/overwrites.d.ts +1 -1
  29. package/lib/cache/resources/overwrites.js +7 -1
  30. package/lib/client/base.d.ts +18 -171
  31. package/lib/client/base.js +12 -15
  32. package/lib/client/client.d.ts +6 -1
  33. package/lib/client/client.js +13 -12
  34. package/lib/client/oninteractioncreate.js +4 -4
  35. package/lib/client/onmessagecreate.js +188 -152
  36. package/lib/client/workerclient.d.ts +15 -1
  37. package/lib/client/workerclient.js +135 -27
  38. package/lib/collection.js +2 -2
  39. package/lib/commands/applications/chat.d.ts +15 -7
  40. package/lib/commands/applications/chat.js +7 -7
  41. package/lib/commands/applications/chatcontext.d.ts +6 -4
  42. package/lib/commands/applications/chatcontext.js +12 -7
  43. package/lib/commands/applications/menu.d.ts +5 -1
  44. package/lib/commands/applications/menu.js +4 -0
  45. package/lib/commands/applications/menucontext.d.ts +5 -3
  46. package/lib/commands/applications/menucontext.js +9 -4
  47. package/lib/commands/applications/options.d.ts +1 -2
  48. package/lib/commands/decorators.d.ts +17 -5
  49. package/lib/commands/decorators.js +17 -7
  50. package/lib/commands/handler.d.ts +5 -5
  51. package/lib/commands/handler.js +40 -36
  52. package/lib/commands/optionresolver.d.ts +11 -4
  53. package/lib/commands/optionresolver.js +6 -4
  54. package/lib/common/index.d.ts +7 -0
  55. package/lib/common/index.js +7 -0
  56. package/lib/common/it/utils.js +2 -0
  57. package/lib/common/shorters/channels.d.ts +67 -129
  58. package/lib/common/shorters/channels.js +119 -135
  59. package/lib/common/shorters/emojis.d.ts +47 -0
  60. package/lib/common/shorters/emojis.js +80 -0
  61. package/lib/common/shorters/guilds.d.ts +22 -249
  62. package/lib/common/shorters/guilds.js +51 -140
  63. package/lib/common/shorters/members.d.ts +82 -108
  64. package/lib/common/shorters/members.js +151 -166
  65. package/lib/common/shorters/messages.d.ts +11 -23
  66. package/lib/common/shorters/messages.js +58 -104
  67. package/lib/common/shorters/reactions.d.ts +10 -0
  68. package/lib/common/shorters/reactions.js +45 -0
  69. package/lib/common/shorters/roles.d.ts +39 -7
  70. package/lib/common/shorters/roles.js +74 -42
  71. package/lib/common/shorters/templates.d.ts +6 -8
  72. package/lib/common/shorters/templates.js +17 -21
  73. package/lib/common/shorters/users.d.ts +4 -0
  74. package/lib/common/shorters/users.js +30 -0
  75. package/lib/common/shorters/webhook.d.ts +62 -26
  76. package/lib/common/shorters/webhook.js +113 -58
  77. package/lib/common/types/options.d.ts +2 -2
  78. package/lib/common/types/util.d.ts +1 -1
  79. package/lib/components/handler.d.ts +11 -8
  80. package/lib/components/handler.js +34 -22
  81. package/lib/index.d.ts +4 -2
  82. package/lib/langs/handler.js +7 -2
  83. package/lib/structures/AutoModerationRule.d.ts +2 -2
  84. package/lib/structures/ClientUser.d.ts +2 -2
  85. package/lib/structures/Guild.d.ts +2 -2
  86. package/lib/structures/GuildEmoji.d.ts +4 -4
  87. package/lib/structures/GuildEmoji.js +7 -7
  88. package/lib/structures/GuildMember.d.ts +6 -6
  89. package/lib/structures/GuildMember.js +2 -2
  90. package/lib/structures/GuildPreview.d.ts +2 -2
  91. package/lib/structures/GuildRole.d.ts +2 -2
  92. package/lib/structures/GuildTemplate.d.ts +2 -2
  93. package/lib/structures/Interaction.d.ts +7 -8
  94. package/lib/structures/Interaction.js +1 -1
  95. package/lib/structures/Message.d.ts +7 -6
  96. package/lib/structures/Message.js +7 -4
  97. package/lib/structures/Sticker.d.ts +2 -2
  98. package/lib/structures/Webhook.d.ts +2 -2
  99. package/lib/structures/Webhook.js +3 -3
  100. package/lib/structures/channels.d.ts +19 -20
  101. package/lib/structures/channels.js +13 -25
  102. package/lib/structures/extra/Base.d.ts +1 -2
  103. package/lib/structures/extra/DiscordBase.d.ts +2 -2
  104. package/lib/websocket/constants/index.js +2 -3
  105. package/lib/websocket/discord/shard.js +4 -2
  106. package/lib/websocket/discord/sharder.d.ts +3 -0
  107. package/lib/websocket/discord/sharder.js +12 -5
  108. package/lib/websocket/discord/shared.d.ts +3 -0
  109. package/lib/websocket/discord/worker.d.ts +24 -7
  110. package/lib/websocket/discord/workermanager.d.ts +30 -6
  111. package/lib/websocket/discord/workermanager.js +160 -51
  112. package/package.json +8 -5
@@ -1,9 +1,15 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.WorkerManager = void 0;
7
+ const node_cluster_1 = __importDefault(require("node:cluster"));
4
8
  const node_crypto_1 = require("node:crypto");
5
9
  const node_worker_threads_1 = require("node:worker_threads");
10
+ const __1 = require("../..");
6
11
  const cache_1 = require("../../cache");
12
+ const base_1 = require("../../client/base");
7
13
  const common_1 = require("../../common");
8
14
  const constants_1 = require("../constants");
9
15
  const structures_1 = require("../structures");
@@ -18,28 +24,18 @@ class WorkerManager extends Map {
18
24
  promises = new Map();
19
25
  memberUpdateHandler = new memberUpdate_1.MemberUpdateHandler();
20
26
  presenceUpdateHandler = new presenceUpdate_1.PresenceUpdateHandler();
27
+ rest;
21
28
  constructor(options) {
22
29
  super();
23
- options.totalShards ??= options.info.shards;
24
- 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
- }
30
+ this.options = options;
38
31
  this.cacheAdapter = new cache_1.MemoryAdapter();
39
32
  }
40
33
  setCache(adapter) {
41
34
  this.cacheAdapter = adapter;
42
35
  }
36
+ setRest(rest) {
37
+ this.rest = rest;
38
+ }
43
39
  get remaining() {
44
40
  return this.options.info.session_start_limit.remaining;
45
41
  }
@@ -50,7 +46,13 @@ class WorkerManager extends Map {
50
46
  return this.options.workers;
51
47
  }
52
48
  get totalShards() {
53
- return this.options.totalShards;
49
+ return this.options.totalShards ?? this.options.info.shards;
50
+ }
51
+ get shardStart() {
52
+ return this.options.shardStart ?? 0;
53
+ }
54
+ get shardEnd() {
55
+ return this.options.shardEnd ?? this.totalShards;
54
56
  }
55
57
  get shardsPerWorker() {
56
58
  return this.options.shardsPerWorker;
@@ -70,10 +72,10 @@ class WorkerManager extends Map {
70
72
  return data.shards.reduce((acc, prv) => acc + prv.latency, 0) / data.shards.length;
71
73
  }
72
74
  calculateShardId(guildId) {
73
- return Number((BigInt(guildId) >> 22n) % BigInt(this.options.info.shards ?? 1));
75
+ return Number((BigInt(guildId) >> 22n) % BigInt(this.totalShards));
74
76
  }
75
77
  calculateWorkerId(shardId) {
76
- const workerId = Math.floor(shardId / this.shardsPerWorker);
78
+ const workerId = Math.floor((shardId - this.shardStart) / this.shardsPerWorker);
77
79
  if (workerId >= this.workers) {
78
80
  throw new Error('Invalid shardId');
79
81
  }
@@ -81,18 +83,29 @@ class WorkerManager extends Map {
81
83
  }
82
84
  prepareSpaces() {
83
85
  this.debugger?.info('Preparing buckets');
84
- const chunks = structures_1.SequentialBucket.chunk(new Array(this.options.shardStart !== undefined && this.options.shardEnd !== undefined
85
- ? this.options.shardEnd - this.options.shardStart
86
- : this.options.totalShards), this.options.shardsPerWorker);
86
+ const chunks = structures_1.SequentialBucket.chunk(new Array(this.shardEnd - this.shardStart), this.options.shardsPerWorker);
87
87
  chunks.forEach((shards, index) => {
88
88
  for (let i = 0; i < shards.length; i++) {
89
- const id = i + (index > 0 ? index * this.options.shardsPerWorker : 0) + (this.options.shardStart ?? 0);
89
+ const id = i + (index > 0 ? index * this.options.shardsPerWorker : 0) + this.shardStart;
90
90
  chunks[index][i] = id;
91
91
  }
92
92
  });
93
93
  this.debugger?.info(`${chunks.length} buckets created`);
94
94
  return chunks;
95
95
  }
96
+ postMessage(id, body) {
97
+ const worker = this.get(id);
98
+ if (!worker)
99
+ return this.debugger?.error(`Worker ${id} doesnt exists.`);
100
+ switch (this.options.mode) {
101
+ case 'clusters':
102
+ worker.send(body);
103
+ break;
104
+ case 'threads':
105
+ worker.postMessage(body);
106
+ break;
107
+ }
108
+ }
96
109
  async prepareWorkers(shards) {
97
110
  for (let i = 0; i < shards.length; i++) {
98
111
  let worker = this.get(i);
@@ -104,21 +117,51 @@ class WorkerManager extends Map {
104
117
  shards: shards[i],
105
118
  intents: this.options.intents,
106
119
  workerId: i,
120
+ workerProxy: this.options.workerProxy,
107
121
  });
108
122
  this.set(i, worker);
109
123
  }
110
- worker.postMessage({
111
- type: 'SPAWN_SHARDS',
112
- compress: this.options.compress ?? false,
113
- info: this.options.info,
114
- properties: this.options.properties,
115
- });
124
+ const listener = (message) => {
125
+ if (message.type !== 'WORKER_START')
126
+ return;
127
+ worker.removeListener('message', listener);
128
+ this.postMessage(i, {
129
+ type: 'SPAWN_SHARDS',
130
+ compress: this.options.compress ?? false,
131
+ info: {
132
+ ...this.options.info,
133
+ shards: this.totalShards,
134
+ },
135
+ properties: this.options.properties,
136
+ });
137
+ };
138
+ worker.on('message', listener);
116
139
  }
117
140
  }
118
141
  createWorker(workerData) {
119
- const worker = new node_worker_threads_1.Worker(workerData.path, { workerData });
120
- worker.on('message', data => this.handleWorkerMessage(data));
121
- return worker;
142
+ const env = {
143
+ SEYFERT_SPAWNING: 'true',
144
+ };
145
+ for (const i in workerData) {
146
+ env[`SEYFERT_WORKER_${i.toUpperCase()}`] = workerData[i];
147
+ }
148
+ switch (this.options.mode) {
149
+ case 'threads': {
150
+ const worker = new node_worker_threads_1.Worker(workerData.path, {
151
+ env,
152
+ });
153
+ worker.on('message', data => this.handleWorkerMessage(data));
154
+ return worker;
155
+ }
156
+ case 'clusters': {
157
+ node_cluster_1.default.setupPrimary({
158
+ exec: workerData.path,
159
+ });
160
+ const worker = node_cluster_1.default.fork(env);
161
+ worker.on('message', data => this.handleWorkerMessage(data));
162
+ return worker;
163
+ }
164
+ }
122
165
  }
123
166
  spawn(workerId, shardId) {
124
167
  this.connectQueue.push(() => {
@@ -127,7 +170,7 @@ class WorkerManager extends Map {
127
170
  this.debugger?.fatal("Trying spawn with worker doesn't exist");
128
171
  return;
129
172
  }
130
- worker.postMessage({
173
+ this.postMessage(workerId, {
131
174
  type: 'ALLOW_CONNECT',
132
175
  shardId,
133
176
  presence: this.options.presence?.(shardId, workerId),
@@ -147,7 +190,7 @@ class WorkerManager extends Map {
147
190
  }
148
191
  // @ts-expect-error
149
192
  const result = await this.cacheAdapter[message.method](...message.args);
150
- worker.postMessage({
193
+ this.postMessage(message.workerId, {
151
194
  type: 'CACHE_RESULT',
152
195
  nonce: message.nonce,
153
196
  result,
@@ -173,48 +216,90 @@ class WorkerManager extends Map {
173
216
  break;
174
217
  case 'RESULT_PAYLOAD':
175
218
  {
176
- const cacheData = this.promises.get(message.nonce);
177
- if (!cacheData) {
219
+ const resultPayload = this.promises.get(message.nonce);
220
+ if (!resultPayload) {
178
221
  return;
179
222
  }
180
223
  this.promises.delete(message.nonce);
181
- clearTimeout(cacheData.timeout);
182
- cacheData.resolve(true);
224
+ clearTimeout(resultPayload.timeout);
225
+ resultPayload.resolve(true);
183
226
  }
184
227
  break;
185
228
  case 'SHARD_INFO':
186
229
  {
187
230
  const { nonce, type, ...data } = message;
188
- const cacheData = this.promises.get(nonce);
189
- if (!cacheData) {
231
+ const shardInfo = this.promises.get(nonce);
232
+ if (!shardInfo) {
190
233
  return;
191
234
  }
192
235
  this.promises.delete(nonce);
193
- clearTimeout(cacheData.timeout);
194
- cacheData.resolve(data);
236
+ clearTimeout(shardInfo.timeout);
237
+ shardInfo.resolve(data);
195
238
  }
196
239
  break;
197
240
  case 'WORKER_INFO':
198
241
  {
199
242
  const { nonce, type, ...data } = message;
200
- const cacheData = this.promises.get(nonce);
201
- if (!cacheData) {
243
+ const workerInfo = this.promises.get(nonce);
244
+ if (!workerInfo) {
202
245
  return;
203
246
  }
204
247
  this.promises.delete(nonce);
205
- clearTimeout(cacheData.timeout);
206
- cacheData.resolve(data);
248
+ clearTimeout(workerInfo.timeout);
249
+ workerInfo.resolve(data);
207
250
  }
208
251
  break;
209
252
  case 'WORKER_READY':
210
253
  {
211
- if (message.workerId === [...this.keys()].at(-1)) {
212
- this.get(this.keys().next().value)?.postMessage({
254
+ this.get(message.workerId).ready = true;
255
+ if ([...this.values()].every(w => w.ready)) {
256
+ this.postMessage(this.keys().next().value, {
213
257
  type: 'BOT_READY',
214
258
  });
259
+ this.forEach(w => {
260
+ delete w.ready;
261
+ });
215
262
  }
216
263
  }
217
264
  break;
265
+ case 'WORKER_API_REQUEST':
266
+ {
267
+ const response = await this.rest.request(message.method, message.url, message.requestOptions);
268
+ this.postMessage(message.workerId, {
269
+ nonce: message.nonce,
270
+ response,
271
+ type: 'API_RESPONSE',
272
+ });
273
+ }
274
+ break;
275
+ case 'EVAL_RESPONSE':
276
+ {
277
+ const { nonce, type, ...data } = message;
278
+ const evalResponse = this.promises.get(nonce);
279
+ if (!evalResponse) {
280
+ return;
281
+ }
282
+ this.promises.delete(nonce);
283
+ clearTimeout(evalResponse.timeout);
284
+ evalResponse.resolve(data.response);
285
+ }
286
+ break;
287
+ case 'EVAL':
288
+ {
289
+ const nonce = this.generateNonce();
290
+ this.postMessage(message.toWorkerId, {
291
+ nonce,
292
+ func: message.func,
293
+ type: 'EXECUTE_EVAL',
294
+ toWorkerId: message.toWorkerId,
295
+ });
296
+ this.generateSendPromise(nonce, 'Eval timeout').then(val => this.postMessage(message.workerId, {
297
+ nonce: message.nonce,
298
+ response: val,
299
+ type: 'EVAL_RESPONSE',
300
+ }));
301
+ }
302
+ break;
218
303
  }
219
304
  }
220
305
  generateNonce(large = true) {
@@ -234,7 +319,7 @@ class WorkerManager extends Map {
234
319
  timeout = setTimeout(() => {
235
320
  this.promises.delete(nonce);
236
321
  rej(new Error(message));
237
- }, 3e3);
322
+ }, 60e3);
238
323
  });
239
324
  this.promises.set(nonce, { resolve, timeout });
240
325
  return promise;
@@ -246,7 +331,7 @@ class WorkerManager extends Map {
246
331
  throw new Error(`Worker #${workerId} doesnt exist`);
247
332
  }
248
333
  const nonce = this.generateNonce();
249
- worker.postMessage({
334
+ this.postMessage(workerId, {
250
335
  type: 'SEND_PAYLOAD',
251
336
  shardId,
252
337
  nonce,
@@ -261,7 +346,7 @@ class WorkerManager extends Map {
261
346
  throw new Error(`Worker #${workerId} doesnt exist`);
262
347
  }
263
348
  const nonce = this.generateNonce(false);
264
- worker.postMessage({ shardId, nonce, type: 'SHARD_INFO' });
349
+ this.postMessage(workerId, { shardId, nonce, type: 'SHARD_INFO' });
265
350
  return this.generateSendPromise(nonce, 'Get shard info timeout');
266
351
  }
267
352
  async getWorkerInfo(workerId) {
@@ -270,10 +355,34 @@ class WorkerManager extends Map {
270
355
  throw new Error(`Worker #${workerId} doesnt exist`);
271
356
  }
272
357
  const nonce = this.generateNonce();
273
- worker.postMessage({ nonce, type: 'WORKER_INFO' });
358
+ this.postMessage(workerId, { nonce, type: 'WORKER_INFO' });
274
359
  return this.generateSendPromise(nonce, 'Get worker info timeout');
275
360
  }
276
361
  async start() {
362
+ const rc = await base_1.BaseClient.prototype.getRC();
363
+ this.options.debug ||= rc.debug;
364
+ this.options.intents ||= rc.intents ?? 0;
365
+ this.options.token ??= rc.token;
366
+ this.rest ??= new __1.ApiHandler({
367
+ token: this.options.token,
368
+ baseUrl: 'api/v10',
369
+ domain: 'https://discord.com',
370
+ debug: this.options.debug,
371
+ });
372
+ this.options.info ??= await new __1.Router(this.rest).createProxy().gateway.bot.get();
373
+ this.options.shardEnd ??= this.options.totalShards ?? this.options.info.shards;
374
+ this.options.totalShards ??= this.options.shardEnd;
375
+ this.options = (0, common_1.MergeOptions)(constants_1.WorkerManagerDefaults, this.options);
376
+ this.options.workers ??= Math.ceil(this.options.totalShards / this.options.shardsPerWorker);
377
+ this.connectQueue = new timeout_1.ConnectQueue(5.5e3, this.concurrency);
378
+ if (this.options.debug) {
379
+ this.debugger = new common_1.Logger({
380
+ name: '[WorkerManager]',
381
+ });
382
+ }
383
+ if (this.totalShards / this.shardsPerWorker > this.workers) {
384
+ throw new Error(`Cannot create enough shards in the specified workers, minimum: ${Math.ceil(this.totalShards / this.shardsPerWorker)}`);
385
+ }
277
386
  const spaces = this.prepareSpaces();
278
387
  await this.prepareWorkers(spaces);
279
388
  }
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "seyfert",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
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",
@@ -17,10 +18,10 @@
17
18
  "check": "biome check --apply --changed --no-errors-on-unmatched ./src"
18
19
  },
19
20
  "author": "MARCROCK22",
20
- "license": "ISC",
21
+ "license": "Apache-2.0",
21
22
  "dependencies": {
22
23
  "chokidar": "^3.6.0",
23
- "discord-api-types": "^0.37.73",
24
+ "discord-api-types": "^0.37.76",
24
25
  "magic-bytes.js": "^1.10.0",
25
26
  "ts-mixer": "^6.0.4",
26
27
  "ws": "^8.16.0"
@@ -33,11 +34,13 @@
33
34
  },
34
35
  "devDependencies": {
35
36
  "@biomejs/biome": "1.6.0",
36
- "@types/node": "^20.11.25",
37
+ "@commitlint/cli": "^19.2.1",
38
+ "@commitlint/config-conventional": "^19.1.0",
39
+ "@types/node": "^20.11.30",
37
40
  "@types/ws": "^8.5.10",
38
41
  "husky": "^9.0.11",
39
42
  "lint-staged": "^15.2.2",
40
- "typescript": "^5.4.2"
43
+ "typescript": "^5.4.3"
41
44
  },
42
45
  "optionalDependencies": {
43
46
  "ioredis": "^5.3.2",