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

fix: rm deprecated class modules, clean up, rm indirection #355

Merged
merged 4 commits into from
Feb 17, 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
4 changes: 2 additions & 2 deletions src/core/_internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ export * from './functions';
export type { VoidResult } from '../types/core-plugin';
export { SernError } from './structures/enums';
export { ModuleStore } from './structures/module-store';
export * as DefaultServices from './structures/services';
export { useContainerRaw } from './ioc/base'
export * as __Services from './structures/services';
export { useContainerRaw } from './ioc/base';

15 changes: 11 additions & 4 deletions src/core/contracts/module-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,19 @@ interface MetadataAccess {
* @internal - direct access to the module manager will be removed in version 4
*/
export interface ModuleManager extends MetadataAccess {
get(id: string): string | undefined;
get(id: string): Module | undefined;

set(id: string, path: string): void;
getPublishableCommands(): Promise<CommandModule[]>;
set(id: string, path: Module): void;
/**
* @deprecated
*/
getPublishableCommands(): CommandModule[];

/*
* @deprecated
*/
getByNameCommandType<T extends CommandType>(
name: string,
commandType: T,
): Promise<CommandModuleDefs[T]> | undefined;
): CommandModuleDefs[T] | undefined;
}
2 changes: 1 addition & 1 deletion src/core/contracts/module-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ import type { CommandMeta, Module } from '../../types/core-modules';
* Represents a core module store that stores IDs mapped to file paths.
*/
export interface CoreModuleStore {
commands: Map<string, string>;
commands: Map<string, Module>;
metadata: WeakMap<Module, CommandMeta>;
}
6 changes: 3 additions & 3 deletions src/core/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import type {
UserContextMenuCommandInteraction,
AutocompleteInteraction
} from 'discord.js';
import { ApplicationCommandOptionType, InteractionType } from 'discord.js'
import { ApplicationCommandOptionType, InteractionType } from 'discord.js';
import { PayloadType, PluginType } from './structures';
import assert from 'assert';
import { Payload } from '../types/utility';
import type { Payload } from '../types/utility';

