From f020e783b3c6caff61e0953ad67f37ada3568729 Mon Sep 17 00:00:00 2001 From: jacob Date: Sun, 28 Jan 2024 15:16:49 -0600 Subject: [PATCH] boss call --- package.json | 2 +- src/core/_internal.ts | 1 + src/core/functions.ts | 16 +++-- src/core/ioc/base.ts | 20 +------ src/core/ioc/container.ts | 5 +- src/core/ioc/dependency-injection.ts | 26 +++++++- src/core/ioc/index.ts | 2 +- src/core/structures/index.ts | 2 +- src/core/structures/sern-emitter.ts | 89 ---------------------------- src/handlers/event-utils.ts | 15 ++--- src/handlers/interaction-event.ts | 7 ++- src/handlers/message-event.ts | 9 +-- src/sern.ts | 1 - src/types/ioc.ts | 3 - src/types/utility.ts | 1 - 15 files changed, 60 insertions(+), 139 deletions(-) delete mode 100644 src/core/structures/sern-emitter.ts diff --git a/package.json b/package.json index 21efa61b..6971bdfd 100644 --- a/package.json +++ b/package.json @@ -97,6 +97,6 @@ }, "homepage": "https://sern.dev", "peerDependencies": { - "shrimple-locales": "^0.1.2" + "shrimple-locales": "^0.2.0" } } diff --git a/src/core/_internal.ts b/src/core/_internal.ts index b1683e06..513abaa2 100644 --- a/src/core/_internal.ts +++ b/src/core/_internal.ts @@ -7,3 +7,4 @@ export { SernError } from './structures/enums'; export { ModuleStore } from './structures/module-store'; export * as DefaultServices from './structures/services'; export { useContainerRaw } from './ioc/base' + diff --git a/src/core/functions.ts b/src/core/functions.ts index 2783d155..60d62e9b 100644 --- a/src/core/functions.ts +++ b/src/core/functions.ts @@ -1,6 +1,5 @@ import { Err, Ok } from 'ts-results-es'; -import { ApplicationCommandOptionType, AutocompleteInteraction } from 'discord.js'; -import type { SernAutocompleteData, SernOptionsData } from '../types/core-modules'; +import type { Module, SernAutocompleteData, SernOptionsData } from '../types/core-modules'; import type { AnyCommandPlugin, AnyEventPlugin, Plugin } from '../types/core-plugin'; import type { AnySelectMenuInteraction, @@ -9,12 +8,12 @@ import type { MessageContextMenuCommandInteraction, ModalSubmitInteraction, UserContextMenuCommandInteraction, + AutocompleteInteraction } from 'discord.js'; -import { InteractionType } from 'discord.js'; - - -import { PluginType } from './structures'; +import { ApplicationCommandOptionType, InteractionType } from 'discord.js' +import { PayloadType, PluginType } from './structures'; import assert from 'assert'; +import { Payload } from '../types/utility'; //function wrappers for empty ok / err export const ok = /* @__PURE__*/ () => Ok.EMPTY; @@ -117,3 +116,8 @@ export function isAutocomplete(i: InteractionTypable): i is AutocompleteInteract export function isModal(i: InteractionTypable): i is ModalSubmitInteraction { return i.type === InteractionType.ModalSubmit; } + +export function resultPayload +(type: T, module?: Module, reason?: unknown) { + return { type, module, reason } as Payload & { type : T }; +} diff --git a/src/core/ioc/base.ts b/src/core/ioc/base.ts index fdd0c6c6..08db7505 100644 --- a/src/core/ioc/base.ts +++ b/src/core/ioc/base.ts @@ -6,9 +6,6 @@ import { Result } from 'ts-results-es'; import { DefaultServices } from '../_internal'; import { AnyFunction } from '../../types/utility'; import type { Logging } from '../contracts/logging'; -import { requir } from '../module-loading'; -import { fileURLToPath } from 'node:url'; -import path from 'path'; //SIDE EFFECT: GLOBAL DI let containerSubject: CoreContainer>; @@ -95,13 +92,6 @@ export const insertLogger = (containerSubject: CoreContainer) => { .upsert({'@sern/logger': () => new DefaultServices.DefaultLogging}); } -const insertLocalizer = async (containerSubject: CoreContainer) => { - const packageDirectory = fileURLToPath(import.meta.url); - const pathToLocalizer= path.resolve(packageDirectory, "../", "optional", "localizer"); - const { ShrimpleLocalizer } = requir(pathToLocalizer); - containerSubject - .upsert({'@sern/localizer': new ShrimpleLocalizer() }); -} /** * Given the user's conf, check for any excluded/included dependency keys. @@ -118,9 +108,9 @@ function composeRoot( if (!hasLogger) { insertLogger(container); } - if(conf.include?.includes('@sern/localizer')) { - insertLocalizer(container); - } +// if(conf.include?.includes('@sern/localizer')) { +// insertLocalizer(container); +// } //Build the container based on the callback provided by the user conf.build(container as CoreContainer>); @@ -147,10 +137,6 @@ export async function makeDependencies insertLogger(containerSubject); } - if(included.includes('@sern/localizer')) { - insertLocalizer(containerSubject); - } - containerSubject.ready(); } else { composeRoot(containerSubject, conf); diff --git a/src/core/ioc/container.ts b/src/core/ioc/container.ts index 9f6b024c..5cacc44b 100644 --- a/src/core/ioc/container.ts +++ b/src/core/ioc/container.ts @@ -1,9 +1,10 @@ import { Container } from 'iti'; -import { Disposable, SernEmitter } from '../'; +import { Disposable } from '../'; import * as assert from 'node:assert'; import { Subject } from 'rxjs'; import { DefaultServices, ModuleStore } from '../_internal'; import * as Hooks from './hooks'; +import { EventEmitter } from 'node:events'; /** @@ -23,7 +24,7 @@ export class CoreContainer> extends Container) .add({ '@sern/errors': () => new DefaultServices.DefaultErrorHandling, - '@sern/emitter': () => new SernEmitter, + '@sern/emitter': () => new EventEmitter({ captureRejections: true }), '@sern/store': () => new ModuleStore }) .add(ctx => { return { '@sern/modules': () => diff --git a/src/core/ioc/dependency-injection.ts b/src/core/ioc/dependency-injection.ts index 8781f94a..a84d3100 100644 --- a/src/core/ioc/dependency-injection.ts +++ b/src/core/ioc/dependency-injection.ts @@ -1,6 +1,10 @@ import assert from 'node:assert'; import type { IntoDependencies } from '../../types/ioc'; import { useContainerRaw } from './base'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; +import { requir } from '../module-loading'; +import type { Localizer } from '../contracts'; /** * @__PURE__ @@ -54,11 +58,31 @@ export function useContainer() { keys.map(key => useContainerRaw().get(key as keyof Dependencies)) as IntoDependencies; } - +/** + * Translates a string to its respective local + * @example + * ```ts + * assert.deepEqual(locals("salute.hello", "es"), "hola") + * ``` + */ export const local = (i: string, local: string) => { return Service('@sern/localizer').translate(i, local) } +/** + * Returns a record of locales to their respective translations. + * @example + * ```ts + * assert.deepEqual(localsFor("salute.hello"), { "en-US": "hello", "es": "hola" }) + * ``` + */ export const localsFor = (path: string) => { return Service('@sern/localizer').translationsFor(path) } + +export const Localization = () => { + const packageDirectory = fileURLToPath(import.meta.url); + const pathToLocalizer= path.resolve(packageDirectory, "../", "optional", "localizer"); + const { ShrimpleLocalizer } = requir(pathToLocalizer); + return new ShrimpleLocalizer() as Localizer; +} diff --git a/src/core/ioc/index.ts b/src/core/ioc/index.ts index a4480d33..8961acb2 100644 --- a/src/core/ioc/index.ts +++ b/src/core/ioc/index.ts @@ -1,2 +1,2 @@ export { makeDependencies } from './base'; -export { Service, Services, single, transient, local, localsFor } from './dependency-injection'; +export { Service, Services, single, transient, local, localsFor, Localization } from './dependency-injection'; diff --git a/src/core/structures/index.ts b/src/core/structures/index.ts index e3c08dcb..8eeb6f92 100644 --- a/src/core/structures/index.ts +++ b/src/core/structures/index.ts @@ -1,5 +1,5 @@ export { CommandType, PluginType, PayloadType, EventType } from './enums'; export * from './context'; -export * from './sern-emitter'; export * from './services'; export * from './module-store'; + diff --git a/src/core/structures/sern-emitter.ts b/src/core/structures/sern-emitter.ts deleted file mode 100644 index 0b4f188d..00000000 --- a/src/core/structures/sern-emitter.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { EventEmitter } from 'node:events'; -import { PayloadType } from '../../core/structures'; -import { Module } from '../../types/core-modules'; -import { SernEventsMapping, Payload } from '../../types/utility'; - -/** - * @since 1.0.0 - */ -export class SernEmitter extends EventEmitter { - constructor() { - super({ captureRejections: true }); - } - /** - * 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/handlers/event-utils.ts b/src/handlers/event-utils.ts index 6182aee3..fd079384 100644 --- a/src/handlers/event-utils.ts +++ b/src/handlers/event-utils.ts @@ -21,11 +21,11 @@ import { handleError, SernError, VoidResult, + resultPayload, } from '../core/_internal'; -import { Emitter, ErrorHandling, Logging, ModuleManager } from '../core'; +import { Emitter, ErrorHandling, Logging, ModuleManager, PayloadType } 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 { Awaitable } from '../types/utility'; import type { ControlPlugin } from '../types/core-plugin'; @@ -168,10 +168,10 @@ export function executeModule( concatMap(() => Result.wrapAsync(async () => task())), concatMap(result => { if (result.isOk()) { - emitter.emit('module.activate', SernEmitter.success(module)); + emitter.emit('module.activate', resultPayload(PayloadType.Success, module)); return EMPTY; } - return throwError(() => SernEmitter.failure(module, result.error)); + return throwError(() => resultPayload(PayloadType.Failure, module, result.error)); }), ); @@ -218,13 +218,10 @@ export function callInitPlugins>(sernEmitter: Emi createResultResolver({ createStream: args => from(args.module.plugins).pipe(callPlugin(args)), onStop: (module: T) => { - sernEmitter.emit( - 'module.register', - SernEmitter.failure(module, SernError.PluginFailure), - ); + sernEmitter.emit('module.register', resultPayload(PayloadType.Failure, module, SernError.PluginFailure)); }, onNext: ({ module }) => { - sernEmitter.emit('module.register', SernEmitter.success(module)); + sernEmitter.emit('module.register', resultPayload(PayloadType.Success, module)); return { module }; }, }), diff --git a/src/handlers/interaction-event.ts b/src/handlers/interaction-event.ts index f9b90e14..06523417 100644 --- a/src/handlers/interaction-event.ts +++ b/src/handlers/interaction-event.ts @@ -1,6 +1,6 @@ import { Interaction } from 'discord.js'; import { mergeMap, merge } from 'rxjs'; -import { SernEmitter } from '../core'; +import { PayloadType } from '../core'; import { isAutocomplete, isCommand, @@ -9,6 +9,7 @@ import { sharedEventStream, SernError, filterTap, + resultPayload, } from '../core/_internal'; import { createInteractionHandler, executeModule, makeModuleExecutor } from './_internal'; import type { DependencyList } from '../types/ioc'; @@ -25,8 +26,8 @@ export function interactionHandler([emitter, err, log, modules, client]: Depende ); return interactionHandler$ .pipe( - filterTap(e => emitter.emit('warning', SernEmitter.warning(e))), + filterTap(e => emitter.emit('warning', resultPayload(PayloadType.Warning, undefined, e))), makeModuleExecutor(module => - emitter.emit('module.activate', SernEmitter.failure(module, SernError.PluginFailure))), + emitter.emit('module.activate', resultPayload(PayloadType.Failure, module, SernError.PluginFailure))), mergeMap(payload => executeModule(emitter, log, err, payload))); } diff --git a/src/handlers/message-event.ts b/src/handlers/message-event.ts index d234ca70..bb84d48b 100644 --- a/src/handlers/message-event.ts +++ b/src/handlers/message-event.ts @@ -1,7 +1,7 @@ import { mergeMap, EMPTY } from 'rxjs'; import type { Message } from 'discord.js'; -import { SernEmitter } from '../core'; -import { sharedEventStream, SernError, filterTap } from '../core/_internal'; +import { PayloadType, SernEmitter } from '../core'; +import { sharedEventStream, SernError, filterTap, resultPayload } from '../core/_internal'; import { createMessageHandler, executeModule, makeModuleExecutor } from './_internal'; import type { DependencyList } from '../types/ioc'; @@ -38,9 +38,10 @@ export function messageHandler( const msgCommands$ = handle(isNonBot(defaultPrefix)); return msgCommands$.pipe( - filterTap((e) => emitter.emit('warning', SernEmitter.warning(e))), + filterTap((e) => emitter.emit('warning', resultPayload(PayloadType.Warning, undefined, e))), makeModuleExecutor(module => { - emitter.emit('module.activate', SernEmitter.failure(module, SernError.PluginFailure)); + const result = resultPayload(PayloadType.Failure, module, SernError.PluginFailure); + emitter.emit('module.activate', result); }), mergeMap(payload => executeModule(emitter, log, err, payload))); } diff --git a/src/sern.ts b/src/sern.ts index 289d3dc2..0d48c03d 100644 --- a/src/sern.ts +++ b/src/sern.ts @@ -23,7 +23,6 @@ import { Client } from 'discord.js'; * }) * ``` */ - export function init(maybeWrapper: Wrapper | 'file') { const startTime = performance.now(); const wrapper = Files.loadConfig(maybeWrapper); diff --git a/src/types/ioc.ts b/src/types/ioc.ts index 042d83db..9d2b1778 100644 --- a/src/types/ioc.ts +++ b/src/types/ioc.ts @@ -43,9 +43,6 @@ export type IntoDependencies = { export interface DependencyConfiguration { //@deprecated. Loggers will always be included in the future exclude?: Set<'@sern/logger'>; - - //Extra modules that are preconfigured and ready to use! @sern/localizer is an example - include?: string[] build: ( root: Container, {}>, ) => Container; diff --git a/src/types/utility.ts b/src/types/utility.ts index a2535875..65efc3d6 100644 --- a/src/types/utility.ts +++ b/src/types/utility.ts @@ -29,5 +29,4 @@ export type Payload = | { type: PayloadType.Warning; reason: string }; - export type ReplyOptions = string | Omit | MessageReplyOptions;