diff --git a/src/handler/events/userDefinedEventsHandling.ts b/src/handler/events/userDefinedEventsHandling.ts index 99f5633..e706943 100644 --- a/src/handler/events/userDefinedEventsHandling.ts +++ b/src/handler/events/userDefinedEventsHandling.ts @@ -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$( 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, - ); - }) - .when(isDiscordEvent, m => { - return fromEvent( - wrapper.client, - m.name!, - m.execute as SpreadParams, - ); - }) - .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).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, + // ).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, + // ).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(); diff --git a/src/handler/structures/wrapper.ts b/src/handler/structures/wrapper.ts index ea854e8..8b1c59c 100644 --- a/src/handler/structures/wrapper.ts +++ b/src/handler/structures/wrapper.ts @@ -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;