Skip to content

Commit

Permalink
freeze module after plugins, updateModule, and more
Browse files Browse the repository at this point in the history
  • Loading branch information
jacoobes committed May 18, 2024
1 parent 6717672 commit 960f90c
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 26 deletions.
4 changes: 2 additions & 2 deletions src/core/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import { PayloadType, PluginType } from './structures/enums';
import assert from 'assert';
import type { Payload } from '../types/utility';

export const ok = (val: unknown) => Ok(val);
export const err = (val: string) => Err(val);
export const ok = (val: unknown=undefined) => Ok(val);
export const err = (val?: string) => Err(val);

export function partitionPlugins<T,V>
(arr: Array<{ type: PluginType }> = []): [T[], V[]] {
Expand Down
1 change: 0 additions & 1 deletion src/handlers/event-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ export function createMessageHandler(
) {
return createGenericHandler(source, async event => {
const [prefix] = fmt(event.content, defaultPrefix);
console.log(prefix)
let module= mg.get(`${prefix}_T`) ?? mg.get(`${prefix}_B`) as Module;
if(!module) {
return Err('Possibly undefined behavior: could not find a static id to resolve');
Expand Down
12 changes: 10 additions & 2 deletions src/handlers/ready.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,26 @@ export default async function(dir: string, deps : UnpackedDependencies) {
// https://observablehq.com/@ehouais/multiple-promises-as-an-async-generator
// possibly optimize to concurrently import modules
for await (const path of Files.readRecursive(dir)) {
const { module } = await Files.importModule<Module>(path);
let { module } = await Files.importModule<Module>(path);
const validType = module.type >= CommandType.Text && module.type <= CommandType.ChannelSelect;
if(!validType) {
throw Error(`Found ${module.name} at ${module.meta.absPath}, which has an incorrect \`type\``);
}
for(const plugin of module.plugins) {
const res = await plugin.execute({ module, absPath: module.meta.absPath });
const res = await plugin.execute({
module,
absPath: module.meta.absPath ,
updateModule: (partial: Partial<Module>) => {
module = { ...module, ...partial };
return module;
}
});
if(res.isErr()) {
sEmitter.emit('module.register', resultPayload(PayloadType.Failure, module, SernError.PluginFailure));
throw Error("Plugin failed with controller.stop()");
}
}
Object.freeze(module); // no more writing!!
commands.set(module.meta.id, module);
sEmitter.emit('module.register', resultPayload(PayloadType.Success, module));
}
Expand Down
8 changes: 4 additions & 4 deletions src/types/core-modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export interface ModalSubmitCommand extends Module {
}

export interface AutocompleteCommand
extends Omit<Module, 'name' | 'type' | 'plugins' | 'description'> {
extends Omit<Module, 'name' | 'type' | 'plugins' | 'description' | 'meta'> {
onEvent: ControlPlugin[];
execute: (ctx: AutocompleteInteraction) => Awaitable<unknown>;
}
Expand All @@ -117,21 +117,21 @@ export interface DiscordEventCommand<T extends keyof ClientEvents = keyof Client
}
export interface TextCommand extends Module {
type: CommandType.Text;
execute: (ctx: Context, args: ['text', string[]]) => Awaitable<unknown>;
execute: (ctx: Context) => Awaitable<unknown>;
}

export interface SlashCommand extends Module {
type: CommandType.Slash;
description: string;
options?: SernOptionsData[];
execute: (ctx: Context, args: ['slash', SlashOptions]) => Awaitable<unknown>;
execute: (ctx: Context) => Awaitable<unknown>;
}

export interface BothCommand extends Module {
type: CommandType.Both;
description: string;
options?: SernOptionsData[];
execute: (ctx: Context, args: Args) => Awaitable<unknown>;
execute: (ctx: Context) => Awaitable<unknown>;
}

export type EventModule = DiscordEventCommand | SernEventCommand | ExternalEventCommand | CronEventCommand;
Expand Down
35 changes: 18 additions & 17 deletions src/types/core-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* Plugins are reminiscent of middleware in express.
*/

import type { Err, Ok } from 'ts-results-es';
import type { Err, Ok, Result } from 'ts-results-es';
import type {
BothCommand,
ButtonCommand,
Expand All @@ -33,7 +33,7 @@ import type {
TextCommand,
UserSelectCommand,
} from './core-modules';
import type { Args, Awaitable, Payload, SlashOptions, VoidResult } from './utility';
import type { Args, Awaitable, Payload, SlashOptions } from './utility';
import type { CommandType, EventType, PluginType } from '../core/structures/enums'
import type { Context } from '../core/structures/context'
import type {
Expand All @@ -49,11 +49,12 @@ import type {
UserSelectMenuInteraction,
} from 'discord.js';

export type PluginResult = Awaitable<VoidResult>;
export type PluginResult = Awaitable<Result<unknown, unknown>>;

export interface InitArgs<T extends Processed<Module>> {
module: T;
absPath: string;
updateModule: (module: Partial<T>) => T
}
export interface Controller {
next: () => Ok<void>;
Expand All @@ -73,8 +74,8 @@ export interface ControlPlugin<Args extends any[] = any[]> {
execute: (...args: Args) => PluginResult;
}

export type AnyCommandPlugin = ControlPlugin | InitPlugin<[InitArgs<Processed<CommandModule>>]>;
export type AnyEventPlugin = ControlPlugin | InitPlugin<[InitArgs<Processed<EventModule>>]>;
export type AnyCommandPlugin = ControlPlugin | InitPlugin<[InitArgs<Processed<Module>>]>;
export type AnyEventPlugin = ControlPlugin | InitPlugin<[InitArgs<Processed<Module>>]>;

export type CommandArgs<
I extends CommandType = CommandType,
Expand All @@ -88,51 +89,51 @@ export type EventArgs< I extends EventType = EventType,
interface CommandArgsMatrix {
[CommandType.Text]: {
[PluginType.Control]: [Context, ['text', string[]]];
[PluginType.Init]: [InitArgs<Processed<TextCommand>>];
[PluginType.Init]: [InitArgs<Processed<Module>>];
};
[CommandType.Slash]: {
[PluginType.Control]: [Context, ['slash', /* library coupled */ SlashOptions]];
[PluginType.Init]: [InitArgs<Processed<SlashCommand>>];
[PluginType.Init]: [InitArgs<Processed<Module>>];
};
[CommandType.Both]: {
[PluginType.Control]: [Context, Args];
[PluginType.Init]: [InitArgs<Processed<BothCommand>>];
[PluginType.Init]: [InitArgs<Processed<Module>>];
};
[CommandType.CtxMsg]: {
[PluginType.Control]: [/* library coupled */ MessageContextMenuCommandInteraction];
[PluginType.Init]: [InitArgs<Processed<ContextMenuMsg>>];
[PluginType.Init]: [InitArgs<Processed<Module>>];
};
[CommandType.CtxUser]: {
[PluginType.Control]: [/* library coupled */ UserContextMenuCommandInteraction];
[PluginType.Init]: [InitArgs<Processed<ContextMenuUser>>];
[PluginType.Init]: [InitArgs<Processed<Module>>];
};
[CommandType.Button]: {
[PluginType.Control]: [/* library coupled */ ButtonInteraction];
[PluginType.Init]: [InitArgs<Processed<ButtonCommand>>];
[PluginType.Init]: [InitArgs<Processed<Module>>];
};
[CommandType.StringSelect]: {
[PluginType.Control]: [/* library coupled */ StringSelectMenuInteraction];
[PluginType.Init]: [InitArgs<Processed<StringSelectCommand>>];
[PluginType.Init]: [InitArgs<Processed<Module>>];
};
[CommandType.RoleSelect]: {
[PluginType.Control]: [/* library coupled */ RoleSelectMenuInteraction];
[PluginType.Init]: [InitArgs<Processed<RoleSelectCommand>>];
[PluginType.Init]: [InitArgs<Processed<Module>>];
};
[CommandType.ChannelSelect]: {
[PluginType.Control]: [/* library coupled */ ChannelSelectMenuInteraction];
[PluginType.Init]: [InitArgs<Processed<ChannelSelectCommand>>];
[PluginType.Init]: [InitArgs<Processed<Module>>];
};
[CommandType.MentionableSelect]: {
[PluginType.Control]: [/* library coupled */ MentionableSelectMenuInteraction];
[PluginType.Init]: [InitArgs<Processed<MentionableSelectCommand>>];
[PluginType.Init]: [InitArgs<Processed<Module>>];
};
[CommandType.UserSelect]: {
[PluginType.Control]: [/* library coupled */ UserSelectMenuInteraction];
[PluginType.Init]: [InitArgs<Processed<UserSelectCommand>>];
[PluginType.Init]: [InitArgs<Processed<Module>>];
};
[CommandType.Modal]: {
[PluginType.Control]: [/* library coupled */ ModalSubmitInteraction];
[PluginType.Init]: [InitArgs<Processed<ModalSubmitCommand>>];
[PluginType.Init]: [InitArgs<Processed<Module>>];
};
}

Expand Down

0 comments on commit 960f90c

Please sign in to comment.