refactor deps list

This commit is contained in:
Jacob Nguyen
2024-05-15 00:29:59 -05:00
parent eb8ba6799b
commit ec45f80be6
10 changed files with 54 additions and 47 deletions

View File

@@ -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<Dependencies[K]>
}
type Insertable =
| ((container: UnpackedDependencies) => unknown)
| object

View File

@@ -66,6 +66,10 @@ export class Container {
this.finished_init = true;
}
deps<T extends Record<string,any>>(): T {
return Object.fromEntries(this.__singletons) as T
}
async executeHooks(name: string) {
const hookFunctions = this.hooks.get(name) || [];
for (const hookFunction of hookFunctions) {

View File

@@ -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',

View File

@@ -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<Interaction>(client, 'interactionCreate');
const modules = new Map();
const handle = createInteractionHandler(interactionStream$, modules);
const interactionHandler$ = merge(handle(isMessageComponent),

View File

@@ -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;

View File

@@ -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" });

View File

@@ -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<EventModule> }) => {
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<EventModule>(allPaths)
// pipe(
// callInitPlugins(emitter),

View File

@@ -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<UnpackedDependencies>();
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();
}

View File

@@ -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<string, Module>
];
export interface CoreDependencies {
'@sern/client': () => Client;

View File

@@ -30,4 +30,7 @@ export type Payload =
//https://github.com/molszanski/iti/blob/0a3a006113b4176316c308805314a135c0f47902/iti/src/_utils.ts#L29C1-L29C76
export type UnpackFunction<T> = T extends (...args: any) => infer U ? U : T
export type UnpackedDependencies = {
[K in keyof Dependencies]: UnpackFunction<Dependencies[K]>
}
export type ReplyOptions = string | Omit<InteractionReplyOptions, 'fetchReply'> | MessageReplyOptions;