mirror of
https://github.com/sern-handler/handler
synced 2026-06-06 01:16:55 +00:00
feat: Add basic event handling, no plugins checked yet!
This commit is contained in:
@@ -1,25 +1,19 @@
|
||||
import { CommandType } from '../structures/enums';
|
||||
import { concatMap, from, fromEvent, map, of, throwError } from 'rxjs';
|
||||
import { from, fromEvent, map, throwError } from 'rxjs';
|
||||
import { SernError } from '../structures/errors';
|
||||
import * as Files from '../utilities/readFile';
|
||||
import { buildData, ExternalEventEmitters } from '../utilities/readFile';
|
||||
import { controller } from '../sern';
|
||||
import type {
|
||||
DefinedEventModule,
|
||||
DefinedModule,
|
||||
Override,
|
||||
SpreadParams,
|
||||
} from '../../types/handler';
|
||||
import type { DefinedEventModule, DefinedModule, SpreadParams } from '../../types/handler';
|
||||
import type { EventModule } from '../structures/module';
|
||||
import type Wrapper from '../structures/wrapper';
|
||||
import { basename } from 'path';
|
||||
import { match, P } from 'ts-pattern';
|
||||
import { isDiscordEvent, isExternalEvent, isSernEvent } from '../utilities/predicates';
|
||||
import { errTap } from './observableHandling';
|
||||
import type { CommandPlugin, Controller } from '../plugins/plugin';
|
||||
import type { Awaitable, Client } from 'discord.js';
|
||||
import type { Result } from 'ts-results';
|
||||
import { isDiscordEvent, isSernEvent } from '../utilities/predicates';
|
||||
import type { CommandPlugin } from '../plugins/plugin';
|
||||
import { Err, Ok } from 'ts-results';
|
||||
import { errTap } from './observableHandling';
|
||||
|
||||
/**
|
||||
* Utility function to process command plugins for all Modules
|
||||
* @param client
|
||||
@@ -80,7 +74,10 @@ export function processCommandPlugins$<T extends DefinedModule>(
|
||||
|
||||
export function processEvents(
|
||||
wrapper: Wrapper,
|
||||
events: string | EventModule[] | (() => EventModule[]),
|
||||
events:
|
||||
| string
|
||||
| { mod: EventModule; absPath: string }[]
|
||||
| (() => { mod: EventModule; absPath: string }[]),
|
||||
) {
|
||||
const eventStream$ = eventObservable$(wrapper, events);
|
||||
const normalize$ = eventStream$.pipe(
|
||||
@@ -92,57 +89,139 @@ export function processEvents(
|
||||
};
|
||||
}),
|
||||
);
|
||||
const processPlugins$ = normalize$.pipe(
|
||||
concatMap(mod => {
|
||||
const cmdPluginRes = processCommandPlugins$(wrapper, mod);
|
||||
if (cmdPluginRes.err) {
|
||||
return cmdPluginRes.val;
|
||||
}
|
||||
return of({ mod, cmdPluginRes: cmdPluginRes.val });
|
||||
}),
|
||||
);
|
||||
const processAndLoadEvents$ = processPlugins$.pipe(
|
||||
concatMap(({ mod, cmdPluginRes }) => {
|
||||
return match(mod as DefinedEventModule)
|
||||
.when(isSernEvent, m => {
|
||||
if (wrapper.sernEmitter === undefined) {
|
||||
return throwError(() => SernError.UndefinedSernEmitter);
|
||||
}
|
||||
return fromEvent(
|
||||
wrapper.sernEmitter,
|
||||
m.name!,
|
||||
m.execute as SpreadParams<typeof m.execute>,
|
||||
);
|
||||
})
|
||||
.when(isDiscordEvent, m => {
|
||||
return fromEvent(
|
||||
wrapper.client,
|
||||
m.name!,
|
||||
m.execute as SpreadParams<typeof m.execute>,
|
||||
);
|
||||
})
|
||||
.when(isExternalEvent, m => {
|
||||
if (!ExternalEventEmitters.has(m.emitter)) {
|
||||
throw Error(
|
||||
SernError.UndefinedSernEmitter +
|
||||
`Could not locate
|
||||
a dependency ${m.emitter} to call this event listener`,
|
||||
);
|
||||
}
|
||||
return fromEvent(ExternalEventEmitters.get(m.emitter)!, m.name!, m.execute);
|
||||
})
|
||||
.run();
|
||||
}),
|
||||
);
|
||||
normalize$.subscribe(e => {
|
||||
const emitter = isSernEvent(e)
|
||||
? wrapper?.sernEmitter
|
||||
: isDiscordEvent(e)
|
||||
? wrapper.client
|
||||
: ExternalEventEmitters.get(e.emitter);
|
||||
if (emitter === undefined) {
|
||||
throw new Error(`Cannot find ${emitter}`);
|
||||
}
|
||||
fromEvent(emitter, e.name, e.execute as SpreadParams<typeof e.execute>).subscribe();
|
||||
});
|
||||
|
||||
// TODO
|
||||
// const processPlugins$ = normalize$.pipe(
|
||||
// concatMap(mod => {
|
||||
// const cmdPluginRes = processCommandPlugins$(wrapper, mod);
|
||||
// if (cmdPluginRes.err) {
|
||||
// return cmdPluginRes.val;
|
||||
// }
|
||||
//
|
||||
// return of({ mod, cmdPluginRes });
|
||||
// }),
|
||||
// );
|
||||
// const processAndLoadEvents$ = processPlugins$.pipe(
|
||||
// concatMap(async ({ mod, cmdPluginRes }) => {
|
||||
// return {
|
||||
// mod,
|
||||
// cmdPluginRes,
|
||||
// eventLoaded: match(mod as DefinedEventModule)
|
||||
// .when(isSernEvent, m => {
|
||||
// if (wrapper.sernEmitter === undefined) {
|
||||
// return throwError(() => SernError.UndefinedSernEmitter);
|
||||
// }
|
||||
// return fromEvent(
|
||||
// wrapper.sernEmitter,
|
||||
// m.name!,
|
||||
// m.execute as SpreadParams<typeof m.execute>,
|
||||
// ).pipe(
|
||||
// concatMap(event => {
|
||||
// return of(
|
||||
// m.onEvent.map(plug => ({
|
||||
// ...plug,
|
||||
// name: plug?.name ?? 'Unnamed Plugin',
|
||||
// description: plug?.description ?? '..',
|
||||
// execute: plug.execute(
|
||||
// [event] as [string | Error] | [Payload],
|
||||
// controller,
|
||||
// ),
|
||||
// })),
|
||||
// );
|
||||
// }),
|
||||
// );
|
||||
// })
|
||||
// .when(isDiscordEvent, m => {
|
||||
// return fromEvent(
|
||||
// wrapper.client,
|
||||
// m.name!,
|
||||
// m.execute as SpreadParams<typeof m.execute>,
|
||||
// ).pipe(
|
||||
// concatMap(event => {
|
||||
// return of(
|
||||
// m.onEvent.map(plug => ({
|
||||
// ...plug,
|
||||
// name: plug?.name ?? 'Unnamed Plugin',
|
||||
// description: plug?.description ?? '..',
|
||||
// execute: plug.execute(
|
||||
// [event] as ClientEvents[keyof ClientEvents],
|
||||
// controller,
|
||||
// ),
|
||||
// })),
|
||||
// );
|
||||
// }),
|
||||
// );
|
||||
// })
|
||||
// .when(isExternalEvent, m => {
|
||||
// if (!ExternalEventEmitters.has(m.emitter)) {
|
||||
// throw Error(
|
||||
// SernError.UndefinedSernEmitter +
|
||||
// `Could not locate
|
||||
// a dependency ${m.emitter} to call this event listener`,
|
||||
// );
|
||||
// }
|
||||
// return fromEvent(
|
||||
// ExternalEventEmitters.get(m.emitter)!,
|
||||
// m.name!,
|
||||
// m.execute,
|
||||
// ).pipe(
|
||||
// concatMap(event => {
|
||||
// return of(
|
||||
// m.onEvent.map(plug => ({
|
||||
// ...plug,
|
||||
// name: plug?.name ?? 'Unnamed Plugin',
|
||||
// description: plug?.description ?? '..',
|
||||
// execute: plug.execute([event], controller),
|
||||
// })),
|
||||
// );
|
||||
// }),
|
||||
// );
|
||||
// })
|
||||
// .run(),
|
||||
// };
|
||||
// }),
|
||||
// );
|
||||
// // Cannot send to Sern's emitter because it hasn't been turned on yet. Don't know if
|
||||
// // this will be changed.
|
||||
// processAndLoadEvents$.subscribe({
|
||||
// async next({ cmdPluginRes, eventLoaded, mod }) {
|
||||
// for (const pl of cmdPluginRes) {
|
||||
// const res = isPromise(pl.execute) ? await pl.execute : pl.execute;
|
||||
// if (res.err) {
|
||||
// throw Error(
|
||||
// 'Could not load an event module correctly, a plugin called controller.stop()',
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// eventLoaded.subscribe();
|
||||
// },
|
||||
// error(e) {
|
||||
// wrapper.sernEmitter?.emit('error', e);
|
||||
// },
|
||||
// });
|
||||
}
|
||||
|
||||
function eventObservable$(
|
||||
{ sernEmitter }: Wrapper,
|
||||
events: string | EventModule[] | (() => EventModule[]),
|
||||
events:
|
||||
| string
|
||||
| { mod: EventModule; absPath: string }[]
|
||||
| (() => { mod: EventModule; absPath: string }[]),
|
||||
) {
|
||||
return match(events)
|
||||
.when(Array.isArray, (arr: EventModule[]) => {
|
||||
return from(arr.map(self => ({ mod: self, absPath: __filename })));
|
||||
.when(Array.isArray, (arr: { mod: EventModule; absPath: string }[]) => {
|
||||
return from(arr);
|
||||
})
|
||||
.when(
|
||||
e => typeof e === 'string',
|
||||
@@ -160,8 +239,8 @@ function eventObservable$(
|
||||
)
|
||||
.when(
|
||||
e => typeof e === 'function',
|
||||
(evs: () => EventModule[]) => {
|
||||
return from(evs().map(self => ({ mod: self, absPath: __filename })));
|
||||
(evs: () => { mod: EventModule; absPath: string }[]) => {
|
||||
return from(evs());
|
||||
},
|
||||
)
|
||||
.run();
|
||||
|
||||
@@ -16,7 +16,10 @@ interface Wrapper {
|
||||
readonly sernEmitter?: SernEmitter;
|
||||
readonly defaultPrefix?: string;
|
||||
readonly commands: string;
|
||||
readonly events?: EventModule[] | string | (() => EventModule[]);
|
||||
readonly events?:
|
||||
| string
|
||||
| { mod: EventModule; absPath: string }[]
|
||||
| (() => { mod: EventModule; absPath: string }[]);
|
||||
}
|
||||
|
||||
export default Wrapper;
|
||||
|
||||
Reference in New Issue
Block a user