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 +5 -0
- package/lib/api/api.js +36 -0
- package/lib/api/shared.d.ts +5 -3
- package/lib/builders/Button.d.ts +2 -2
- package/lib/cache/adapters/default.d.ts +1 -0
- package/lib/cache/adapters/default.js +1 -0
- package/lib/cache/adapters/redis.d.ts +1 -0
- package/lib/cache/adapters/redis.js +1 -0
- package/lib/cache/adapters/types.d.ts +1 -0
- package/lib/cache/adapters/workeradapter.d.ts +1 -0
- package/lib/cache/adapters/workeradapter.js +1 -0
- package/lib/cache/index.d.ts +1 -2
- package/lib/cache/index.js +1 -3
- package/lib/client/base.d.ts +0 -1
- package/lib/client/base.js +2 -2
- package/lib/client/client.d.ts +1 -1
- package/lib/client/client.js +9 -11
- package/lib/client/oninteractioncreate.js +2 -2
- package/lib/client/workerclient.d.ts +14 -1
- package/lib/client/workerclient.js +101 -14
- package/lib/commands/applications/chatcontext.d.ts +1 -1
- package/lib/commands/applications/chatcontext.js +6 -6
- package/lib/commands/applications/menucontext.d.ts +2 -2
- package/lib/commands/applications/menucontext.js +3 -3
- package/lib/common/types/util.d.ts +1 -1
- package/lib/components/handler.d.ts +2 -2
- package/lib/components/handler.js +17 -20
- package/lib/websocket/constants/index.js +1 -3
- package/lib/websocket/discord/shared.d.ts +2 -0
- package/lib/websocket/discord/worker.d.ts +23 -7
- package/lib/websocket/discord/workermanager.d.ts +23 -4
- package/lib/websocket/discord/workermanager.js +89 -28
- package/package.json +3 -2
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) => {
|
package/lib/api/shared.d.ts
CHANGED
|
@@ -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
|
|
8
|
-
domain
|
|
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 {
|
package/lib/builders/Button.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
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():
|
|
49
|
+
toJSON(): When<Type, APIButtonComponentWithCustomId, APIButtonComponentWithURL>;
|
|
50
50
|
}
|
|
@@ -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;
|
package/lib/cache/index.d.ts
CHANGED
|
@@ -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,
|
|
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;
|
package/lib/cache/index.js
CHANGED
|
@@ -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,
|
|
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')) {
|
package/lib/client/base.d.ts
CHANGED
package/lib/client/base.js
CHANGED
|
@@ -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.
|
|
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(),
|
|
111
|
+
this.cache = new cache_1.Cache(0, new cache_1.MemoryAdapter(), [], this);
|
|
112
112
|
}
|
|
113
113
|
else {
|
|
114
114
|
this.cache.__setClient(this);
|
package/lib/client/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Command, CommandContext, Message, SubCommand } from '..';
|
|
2
|
-
import type
|
|
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';
|
package/lib/client/client.js
CHANGED
|
@@ -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
|
-
|
|
128
|
-
|
|
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(
|
|
182
|
-
await self.components.onComponent(
|
|
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<
|
|
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
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
-
|
|
186
|
-
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
2
|
-
import { type
|
|
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.
|
|
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.
|
|
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.
|
|
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(
|
|
30
|
-
hasComponent(
|
|
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(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (row.options
|
|
65
|
-
|
|
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(
|
|
79
|
-
return
|
|
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: (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
177
|
-
if (!
|
|
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(
|
|
182
|
-
|
|
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
|
|
189
|
-
if (!
|
|
181
|
+
const shardInfo = this.promises.get(nonce);
|
|
182
|
+
if (!shardInfo) {
|
|
190
183
|
return;
|
|
191
184
|
}
|
|
192
185
|
this.promises.delete(nonce);
|
|
193
|
-
clearTimeout(
|
|
194
|
-
|
|
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
|
|
201
|
-
if (!
|
|
193
|
+
const workerInfo = this.promises.get(nonce);
|
|
194
|
+
if (!workerInfo) {
|
|
202
195
|
return;
|
|
203
196
|
}
|
|
204
197
|
this.promises.delete(nonce);
|
|
205
|
-
clearTimeout(
|
|
206
|
-
|
|
198
|
+
clearTimeout(workerInfo.timeout);
|
|
199
|
+
workerInfo.resolve(data);
|
|
207
200
|
}
|
|
208
201
|
break;
|
|
209
202
|
case 'WORKER_READY':
|
|
210
203
|
{
|
|
211
|
-
|
|
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
|
-
},
|
|
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.
|
|
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
|
+
}
|