Skip to content

Commit

Permalink
feat: array based module loading (#379)
Browse files Browse the repository at this point in the history
Co-authored-by: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com>
  • Loading branch information
DuroCodes and jacoobes authored Jan 18, 2025
1 parent de6ae91 commit 495402f
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 37 deletions.
27 changes: 16 additions & 11 deletions src/handlers/ready.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { once } from 'node:events';
import { resultPayload } from '../core/functions';
import { CommandType } from '../core/structures/enums';
import { Module } from '../types/core-modules';
import type { UnpackedDependencies } from '../types/utility';
import type { UnpackedDependencies, Wrapper } from '../types/utility';
import { callInitPlugins } from './event-utils';

export default async function(dir: string, deps : UnpackedDependencies) {
export default async function(dirs: string | string[], deps : UnpackedDependencies) {
const { '@sern/client': client,
'@sern/logger': log,
'@sern/emitter': sEmitter,
Expand All @@ -17,16 +17,21 @@ export default async function(dir: string, deps : UnpackedDependencies) {

// https://observablehq.com/@ehouais/multiple-promises-as-an-async-generator
// possibly optimize to concurrently import modules
for await (const path of Files.readRecursive(dir)) {
let { module } = await Files.importModule<Module>(path);
const validType = module.type >= CommandType.Text && module.type <= CommandType.ChannelSelect;
if(!validType) {
throw Error(`Found ${module.name} at ${module.meta.absPath}, which has incorrect \`type\``);

const directories = Array.isArray(dirs) ? dirs : [dirs];

for (const dir of directories) {
for await (const path of Files.readRecursive(dir)) {
let { module } = await Files.importModule<Module>(path);
const validType = module.type >= CommandType.Text && module.type <= CommandType.ChannelSelect;
if(!validType) {
throw Error(`Found ${module.name} at ${module.meta.absPath}, which has incorrect \`type\``);
}
const resultModule = await callInitPlugins(module, deps, true);
// FREEZE! no more writing!!
commands.set(resultModule.meta.id, Object.freeze(resultModule));
sEmitter.emit('module.register', resultPayload('success', resultModule));
}
const resultModule = await callInitPlugins(module, deps, true);
// FREEZE! no more writing!!
commands.set(resultModule.meta.id, Object.freeze(resultModule));
sEmitter.emit('module.register', resultPayload('success', resultModule));
}
sEmitter.emit('modulesLoaded');
}
21 changes: 13 additions & 8 deletions src/handlers/tasks.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import * as Files from '../core/module-loading'
import { UnpackedDependencies } from "../types/utility";
import { UnpackedDependencies, Wrapper } from "../types/utility";
import type { ScheduledTask } from "../types/core-modules";
import { relative } from "path";
import { fileURLToPath } from "url";

export const registerTasks = async (tasksPath: string, deps: UnpackedDependencies) => {
export const registerTasks = async (tasksDirs: string | string[], deps: UnpackedDependencies) => {
const taskManager = deps['@sern/scheduler']
for await (const f of Files.readRecursive(tasksPath)) {
let { module } = await Files.importModule<ScheduledTask>(f);
//module.name is assigned by Files.importModule<>
// the id created for the task is unique
const uuid = module.name+"/"+relative(tasksPath,fileURLToPath(f))
taskManager.schedule(uuid, module, deps)

const directories = Array.isArray(tasksDirs) ? tasksDirs : [tasksDirs];

for (const dir of directories) {
for await (const path of Files.readRecursive(dir)) {
let { module } = await Files.importModule<ScheduledTask>(path);
//module.name is assigned by Files.importModule<>
// the id created for the task is unique
const uuid = module.name+"/"+relative(dir,fileURLToPath(path))
taskManager.schedule(uuid, module, deps)
}
}
}
15 changes: 10 additions & 5 deletions src/handlers/user-defined-events.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { EventType, SernError } from '../core/structures/enums';
import { callInitPlugins } from './event-utils'
import { EventModule, Module } from '../types/core-modules';
import { EventModule } from '../types/core-modules';
import * as Files from '../core/module-loading'
import type { UnpackedDependencies } from '../types/utility';
import type { Emitter } from '../core/interfaces';
Expand All @@ -10,11 +10,16 @@ import type { Wrapper } from '../'

export default async function(deps: UnpackedDependencies, wrapper: Wrapper) {
const eventModules: EventModule[] = [];
for await (const path of Files.readRecursive(wrapper.events!)) {
let { module } = await Files.importModule<Module>(path);
await callInitPlugins(module, deps)
eventModules.push(module as EventModule);
const eventDirs = Array.isArray(wrapper.events!) ? wrapper.events! : [wrapper.events!];

for (const dir of eventDirs) {
for await (const path of Files.readRecursive(dir)) {
let { module } = await Files.importModule<EventModule>(path);
await callInitPlugins(module, deps)
eventModules.push(module);
}
}

const logger = deps['@sern/logger'], report = deps['@sern/emitter'];
for (const module of eventModules) {
let source: Emitter;
Expand Down
22 changes: 9 additions & 13 deletions src/types/utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,15 @@ export type ReplyOptions = string | Omit<InteractionReplyOptions, 'fetchReply'>
*/
export interface Wrapper {
/**
* @property {string} commands
* @property {string|string[]} commands
* @description Specifies the directory path where command modules are located.
* This is a required property that tells Sern where to find and load command files.
* The path should be relative to the project root.
*
* @example
* commands: "./dist/commands"
* commands: ["./dist/commands"]
*/
commands: string;

commands: string | string[];
/**
* @property {boolean} [autoHandleErrors]
* @description Optional flag to enable automatic error handling for modules.
Expand All @@ -53,7 +52,6 @@ export interface Wrapper {
* @default false
*/
autoHandleErrors?: boolean;

/**
* @property {string} [defaultPrefix]
* @description Optional prefix for text commands. This prefix will be used
Expand All @@ -64,26 +62,24 @@ export interface Wrapper {
* defaultPrefix: "?"
*/
defaultPrefix?: string;

/**
* @property {string} [events]
* @property {string|string[]} [events]
* @description Optional directory path where event modules are located.
* If provided, Sern will automatically register and handle events from
* modules in this directory. The path should be relative to the project root.
*
* @example
* events: "./dist/events"
* events: ["./dist/events"]
*/
events?: string;

events?: string | string[];
/**
* @property {string} [tasks]
* @property {string|string[]} [tasks]
* @description Optional directory path where scheduled task modules are located.
* If provided, Sern will automatically register and handle scheduled tasks
* from modules in this directory. The path should be relative to the project root.
*
* @example
* tasks: "./dist/tasks"
* tasks: ["./dist/tasks"]
*/
tasks?: string;
tasks?: string | string[];
}

0 comments on commit 495402f

Please sign in to comment.