Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: minor #347

Merged
merged 5 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/core/create-plugins.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CommandType, EventType, PluginType } from './structures';
import type { Plugin, PluginResult, EventArgs, CommandArgs } from '../types/core-plugin';
import type { ClientEvents } from 'discord.js';
import { err, ok } from './functions';

export function makePlugin<V extends unknown[]>(
type: PluginType,
Expand Down Expand Up @@ -60,3 +61,12 @@ export function DiscordEventControlPlugin<T extends keyof ClientEvents>(
) {
return makePlugin(PluginType.Control, execute);
}

/**
* @since 1.0.0
* The object passed into every plugin to control a command's behavior
*/
export const controller = {
next: ok,
stop: err,
};
2 changes: 1 addition & 1 deletion src/core/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function treeSearch(
const choice = iAutocomplete.options.getFocused(true);
assert(
'command' in cur,
'No command property found for autocomplete option',
'No `command` property found for autocomplete option',
);
if (subcommands.size > 0) {
const parent = iAutocomplete.options.getSubcommand();
Expand Down
1 change: 1 addition & 0 deletions src/core/id.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const CommandTypeDiscordApi = [
ComponentType.MentionableSelect,
ComponentType.ChannelSelect,
];

/*
* Generates a number based on CommandType.
* This corresponds to an ApplicationCommandType or ComponentType
Expand Down
11 changes: 9 additions & 2 deletions src/core/ioc/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { CoreContainer } from './container';
import { Result } from 'ts-results-es'
import { DefaultServices } from '../_internal';
import { AnyFunction } from '../../types/utility';
import type { Logging } from '../contracts/logging';
//SIDE EFFECT: GLOBAL DI
let containerSubject: CoreContainer<Partial<Dependencies>>;

Expand All @@ -22,6 +23,12 @@ export function useContainerRaw() {
return containerSubject;
}

export function disposeAll(logger: Logging|undefined) {
containerSubject
?.disposeAll()
.then(() => logger?.info({ message: 'Cleaning container and crashing' }));
}

const dependencyBuilder = (container: any, excluded: string[]) => {
type Insertable =
| ((container: CoreContainer<Dependencies>) => unknown )
Expand Down Expand Up @@ -82,16 +89,16 @@ export const insertLogger = (containerSubject: CoreContainer<any>) => {
}
export async function makeDependencies<const T extends Dependencies>
(conf: ValidDependencyConfig) {
//Until there are more optional dependencies, just check if the logger exists
//SIDE EFFECT
containerSubject = new CoreContainer();
if(typeof conf === 'function') {
const excluded: string[] = [];
conf(dependencyBuilder(containerSubject, excluded));

if(!excluded.includes('@sern/logger')
&& !containerSubject.getTokens()['@sern/logger']) {
insertLogger(containerSubject);
}

containerSubject.ready();
} else {
composeRoot(containerSubject, conf);
Expand Down
11 changes: 5 additions & 6 deletions src/core/ioc/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,18 @@ export class CoreContainer<T extends Partial<Dependencies>> extends Container<T,

(this as Container<{}, {}>)
.add({ '@sern/errors': () => new DefaultServices.DefaultErrorHandling(),
'@sern/emitter': () => new SernEmitter(),
'@sern/store': () => new ModuleStore() })
'@sern/emitter': () => new SernEmitter,
'@sern/store': () => new ModuleStore })
.add(ctx => {
return {
'@sern/modules': () =>
new DefaultServices.DefaultModuleManager(ctx['@sern/store']),
};
return { '@sern/modules': () =>
new DefaultServices.DefaultModuleManager(ctx['@sern/store']) };
});
}

isReady() {
return this.ready$.closed;
}

override async disposeAll() {

const otherDisposables = Object
Expand Down
1 change: 0 additions & 1 deletion src/core/module-loading.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ export function loadConfig(wrapper: Wrapper | 'file'): Wrapper {
eventsPath = makePath('events');
console.log('Events path is set to', eventsPath);
}


return {
defaultPrefix: config.defaultPrefix,
Expand Down
6 changes: 3 additions & 3 deletions src/core/modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ export abstract class CommandExecutable<const Type extends CommandType = Command
}

/**
* @deprecated
* Will be removed in future
*/
* @deprecated
* Will be removed in future
*/
export abstract class EventExecutable<Type extends EventType> {
abstract type: Type;
plugins: AnyEventPlugin[] = [];
Expand Down
15 changes: 6 additions & 9 deletions src/core/operators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,15 @@ export function filterMapTo<V>(item: () => V): OperatorFunction<boolean, V> {
return concatMap(shouldKeep => (shouldKeep ? of(item()) : EMPTY));
}

interface PluginExecutable {
execute: (...args: unknown[]) => PluginResult;
};
/**
* Calls any plugin with {args}.
* @param args if an array, its spread and plugin called.
*/
export function callPlugin(args: unknown): OperatorFunction<
{
execute: (...args: unknown[]) => PluginResult;
},
VoidResult
> {
export function callPlugin(args: unknown): OperatorFunction<PluginExecutable, VoidResult>
{
return concatMap(async plugin => {
if (Array.isArray(args)) {
return plugin.execute(...args);
Expand Down Expand Up @@ -79,8 +78,6 @@ export const filterTap = <K, R>(onErr: (e: R) => void): OperatorFunction<Result<
}
onErr(result.error);
return EMPTY

})
)
}))


41 changes: 0 additions & 41 deletions src/core/structures/command-error.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/core/structures/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export class Context extends CoreContext<Message, ChatInputCommandInteraction> {
if ('interaction' in wrappable) {
return new Context(Ok(wrappable));
}
assert.ok(wrappable.isChatInputCommand());
assert.ok(wrappable.isChatInputCommand(), "Context created with bad interaction.");
return new Context(Err(wrappable));
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/structures/core-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as assert from 'node:assert';
*/
export abstract class CoreContext<M, I> {
protected constructor(protected ctx: Either<M, I>) {
assert.ok(typeof ctx === 'object' && ctx != null);
assert.ok(typeof ctx === 'object' && ctx != null, "Context was nonobject or null");
}
get message(): M {
return this.ctx.expect(SernError.MismatchEvent);
Expand Down
1 change: 0 additions & 1 deletion src/core/structures/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ export * from './context';
export * from './sern-emitter';
export * from './services';
export * from './module-store';
export * as CommandError from './command-error';
6 changes: 2 additions & 4 deletions src/handlers/dispatchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { createResultResolver } from './event-utils';
import { BaseInteraction, Message } from 'discord.js';
import { CommandType, Context } from '../core';
import type { AnyFunction, Args } from '../types/utility';
import { inspect } from 'node:util'
import type { CommandModule, Module, Processed } from '../types/core-modules';

//TODO: refactor dispatchers so that it implements a strategy for each different type of payload?
Expand Down Expand Up @@ -75,10 +76,7 @@ export function createDispatcher(payload: {
case CommandType.Both: {
if (isAutocomplete(payload.event)) {
const option = treeSearch(payload.event, payload.module.options);
assert.ok(
option,
Error(SernError.NotSupportedInteraction + ` There is no autocomplete tag for this option`),
);
assert.ok(option, SernError.NotSupportedInteraction + ` There is no autocomplete tag for ` + inspect(payload.module));
const { command, name, parent } = option;

return {
Expand Down
25 changes: 11 additions & 14 deletions src/handlers/event-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ import {
handleError,
SernError,
VoidResult,
useContainerRaw,
} from '../core/_internal';
import { Emitter, ErrorHandling, Logging, ModuleManager } from '../core';
import { contextArgs, createDispatcher } from './dispatchers';
import { ObservableInput, pipe } from 'rxjs';
import { SernEmitter } from '../core';
import { Err, Ok, Result } from 'ts-results-es';
import type { AnyFunction, Awaitable } from '../types/utility';
import type { Awaitable } from '../types/utility';
import type { ControlPlugin } from '../types/core-plugin';
import type { AnyModule, CommandModule, Module, Processed } from '../types/core-modules';
import type { ImportPayload } from '../types/core';
import { disposeAll } from '../core/ioc/base';

function createGenericHandler<Source, Narrowed extends Source, Output>(
source: Observable<Source>,
Expand Down Expand Up @@ -77,11 +77,10 @@ export function createInteractionHandler<T extends Interaction>(
}
return Files
.defaultModuleLoader<Processed<CommandModule>>(fullPath)
.then(payload =>
Ok(createDispatcher({
module: payload.module,
event,
})));
.then(payload => Ok(createDispatcher({
module: payload.module,
event,
})));
},
);
}
Expand All @@ -100,10 +99,9 @@ export function createMessageHandler(
}
return Files
.defaultModuleLoader<Processed<CommandModule>>(fullPath)
.then((payload)=> {
.then(payload => {
const args = contextArgs(event, rest);
return Ok({ args, ...payload });

});
});
}
Expand Down Expand Up @@ -172,6 +170,8 @@ export function executeModule(
);
}



/**
* A higher order function that
* - creates a stream of {@link VoidResult} { config.createStream }
Expand Down Expand Up @@ -258,8 +258,5 @@ export const handleCrash = (err: ErrorHandling, log?: Logging) =>
log?.info({
message: 'A stream closed or reached end of lifetime',
});
useContainerRaw()
?.disposeAll()
.then(() => log?.info({ message: 'Cleaning container and crashing' }));
}),
);
disposeAll(log);
}));
3 changes: 1 addition & 2 deletions src/handlers/interaction-event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,5 @@ export function interactionHandler([emitter, err, log, modules, client]: Depende
filterTap(e => emitter.emit('warning', SernEmitter.warning(e))),
makeModuleExecutor(module =>
emitter.emit('module.activate', SernEmitter.failure(module, SernError.PluginFailure))),
mergeMap(payload => executeModule(emitter, log, err, payload)),
);
mergeMap(payload => executeModule(emitter, log, err, payload)));
}
3 changes: 1 addition & 2 deletions src/handlers/message-event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,5 @@ export function messageHandler(
makeModuleExecutor(module => {
emitter.emit('module.activate', SernEmitter.failure(module, SernError.PluginFailure));
}),
mergeMap(payload => executeModule(emitter, log, err, payload)),
);
mergeMap(payload => executeModule(emitter, log, err, payload)));
}
2 changes: 1 addition & 1 deletion src/handlers/presence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@ export const presenceHandler = (path: string, setPresence: SetPresence) => {
//concatMap resolves the promise, and passes it to the next concatMap.
concatMap(fn => parseConfig(fn())),
// subscribe to the observable parseConfig yields, and set the presence.
concatMap(conf => conf.pipe(map(setPresence))))
concatMap(conf => conf.pipe(map(setPresence))));
}
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,3 @@ export * as Presence from './core/presences'
export {
useContainerRaw
} from './core/_internal'
export { controller } from './sern';
9 changes: 1 addition & 8 deletions src/sern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,4 @@ function useDependencies() {
);
}

/**
* @since 1.0.0
* The object passed into every plugin to control a command's behavior
*/
export const controller = {
next: ok,
stop: err,
};