import { Client, ShardingManager } from 'discord.js'; import type { AutoShardOptions, Logger } from '../types/index.js'; export interface ShardInfo { id: number; status: string; guilds: number; ping: number; uptime: number; } export interface ShardHealth { total: number; online: number; offline: number; shards: ShardInfo[]; averagePing: number; totalGuilds: number; } /** * Automatically handles sharding based on guild count. * Provides auto-scaling for large bots with health monitoring. * * @param token - Discord bot token * @param options - Sharding configuration options * @returns ShardingManager instance * * @example * ```typescript * import { autoShard } from 'djs-helper-kit'; * * const manager = autoShard(process.env.DISCORD_TOKEN!, { * totalShards: 'auto', * respawn: true * }); * * manager.on('shardCreate', shard => { * console.log(`Launched shard ${shard.id}`); * }); * ``` */ export function autoShard(token: string, options: AutoShardOptions = {}): ShardingManager { const { totalShards = 'auto', respawn = true, logger = createDefaultLogger() } = options; const manager = new ShardingManager('./dist/bot.js', { token, totalShards, respawn }); // Handle shard events manager.on('shardCreate', (shard) => { logger.info(`Launched shard ${shard.id}`); }); return manager; } /** * Check health of all shards in a sharded client. * Provides comprehensive health monitoring for large bots. * * @param client - Discord.js client (can be any shard) * @returns Promise resolving to shard health information * * @example * ```typescript * import { shardHealth } from 'djs-helper-kit'; * * // Check health every 5 minutes * setInterval(async () => { * const health = await shardHealth(client); * console.log(`Online shards: ${health.online}/${health.total}`); * console.log(`Average ping: ${health.averagePing}ms`); * }, 300000); * ``` */ export async function shardHealth(client: Client): Promise { // For now, return basic info for single shard // Full implementation would require complex shard communication const shardInfo: ShardInfo = { id: 0, status: client.ws.status.toString(), guilds: client.guilds.cache.size, ping: client.ws.ping, uptime: client.uptime || 0 }; return { total: 1, online: shardInfo.status === 'ready' ? 1 : 0, offline: shardInfo.status === 'ready' ? 0 : 1, shards: [shardInfo], averagePing: shardInfo.ping, totalGuilds: shardInfo.guilds }; } /** * Broadcast a message to all shards. * Useful for updating configuration or sending commands across all shards. * * @param client - Discord.js client (can be any shard) * @param message - Message to broadcast * @returns Promise resolving to responses from all shards * * @example * ```typescript * import { broadcastToShards } from 'djs-helper-kit'; * * // Update configuration across all shards * await broadcastToShards(client, { * type: 'UPDATE_CONFIG', * data: { maintenance: true } * }); * ``` */ export async function broadcastToShards(client: Client, message: unknown): Promise { // For single shard, just emit the event client.emit('broadcast', message); return [true]; } /** * Get guild count across all shards. * * @param client - Discord.js client * @returns Promise resolving to total guild count */ export async function getTotalGuildCount(client: Client): Promise { const health = await shardHealth(client); return health.totalGuilds; } /** * Creates a default logger for sharding operations */ function createDefaultLogger(): Logger { return { debug: (message: string, ...args: unknown[]) => console.debug(`[SHARD] ${message}`, ...args), info: (message: string, ...args: unknown[]) => console.info(`[SHARD] ${message}`, ...args), warn: (message: string, ...args: unknown[]) => console.warn(`[SHARD] ${message}`, ...args), error: (message: string, ...args: unknown[]) => console.error(`[SHARD] ${message}`, ...args), }; }