From ff478123a870b9491b2deb62583bdf6bf43e775f Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Fri, 5 May 2023 23:31:51 -0500 Subject: [PATCH] chore: revert multi and clean up code --- src/classic/context.ts | 12 ++-- src/commands.ts | 63 +++++++---------- src/core/dependencies.ts | 12 +++- src/core/functions.ts | 4 +- src/core/index.ts | 5 +- src/core/io.ts | 67 ------------------ src/core/module-loading.ts | 105 +++++++++++++++-------------- src/core/platform.ts | 5 +- src/core/plugins/index.ts | 2 +- src/core/sernEmitter.ts | 87 ------------------------ src/core/structures/sernEmitter.ts | 6 +- src/handler/events/generic.ts | 2 +- src/handler/events/userDefined.ts | 2 +- src/handler/sern.ts | 2 +- src/index.ts | 2 +- src/serverless/sern.ts | 24 ------- src/types/handler.ts | 3 - 17 files changed, 107 insertions(+), 296 deletions(-) delete mode 100644 src/core/io.ts delete mode 100644 src/core/sernEmitter.ts delete mode 100644 src/serverless/sern.ts diff --git a/src/classic/context.ts b/src/classic/context.ts index 81597d1..d0a361d 100644 --- a/src/classic/context.ts +++ b/src/classic/context.ts @@ -8,19 +8,19 @@ import { User } from "discord.js"; import { CoreContext } from "../core/structures/context"; -import { Result as Either, Ok as Right, Err as Left } from 'ts-results-es'; +import { Result , Ok , Err } from 'ts-results-es'; import { ReplyOptions } from "../types/handler"; /** * @since 1.0.0 * Provides values shared between * Message and ChatInputCommandInteraction */ -export default class Context extends CoreContext { +export class Context extends CoreContext { get options() { return this.interaction.options } - protected constructor(protected ctx: Either) { + protected constructor(protected ctx: Result) { super(ctx) } @@ -77,14 +77,14 @@ export default class Context extends CoreContext(res: Either) { +function safeUnwrap(res: Result) { return res.val; } diff --git a/src/commands.ts b/src/commands.ts index b311640..f1172c6 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1,13 +1,12 @@ import { ClientEvents } from "discord.js"; import { CommandType, EventType, PluginType } from "./core/structures"; -import { AnyEventPlugin, ControlPlugin, InitPlugin, Plugin } from "./types/plugin"; -import { Awaitable } from "./types/handler"; -import { CommandModule, CommandModuleDefs, EventModule, EventModuleDefs, InputCommand, InputEvent } from "./types/module"; +import { AnyEventPlugin, Plugin } from "./types/plugin"; +import { CommandModule, EventModule, InputCommand, InputEvent } from "./types/module"; import { partition } from "./core/functions"; import { filename, filePath } from "./core/module-loading"; -import { fileURLToPath } from "url"; +import { Awaitable } from "./types/handler"; export const sernMeta = Symbol('@sern/meta') - +const appBitField = 0b000000011111; /* * Generates a number based on CommandType. * This corresponds to an ApplicationCommandType or ComponentType @@ -15,7 +14,10 @@ export const sernMeta = Symbol('@sern/meta') */ function apiType(t: CommandType) { if(t === CommandType.Both || t === CommandType.Modal) return 1; - return Math.log2(t) - 2; + const log = Math.log2(t); + return (appBitField & t) !== 0 + ? log + : log-2; } /* @@ -24,10 +26,10 @@ function apiType(t: CommandType) { * Then, another number generated by apiType function is appended */ function uniqueId(t: CommandType) { - const appBitField = 0b000000011111; const am = ((appBitField & t) !== 0) ? 'A' : 'C'; return am+apiType(t); } + /** * @since 1.0.0 The wrapper function to define command modules for sern * @param mod @@ -37,16 +39,17 @@ export function commandModule(mod: InputCommand): CommandModule { mod.plugins ?? [], el => (el as Plugin).type === PluginType.Control, ); - const path = filePath() - const name = mod.name ?? filename(path) + const fullPath = filePath() + const name = mod.name ?? filename(fullPath) return { ...mod, + description: mod.description ?? "...", name, onEvent, plugins, [sernMeta]: { id: `${name}__${uniqueId(mod.type)}`, - fullPath: fileURLToPath(path), + fullPath, } } as CommandModule; } @@ -60,20 +63,20 @@ export function eventModule(mod: InputEvent): EventModule { mod.plugins ?? [], el => (el as Plugin).type === PluginType.Control, ); - const path = filePath(); + const fullPath = filePath(); return { - ...mod, - name: mod.name ?? filename(path), + name: mod.name ?? filename(fullPath), onEvent, plugins, [sernMeta]: { - id: 'string' - } + id: 'no-id', + fullPath + }, + ...mod, } as EventModule; } -/** - * Create event modules from discord.js client events, +/** Create event modules from discord.js client events, * This is an {@link eventModule} for discord events, * where typings can be very bad. * @param mod @@ -83,27 +86,9 @@ export function discordEvent(mod: { plugins?: AnyEventPlugin[]; execute: (...args: ClientEvents[T]) => Awaitable; }) { - return eventModule({ type: EventType.Discord, ...mod }); + return eventModule({ + type: EventType.Discord, + ...mod + }); } - -/** - * @Experimental - * Will be refactored / changed in future - */ -export abstract class CommandExecutable { - abstract type: Type; - plugins: InitPlugin[] = []; - onEvent: ControlPlugin[] = []; - abstract execute: CommandModuleDefs[Type]['execute']; -} -/** - * @Experimental - * Will be refactored in future - */ -export abstract class EventExecutable { - abstract type: Type; - plugins: InitPlugin[] = []; - onEvent: ControlPlugin[] = []; - abstract execute: EventModuleDefs[Type]['execute']; -} diff --git a/src/core/dependencies.ts b/src/core/dependencies.ts index 3511aaf..7e6315f 100644 --- a/src/core/dependencies.ts +++ b/src/core/dependencies.ts @@ -1,11 +1,10 @@ import type { Container } from 'iti'; import type { AnyDependencies, DependencyConfiguration, MapDeps, ServerlessDependencies, WebsocketDependencies } from '../types/core'; -import { SernEmitter } from './sernEmitter'; import { DefaultErrorHandling, DefaultLogging, DefaultModuleManager } from './contracts'; import { Result } from 'ts-results-es'; import { BehaviorSubject } from 'rxjs'; import { createContainer } from 'iti'; -import { ModuleStore } from './structures'; +import { ModuleStore, SernEmitter } from './structures'; import { AnyWrapper, ServerlessWrapper, WebsocketWrapper } from './structures/wrapper'; export const containerSubject = new BehaviorSubject(defaultContainer()); @@ -124,3 +123,12 @@ export function makeFetcher(containerConfig : AnyWr >; } +/** + * @since 2.0.0 + * @param conf a configuration for creating your project dependencies + */ +export function makeDependencies(conf: DependencyConfiguration) { + //Until there are more optional dependencies, just check if the logger exists + composeRoot(conf); + return useContainer(); +} diff --git a/src/core/functions.ts b/src/core/functions.ts index e725eca..9ce8fc9 100644 --- a/src/core/functions.ts +++ b/src/core/functions.ts @@ -4,8 +4,8 @@ import type { SernAutocompleteData, SernOptionsData } from '../types/module'; //function wrappers for empty ok / err -export const ok = () => Ok.EMPTY; -export const err = () => Err.EMPTY; +export const ok = /* @__PURE__*/ () => Ok.EMPTY; +export const err =/* @__PURE__*/ () => Err.EMPTY; export function partition(arr: (T & V)[], condition: (e: T & V) => boolean): [T[], V[]] { const t: T[] = []; diff --git a/src/core/index.ts b/src/core/index.ts index 5f5a13e..691442d 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -1,6 +1,5 @@ -export * from './sernEmitter'; export * from './contracts'; export * from './platform'; export * from './plugins'; -export * from './structures/'; -export { single, transient, useContainerRaw } from './dependencies' +export * from './structures'; +export { single, transient, useContainerRaw, makeDependencies } from './dependencies' diff --git a/src/core/io.ts b/src/core/io.ts deleted file mode 100644 index 5c3a8ec..0000000 --- a/src/core/io.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Module } from "../types/module"; -import { Result } from "ts-results-es"; -import { Processed } from "../types/core"; -import { SernError } from "./structures/errors"; -import { readdir, stat } from 'fs/promises'; -import { join, resolve } from 'path'; -import { type Observable, from, mergeMap, ObservableInput } from 'rxjs'; -import { defaultModuleLoader } from "./module-loading"; - -export const fmtFileName = (n: string) => n.substring(0, n.length - 3); -/** - * a directory string is converted into a stream of modules. - * starts the stream of modules that sern needs to process on init - * @returns {Observable<{ mod: Module; absPath: string; }[]>} data from command files - * @param commandDir - */ -export function buildModuleStream( - input: ObservableInput -): Observable, SernError>> { - return from(input).pipe(mergeMap(defaultModuleLoader)); -} - -export function getCommands(dir: string) { - return readPath(resolve(dir)); -} - -export function filename(path: string) { - const i = path.lastIndexOf('/') - return fmtFileName(path.substring(i)) -} - -async function* readPath(dir: string): AsyncGenerator { - try { - const files = await readdir(dir); - for (const file of files) { - const fullPath = join(dir, file); - const fileStats = await stat(fullPath); - if (fileStats.isDirectory()) { - yield* readPath(fullPath); - } else { - /// #if MODE === 'esm' - yield 'file:///'+fullPath; - /// #elif MODE === 'cjs' - yield fullPath; - /// #endif - } - } - } catch (err) { - throw err; - } -} - -//https://stackoverflow.com/questions/16697791/nodejs-get-filename-of-caller-function -export function filePath() { - const err = new Error(); - - Error.prepareStackTrace = (_, stack) => stack; - - const stack = err.stack as unknown as NodeJS.CallSite[]; - - Error.prepareStackTrace = undefined; - const path = stack[2].getFileName(); - if(path === null) { - throw Error("Could not get the name of commandModule.") - } - return path; -} diff --git a/src/core/module-loading.ts b/src/core/module-loading.ts index 1471073..11389e6 100644 --- a/src/core/module-loading.ts +++ b/src/core/module-loading.ts @@ -1,12 +1,61 @@ -import { readdir, stat } from 'fs/promises'; -import { join, basename, resolve } from 'path'; -import { type Observable, from, mergeMap } from 'rxjs'; import { SernError } from './structures/errors'; import { type Result, Err, Ok } from 'ts-results-es'; import { Processed } from '../types/core'; import { Module } from '../types/module'; import * as assert from 'node:assert' import * as util from 'node:util' +import { type Observable, from, mergeMap, ObservableInput } from 'rxjs'; +import { readdir, stat } from 'fs/promises'; +import { basename, join, resolve } from 'path'; + +type ModuleResult = Promise, SernError>> +export type Loader = (absPath: string) => ModuleResult + +export async function defaultModuleLoader( + absPath: string, +): ModuleResult { + // prettier-ignore + let module: T | undefined + /// #if MODE === 'esm' + = (await import(absPath)).default + /// #elif MODE === 'cjs' + = require(absPath).default; // eslint-disable-line + /// #endif + if (module === undefined) { + return Err(SernError.UndefinedModule); + } + try { + module = new (module as unknown as new () => T)(); + } catch {} + checkIsProcessed(module) + return Ok(module); +} + +function checkIsProcessed(m: T): asserts m is Processed { + assert.ok(m.name !== undefined, `name is not defined for ${util.format(m)}`) +} + + +export const fmtFileName = (n: string) => n.substring(0, n.length - 3); +/** + * a directory string is converted into a stream of modules. + * starts the stream of modules that sern needs to process on init + * @returns {Observable<{ mod: Module; absPath: string; }[]>} data from command files + * @param commandDir + */ +export function buildModuleStream( + input: ObservableInput +): Observable, SernError>> { + return from(input).pipe(mergeMap(defaultModuleLoader)); +} + +export function getCommands(dir: string) { + return readPath(resolve(dir)); +} + +export function filename(path: string) { + return fmtFileName(basename(path)) +} async function* readPath(dir: string): AsyncGenerator { try { @@ -29,53 +78,6 @@ async function* readPath(dir: string): AsyncGenerator { } } - -export const fmtFileName = (n: string) => n.substring(0, n.length - 3); - -export async function defaultModuleLoader( - absPath: string, -): Promise, SernError>> { - // prettier-ignore - let module: T | undefined - /// #if MODE === 'esm' - = (await import(absPath)).default - /// #elif MODE === 'cjs' - = require(absPath).default; // eslint-disable-line - /// #endif - if (module === undefined) { - return Err(SernError.UndefinedModule); - } - try { - module = new (module as unknown as new () => T)(); - } catch {} - checkIsProcessed(module) - return Ok(module); -} - -function checkIsProcessed(m: T): asserts m is Processed { - assert.ok(m.name !== undefined, `name is not defined for ${util.format(m)}`) -} - -/** - * a directory string is converted into a stream of modules. - * starts the stream of modules that sern needs to process on init - * @returns {Observable<{ mod: Module; absPath: string; }[]>} data from command files - * @param commandDir - */ -export function buildModuleStream( - commandDir: string, -): Observable, SernError>> { - const commands = getCommands(commandDir); - return from(commands).pipe(mergeMap(defaultModuleLoader)); -} - -export function getCommands(dir: string) { - return readPath(resolve(dir)); -} - -export function filename(path: string) { - return fmtFileName(basename(path)) -} //https://stackoverflow.com/questions/16697791/nodejs-get-filename-of-caller-function export function filePath() { const err = new Error(); @@ -89,5 +91,4 @@ export function filePath() { if(path === null) { throw Error("Could not get the name of commandModule.") } - return path; -} + return path; } diff --git a/src/core/platform.ts b/src/core/platform.ts index 150618b..084e3ff 100644 --- a/src/core/platform.ts +++ b/src/core/platform.ts @@ -28,10 +28,9 @@ export function makeWebsocketAdapter( }; } -export function makeServerlessAdapter(i : { endpoint: string }): ServerlessStrategy { +export function makeServerlessAdapter(): ServerlessStrategy { return { - type: DispatchType.Serverless , - ...i + type: DispatchType.Serverless, }; } diff --git a/src/core/plugins/index.ts b/src/core/plugins/index.ts index 37c4f0a..e03a2f5 100644 --- a/src/core/plugins/index.ts +++ b/src/core/plugins/index.ts @@ -1,2 +1,2 @@ -export { type EventArgs, type InitArgs, type CommandArgs } from './args'; +export * from './args'; export * from './createPlugin'; diff --git a/src/core/sernEmitter.ts b/src/core/sernEmitter.ts deleted file mode 100644 index 1b13c10..0000000 --- a/src/core/sernEmitter.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { EventEmitter } from 'events'; -import type { Payload, SernEventsMapping } from '../types/handler'; -import { PayloadType } from '../core/structures'; -import type { Module } from '../types/module'; - -/** - * @since 1.0.0 - */ -export class SernEmitter extends EventEmitter { - /** - * Listening to sern events with on. This event stays on until a crash or a normal exit - * @param eventName - * @param listener what to do with the data - */ - public override on( - eventName: T, - listener: (...args: SernEventsMapping[T][]) => void, - ): this { - return super.on(eventName, listener); - } - /** - * Listening to sern events with on. This event stays on until a crash or a normal exit - * @param eventName - * @param listener what to do with the data - */ - public override once( - eventName: T, - listener: (...args: SernEventsMapping[T][]) => void, - ): this { - return super.once(eventName, listener); - } - /** - * Listening to sern events with on. This event stays on until a crash or a normal exit - * @param eventName - * @param args the arguments for emitting the eventName - */ - public override emit( - eventName: T, - ...args: SernEventsMapping[T] - ): boolean { - return super.emit(eventName, ...args); - } - private static payload( - type: PayloadType, - module?: Module, - reason?: unknown, - ) { - return { type, module, reason } as T; - } - - /** - * Creates a compliant SernEmitter failure payload - * @param module - * @param reason - */ - static failure(module?: Module, reason?: unknown) { - //The generic cast Payload & { type : PayloadType.* } coerces the type to be a failure payload - // same goes to the other methods below - return SernEmitter.payload( - PayloadType.Failure, - module, - reason, - ); - } - /** - * Creates a compliant SernEmitter module success payload - * @param module - */ - static success(module: Module) { - return SernEmitter.payload( - PayloadType.Success, - module, - ); - } - /** - * Creates a compliant SernEmitter module warning payload - * @param reason - */ - static warning(reason: unknown) { - return SernEmitter.payload( - PayloadType.Warning, - undefined, - reason, - ); - } -} - diff --git a/src/core/structures/sernEmitter.ts b/src/core/structures/sernEmitter.ts index d7bcce1..43bfd82 100644 --- a/src/core/structures/sernEmitter.ts +++ b/src/core/structures/sernEmitter.ts @@ -1,7 +1,7 @@ import { EventEmitter } from 'node:events'; -import type { Payload, SernEventsMapping } from '../types/handler'; -import { PayloadType } from '../core/structures'; -import type { Module } from '../types/module'; +import type { Payload, SernEventsMapping } from '../../types/handler'; +import { PayloadType } from '../../core/structures'; +import type { Module } from '../../types/module'; /** * @since 1.0.0 diff --git a/src/handler/events/generic.ts b/src/handler/events/generic.ts index 319f327..7c878a1 100644 --- a/src/handler/events/generic.ts +++ b/src/handler/events/generic.ts @@ -12,7 +12,7 @@ import { err } from "../../core/functions"; import { ObservableInput, pipe, switchMap} from "rxjs"; import { SernEmitter } from "../../core"; import { errTap } from '../../core/operators'; -import * as Files from '../../core/io'; +import * as Files from '../../core/module-loading'; import { sernMeta } from "../../commands"; import { AnyModule } from "../../types/module"; diff --git a/src/handler/events/userDefined.ts b/src/handler/events/userDefined.ts index c8efad0..5370467 100644 --- a/src/handler/events/userDefined.ts +++ b/src/handler/events/userDefined.ts @@ -3,7 +3,7 @@ import type { Processed, WebsocketDependencies } from '../../types/core'; import { callInitPlugins } from './observableHandling'; import type { CommandModule, EventModule } from '../../types/module'; import type { EventEmitter } from 'node:events'; -import { SernEmitter } from '../../core/sernEmitter'; +import { SernEmitter } from '../../core'; import type { ErrorHandling, Logging } from '../../core/contracts'; import { EventType } from '../../core/structures' import { SernError } from '../../core/structures/errors'; diff --git a/src/handler/sern.ts b/src/handler/sern.ts index 63cdbe3..27734f2 100644 --- a/src/handler/sern.ts +++ b/src/handler/sern.ts @@ -6,7 +6,7 @@ import { makeFetcher, makeDependencies } from '../core/dependencies'; import { err, ok } from '../core/functions'; import { DefaultWrapper } from '../core/structures/wrapper'; import { discordjs } from '../core'; -import { getCommands } from '../core/io'; +import { getCommands } from '../core/module-loading'; /** * @since 1.0.0 * @param wrapper Options to pass into sern. diff --git a/src/index.ts b/src/index.ts index c380da9..211ae9b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,8 @@ export * as Sern from './handler/sern'; export * from './types/handler'; +export * from './types/module'; export * from './types/plugin'; export * from './core'; export { controller } from './handler/sern' export { commandModule, eventModule } from './commands' export { Context } from './classic/context' -export * from './classic/module'; diff --git a/src/serverless/sern.ts b/src/serverless/sern.ts deleted file mode 100644 index 6260637..0000000 --- a/src/serverless/sern.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { makeFetcher } from "../core/dependencies"; -import { ServerlessWrapper } from "../core/structures/wrapper"; -import { makeReadyEvent } from "../handler/events/ready"; - - - - -function initServerless(wrapper: ServerlessWrapper) { - const dependenciesAnd = makeFetcher(wrapper.containerConfig); - const dependencies = dependenciesAnd(['@sern/modules']); - - makeReadyEvent(dependencies, wrapper.commands, wrapper.platform) - -} - -/** - * For Sern to handle serverless - */ -function handle(wrapper: ServerlessWrapper) { - return (r: Request) => { - - } -} - diff --git a/src/types/handler.ts b/src/types/handler.ts index 2bc528b..82cf19d 100644 --- a/src/types/handler.ts +++ b/src/types/handler.ts @@ -1,7 +1,4 @@ import type { InteractionReplyOptions, MessageReplyOptions, CommandInteractionOptionResolver } from 'discord.js'; -import type { EventEmitter } from 'node:events'; -import type { ErrorHandling, Logging, ModuleManager } from '../core/contracts'; -import type { SernEmitter } from '../core/sernEmitter'; import { Processed } from './core'; import { AnyModule, CommandModule, EventModule } from './module'; import { PayloadType } from '../core';