mirror of
https://github.com/sern-handler/handler
synced 2026-06-06 01:16:55 +00:00
add separate id for id processing
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import * as assert from "assert";
|
||||
import { composeRoot, useContainer } from "./dependency-injection";
|
||||
import { DependencyConfiguration, Dependencies } from "./types";
|
||||
import { DependencyConfiguration } from "./types";
|
||||
import { CoreContainer } from "../structures/container";
|
||||
|
||||
|
||||
@@ -24,16 +24,13 @@ export function useContainerRaw() {
|
||||
* @param conf a configuration for creating your project dependencies
|
||||
*/
|
||||
export async function makeDependencies<const T extends Dependencies>(
|
||||
conf: DependencyConfiguration<T>,
|
||||
conf: DependencyConfiguration,
|
||||
) {
|
||||
//Until there are more optional dependencies, just check if the logger exists
|
||||
//SIDE EFFECT
|
||||
containerSubject = new CoreContainer()
|
||||
await composeRoot(conf);
|
||||
await composeRoot(containerSubject, conf);
|
||||
|
||||
//SIDE EFFECT
|
||||
containerSubject.ready();
|
||||
|
||||
return useContainer<T>();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { CoreDependencies, Dependencies, DependencyConfiguration, MapDeps, IntoDependencies } from './types';
|
||||
import type { DependencyConfiguration, MapDeps, IntoDependencies } from './types';
|
||||
import { DefaultLogging } from '../structures';
|
||||
import { SernError } from '../structures/errors';
|
||||
import { useContainerRaw } from './base';
|
||||
@@ -24,8 +24,7 @@ export function single<T>(cb: () => T) {
|
||||
export function transient<T>(cb: () => () => T) {
|
||||
return cb;
|
||||
}
|
||||
|
||||
export function Service(key: string): unknown
|
||||
export function Service(key: string) : unknown
|
||||
export function Service<T extends keyof Dependencies>(key: T) {
|
||||
return useContainerRaw().get(key)!
|
||||
}
|
||||
@@ -41,31 +40,35 @@ export function Services<const T extends (keyof Dependencies)[]>(...keys: [...T]
|
||||
* Finally, update the containerSubject with the new container state
|
||||
* @param conf
|
||||
*/
|
||||
export async function composeRoot<T extends Dependencies>(conf: DependencyConfiguration<T>) {
|
||||
export async function composeRoot(
|
||||
container: CoreContainer<Partial<Dependencies>>,
|
||||
conf: DependencyConfiguration
|
||||
) {
|
||||
//container should have no client or logger yet.
|
||||
const excludeLogger = conf.exclude?.has('@sern/logger');
|
||||
const container = useContainerRaw();
|
||||
if (!excludeLogger) {
|
||||
const hasLogger = conf.exclude?.has('@sern/logger');
|
||||
if (!hasLogger) {
|
||||
container.upsert({
|
||||
'@sern/logger': () => new DefaultLogging(),
|
||||
});
|
||||
}
|
||||
//Build the container based on the callback provided by the user
|
||||
const updatedContainer = await conf.build(container as CoreContainer<CoreDependencies>);
|
||||
conf.build(container as CoreContainer<CoreDependencies>);
|
||||
try {
|
||||
updatedContainer.get('@sern/client');
|
||||
container.get('@sern/client');
|
||||
} catch {
|
||||
throw new Error(SernError.MissingRequired + " No client was provided")
|
||||
}
|
||||
|
||||
if (!excludeLogger) {
|
||||
updatedContainer.get('@sern/logger')?.info({ message: 'All dependencies loaded successfully.' });
|
||||
if (!hasLogger) {
|
||||
container.get('@sern/logger')?.info({ message: 'All dependencies loaded successfully.' });
|
||||
}
|
||||
|
||||
container.ready();
|
||||
}
|
||||
|
||||
export function useContainer<const T extends Dependencies>() {
|
||||
console.warn(`
|
||||
Warning: using a container hook is not recommended.
|
||||
Warning: using a container hook (useContainer) is not recommended.
|
||||
Could lead to many unwanted side effects.
|
||||
Use the new Service(s) api function instead.
|
||||
`
|
||||
|
||||
16
src/core/ioc/ioc.d.ts
vendored
Normal file
16
src/core/ioc/ioc.d.ts
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
type Singleton<T> = () => T;
|
||||
type Transient<T> = () => () => T;
|
||||
|
||||
interface CoreDependencies {
|
||||
'@sern/logger'?: Singleton<import('../contracts/logging').Logging>;
|
||||
'@sern/emitter': Singleton<import('../structures/sern-emitter').SernEmitter>;
|
||||
'@sern/store': Singleton<import('../contracts/module-store').CoreModuleStore>;
|
||||
'@sern/modules': Singleton<import('../contracts/module-manager').ModuleManager>;
|
||||
'@sern/errors': Singleton<import('../contracts/error-handling').ErrorHandling>;
|
||||
}
|
||||
|
||||
interface Dependencies extends CoreDependencies {
|
||||
'@sern/client': Singleton<import('node:events').EventEmitter>;
|
||||
}
|
||||
|
||||
@@ -1,35 +1,22 @@
|
||||
import { Container, UnpackFunction } from "iti";
|
||||
import { Awaitable, ModuleStore } from "../../shared";
|
||||
import { ErrorHandling, Logging, ModuleManager } from "../contracts";
|
||||
import { SernEmitter } from "../";
|
||||
import EventEmitter from "node:events";
|
||||
|
||||
export type Singleton<T> = () => T;
|
||||
export type Transient<T> = () => () => T;
|
||||
|
||||
|
||||
export interface CoreDependencies {
|
||||
'@sern/logger'?: Singleton<Logging>;
|
||||
'@sern/emitter': Singleton<SernEmitter>;
|
||||
'@sern/store': Singleton<ModuleStore>;
|
||||
'@sern/modules': Singleton<ModuleManager>;
|
||||
'@sern/errors': Singleton<ErrorHandling>;
|
||||
}
|
||||
|
||||
export interface Dependencies extends CoreDependencies {
|
||||
'@sern/client': Singleton<EventEmitter>;
|
||||
}
|
||||
|
||||
|
||||
export type DependencyFromKey<T extends keyof Dependencies> = Dependencies[T];
|
||||
|
||||
export type IntoDependencies<Tuple extends [...any[]]> = {
|
||||
[Index in keyof Tuple]: UnpackFunction<DependencyFromKey<Tuple[Index]>&{}>; //Unpack and make NonNullable
|
||||
} & { length: Tuple['length'] };
|
||||
|
||||
export interface DependencyConfiguration<T extends Dependencies> {
|
||||
export interface DependencyConfiguration {
|
||||
//@deprecated. Loggers will always be included in the future
|
||||
exclude?: Set<'@sern/logger'>;
|
||||
build: (root: Container<CoreDependencies, {}>) => Awaitable<Container<T, {}>>;
|
||||
build: (root: Container<CoreDependencies, {}>) => Container<Dependencies, {}>;
|
||||
}
|
||||
|
||||
//To be removed in future
|
||||
|
||||
46
src/handler/id.ts
Normal file
46
src/handler/id.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { Interaction, InteractionType } from "discord.js";
|
||||
import { CommandType, EventType } from "../core";
|
||||
|
||||
/**
|
||||
* Creates a unique ID for a given interaction object.
|
||||
* @param event The interaction object for which to create an ID.
|
||||
* @returns A unique string ID based on the type and properties of the interaction object.
|
||||
*/
|
||||
export function createId<T extends Interaction>(event: T) {
|
||||
switch (event.type) {
|
||||
case InteractionType.MessageComponent: {
|
||||
return `${event.customId}_C${event.componentType}`;
|
||||
}
|
||||
case InteractionType.ApplicationCommand:
|
||||
case InteractionType.ApplicationCommandAutocomplete: {
|
||||
return `${event.commandName}_A${event.commandType}`;
|
||||
}
|
||||
case InteractionType.ModalSubmit: {
|
||||
return `${event.customId}_C1`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const appBitField = 0b000000011111;
|
||||
/*
|
||||
* 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) {
|
||||
if (t === CommandType.Both || t === CommandType.Modal) return 1;
|
||||
const log = Math.log2(t);
|
||||
return (appBitField & t) !== 0 ? log : log - 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates an id based on CommandType.
|
||||
* A is for any ApplicationCommand. C is for any ComponentCommand
|
||||
* Then, another number generated by apiType function is appended
|
||||
*/
|
||||
export function uniqueId(t: CommandType|EventType) {
|
||||
const am = (appBitField & t) !== 0 ? 'A' : 'C';
|
||||
return am + apiType(t);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user