From dcdf120ba7ca68aa98ecd126918b7492ce8c1ad8 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Wed, 26 Apr 2023 11:58:22 -0500 Subject: [PATCH] chore: update typings --- src/core/dependencies/lifetimeFunctions.ts | 11 +--- src/core/dependencies/provider.ts | 17 +++--- src/core/platform/index.ts | 1 + src/core/platform/strategy.ts | 8 +-- src/core/structures/wrapper.ts | 55 ++++++++++++------- src/handler/events/observableHandling.ts | 5 +- src/handler/events/readyHandler.ts | 12 ++-- .../events/userDefinedEventsHandling.ts | 18 +++--- src/handler/sern.ts | 35 +++++++----- src/types/handler.ts | 24 ++++++-- 10 files changed, 109 insertions(+), 77 deletions(-) create mode 100644 src/core/platform/index.ts diff --git a/src/core/dependencies/lifetimeFunctions.ts b/src/core/dependencies/lifetimeFunctions.ts index 2a84afa..2f71f8d 100644 --- a/src/core/dependencies/lifetimeFunctions.ts +++ b/src/core/dependencies/lifetimeFunctions.ts @@ -1,10 +1,3 @@ -import { _const } from '../utilities/functions'; -/** - * New signature - * @since 2.0.0 - * @param cb - */ -export function single unknown>(cb: T): T; /** * @__PURE__ * @since 2.0.0. @@ -13,8 +6,8 @@ export function single unknown>(cb: T): T; * For future versions, ensure that single is being passed as a **callback!!** * @param cb */ -export function single(cb: T) { - return () => cb; +export function single(cb: () => T) { + return cb; } /** diff --git a/src/core/dependencies/provider.ts b/src/core/dependencies/provider.ts index 64b8e89..192b380 100644 --- a/src/core/dependencies/provider.ts +++ b/src/core/dependencies/provider.ts @@ -1,11 +1,12 @@ import type { Container } from 'iti'; -import type { Dependencies, DependencyConfiguration, MapDeps } from '../../types/handler'; +import type { AnyDependencies, Dependencies, DependencyConfiguration, MapDeps } from '../../types/handler'; 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 { type Wrapper, ModuleStore, SernError } from '../structures'; +import { AnyWrapper } from '../structures/wrapper'; export const containerSubject = new BehaviorSubject(defaultContainer()); @@ -15,7 +16,7 @@ export const containerSubject = new BehaviorSubject(defaultContainer()); * Finally, update the containerSubject with the new container state * @param conf */ -export function composeRoot(conf: DependencyConfiguration) { +export function composeRoot(conf: DependencyConfiguration) { //Get the current container. This should have no client or possible logger yet. const currentContainer = containerSubject.getValue(); const excludeLogger = conf.exclude?.has('@sern/logger'); @@ -37,7 +38,7 @@ export function composeRoot(conf: DependencyConfiguratio containerSubject.next(container as any); } -export function useContainer() { +export function useContainer() { const container = containerSubject.getValue() as Container; return (...keys: [...V]) => keys.map(key => Result.wrap(() => container.get(key)).unwrapOr(undefined)) as MapDeps; @@ -48,7 +49,7 @@ export function useContainer() { * Please be careful as this only gets the client's current state. * Exposes some methods from iti */ -export function useContainerRaw() { +export function useContainerRaw() { return containerSubject.getValue() as Container; } @@ -66,7 +67,7 @@ function defaultContainer() { }; }) .add({ '@sern/emitter': () => new SernEmitter() }) as Container< - Omit, + Omit, {} >; } @@ -74,16 +75,16 @@ function defaultContainer() { * A way for sern to grab only the necessary dependencies. * Returns a function which allows for the user to call for more dependencies. */ -export function makeFetcher(wrapper: Wrapper) { +export function makeFetcher(wrapper: AnyWrapper) { const requiredDependencyKeys = [ '@sern/emitter', '@sern/client', '@sern/errors', '@sern/logger', ] as ['@sern/emitter', '@sern/client', '@sern/errors', '@sern/logger']; - return (otherKeys: [...Keys]) => + return (otherKeys: [...Keys]) => wrapper.containerConfig.get(...requiredDependencyKeys, ...otherKeys) as MapDeps< - Dependencies, + AnyDependencies, [...typeof requiredDependencyKeys, ...Keys] >; } diff --git a/src/core/platform/index.ts b/src/core/platform/index.ts new file mode 100644 index 0000000..b7b40ac --- /dev/null +++ b/src/core/platform/index.ts @@ -0,0 +1 @@ +export * from './strategy'; diff --git a/src/core/platform/strategy.ts b/src/core/platform/strategy.ts index 3597992..9b58c77 100644 --- a/src/core/platform/strategy.ts +++ b/src/core/platform/strategy.ts @@ -1,5 +1,5 @@ -enum DispatchType { +export const enum DispatchType { Websocket, Serverless } @@ -8,15 +8,15 @@ export type PlatformStrategy = | WebsocketStrategy | ServerlessStrategy; -interface WebsocketStrategy { +export interface WebsocketStrategy { type: DispatchType.Websocket; interactionCreate: string; messageCreate: string; ready: string; - defaultPrefix: string; + defaultPrefix?: string; } -interface ServerlessStrategy { +export interface ServerlessStrategy { type: DispatchType.Serverless; endpoint: string; } diff --git a/src/core/structures/wrapper.ts b/src/core/structures/wrapper.ts index bbbd476..4a5b32a 100644 --- a/src/core/structures/wrapper.ts +++ b/src/core/structures/wrapper.ts @@ -1,22 +1,39 @@ -import type { Dependencies } from '../../types/handler'; -import { PlatformStrategy } from '../platform/strategy'; +import type { ServerlessDependencies, WebsocketDependencies } from '../../types/handler'; +import { DispatchType, ServerlessStrategy, WebsocketStrategy } from '../platform/strategy'; -/** - * @since 1.0.0 - * An object to be passed into Sern#init() function. - * @typedef {object} Wrapper - */ -interface Wrapper { - readonly platform: PlatformStrategy; + +export interface WebsocketWrapper { + readonly platform: WebsocketStrategy; + commands: string; /** - * @deprecated - * Add defaultPrefix to platform field instead - */ - readonly defaultPrefix?: string; - readonly commands: string; - readonly events?: string; - readonly containerConfig: { - get: (...keys: (keyof Dependencies)[]) => unknown[]; - }; + * @deprecated + * Please specify this in platform specification + */ + defaultPrefix?: string; + events?: string; + containerConfig: { + get: (...keys: (keyof WebsocketDependencies)[]) => unknown[]; + } +} +/** + * @deprecated + * Type alias for WebsocketWrapper + */ +export type Wrapper = WebsocketWrapper + +export interface ServerlessWrapper { + readonly platform: ServerlessStrategy + containerConfig: { + get: (...keys: (keyof ServerlessDependencies)[]) => unknown[]; + } + +} + +export type AnyWrapper = + | WebsocketWrapper + | ServerlessWrapper + + +export function isServerless(wrapper: AnyWrapper): wrapper is ServerlessWrapper { + return wrapper.platform.type === DispatchType.Serverless; } -export default Wrapper; diff --git a/src/handler/events/observableHandling.ts b/src/handler/events/observableHandling.ts index 43bc2e3..84da392 100644 --- a/src/handler/events/observableHandling.ts +++ b/src/handler/events/observableHandling.ts @@ -2,8 +2,8 @@ import type { Awaitable, Message } from 'discord.js'; import { concatMap, EMPTY, filter, from, Observable, of, tap, throwError } from 'rxjs'; import { Result } from 'ts-results-es'; import type { CommandModule, EventModule, Module } from '../../types/module'; -import SernEmitter from '../sernEmitter'; -import { callPlugin, everyPluginOk, filterMapTo } from './operators'; +import { SernEmitter } from '../../core'; +import { callPlugin, everyPluginOk, filterMapTo } from '../../core/operators'; import type { ImportPayload, Processed } from '../../types/handler'; import type { ControlPlugin, VoidResult } from '../../types/plugin'; @@ -12,6 +12,7 @@ function hasPrefix(prefix: string, content: string) { return prefixInContent.localeCompare(prefix, undefined, { sensitivity: 'accent' }) === 0; } + /** * Ignores messages from any person / bot except itself * @param prefix diff --git a/src/handler/events/readyHandler.ts b/src/handler/events/readyHandler.ts index 4e489ab..86d9738 100644 --- a/src/handler/events/readyHandler.ts +++ b/src/handler/events/readyHandler.ts @@ -1,15 +1,15 @@ import { fromEvent, map, pipe, switchMap, take } from 'rxjs'; -import * as Files from '../module-loading/readFile'; +import * as Files from '../../core/module-loading/readFile'; import { callInitPlugins } from './observableHandling'; -import { CommandType, type ModuleStore, SernError } from '../structures'; +import { CommandType, type ModuleStore, SernError } from '../../core/structures'; import { Result } from 'ts-results-es'; import { ApplicationCommandType, ComponentType } from 'discord.js'; import type { CommandModule } from '../../types/module'; import type { Processed } from '../../types/handler'; -import type { ErrorHandling, Logging, ModuleManager } from '../contracts'; -import { err, ok } from '../utilities/functions'; -import { errTap, fillDefaults } from './operators'; -import SernEmitter from '../sernEmitter'; +import type { ErrorHandling, Logging, ModuleManager } from '../../core/contracts'; +import { err, ok } from '../../core/utilities/functions'; +import { errTap, fillDefaults } from '../../core/operators'; +import SernEmitter from '../../core/sernEmitter'; import type { EventEmitter } from 'node:events'; function buildCommandModules(commandDir: string, sernEmitter: SernEmitter) { diff --git a/src/handler/events/userDefinedEventsHandling.ts b/src/handler/events/userDefinedEventsHandling.ts index 9902bb2..c145216 100644 --- a/src/handler/events/userDefinedEventsHandling.ts +++ b/src/handler/events/userDefinedEventsHandling.ts @@ -1,23 +1,23 @@ import { catchError, finalize, map, mergeAll } from 'rxjs'; -import * as Files from '../module-loading/readFile'; -import type { Dependencies, Processed } from '../../types/handler'; +import * as Files from '../../core/module-loading/readFile'; +import type { Processed, WebsocketDependencies } from '../../types/handler'; import { callInitPlugins } from './observableHandling'; import type { CommandModule, EventModule } from '../../types/module'; import type { EventEmitter } from 'events'; -import SernEmitter from '../sernEmitter'; -import type { ErrorHandling, Logging } from '../contracts'; -import { SernError, EventType, type Wrapper } from '../structures'; +import SernEmitter from '../../core/sernEmitter'; +import type { ErrorHandling, Logging } from '../../core/contracts'; +import { SernError, EventType, type Wrapper } from '../../core/structures'; import { eventDispatcher } from './dispatchers'; -import { handleError } from '../contracts/errorHandling'; -import { errTap, fillDefaults } from './operators'; -import { useContainerRaw } from '../dependencies'; +import { handleError } from '../../core/contracts/errorHandling'; +import { errTap, fillDefaults } from '../../core/operators'; +import { useContainerRaw } from '../../core/dependencies'; export function makeEventsHandler( [s, client, err, log]: [SernEmitter, EventEmitter, ErrorHandling, Logging | undefined], eventsPath: string, containerGetter: Wrapper['containerConfig'], ) { - const lazy = (k: string) => containerGetter.get(k as keyof Dependencies)[0]; + const lazy = (k: string) => containerGetter.get(k as keyof WebsocketDependencies)[0]; const eventStream$ = eventObservable(eventsPath, s); const eventCreation$ = eventStream$.pipe( diff --git a/src/handler/sern.ts b/src/handler/sern.ts index a0e831b..65a109e 100644 --- a/src/handler/sern.ts +++ b/src/handler/sern.ts @@ -1,4 +1,5 @@ import { Wrapper, CommandType, EventType, PluginType } from '../core/structures'; +import { DispatchType } from '../core/platform'; import { makeEventsHandler } from './events/userDefinedEventsHandling'; import { AnyEventPlugin, ControlPlugin, InitPlugin, type Plugin } from '../types/plugin'; import { makeInteractionCreate } from './events/interactionHandler'; @@ -12,12 +13,12 @@ import type { InputCommand, InputEvent, } from '../types/module'; -import type { Dependencies, DependencyConfiguration } from '../types/handler'; +import type { AnyDependencies, Dependencies, DependencyConfiguration } from '../types/handler'; import { composeRoot, makeFetcher, useContainer } from '../core/dependencies/provider'; import type { Logging } from '../core/contracts'; import { err, ok, partition } from '../core/utilities/functions'; import type { Awaitable, ClientEvents } from 'discord.js'; - +import { AnyWrapper, isServerless } from '../core/structures/wrapper'; /** * @since 1.0.0 * @param wrapper Options to pass into sern. @@ -34,20 +35,25 @@ import type { Awaitable, ClientEvents } from 'discord.js'; * }) * ``` */ -export function init(wrapper: Wrapper) { +export function init(wrapper: AnyWrapper) { const logger = wrapper.containerConfig.get('@sern/logger')[0] as Logging | undefined; const requiredDependenciesAnd = makeFetcher(wrapper); const startTime = performance.now(); - const { events } = wrapper; - if (events !== undefined) { - makeEventsHandler(requiredDependenciesAnd([]), events, wrapper.containerConfig); + if(isServerless(wrapper)) { + + + } else { + const dependencies = requiredDependenciesAnd(['@sern/modules']); + const { events } = wrapper; + if (events !== undefined) { + makeEventsHandler(requiredDependenciesAnd([]), events, wrapper.containerConfig); + } + makeReadyEvent(dependencies, wrapper.commands); + makeMessageCreate(dependencies, wrapper?.defaultPrefix ?? wrapper.platform.defaultPrefix); + makeInteractionCreate(dependencies); + const endTime = performance.now(); + logger?.info({ message: `sern : ${(endTime - startTime).toFixed(2)} ms` }); } - const dependencies = requiredDependenciesAnd(['@sern/modules']); - makeReadyEvent(dependencies, wrapper.commands); - makeMessageCreate(dependencies, wrapper.defaultPrefix); - makeInteractionCreate(dependencies); - const endTime = performance.now(); - logger?.info({ message: `sern : ${(endTime - startTime).toFixed(2)} ms` }); } /** @@ -60,8 +66,7 @@ export const controller = { }; /** - * @since 1.0.0 - * The wrapper function to define command modules for sern + * @since 1.0.0 The wrapper function to define command modules for sern * @param mod */ export function commandModule(mod: InputCommand): CommandModule { @@ -109,7 +114,7 @@ export function discordEvent(mod: { * @since 2.0.0 * @param conf a configuration for creating your project dependencies */ -export function makeDependencies(conf: DependencyConfiguration) { +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/types/handler.ts b/src/types/handler.ts index ae4c7f9..d349a9b 100644 --- a/src/types/handler.ts +++ b/src/types/handler.ts @@ -39,21 +39,35 @@ export type LogPayload = { message: T }; export type Singleton = () => T; export type Transient = () => () => T; -export interface Dependencies { - '@sern/client': Singleton; +export interface CoreDependencies { '@sern/logger'?: Singleton; '@sern/emitter': Singleton; '@sern/store': Singleton; '@sern/modules': Singleton; '@sern/errors': Singleton; } +/** + * To support older versions. Type alias for WebsocketDependencies + * @deprecated + */ +export type Dependencies = WebsocketDependencies +export interface ServerlessDependencies extends CoreDependencies { + '@sern/client': never +} + +export interface WebsocketDependencies extends CoreDependencies { + '@sern/client': Singleton; +} +export type AnyDependencies = + | ServerlessDependencies + | WebsocketDependencies; export type ReplyOptions = | string | Omit | MessageReplyOptions; //prettier-ignore -export type MapDeps = T extends [ +export type MapDeps = T extends [ infer First extends keyof Deps, ...infer Rest extends readonly unknown[], ] @@ -66,9 +80,9 @@ export type MapDeps = T export type OptionalDependencies = '@sern/logger'; export type Processed = T & { name: string; description: string }; export type Deprecated = [never, Message]; -export interface DependencyConfiguration { +export interface DependencyConfiguration { exclude?: Set; - build: (root: Container, {}>) => Container; + build: (root: Container, {}>) => Container; } export type ImportPayload = { module: T; absPath: string };