diff --git a/biome.json b/biome.json index f1a5baa..6b405c8 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.2/schema.json", + "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", "vcs": { "enabled": true, "clientKind": "git", @@ -8,15 +8,7 @@ }, "files": { "ignoreUnknown": true, - "ignore": [ - "node_modules/", - "build", - "lib", - "__test__", - "package.json", - "tsconfig.json", - ".vscode" - ] + "ignore": ["node_modules/", "build", "lib", "__test__", "package.json", "tsconfig.json", ".vscode"] }, "formatter": { "enabled": true, diff --git a/package.json b/package.json index cd9e827..1899ff5 100644 --- a/package.json +++ b/package.json @@ -21,10 +21,10 @@ "author": "MARCROCK22", "license": "MIT", "devDependencies": { - "@biomejs/biome": "1.9.3", + "@biomejs/biome": "1.9.4", "@commitlint/cli": "^19.5.0", "@commitlint/config-conventional": "^19.5.0", - "@types/node": "^22.7.6", + "@types/node": "^22.7.7", "husky": "^9.1.6", "lint-staged": "^15.2.10", "typescript": "^5.6.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b3b336c..868f588 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,17 +9,17 @@ importers: .: devDependencies: '@biomejs/biome': - specifier: 1.9.3 - version: 1.9.3 + specifier: 1.9.4 + version: 1.9.4 '@commitlint/cli': specifier: ^19.5.0 - version: 19.5.0(@types/node@22.7.6)(typescript@5.6.3) + version: 19.5.0(@types/node@22.7.7)(typescript@5.6.3) '@commitlint/config-conventional': specifier: ^19.5.0 version: 19.5.0 '@types/node': - specifier: ^22.7.6 - version: 22.7.6 + specifier: ^22.7.7 + version: 22.7.7 husky: specifier: ^9.1.6 version: 9.1.6 @@ -31,7 +31,7 @@ importers: version: 5.6.3 vitest: specifier: ^2.1.3 - version: 2.1.3(@types/node@22.7.6) + version: 2.1.3(@types/node@22.7.7) packages: @@ -47,55 +47,55 @@ packages: resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==} engines: {node: '>=6.9.0'} - '@biomejs/biome@1.9.3': - resolution: {integrity: sha512-POjAPz0APAmX33WOQFGQrwLvlu7WLV4CFJMlB12b6ZSg+2q6fYu9kZwLCOA+x83zXfcPd1RpuWOKJW0GbBwLIQ==} + '@biomejs/biome@1.9.4': + resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@1.9.3': - resolution: {integrity: sha512-QZzD2XrjJDUyIZK+aR2i5DDxCJfdwiYbUKu9GzkCUJpL78uSelAHAPy7m0GuPMVtF/Uo+OKv97W3P9nuWZangQ==} + '@biomejs/cli-darwin-arm64@1.9.4': + resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@1.9.3': - resolution: {integrity: sha512-vSCoIBJE0BN3SWDFuAY/tRavpUtNoqiceJ5PrU3xDfsLcm/U6N93JSM0M9OAiC/X7mPPfejtr6Yc9vSgWlEgVw==} + '@biomejs/cli-darwin-x64@1.9.4': + resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@1.9.3': - resolution: {integrity: sha512-VBzyhaqqqwP3bAkkBrhVq50i3Uj9+RWuj+pYmXrMDgjS5+SKYGE56BwNw4l8hR3SmYbLSbEo15GcV043CDSk+Q==} + '@biomejs/cli-linux-arm64-musl@1.9.4': + resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-arm64@1.9.3': - resolution: {integrity: sha512-vJkAimD2+sVviNTbaWOGqEBy31cW0ZB52KtpVIbkuma7PlfII3tsLhFa+cwbRAcRBkobBBhqZ06hXoZAN8NODQ==} + '@biomejs/cli-linux-arm64@1.9.4': + resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-x64-musl@1.9.3': - resolution: {integrity: sha512-TJmnOG2+NOGM72mlczEsNki9UT+XAsMFAOo8J0me/N47EJ/vkLXxf481evfHLlxMejTY6IN8SdRSiPVLv6AHlA==} + '@biomejs/cli-linux-x64-musl@1.9.4': + resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-linux-x64@1.9.3': - resolution: {integrity: sha512-x220V4c+romd26Mu1ptU+EudMXVS4xmzKxPVb9mgnfYlN4Yx9vD5NZraSx/onJnd3Gh/y8iPUdU5CDZJKg9COA==} + '@biomejs/cli-linux-x64@1.9.4': + resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-win32-arm64@1.9.3': - resolution: {integrity: sha512-lg/yZis2HdQGsycUvHWSzo9kOvnGgvtrYRgoCEwPBwwAL8/6crOp3+f47tPwI/LI1dZrhSji7PNsGKGHbwyAhw==} + '@biomejs/cli-win32-arm64@1.9.4': + resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@1.9.3': - resolution: {integrity: sha512-cQMy2zanBkVLpmmxXdK6YePzmZx0s5Z7KEnwmrW54rcXK3myCNbQa09SwGZ8i/8sLw0H9F3X7K4rxVNGU8/D4Q==} + '@biomejs/cli-win32-x64@1.9.4': + resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -396,8 +396,8 @@ packages: '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - '@types/node@22.7.6': - resolution: {integrity: sha512-/d7Rnj0/ExXDMcioS78/kf1lMzYk4BZV8MZGTBKzTGZ6/406ukkbYlIsZmMPhcR5KlkunDHQLrtAVmSq7r+mSw==} + '@types/node@22.7.7': + resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} '@vitest/expect@2.1.3': resolution: {integrity: sha512-SNBoPubeCJhZ48agjXruCI57DvxcsivVDdWz+SSsmjTT4QN/DfHk3zB/xKsJqMs26bLZ/pNRLnCf0j679i0uWQ==} @@ -546,8 +546,8 @@ packages: engines: {node: '>=16'} hasBin: true - cosmiconfig-typescript-loader@5.0.0: - resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} + cosmiconfig-typescript-loader@5.1.0: + resolution: {integrity: sha512-7PtBB+6FdsOvZyJtlF3hEPpACq7RQX6BVGsgC7/lfVXnKMvNCu/XY3ykreqG5w/rBNdu2z8LCIKoF3kpHHdHlA==} engines: {node: '>=v16'} peerDependencies: '@types/node': '*' @@ -1152,46 +1152,46 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@biomejs/biome@1.9.3': + '@biomejs/biome@1.9.4': optionalDependencies: - '@biomejs/cli-darwin-arm64': 1.9.3 - '@biomejs/cli-darwin-x64': 1.9.3 - '@biomejs/cli-linux-arm64': 1.9.3 - '@biomejs/cli-linux-arm64-musl': 1.9.3 - '@biomejs/cli-linux-x64': 1.9.3 - '@biomejs/cli-linux-x64-musl': 1.9.3 - '@biomejs/cli-win32-arm64': 1.9.3 - '@biomejs/cli-win32-x64': 1.9.3 + '@biomejs/cli-darwin-arm64': 1.9.4 + '@biomejs/cli-darwin-x64': 1.9.4 + '@biomejs/cli-linux-arm64': 1.9.4 + '@biomejs/cli-linux-arm64-musl': 1.9.4 + '@biomejs/cli-linux-x64': 1.9.4 + '@biomejs/cli-linux-x64-musl': 1.9.4 + '@biomejs/cli-win32-arm64': 1.9.4 + '@biomejs/cli-win32-x64': 1.9.4 - '@biomejs/cli-darwin-arm64@1.9.3': + '@biomejs/cli-darwin-arm64@1.9.4': optional: true - '@biomejs/cli-darwin-x64@1.9.3': + '@biomejs/cli-darwin-x64@1.9.4': optional: true - '@biomejs/cli-linux-arm64-musl@1.9.3': + '@biomejs/cli-linux-arm64-musl@1.9.4': optional: true - '@biomejs/cli-linux-arm64@1.9.3': + '@biomejs/cli-linux-arm64@1.9.4': optional: true - '@biomejs/cli-linux-x64-musl@1.9.3': + '@biomejs/cli-linux-x64-musl@1.9.4': optional: true - '@biomejs/cli-linux-x64@1.9.3': + '@biomejs/cli-linux-x64@1.9.4': optional: true - '@biomejs/cli-win32-arm64@1.9.3': + '@biomejs/cli-win32-arm64@1.9.4': optional: true - '@biomejs/cli-win32-x64@1.9.3': + '@biomejs/cli-win32-x64@1.9.4': optional: true - '@commitlint/cli@19.5.0(@types/node@22.7.6)(typescript@5.6.3)': + '@commitlint/cli@19.5.0(@types/node@22.7.7)(typescript@5.6.3)': dependencies: '@commitlint/format': 19.5.0 '@commitlint/lint': 19.5.0 - '@commitlint/load': 19.5.0(@types/node@22.7.6)(typescript@5.6.3) + '@commitlint/load': 19.5.0(@types/node@22.7.7)(typescript@5.6.3) '@commitlint/read': 19.5.0 '@commitlint/types': 19.5.0 tinyexec: 0.3.1 @@ -1238,7 +1238,7 @@ snapshots: '@commitlint/rules': 19.5.0 '@commitlint/types': 19.5.0 - '@commitlint/load@19.5.0(@types/node@22.7.6)(typescript@5.6.3)': + '@commitlint/load@19.5.0(@types/node@22.7.7)(typescript@5.6.3)': dependencies: '@commitlint/config-validator': 19.5.0 '@commitlint/execute-rule': 19.5.0 @@ -1246,7 +1246,7 @@ snapshots: '@commitlint/types': 19.5.0 chalk: 5.3.0 cosmiconfig: 9.0.0(typescript@5.6.3) - cosmiconfig-typescript-loader: 5.0.0(@types/node@22.7.6)(cosmiconfig@9.0.0(typescript@5.6.3))(typescript@5.6.3) + cosmiconfig-typescript-loader: 5.1.0(@types/node@22.7.7)(cosmiconfig@9.0.0(typescript@5.6.3))(typescript@5.6.3) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -1418,11 +1418,11 @@ snapshots: '@types/conventional-commits-parser@5.0.0': dependencies: - '@types/node': 22.7.6 + '@types/node': 22.7.7 '@types/estree@1.0.6': {} - '@types/node@22.7.6': + '@types/node@22.7.7': dependencies: undici-types: 6.19.8 @@ -1433,13 +1433,13 @@ snapshots: chai: 5.1.1 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.3(@vitest/spy@2.1.3)(vite@5.4.9(@types/node@22.7.6))': + '@vitest/mocker@2.1.3(@vitest/spy@2.1.3)(vite@5.4.9(@types/node@22.7.7))': dependencies: '@vitest/spy': 2.1.3 estree-walker: 3.0.3 magic-string: 0.30.12 optionalDependencies: - vite: 5.4.9(@types/node@22.7.6) + vite: 5.4.9(@types/node@22.7.7) '@vitest/pretty-format@2.1.3': dependencies: @@ -1579,9 +1579,9 @@ snapshots: meow: 12.1.1 split2: 4.2.0 - cosmiconfig-typescript-loader@5.0.0(@types/node@22.7.6)(cosmiconfig@9.0.0(typescript@5.6.3))(typescript@5.6.3): + cosmiconfig-typescript-loader@5.1.0(@types/node@22.7.7)(cosmiconfig@9.0.0(typescript@5.6.3))(typescript@5.6.3): dependencies: - '@types/node': 22.7.6 + '@types/node': 22.7.7 cosmiconfig: 9.0.0(typescript@5.6.3) jiti: 1.21.6 typescript: 5.6.3 @@ -2012,12 +2012,12 @@ snapshots: unicorn-magic@0.1.0: {} - vite-node@2.1.3(@types/node@22.7.6): + vite-node@2.1.3(@types/node@22.7.7): dependencies: cac: 6.7.14 debug: 4.3.7 pathe: 1.1.2 - vite: 5.4.9(@types/node@22.7.6) + vite: 5.4.9(@types/node@22.7.7) transitivePeerDependencies: - '@types/node' - less @@ -2029,19 +2029,19 @@ snapshots: - supports-color - terser - vite@5.4.9(@types/node@22.7.6): + vite@5.4.9(@types/node@22.7.7): dependencies: esbuild: 0.21.5 postcss: 8.4.47 rollup: 4.24.0 optionalDependencies: - '@types/node': 22.7.6 + '@types/node': 22.7.7 fsevents: 2.3.3 - vitest@2.1.3(@types/node@22.7.6): + vitest@2.1.3(@types/node@22.7.7): dependencies: '@vitest/expect': 2.1.3 - '@vitest/mocker': 2.1.3(@vitest/spy@2.1.3)(vite@5.4.9(@types/node@22.7.6)) + '@vitest/mocker': 2.1.3(@vitest/spy@2.1.3)(vite@5.4.9(@types/node@22.7.7)) '@vitest/pretty-format': 2.1.3 '@vitest/runner': 2.1.3 '@vitest/snapshot': 2.1.3 @@ -2056,11 +2056,11 @@ snapshots: tinyexec: 0.3.1 tinypool: 1.0.1 tinyrainbow: 1.2.0 - vite: 5.4.9(@types/node@22.7.6) - vite-node: 2.1.3(@types/node@22.7.6) + vite: 5.4.9(@types/node@22.7.7) + vite-node: 2.1.3(@types/node@22.7.7) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.7.6 + '@types/node': 22.7.7 transitivePeerDependencies: - less - lightningcss diff --git a/src/client/workerclient.ts b/src/client/workerclient.ts index 6b4521e..17605fc 100644 --- a/src/client/workerclient.ts +++ b/src/client/workerclient.ts @@ -13,11 +13,11 @@ import type { WorkerReceivePayload, WorkerRequestConnect, WorkerRequestConnectResharding, - WorkerSendEval, WorkerSendEvalResponse, WorkerSendInfo, WorkerSendResultPayload, WorkerSendShardInfo, + WorkerSendToWorkerEval, WorkerShardInfo, WorkerShardsConnected, WorkerStart, @@ -38,16 +38,17 @@ let manager: import('node:worker_threads').MessagePort; try { workerData = { debug: process.env.SEYFERT_WORKER_DEBUG === 'true', - intents: Number.parseInt(process.env.SEYFERT_WORKER_INTENTS!), + intents: Number(process.env.SEYFERT_WORKER_INTENTS), path: process.env.SEYFERT_WORKER_PATH!, - shards: process.env.SEYFERT_WORKER_SHARDS!.split(',').map(id => Number.parseInt(id)), + shards: process.env.SEYFERT_WORKER_SHARDS!.split(',').map(id => Number(id)), token: process.env.SEYFERT_WORKER_TOKEN!, - workerId: Number.parseInt(process.env.SEYFERT_WORKER_WORKERID!), + workerId: Number(process.env.SEYFERT_WORKER_WORKERID), workerProxy: process.env.SEYFERT_WORKER_WORKERPROXY === 'true', totalShards: Number(process.env.SEYFERT_WORKER_TOTALSHARDS), - mode: process.env.SEYFERT_WORKER_MODE, + mode: process.env.SEYFERT_WORKER_MODE as 'custom' | 'threads' | 'clusters', resharding: process.env.SEYFERT_WORKER_RESHARDING === 'true', - } as WorkerData; + totalWorkers: Number(process.env.SEYFERT_WORKER_TOTALWORKERS), + } satisfies WorkerData; } catch { // } @@ -372,6 +373,7 @@ export class WorkerClient extends BaseClient { } break; case 'EXECUTE_EVAL': + case 'EXECUTE_EVAL_TO_WORKER': { let result: unknown; try { @@ -451,16 +453,24 @@ export class WorkerClient extends BaseClient { }); } - tellWorker(workerId: number, func: (_: this) => any) { + tellWorker(workerId: number, func: (_: this) => R) { const nonce = this.generateNonce(); this.postMessage({ - type: 'EVAL', + type: 'EVAL_TO_WORKER', func: func.toString(), toWorkerId: workerId, workerId: workerData.workerId, nonce, - } satisfies WorkerSendEval); - return this.generateSendPromise(nonce); + } satisfies WorkerSendToWorkerEval); + return this.generateSendPromise(nonce); + } + + tellWorkers(func: (_: this) => R) { + const promises: Promise[] = []; + for (let i = 0; i < workerData.totalWorkers; i++) { + promises.push(this.tellWorker(i, func)); + } + return Promise.all(promises); } protected async onPacket(packet: GatewayDispatchPayload, shardId: number) { @@ -564,6 +574,7 @@ export function generateShardInfo(shard: Shard): WorkerShardInfo { shardId: shard.id, latency: shard.latency, resumable: shard.resumable, + workerId: workerData.workerId, }; } diff --git a/src/commands/applications/entrycontext.ts b/src/commands/applications/entrycontext.ts index aebeb76..b4c932b 100644 --- a/src/commands/applications/entrycontext.ts +++ b/src/commands/applications/entrycontext.ts @@ -54,8 +54,11 @@ export class EntryPointContext ex return this.interaction.modal(body); } - deferReply(ephemeral = false): Promise> { - return this.interaction.deferReply(ephemeral ? MessageFlags.Ephemeral : undefined); + deferReply( + ephemeral = false, + withResponse?: WR, + ): Promise> { + return this.interaction.deferReply(ephemeral ? MessageFlags.Ephemeral : undefined, withResponse); } editResponse(body: InteractionMessageUpdateBodyRequest) { diff --git a/src/commands/applications/menucontext.ts b/src/commands/applications/menucontext.ts index f753e81..fa0c7b3 100644 --- a/src/commands/applications/menucontext.ts +++ b/src/commands/applications/menucontext.ts @@ -79,8 +79,11 @@ export class MenuCommandContext< return this.interaction.modal(body); } - deferReply(ephemeral = false): Promise> { - return this.interaction.deferReply(ephemeral ? MessageFlags.Ephemeral : undefined); + deferReply( + ephemeral = false, + withResponse?: WR, + ): Promise> { + return this.interaction.deferReply(ephemeral ? MessageFlags.Ephemeral : undefined, withResponse); } editResponse(body: InteractionMessageUpdateBodyRequest) { diff --git a/src/structures/Interaction.ts b/src/structures/Interaction.ts index 03ee770..f6aec66 100644 --- a/src/structures/Interaction.ts +++ b/src/structures/Interaction.ts @@ -249,7 +249,7 @@ export class BaseInteraction< deferReply( flags?: MessageFlags, - withResponse = false, + withResponse?: WR, ): Promise> { return this.reply( { diff --git a/src/websocket/discord/shared.ts b/src/websocket/discord/shared.ts index 74b906a..61e2582 100644 --- a/src/websocket/discord/shared.ts +++ b/src/websocket/discord/shared.ts @@ -135,6 +135,7 @@ export interface WorkerData { path: string; shards: number[]; totalShards: number; + totalWorkers: number; mode: 'custom' | 'clusters' | 'threads'; workerId: number; debug: boolean; diff --git a/src/websocket/discord/worker.ts b/src/websocket/discord/worker.ts index dda8da2..5f79906 100644 --- a/src/websocket/discord/worker.ts +++ b/src/websocket/discord/worker.ts @@ -6,6 +6,7 @@ export interface WorkerShardInfo { shardId: number; latency: number; resumable: boolean; + workerId: number; } export type WorkerInfo = { shards: WorkerShardInfo[] }; @@ -75,8 +76,8 @@ export type WorkerSendEvalResponse = CreateWorkerMessage< } >; -export type WorkerSendEval = CreateWorkerMessage< - 'EVAL', +export type WorkerSendToWorkerEval = CreateWorkerMessage< + 'EVAL_TO_WORKER', { func: string; nonce: string; @@ -95,7 +96,7 @@ export type WorkerMessage = | WorkerShardsConnected | WorkerSendApiRequest | WorkerSendEvalResponse - | WorkerSendEval + | WorkerSendToWorkerEval | WorkerStart | WorkerStartResharding | WorkerRequestConnectResharding diff --git a/src/websocket/discord/workermanager.ts b/src/websocket/discord/workermanager.ts index 2e46845..6e25d69 100644 --- a/src/websocket/discord/workermanager.ts +++ b/src/websocket/discord/workermanager.ts @@ -1,6 +1,7 @@ import cluster, { type Worker as ClusterWorker } from 'node:cluster'; import { type UUID, randomUUID } from 'node:crypto'; -import { ApiHandler, Logger } from '../..'; +import type { Worker as WorkerThreadsWorker } from 'node:worker_threads'; +import { ApiHandler, Logger, type UsingClient, type WorkerClient } from '../..'; import { type Adapter, MemoryAdapter } from '../../cache'; import { BaseClient, type InternalRuntimeConfig } from '../../client/base'; import { type MakePartial, MergeOptions, lazyLoadPackage } from '../../common'; @@ -13,7 +14,7 @@ import type { WorkerInfo, WorkerMessage, WorkerShardInfo } from './worker'; export class WorkerManager extends Map< number, - (ClusterWorker | import('node:worker_threads').Worker | { ready?: boolean }) & { + (ClusterWorker | WorkerThreadsWorker | { ready?: boolean }) & { ready?: boolean; disconnected?: boolean; resharded?: boolean; @@ -148,7 +149,7 @@ export class WorkerManager extends Map< } } - async prepareWorkers(shards: number[][], resharding = false) { + prepareWorkers(shards: number[][], resharding = false) { const worker_threads = lazyLoadPackage('node:worker_threads'); if (!worker_threads) throw new Error('Cannot prepare workers without worker_threads.'); @@ -167,6 +168,7 @@ export class WorkerManager extends Map< totalShards: resharding ? this._info!.shards : this.totalShards, mode: this.options.mode, resharding, + totalWorkers: shards.length, }); this.set(i, worker); }); @@ -405,25 +407,25 @@ export class WorkerManager extends Map< break; case 'EVAL_RESPONSE': { - const { nonce, type, ...data } = message; + const { nonce, response } = message; const evalResponse = this.promises.get(nonce); if (!evalResponse) { return; } this.promises.delete(nonce); clearTimeout(evalResponse.timeout); - evalResponse.resolve(data.response); + evalResponse.resolve(response); } break; - case 'EVAL': + case 'EVAL_TO_WORKER': { const nonce = this.generateNonce(); this.postMessage(message.toWorkerId, { nonce, func: message.func, - type: 'EXECUTE_EVAL', + type: 'EXECUTE_EVAL_TO_WORKER', toWorkerId: message.toWorkerId, - } satisfies ManagerExecuteEval); + } satisfies ManagerExecuteEvalToWorker); this.generateSendPromise(nonce, 'Eval timeout').then(val => this.postMessage(message.workerId, { nonce: message.nonce, @@ -501,6 +503,24 @@ export class WorkerManager extends Map< return this.generateSendPromise(nonce, 'Get worker info timeout'); } + tellWorker(workerId: number, func: (_: WorkerClient & UsingClient) => R) { + const nonce = this.generateNonce(); + this.postMessage(workerId, { + type: 'EXECUTE_EVAL', + func: func.toString(), + nonce, + } satisfies ManagerExecuteEval); + return this.generateSendPromise(nonce); + } + + tellWorkers(func: (_: WorkerClient & UsingClient) => R) { + const promises: Promise[] = []; + for (const i of this.keys()) { + promises.push(this.tellWorker(i, func)); + } + return Promise.all(promises); + } + async start() { const rc = await BaseClient.prototype.getRC(); @@ -620,14 +640,23 @@ export type ManagerSendApiResponse = CreateManagerMessage< nonce: string; } >; -export type ManagerExecuteEval = CreateManagerMessage< - 'EXECUTE_EVAL', +export type ManagerExecuteEvalToWorker = CreateManagerMessage< + 'EXECUTE_EVAL_TO_WORKER', { func: string; nonce: string; toWorkerId: number; } >; + +export type ManagerExecuteEval = CreateManagerMessage< + 'EXECUTE_EVAL', + { + func: string; + nonce: string; + } +>; + export type ManagerSendEvalResponse = CreateManagerMessage< 'EVAL_RESPONSE', { @@ -646,9 +675,10 @@ export type ManagerMessages = | ManagerSendBotReady | ManagerSendApiResponse | ManagerSendEvalResponse - | ManagerExecuteEval + | ManagerExecuteEvalToWorker | ManagerWorkerAlreadyExistsResharding | ManagerSpawnShardsResharding | ManagerAllowConnectResharding | DisconnectAllShardsResharding - | ConnnectAllShardsResharding; + | ConnnectAllShardsResharding + | ManagerExecuteEval; diff --git a/tests/cache.test.mts b/tests/cache.test.mts index ffe0904..f4d9414 100644 --- a/tests/cache.test.mts +++ b/tests/cache.test.mts @@ -1,51 +1,51 @@ -import { describe, test } from 'vitest'; -import { Client, LimitedMemoryAdapter, MemoryAdapter } from '../lib/index'; - -// all intents -const intents = 53608447; - -describe('test memory cache adapter', () => { - const adapter = new MemoryAdapter(); - - test('discord cache', () => { - const client = new Client({ - getRC: () => ({ - locations: { - base: '', - output: '', - }, - intents, - token: '', - }), - }); - client.setServices({ - cache: { - adapter, - }, - }); - return client.cache.testAdapter(); - }); -}); - -describe('test limited memory cache adapter', () => { - const adapter = new LimitedMemoryAdapter(); - - test('discord cache', () => { - const client = new Client({ - getRC: () => ({ - locations: { - base: '', - output: '', - }, - intents, - token: '', - }), - }); - client.setServices({ - cache: { - adapter, - }, - }); - return client.cache.testAdapter(); - }); -}); +import { describe, test } from 'vitest'; +import { Client, LimitedMemoryAdapter, MemoryAdapter } from '../lib/index'; + +// all intents +const intents = 53608447; + +describe('test memory cache adapter', () => { + const adapter = new MemoryAdapter(); + + test('discord cache', () => { + const client = new Client({ + getRC: () => ({ + locations: { + base: '', + output: '', + }, + intents, + token: '', + }), + }); + client.setServices({ + cache: { + adapter, + }, + }); + return client.cache.testAdapter(); + }); +}); + +describe('test limited memory cache adapter', () => { + const adapter = new LimitedMemoryAdapter(); + + test('discord cache', () => { + const client = new Client({ + getRC: () => ({ + locations: { + base: '', + output: '', + }, + intents, + token: '', + }), + }); + client.setServices({ + cache: { + adapter, + }, + }); + return client.cache.testAdapter(); + }); +}); diff --git a/tests/vitest.config.mts b/tests/vitest.config.mts index 692db49..28830d2 100644 --- a/tests/vitest.config.mts +++ b/tests/vitest.config.mts @@ -1,9 +1,8 @@ -// @ts-check -import { defineConfig } from 'vitest/config' - -export default defineConfig({ - test: { - fileParallelism: false, - isolate: false, - }, -}) \ No newline at end of file +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + fileParallelism: false, + isolate: false, + }, +}); diff --git a/tsconfig.json b/tsconfig.json index a67397f..9e8e84b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,6 +23,10 @@ "noErrorTruncation": true, "outDir": "./lib", "stripInternal": true, + "strictBindCallApply": true, + "strictBuiltinIteratorReturn": true, + "strictPropertyInitialization": true, + "alwaysStrict": true, }, "exclude": [ "**/lib", @@ -33,4 +37,4 @@ "include": [ "src" ] -} \ No newline at end of file +}