chore: update typings

This commit is contained in:
Jacob Nguyen
2023-04-26 11:58:22 -05:00
parent 1fa7eef336
commit dcdf120ba7
10 changed files with 109 additions and 77 deletions

View File

@@ -1,10 +1,3 @@
import { _const } from '../utilities/functions';
/**
* New signature
* @since 2.0.0
* @param cb
*/
export function single<T extends () => unknown>(cb: T): T;
/**
* @__PURE__
* @since 2.0.0.
@@ -13,8 +6,8 @@ export function single<T extends () => unknown>(cb: T): T;
* For future versions, ensure that single is being passed as a **callback!!**
* @param cb
*/
export function single<T>(cb: T) {
return () => cb;
export function single<T>(cb: () => T) {
return cb;
}
/**

View File

@@ -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<T extends Dependencies>(conf: DependencyConfiguration<T>) {
export function composeRoot<T extends AnyDependencies>(conf: DependencyConfiguration<T>) {
//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<T extends Dependencies>(conf: DependencyConfiguratio
containerSubject.next(container as any);
}
export function useContainer<T extends Dependencies>() {
export function useContainer<const T extends AnyDependencies>() {
const container = containerSubject.getValue() as Container<T, {}>;
return <V extends (keyof T)[]>(...keys: [...V]) =>
keys.map(key => Result.wrap(() => container.get(key)).unwrapOr(undefined)) as MapDeps<T, V>;
@@ -48,7 +49,7 @@ export function useContainer<T extends Dependencies>() {
* Please be careful as this only gets the client's current state.
* Exposes some methods from iti
*/
export function useContainerRaw<T extends Dependencies>() {
export function useContainerRaw<T extends AnyDependencies>() {
return containerSubject.getValue() as Container<T, {}>;
}
@@ -66,7 +67,7 @@ function defaultContainer() {
};
})
.add({ '@sern/emitter': () => new SernEmitter() }) as Container<
Omit<Dependencies, '@sern/client' | '@sern/logger'>,
Omit<AnyDependencies, '@sern/client' | '@sern/logger'>,
{}
>;
}
@@ -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<const Dep extends AnyDependencies>(wrapper: AnyWrapper) {
const requiredDependencyKeys = [
'@sern/emitter',
'@sern/client',
'@sern/errors',
'@sern/logger',
] as ['@sern/emitter', '@sern/client', '@sern/errors', '@sern/logger'];
return <Keys extends (keyof Dependencies)[]>(otherKeys: [...Keys]) =>
return <const Keys extends (keyof Dep)[]>(otherKeys: [...Keys]) =>
wrapper.containerConfig.get(...requiredDependencyKeys, ...otherKeys) as MapDeps<
Dependencies,
AnyDependencies,
[...typeof requiredDependencyKeys, ...Keys]
>;
}

View File

@@ -0,0 +1 @@
export * from './strategy';

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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) {

View File

@@ -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(

View File

@@ -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<T extends keyof ClientEvents>(mod: {
* @since 2.0.0
* @param conf a configuration for creating your project dependencies
*/
export function makeDependencies<T extends Dependencies>(conf: DependencyConfiguration<T>) {
export function makeDependencies<const T extends AnyDependencies>(conf: DependencyConfiguration<T>) {
//Until there are more optional dependencies, just check if the logger exists
composeRoot(conf);
return useContainer<T>();

View File

@@ -39,21 +39,35 @@ export type LogPayload<T = unknown> = { message: T };
export type Singleton<T> = () => T;
export type Transient<T> = () => () => T;
export interface Dependencies {
'@sern/client': Singleton<EventEmitter>;
export interface CoreDependencies {
'@sern/logger'?: Singleton<Logging>;
'@sern/emitter': Singleton<SernEmitter>;
'@sern/store': Singleton<ModuleStore>;
'@sern/modules': Singleton<ModuleManager>;
'@sern/errors': Singleton<ErrorHandling>;
}
/**
* 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<EventEmitter>;
}
export type AnyDependencies =
| ServerlessDependencies
| WebsocketDependencies;
export type ReplyOptions =
| string
| Omit<InteractionReplyOptions, 'fetchReply'>
| MessageReplyOptions;
//prettier-ignore
export type MapDeps<Deps extends Dependencies, T extends readonly unknown[]> = T extends [
export type MapDeps<Deps extends AnyDependencies, T extends readonly unknown[]> = T extends [
infer First extends keyof Deps,
...infer Rest extends readonly unknown[],
]
@@ -66,9 +80,9 @@ export type MapDeps<Deps extends Dependencies, T extends readonly unknown[]> = T
export type OptionalDependencies = '@sern/logger';
export type Processed<T> = T & { name: string; description: string };
export type Deprecated<Message extends string> = [never, Message];
export interface DependencyConfiguration<T extends Dependencies> {
export interface DependencyConfiguration<T extends AnyDependencies> {
exclude?: Set<OptionalDependencies>;
build: (root: Container<Omit<Dependencies, '@sern/client'>, {}>) => Container<T, {}>;
build: (root: Container<Omit<AnyDependencies, '@sern/client'>, {}>) => Container<T, {}>;
}
export type ImportPayload<T> = { module: T; absPath: string };