diff --git a/src/core/ioc/base.ts b/src/core/ioc/base.ts index 6ab3464..6137a6f 100644 --- a/src/core/ioc/base.ts +++ b/src/core/ioc/base.ts @@ -1,7 +1,7 @@ import type { DependencyConfiguration } from '../../types/ioc'; import { Container } from './container'; import * as __Services from '../structures/default-services'; -import { UnpackFunction } from '../../types/utility'; +import { UnpackedDependencies } from '../../types/utility'; import type { Logging } from '../interfaces'; import { __add_container, __init_container, __swap_container, useContainerRaw } from './global'; @@ -12,9 +12,6 @@ export function disposeAll(logger: Logging|undefined) { } -type UnpackedDependencies = { - [K in keyof Dependencies]: UnpackFunction -} type Insertable = | ((container: UnpackedDependencies) => unknown) | object diff --git a/src/core/ioc/container.ts b/src/core/ioc/container.ts index 1151db6..7ba9828 100644 --- a/src/core/ioc/container.ts +++ b/src/core/ioc/container.ts @@ -66,6 +66,10 @@ export class Container { this.finished_init = true; } + deps>(): T { + return Object.fromEntries(this.__singletons) as T + } + async executeHooks(name: string) { const hookFunctions = this.hooks.get(name) || []; for (const hookFunction of hookFunctions) { diff --git a/src/handlers/event-utils.ts b/src/handlers/event-utils.ts index 763bc8b..40d88bc 100644 --- a/src/handlers/event-utils.ts +++ b/src/handlers/event-utils.ts @@ -20,7 +20,7 @@ import * as Id from '../core/id' import type { Emitter, ErrorHandling, Logging } from '../core/interfaces'; import { PayloadType, SernError } from '../core/structures/enums' import { Err, Ok, Result } from 'ts-results-es'; -import type { Awaitable } from '../types/utility'; +import type { Awaitable, UnpackedDependencies } from '../types/utility'; import type { ControlPlugin } from '../types/core-plugin'; import type { CommandMeta, CommandModule, Module, Processed } from '../types/core-modules'; import { EventEmitter } from 'node:events'; @@ -246,8 +246,10 @@ export function makeModuleExecutor< }) } -export const handleCrash = (err: ErrorHandling,sernemitter: Emitter, log?: Logging) => - pipe(catchError(handleError(err, sernemitter, log)), +export const handleCrash = ({ "@sern/errors": err, + '@sern/emitter': sem, + '@sern/logger': log } : UnpackedDependencies) => + pipe(catchError(handleError(err, sem, log)), finalize(() => { log?.info({ message: 'A stream closed or reached end of lifetime', diff --git a/src/handlers/interaction.ts b/src/handlers/interaction.ts index 7c86da3..c055260 100644 --- a/src/handlers/interaction.ts +++ b/src/handlers/interaction.ts @@ -3,13 +3,18 @@ import { mergeMap, merge, concatMap } from 'rxjs'; import { PayloadType } from '../core/structures/enums'; import { filterTap, sharedEventStream } from '../core/operators' import { createInteractionHandler, executeModule, makeModuleExecutor } from './event-utils'; -import type { DependencyList } from '../types/ioc'; import { SernError } from '../core/structures/enums' import { isAutocomplete, isCommand, isMessageComponent, isModal, resultPayload, } from '../core/functions' +import { UnpackedDependencies } from '../types/utility'; -export function interactionHandler([emitter, err, log, client]: DependencyList) { +export function interactionHandler(deps: UnpackedDependencies) { + //i wish javascript had clojure destructuring + const { '@sern/modules': modules, + '@sern/client': client, + '@sern/logger': log, + '@sern/errors': err, + '@sern/emitter': emitter } = deps const interactionStream$ = sharedEventStream(client, 'interactionCreate'); - const modules = new Map(); const handle = createInteractionHandler(interactionStream$, modules); const interactionHandler$ = merge(handle(isMessageComponent), diff --git a/src/handlers/message.ts b/src/handlers/message.ts index 8c851e5..a1a0556 100644 --- a/src/handlers/message.ts +++ b/src/handlers/message.ts @@ -1,10 +1,10 @@ import { EMPTY, mergeMap, concatMap } from 'rxjs'; import type { Message } from 'discord.js'; -import type { DependencyList } from '../types/ioc'; import { createMessageHandler, executeModule, makeModuleExecutor } from './event-utils'; import { PayloadType, SernError } from '../core/structures/enums' import { resultPayload } from '../core/functions' import { filterTap, sharedEventStream } from '../core/operators' +import { UnpackedDependencies } from '../types/utility'; /** * Ignores messages from any person / bot except itself @@ -19,10 +19,10 @@ function hasPrefix(prefix: string, content: string) { return (prefixInContent.localeCompare(prefix, undefined, { sensitivity: 'accent' }) === 0); } -export function messageHandler( - [emitter, err, log, client, commands]: DependencyList, - defaultPrefix: string | undefined, -) { +export function messageHandler({"@sern/emitter": emitter, '@sern/errors':err, + '@sern/logger': log, '@sern/client': client, + '@sern/modules': commands}: UnpackedDependencies, + defaultPrefix: string | undefined) { if (!defaultPrefix) { log?.debug({ message: 'No prefix found. message handler shutting down' }); return EMPTY; diff --git a/src/handlers/ready.ts b/src/handlers/ready.ts index 38ba398..74474c6 100644 --- a/src/handlers/ready.ts +++ b/src/handlers/ready.ts @@ -1,12 +1,16 @@ -import type { DependencyList } from '../types/ioc'; import * as Files from '../core/module-loading' import { once } from 'events'; import { resultPayload } from '../core/functions'; import { PayloadType } from '..'; import { SernError } from '../core/structures/enums'; import { Module } from '../types/core-modules'; +import { UnpackedDependencies } from '../types/utility'; -export default async function(dir: string, [sEmitter,, log, client, commands]: DependencyList) { +export default async function(dir: string, deps : UnpackedDependencies) { + const { "@sern/client": client, + '@sern/logger': log, + '@sern/emitter': sEmitter, + '@sern/modules': commands} = deps; log?.info({ message: "Waiting on discord client to be ready..." }) await once(client, "ready"); log?.info({ message: "Client signaled ready, registering modules" }); diff --git a/src/handlers/user-defined-events.ts b/src/handlers/user-defined-events.ts index d1ff2fe..40d1977 100644 --- a/src/handlers/user-defined-events.ts +++ b/src/handlers/user-defined-events.ts @@ -1,26 +1,27 @@ import { EventType, SernError } from '../core/structures/enums'; import { eventDispatcher } from './event-utils' -import { Service } from '../core/ioc'; -import type { DependencyList } from '../types/ioc'; import type { EventModule, Processed } from '../types/core-modules'; +import * as Files from '../core/module-loading' +import type { UnpackedDependencies } from '../types/utility'; -export default function( [emitter, err, log, client]: DependencyList, eventDir: string) { +export default function(deps: UnpackedDependencies, eventDir: string) { //code smell const intoDispatcher = (e: { module: Processed }) => { switch (e.module.type) { case EventType.Sern: - return eventDispatcher(e.module, emitter); + return eventDispatcher(e.module, deps['@sern/emitter']); case EventType.Discord: - return eventDispatcher(e.module, client); + return eventDispatcher(e.module, deps['@sern/client']); case EventType.External: - return eventDispatcher(e.module, Service(e.module.emitter)); + return eventDispatcher(e.module, deps[e.module.emitter]); case EventType.Cron: - //@ts-ignore - return eventDispatcher(e.module, Service('@sern/cron')) + //@ts-ignore TODO + return eventDispatcher(e.module, deps['@sern/cron']) default: throw Error(SernError.InvalidModuleType + ' while creating event handler'); } }; + Files.readRecursive(eventDir) //buildModules(allPaths) // pipe( // callInitPlugins(emitter), diff --git a/src/sern.ts b/src/sern.ts index 8e865a6..49aeb6f 100644 --- a/src/sern.ts +++ b/src/sern.ts @@ -9,11 +9,13 @@ import { interactionHandler } from './handlers/interaction'; import { presenceHandler } from './handlers/presence'; import { Client } from 'discord.js'; import { handleCrash } from './handlers/event-utils'; +import { useContainerRaw } from './core/ioc/global'; +import { UnpackedDependencies } from './types/utility'; interface Wrapper { commands: string; defaultPrefix?: string; - events: string; + events?: string; } /** * @since 1.0.0 @@ -27,27 +29,22 @@ interface Wrapper { * }) * ``` */ -export function init(maybeWrapper: Wrapper = { commands: "./dist/commands", events: "./dist/events" }) { + +export function init(maybeWrapper: Wrapper = { commands: "./dist/commands" }) { const startTime = performance.now(); - const dependencies = Services('@sern/emitter', - '@sern/errors', - '@sern/logger', - '@sern/client', - '@sern/modules'); - const logger = dependencies[2], - errorHandler = dependencies[1]; + const deps = useContainerRaw().deps(); if (maybeWrapper.events !== undefined) { - eventsHandler(dependencies, maybeWrapper.events); + eventsHandler(deps, maybeWrapper.events); } const initCallsite = callsites()[1].getFileName(); const presencePath = Files.shouldHandle(initCallsite!, "presence"); //Ready event: load all modules and when finished, time should be taken and logged - ready(maybeWrapper.commands, dependencies) + ready(maybeWrapper.commands, deps) .then(() => { const time = ((performance.now() - startTime) / 1000).toFixed(2); - logger?.info({ message: `sern: registered in ${time} s`, }); + deps['@sern/logger']?.info({ message: `sern: registered in ${time} s` }); if(presencePath.exists) { const setPresence = async (p: any) => { //@ts-ignore @@ -58,8 +55,8 @@ export function init(maybeWrapper: Wrapper = { commands: "./dist/commands", even }) .catch(err => { throw err }); - const messages$ = messageHandler(dependencies, maybeWrapper.defaultPrefix); - const interactions$ = interactionHandler(dependencies); + const messages$ = messageHandler(deps, maybeWrapper.defaultPrefix); + const interactions$ = interactionHandler(deps); // listening to the message stream and interaction stream - merge(messages$, interactions$).pipe(handleCrash(errorHandler, dependencies[0], logger)).subscribe(); + merge(messages$, interactions$).pipe(handleCrash(deps)).subscribe(); } diff --git a/src/types/ioc.ts b/src/types/ioc.ts index 8fc92e3..cac4d3f 100644 --- a/src/types/ioc.ts +++ b/src/types/ioc.ts @@ -3,13 +3,7 @@ import * as Contracts from '../core/interfaces'; import type { UnpackFunction } from './utility' import type { Client } from 'discord.js' import { Module } from './core-modules'; -export type DependencyList = [ - Contracts.Emitter, - Contracts.ErrorHandling, - Contracts.Logging | undefined, - Client, - Map -]; + export interface CoreDependencies { '@sern/client': () => Client; diff --git a/src/types/utility.ts b/src/types/utility.ts index 60fad87..d215ea1 100644 --- a/src/types/utility.ts +++ b/src/types/utility.ts @@ -30,4 +30,7 @@ export type Payload = //https://github.com/molszanski/iti/blob/0a3a006113b4176316c308805314a135c0f47902/iti/src/_utils.ts#L29C1-L29C76 export type UnpackFunction = T extends (...args: any) => infer U ? U : T +export type UnpackedDependencies = { + [K in keyof Dependencies]: UnpackFunction +} export type ReplyOptions = string | Omit | MessageReplyOptions;