diff --git a/src/core/functions.ts b/src/core/functions.ts index d9b8861..f3eacb3 100644 --- a/src/core/functions.ts +++ b/src/core/functions.ts @@ -36,7 +36,7 @@ export function partitionPlugins( export function treeSearch( iAutocomplete: AutocompleteInteraction, options: SernOptionsData[] | undefined, -): SernAutocompleteData | undefined { +): SernAutocompleteData & { parent?: string } | undefined { if (options === undefined) return undefined; //clone to prevent mutation of original command module const _options = options.map(a => ({ ...a })); @@ -68,11 +68,11 @@ export function treeSearch( const parentAndOptionMatches = subcommands.has(parent) && cur.name === choice.name; if (parentAndOptionMatches) { - return cur; + return { ...cur, parent }; } } else { if (cur.name === choice.name) { - return cur; + return { ...cur, parent: undefined }; } } } diff --git a/src/handlers/dispatchers.ts b/src/handlers/dispatchers.ts index 4d5e25a..e111467 100644 --- a/src/handlers/dispatchers.ts +++ b/src/handlers/dispatchers.ts @@ -11,7 +11,7 @@ import { import { createResultResolver } from './event-utils'; import { BaseInteraction, Message } from 'discord.js'; import { CommandType, Context } from '../core'; -import type { Args } from '../types/utility'; +import type { AnyFunction, Args } from '../types/utility'; import type { CommandModule, Module, OnError, Processed } from '../types/core-modules'; //TODO: refactor dispatchers so that it implements a strategy for each different type of payload? @@ -32,7 +32,7 @@ function interactionArg(interaction: T) { return [interaction] as [T]; } -function intoPayload(module: Processed, onError: OnError) { +function intoPayload(module: Processed, onError: AnyFunction|undefined) { return pipe( arrayifySource, map(args => ({ module, args, onError })), @@ -41,7 +41,7 @@ function intoPayload(module: Processed, onError: OnError) { const createResult = createResultResolver< Processed, - { module: Processed; args: unknown[], onError: OnError }, + { module: Processed; args: unknown[], onError: AnyFunction|undefined }, unknown[] >({ createStream: ({ module, args }) => from(module.onEvent).pipe(callPlugin(args)), @@ -59,7 +59,7 @@ export function eventDispatcher(module: Processed, onError: OnError, sou module.execute(...args), ); return fromEvent(source, module.name).pipe( - intoPayload(module, onError), + intoPayload(module, onError?.default), concatMap(createResult), execute, ); @@ -83,21 +83,28 @@ export function createDispatcher(payload: { option, Error(SernError.NotSupportedInteraction + ` There is no autocomplete tag for this option`), ); + const { command, name, parent } = option; + const resolvedErrorHandler = parent + ? 'option:'+parent+':'+name + : 'option:'+name return { - module: option.command as Processed, //autocomplete is not a true "module" warning cast! + ...payload, + module: command as Processed, //autocomplete is not a true "module" warning cast! args: [payload.event], - onError: undefined + onError: payload.onError?.[resolvedErrorHandler] }; } return { args: contextArgs(payload.event), - ...payload + ...payload, + onError: payload.onError?.default }; } default: return { args: interactionArg(payload.event), - ...payload + ...payload, + onError: payload.onError?.default } } } diff --git a/src/handlers/event-utils.ts b/src/handlers/event-utils.ts index 559acdf..33cd410 100644 --- a/src/handlers/event-utils.ts +++ b/src/handlers/event-utils.ts @@ -24,11 +24,11 @@ import { useContainerRaw, } from '../core/_internal'; import { Emitter, ErrorHandling, Logging, ModuleManager } from '../core'; -import { contextArgs, createDispatcher, dispatchMessage } from './dispatchers'; +import { contextArgs, createDispatcher } from './dispatchers'; import { ObservableInput, pipe } from 'rxjs'; import { SernEmitter } from '../core'; import { Err, Ok, Result } from 'ts-results-es'; -import type { Awaitable } from '../types/utility'; +import type { AnyFunction, Awaitable } from '../types/utility'; import type { ControlPlugin } from '../types/core-plugin'; import type { AnyModule, CommandModule, Module, OnError, Processed } from '../types/core-modules'; import type { ImportPayload } from '../types/core'; @@ -97,13 +97,13 @@ export function createMessageHandler( const fullPath = mg.get(`${prefix}_A1`); if(!fullPath) { - return Err('Possibly undefined behavior: could not find a static id to resolve ') + return Err('Possibly undefined behavior: could not find a static id to resolve') } return Files .defaultModuleLoader>(fullPath) .then(payload => { const args = contextArgs(event, rest); - return Ok({ args, ...payload }); + return Ok({ args, ...payload, onError: payload.onError?.default }); }); }); } @@ -136,7 +136,8 @@ export function buildModules( interface ExecutePayload { module: Processed; task: () => Awaitable; - onError: OnError + onError: AnyFunction|undefined + args: unknown[] } /** * Wraps the task in a Result as a try / catch. @@ -151,7 +152,8 @@ export function executeModule( { module, task, - onError + onError, + args }: ExecutePayload, ) { return of(module).pipe( @@ -163,7 +165,8 @@ export function executeModule( return EMPTY; } else { if(onError) { - + console.log(onError()) + return EMPTY } return throwError(() => SernEmitter.failure(module, result.error)); } @@ -182,7 +185,7 @@ export function executeModule( */ export function createResultResolver< T extends { execute: (...args: any[]) => any; onEvent: ControlPlugin[] }, - Args extends { module: T; onError: OnError, [key: string]: unknown }, + Args extends { module: T; onError: unknown, [key: string]: unknown }, Output, >(config: { onStop?: (module: T) => unknown; @@ -217,7 +220,7 @@ export function callInitPlugins>(sernEmitter: Emi }, onNext: ({ module, onError }) => { sernEmitter.emit('module.register', SernEmitter.success(module)); - return { module, onError }; + return { module, onError: onError as OnError }; }, }), ); @@ -232,13 +235,14 @@ export function makeModuleExecutor< Args extends { module: M; args: unknown[]; - onError: OnError + onError: AnyFunction|undefined }, >(onStop: (m: M) => unknown) { const onNext = ({ args, module, onError }: Args) => ({ task: () => module.execute(...args), module, - onError + onError, + args }); return concatMap( createResultResolver({ diff --git a/src/handlers/ready-event.ts b/src/handlers/ready-event.ts index f7c8943..017a967 100644 --- a/src/handlers/ready-event.ts +++ b/src/handlers/ready-event.ts @@ -7,7 +7,7 @@ import { buildModules, callInitPlugins } from './_internal'; import * as assert from 'node:assert'; import * as util from 'node:util'; import type { DependencyList } from '../types/ioc'; -import type { AnyModule, OnError, Processed } from '../types/core-modules'; +import type { AnyModule, Processed } from '../types/core-modules'; export function startReadyEvent( [sEmitter, , , moduleManager, client]: DependencyList, @@ -17,11 +17,9 @@ export function startReadyEvent( return concat(ready$, buildModules(allPaths, moduleManager)) .pipe(callInitPlugins(sEmitter)) - .subscribe(({ module, onError }) => { + .subscribe(({ module }) => { register(moduleManager, module) .expect(SernError.InvalidModuleType + ' ' + util.inspect(module)); - registerOnError(moduleManager, module, onError); - }); } @@ -30,11 +28,6 @@ const once = () => pipe( ignoreElements() ) -const registerOnError = (manager: ModuleManager, module: Processed, onError: OnError) => { - if(onError) { - manager.setErrorCallback(module, onError) - } -} function register>( manager: ModuleManager,