//function wrappers for empty ok / err
export const ok = /* @__PURE__*/ () => Ok.EMPTY;
Expand Down Expand Up @@ -50,7 +50,7 @@ export function treeSearch(
if (options === undefined) return undefined;
//clone to prevent mutation of original command module
const _options = options.map(a => ({ ...a }));
let subcommands = new Set();
const subcommands = new Set();
while (_options.length > 0) {
const cur = _options.pop()!;
switch (cur.type) {
Expand Down
13 changes: 2 additions & 11 deletions src/core/id.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,10 @@ const TypeMap = new Map<number, number>([
[CommandType.RoleSelect, ComponentType.RoleSelect],
[CommandType.ChannelSelect, ComponentType.ChannelSelect]]);

/*
* Generates a number based on CommandType.
* This corresponds to an ApplicationCommandType or ComponentType
* TextCommands are 0 as they aren't either or.
*/
function apiType(t: CommandType | EventType) {
return TypeMap.get(t)!;
}

/*
* Generates an id based on name and CommandType.
* A is for any ApplicationCommand. C is for any ComponentCommand
* Then, another number generated by apiType function is appended
* Then, another number fetched from TypeMap
*/
export function create(name: string, type: CommandType | EventType) {
if(type == CommandType.Text) {
Expand All @@ -67,7 +58,7 @@ export function create(name: string, type: CommandType | EventType) {
return `${name}_M`;
}
const am = (appBitField & type) !== 0 ? 'A' : 'C';
return `${name}_${am}${apiType(type)}`
return `${name}_${am}${TypeMap.get(type)!}`
}


Expand Down
62 changes: 44 additions & 18 deletions src/core/ioc/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,27 @@ import type { Logging } from '../contracts/logging';
let containerSubject: CoreContainer<Partial<Dependencies>>;

/**
* @deprecated
* @internal
* Don't use this unless you know what you're doing. Destroys old containerSubject if it exists and disposes everything
* then it will swap
*/
export async function __swap_container(c: CoreContainer<Partial<Dependencies>>) {
if(containerSubject) {
await containerSubject.disposeAll()
}
containerSubject = c;
}

/**
* @internal
* Don't use this unless you know what you're doing. Destroys old containerSubject if it exists and disposes everything
* then it will swap
*/
export function __add_container(key: string,v : Insertable) {
containerSubject.add({ [key]: v });
}

/**
* Returns the underlying data structure holding all dependencies.
* Exposes methods from iti
* Use the Service API. The container should be readonly
Expand All @@ -29,19 +49,24 @@ export function disposeAll(logger: Logging|undefined) {
?.disposeAll()
.then(() => logger?.info({ message: 'Cleaning container and crashing' }));
}

const dependencyBuilder = (container: any, excluded: string[] ) => {
type Insertable =
| ((container: CoreContainer<Dependencies>) => unknown )
type Insertable =
| ((container: CoreContainer<Dependencies>) => unknown)
| object
const dependencyBuilder = (container: any, excluded: string[] ) => {
return {
/**
* Insert a dependency into your container.
* Supply the correct key and dependency
*/
add(key: keyof Dependencies, v: Insertable) {
Result.wrap(() => container.add({ [key]: v}))
.expect("Failed to add " + key);
if(typeof v !== 'function') {
Result.wrap(() => container.add({ [key]: v}))
.expect("Failed to add " + key);
} else {
Result.wrap(() =>
container.add((cntr: CoreContainer<Dependencies>) => ({ [key]: v(cntr)} )))
.expect("Failed to add " + key);
}
},
/**
* Exclude any dependencies from being added.
Expand All @@ -57,8 +82,14 @@ const dependencyBuilder = (container: any, excluded: string[] ) => {
* Swap out a preexisting dependency.
*/
swap(key: keyof Dependencies, v: Insertable) {
Result.wrap(() => container.upsert({ [key]: v }))
.expect("Failed to update " + key);
if(typeof v !== 'function') {
Result.wrap(() => container.upsert({ [key]: v}))
.expect("Failed to update " + key);
} else {
Result.wrap(() =>
container.upsert((cntr: CoreContainer<Dependencies>) => ({ [key]: v(cntr)})))
.expect("Failed to update " + key);
}
},
/**
* @param key the key of the dependency
Expand All @@ -82,11 +113,6 @@ type ValidDependencyConfig =
| CallbackBuilder
| DependencyConfiguration;

export const insertLogger = (containerSubject: CoreContainer<any>) => {
containerSubject
.upsert({'@sern/logger': () => new DefaultServices.DefaultLogging});
}


/**
* Given the user's conf, check for any excluded/included dependency keys.
Expand All @@ -101,7 +127,7 @@ function composeRoot(
//container should have no client or logger yet.
const hasLogger = conf.exclude?.has('@sern/logger');
if (!hasLogger) {
insertLogger(container);
__add_container('@sern/logger', new DefaultServices.DefaultLogging);
}
//Build the container based on the callback provided by the user
conf.build(container as CoreContainer<Omit<CoreDependencies, '@sern/client'>>);
Expand All @@ -119,13 +145,13 @@ export async function makeDependencies<const T extends Dependencies>
if(typeof conf === 'function') {
const excluded: string[] = [];
conf(dependencyBuilder(containerSubject, excluded));

//We only include logger if it does not exist
const includeLogger =
!excluded.includes('@sern/logger')
&& !containerSubject.getTokens()['@sern/logger'];
&& !containerSubject.hasKey('@sern/logger');

if(includeLogger) {
insertLogger(containerSubject);
__add_container('@sern/logger', new DefaultServices.DefaultLogging);
}

containerSubject.ready();
Expand Down
9 changes: 3 additions & 6 deletions src/core/ioc/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Container } from 'iti';
import { Disposable } from '../';
import * as assert from 'node:assert';
import { Subject } from 'rxjs';
import { DefaultServices, ModuleStore } from '../_internal';
import { __Services, ModuleStore } from '../_internal';
import * as Hooks from './hooks';
import { EventEmitter } from 'node:events';

Expand All @@ -23,12 +23,11 @@ export class CoreContainer<T extends Partial<Dependencies>> extends Container<T,
.subscribe({ complete: unsubscribe });

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

Expand All @@ -52,8 +51,6 @@ export class CoreContainer<T extends Partial<Dependencies>> extends Container<T,
await super.disposeAll();
}



ready() {
this.ready$.complete();
this.ready$.unsubscribe();
Expand Down
58 changes: 1 addition & 57 deletions src/core/modules.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
import { ClientEvents } from 'discord.js';
import { CommandType, EventType, PluginType } from '../core/structures';
import { EventType } from '../core/structures';
import type {
AnyCommandPlugin,
AnyEventPlugin,
CommandArgs,
ControlPlugin,
EventArgs,
InitPlugin,
} from '../types/core-plugin';
import type {
CommandModule,
EventModule,
InputCommand,
InputEvent,
Module,
} from '../types/core-modules';
import { partitionPlugins } from './_internal';
import type { Awaitable } from '../types/utility';
Expand Down Expand Up @@ -61,53 +55,3 @@ export function discordEvent<T extends keyof ClientEvents>(mod: {
});
}


/**
* @deprecated
*/
function prepareClassPlugins(c: Module) {
const [onEvent, initPlugins] = partitionPlugins(c.plugins);
c.plugins = initPlugins as InitPlugin[];
c.onEvent = onEvent as ControlPlugin[];
}

/**
* @deprecated
* Will be removed in future
*/
export abstract class CommandExecutable<const Type extends CommandType = CommandType> {
abstract type: Type;
plugins: AnyCommandPlugin[] = [];
private static _instance: CommandModule;

static getInstance() {
if (!CommandExecutable._instance) {
//@ts-ignore
CommandExecutable._instance = new this();
prepareClassPlugins(CommandExecutable._instance);
}
return CommandExecutable._instance;
}

abstract execute(...args: CommandArgs<Type, PluginType.Control>): Awaitable<unknown>;
}

/**
* @deprecated
* Will be removed in future
*/
export abstract class EventExecutable<Type extends EventType> {
abstract type: Type;
plugins: AnyEventPlugin[] = [];

private static _instance: EventModule;
static getInstance() {
if (!EventExecutable._instance) {
//@ts-ignore
EventExecutable._instance = new this();
prepareClassPlugins(EventExecutable._instance);
}
return EventExecutable._instance;
}
abstract execute(...args: EventArgs<Type, PluginType.Control>): Awaitable<unknown>;
}
2 changes: 1 addition & 1 deletion src/core/structures/module-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ import { CommandMeta, Module } from '../../types/core-modules';
*/
export class ModuleStore {
metadata = new WeakMap<Module, CommandMeta>();
commands = new Map<string, string>();
commands = new Map<string, Module>();
}
17 changes: 7 additions & 10 deletions src/core/structures/services/module-manager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as Id from '../../../core/id';
import { CoreModuleStore, ModuleManager } from '../../contracts';
import { Files } from '../../_internal';
import { CommandMeta, CommandModule, CommandModuleDefs, Module } from '../../../types/core-modules';
import { CommandType } from '../enums';
/**
Expand All @@ -13,11 +12,11 @@ export class DefaultModuleManager implements ModuleManager {


getByNameCommandType<T extends CommandType>(name: string, commandType: T) {
const id = this.get(Id.create(name, commandType));
if (!id) {
const module = this.get(Id.create(name, commandType));
if (!module) {
return undefined;
}
return Files.importModule<CommandModuleDefs[T]>(id);
return module as CommandModuleDefs[T];
}

setMetadata(m: Module, c: CommandMeta): void {
Expand All @@ -35,20 +34,18 @@ export class DefaultModuleManager implements ModuleManager {
get(id: string) {
return this.moduleStore.commands.get(id);
}
set(id: string, path: string): void {
set(id: string, path: CommandModule): void {
this.moduleStore.commands.set(id, path);
}
//not tested
getPublishableCommands(): Promise<CommandModule[]> {
getPublishableCommands(): CommandModule[] {
const entries = this.moduleStore.commands.entries();
const publishable = 0b000000110;
return Promise.all(
Array.from(entries)
return Array.from(entries)
.filter(([id]) => {
const last_entry = id.at(-1);
return last_entry == 'B' || !(publishable & Number.parseInt(last_entry!));
})
.map(([, path]) => Files.importModule<CommandModule>(path)),
);
.map(([, path]) => path as CommandModule);
}
}
10 changes: 2 additions & 8 deletions src/handlers/dispatchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ import type { CommandModule, Module, Processed } from '../types/core-modules';

//TODO: refactor dispatchers so that it implements a strategy for each different type of payload?
export function dispatchMessage(module: Processed<CommandModule>, args: [Context, Args]) {
return {
module,
args,
};
return { module, args };
}

export function contextArgs(wrappable: Message | BaseInteraction, messageArgs?: string[]) {
Expand Down Expand Up @@ -87,9 +84,6 @@ export function createDispatcher(payload: {
}
return { module: payload.module, args: contextArgs(payload.event) };
}
default: return {
module: payload.module,
args: [payload.event],
};
default: return { module: payload.module, args: [payload.event] };
}
}
Loading
Loading