mirror of
https://github.com/sern-handler/handler
synced 2026-06-14 20:02:16 +00:00
refactor: change loading strategy, eliminate bloat
This commit is contained in:
@@ -17,7 +17,7 @@ import type { Args } from '../../types/handler';
|
||||
import type { MessageComponentInteraction } from 'discord.js';
|
||||
import { ComponentType } from 'discord.js';
|
||||
import type { UnionToTuple } from '../utilities/resolveParameters';
|
||||
import type { Module } from '../structures/modules/commands/module';
|
||||
import type { Module } from '../structures/module';
|
||||
import type { EventPlugin } from '../plugins/plugin';
|
||||
|
||||
|
||||
@@ -90,13 +90,13 @@ export const onInteractionCreate = (wrapper: Wrapper) => {
|
||||
concatMap(interaction => {
|
||||
if (interaction.isCommand()) {
|
||||
const modul =
|
||||
Files.ApplicationCommandStore[interaction.commandType].get(interaction.commandName) ??
|
||||
Files.BothCommand.get(interaction.commandName);
|
||||
Files.ApplicationCommands[interaction.commandType].get(interaction.commandName) ??
|
||||
Files.BothCommands.get(interaction.commandName);
|
||||
return applicationCommandHandler(modul, interaction);
|
||||
}
|
||||
if (interaction.isMessageComponent()) {
|
||||
const modul = Files
|
||||
.MessageCompCommandStore[interaction.componentType]
|
||||
.MessageCompCommands[interaction.componentType]
|
||||
.get(interaction.customId);
|
||||
return messageComponentInteractionHandler(modul, interaction);
|
||||
} else return throwError(() => SernError.NotSupportedInteraction);
|
||||
|
||||
@@ -23,9 +23,9 @@ export const onMessageCreate = (wrapper: Wrapper) => {
|
||||
ctx: Context.wrap(message), //TODO : check for BothCommand
|
||||
args: <Args>['text', rest],
|
||||
mod:
|
||||
Files.ApplicationCommandStore[1].get(prefix) ??
|
||||
Files.BothCommand.get(prefix) ??
|
||||
Files.TextCommandStore.aliases.get(prefix),
|
||||
Files.ApplicationCommands[1].get(prefix) ??
|
||||
Files.BothCommands.get(prefix) ??
|
||||
Files.TextCommands.aliases.get(prefix),
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import type { Message } from 'discord.js';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import type { ModuleDefs } from '../structures/modules/commands/moduleHandler';
|
||||
import { SernError } from '../structures/errors';
|
||||
import { isNotFromBot } from '../utilities/messageHelpers';
|
||||
import type { Module } from '../structures/modules/commands/module';
|
||||
import type { Module, ModuleDefs } from '../structures/module';
|
||||
|
||||
export function correctModuleType<T extends keyof ModuleDefs>(
|
||||
plug: Module | undefined,
|
||||
|
||||
@@ -2,17 +2,13 @@ import { concat, concatMap, from, fromEvent, map, Observable, of, skip, take } f
|
||||
import { basename } from 'path';
|
||||
import * as Files from '../utilities/readFile';
|
||||
import type Wrapper from '../structures/wrapper';
|
||||
import type {
|
||||
HandlerCallback,
|
||||
ModuleHandlers,
|
||||
ModuleStates,
|
||||
ModuleType,
|
||||
} from '../structures/modules/commands/moduleHandler';
|
||||
import { CommandType } from '../sern';
|
||||
import { CommandType, controller } from '../sern';
|
||||
import type { PluginType } from '../plugins/plugin';
|
||||
import { Err, Ok, Result } from 'ts-results';
|
||||
import type { Result } from 'ts-results';
|
||||
import type { Awaitable } from 'discord.js';
|
||||
import type { Module } from '../structures/modules/commands/module';
|
||||
import type { Module } from '../structures/module';
|
||||
import { match, P } from 'ts-pattern';
|
||||
import { ApplicationCommandType, ComponentType } from 'discord.js';
|
||||
|
||||
export const onReady = (wrapper: Wrapper) => {
|
||||
const { client, commands } = wrapper;
|
||||
@@ -32,10 +28,7 @@ export const onReady = (wrapper: Wrapper) => {
|
||||
return {
|
||||
...plug,
|
||||
name: plug?.name ?? 'Unnamed Plugin',
|
||||
execute: plug.execute(client, mod, {
|
||||
next: () => Ok.EMPTY,
|
||||
stop: () => Err.EMPTY,
|
||||
}),
|
||||
execute: plug.execute(client, mod, controller),
|
||||
};
|
||||
});
|
||||
return of({ mod, cmdPluginsRes });
|
||||
@@ -63,7 +56,7 @@ export const onReady = (wrapper: Wrapper) => {
|
||||
.subscribe(({ mod, cmdPluginsRes }) => {
|
||||
const loadedPluginsCorrectly = cmdPluginsRes.every(res => res.execute.ok);
|
||||
if (loadedPluginsCorrectly) {
|
||||
registerModule(mod.name!, mod);
|
||||
registerModule(mod);
|
||||
} else {
|
||||
console.log(`Failed to load command ${mod.name!}`);
|
||||
console.log(mod);
|
||||
@@ -71,34 +64,30 @@ export const onReady = (wrapper: Wrapper) => {
|
||||
});
|
||||
};
|
||||
|
||||
function handler(name: string): ModuleHandlers {
|
||||
return {
|
||||
[CommandType.Text]: (mod) => {
|
||||
mod.alias.forEach(a => Files.TextCommandStore.aliases.set(a, mod));
|
||||
Files.TextCommandStore.text.set(name, mod);
|
||||
},
|
||||
[CommandType.Slash]: (mod) => {
|
||||
Files.ApplicationCommandStore[1].set(name, mod);
|
||||
},
|
||||
[CommandType.Both]: (mod) => {
|
||||
Files.BothCommand.set(name, mod);
|
||||
mod.alias.forEach(a => Files.TextCommandStore.aliases.set(a, mod));
|
||||
},
|
||||
[CommandType.MenuUser]: (mod) => {
|
||||
Files.ApplicationCommandStore[2].set(name, mod);
|
||||
},
|
||||
[CommandType.MenuMsg]: (mod) => {
|
||||
Files.ApplicationCommandStore[3].set(name, mod);
|
||||
},
|
||||
[CommandType.Button]: (mod) => {
|
||||
Files.MessageCompCommandStore[2].set(name, mod);
|
||||
},
|
||||
[CommandType.MenuSelect]: (mod) => {
|
||||
Files.MessageCompCommandStore[2].set(name, mod);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function registerModule<T extends ModuleType>(name: string, mod: ModuleStates[T]) {
|
||||
return (<HandlerCallback<CommandType>>handler(name)[mod.type])(mod);
|
||||
function registerModule(mod : Module) {
|
||||
const name = mod.name!;
|
||||
match<Module>(mod)
|
||||
.with({type : CommandType.Text }, mod => {
|
||||
mod.alias.forEach(a => Files.TextCommands.aliases.set(a, mod));
|
||||
Files.TextCommands.text.set(name, mod);
|
||||
})
|
||||
.with({ type : CommandType.Slash }, mod => {
|
||||
Files.ApplicationCommands[ApplicationCommandType.ChatInput].set(name, mod);
|
||||
})
|
||||
.with( { type : CommandType.Both }, mod => {
|
||||
Files.BothCommands.set(name, mod);
|
||||
mod.alias.forEach(a => Files.TextCommands.aliases.set(a, mod));
|
||||
})
|
||||
.with( { type : CommandType.MenuUser }, mod => {
|
||||
Files.ApplicationCommands[ApplicationCommandType.User].set(name, mod);
|
||||
})
|
||||
.with( { type : CommandType.MenuMsg }, mod => {
|
||||
Files.ApplicationCommands[ApplicationCommandType.Message].set(name, mod);
|
||||
})
|
||||
.with( { type : CommandType.Button }, mod => {
|
||||
Files.ApplicationCommands[ComponentType.Button].set(name, mod);
|
||||
})
|
||||
.with( { type: CommandType.MenuSelect }, mod => {
|
||||
Files.MessageCompCommands[ComponentType.SelectMenu].set(name, mod);
|
||||
})
|
||||
}
|
||||
|
||||
@@ -14,9 +14,8 @@
|
||||
import type { Awaitable, Client } from 'discord.js';
|
||||
import type { Err, Ok, Result } from 'ts-results';
|
||||
import type { Module, Override, Wrapper } from '../..';
|
||||
import type { ModuleDefs } from '../structures/modules/commands/moduleHandler';
|
||||
import type { BaseModule } from '../structures/modules/module';
|
||||
import type { CommandType } from '../sern';
|
||||
import type { BaseModule, ModuleDefs } from '../structures/module';
|
||||
|
||||
|
||||
export interface Controller {
|
||||
|
||||
@@ -4,12 +4,19 @@ import type {
|
||||
ButtonInteraction,
|
||||
MessageContextMenuCommandInteraction,
|
||||
SelectMenuInteraction,
|
||||
UserContextMenuCommandInteraction,
|
||||
} from 'discord.js';
|
||||
import type { Override } from '../../../../types/handler';
|
||||
import type { CommandType } from '../../../sern';
|
||||
import type { BaseModule } from '../module';
|
||||
import type { UserContextMenuCommandInteraction } from 'discord.js';
|
||||
import type { CommandPlugin, EventPlugin } from '../../../plugins/plugin';
|
||||
import type { Override } from '../../types/handler';
|
||||
import type { Args } from '../../types/handler';
|
||||
import type { CommandType } from '../sern';
|
||||
import type { CommandPlugin, EventPlugin } from '../plugins/plugin';
|
||||
import type Context from './context';
|
||||
|
||||
export interface BaseModule {
|
||||
name?: string;
|
||||
description: string;
|
||||
execute: (ctx: Context, args: Args) => Awaitable<void>;
|
||||
}
|
||||
|
||||
//possible refactoring types into interfaces and not types
|
||||
export type TextCommand = {
|
||||
@@ -66,3 +73,15 @@ export type Module =
|
||||
| ContextMenuMsg
|
||||
| ButtonCommand
|
||||
| SelectMenuCommand;
|
||||
|
||||
//https://stackoverflow.com/questions/64092736/alternative-to-switch-statement-for-typescript-discriminated-union
|
||||
// Explicit Module Definitions for mapping
|
||||
export type ModuleDefs = {
|
||||
[CommandType.Text]: TextCommand;
|
||||
[CommandType.Slash]: SlashCommand;
|
||||
[CommandType.Both]: BothCommand;
|
||||
[CommandType.MenuMsg]: ContextMenuMsg;
|
||||
[CommandType.MenuUser]: ContextMenuUser;
|
||||
[CommandType.Button]: ButtonCommand;
|
||||
[CommandType.MenuSelect]: SelectMenuCommand;
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
import { CommandType } from '../../../sern';
|
||||
import type {
|
||||
BothCommand,
|
||||
ButtonCommand,
|
||||
ContextMenuMsg,
|
||||
ContextMenuUser,
|
||||
SelectMenuCommand,
|
||||
SlashCommand,
|
||||
TextCommand,
|
||||
} from './module';
|
||||
//https://stackoverflow.com/questions/64092736/alternative-to-switch-statement-for-typescript-discriminated-union
|
||||
// Explicit Module Definitions for mapping
|
||||
export type ModuleDefs = {
|
||||
[CommandType.Text]: TextCommand;
|
||||
[CommandType.Slash]: SlashCommand;
|
||||
[CommandType.Both]: BothCommand;
|
||||
[CommandType.MenuMsg]: ContextMenuMsg;
|
||||
[CommandType.MenuUser]: ContextMenuUser;
|
||||
[CommandType.Button]: ButtonCommand;
|
||||
[CommandType.MenuSelect]: SelectMenuCommand;
|
||||
};
|
||||
|
||||
//Keys of ModuleDefs
|
||||
export type ModuleType = keyof ModuleDefs;
|
||||
// The keys mapped to a constructed union with its type
|
||||
export type ModuleStates = {
|
||||
[K in ModuleType]: { type: K } & ModuleDefs[K];
|
||||
};
|
||||
// A handler callback that is called on each ModuleDef
|
||||
export type HandlerCallback<K extends ModuleType> = (mod: ModuleStates[K]) => unknown;
|
||||
//An object that acts as the mapped object to handler
|
||||
export type ModuleHandlers = { [K in ModuleType]: HandlerCallback<K> };
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { Awaitable } from 'discord.js';
|
||||
import type { Args } from '../../..';
|
||||
import type Context from '../context';
|
||||
|
||||
export interface BaseModule {
|
||||
name?: string;
|
||||
description: string;
|
||||
execute: (ctx: Context, args: Args) => Awaitable<void>;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import Context from './context';
|
||||
import type { BothCommand, Module, SlashCommand, TextCommand } from './modules/commands/module';
|
||||
import type { BothCommand, Module, SlashCommand, TextCommand } from './module';
|
||||
import type Wrapper from './wrapper';
|
||||
|
||||
export { Context, SlashCommand, TextCommand, BothCommand, Module, Wrapper };
|
||||
|
||||
@@ -2,21 +2,21 @@ import { ApplicationCommandType, ComponentType } from 'discord.js';
|
||||
import { readdirSync, statSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { from, Observable } from 'rxjs';
|
||||
import type { Module } from '../structures/modules/commands/module';
|
||||
import type { Module } from '../structures/module';
|
||||
|
||||
export const BothCommand = new Map<string, Module>();
|
||||
export const ApplicationCommandStore = {
|
||||
export const BothCommands = new Map<string, Module>();
|
||||
export const ApplicationCommands = {
|
||||
[ApplicationCommandType.User]: new Map<string, Module>(),
|
||||
[ApplicationCommandType.Message]: new Map<string, Module>(),
|
||||
[ApplicationCommandType.ChatInput]: new Map<string, Module>(),
|
||||
} as { [K in ApplicationCommandType]: Map<string, Module> };
|
||||
|
||||
export const MessageCompCommandStore = {
|
||||
export const MessageCompCommands = {
|
||||
[ComponentType.Button]: new Map<string, Module>(),
|
||||
[ComponentType.SelectMenu]: new Map<string, Module>(),
|
||||
[ComponentType.TextInput]: new Map<string, Module>(),
|
||||
};
|
||||
export const TextCommandStore = {
|
||||
export const TextCommands = {
|
||||
text: new Map<string, Module>(),
|
||||
aliases: new Map<string, Module>(),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user