Skip to content

Commit

Permalink
statically register modules
Browse files Browse the repository at this point in the history
  • Loading branch information
meadowsys committed Nov 14, 2023
1 parent 566ac05 commit 3c80be4
Show file tree
Hide file tree
Showing 4 changed files with 250 additions and 73 deletions.
254 changes: 231 additions & 23 deletions lib/Application.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ const merge = require("merge");
const EventEmitter = require("events").EventEmitter;
const emitterInstance = new EventEmitter();
const Tools = require("./Tools.js");

const path = require("path");

class Application {
static emitter = new EventEmitter();
/** @type { ReturnType<typeof Application["getLogger"]> } */
static log = /** @type { any } */ (undefined);

// TODO: improve this type
/** @type { Array<{ instance: Module }> } */
static moduleObjs = [];
static modules = {};

static stop() {
return new Promise(() => {
Expand Down Expand Up @@ -42,6 +46,175 @@ class Application {

this.log = this.getLogger("application");
this.scriptName = null;

this.modules_init();
}

static modules_init() {
this.modules = {
// Activity: this.make_module({
// name: "Discord",
// main_path: "../modules/Activity/module.js",
// main_class: require("../modules/Activity/module.js"),
// config: require("../config/Activity.json")
// }),
Discord: this.make_module({
name: "Discord",
main_path: "../modules/Discord/module.js",
main_class: require("../modules/Discord/module.js"),
config: require("../config/Discord.json")
}),
Overload: this.make_module({
name: "Overload",
main_path: "../modules/Overload/module.js",
main_class: require("../modules/Overload/module.js"),
config: require("../config/Overload.json")
}),
Ignore: this.make_module({
name: "Ignore",
main_path: "../modules/Ignore/module.js",
main_class: require("../modules/Ignore/module.js"),
config: require("../config/Ignore.json")
}),
Holiday: this.make_module({
name: "Holiday",
main_path: "../modules/Holiday/module.js",
main_class: require("../modules/Holiday/module.js"),
config: require("../config/Holiday.json")
}),
Potato: this.make_module({
name: "Potato",
main_path: "../modules/Potato/module.js",
main_class: require("../modules/Potato/module.js"),
config: require("../config/Potato.json")
}),
UserJoined: this.make_module({
name: "UserJoined",
main_path: "../modules/UserJoined/module.js",
main_class: require("../modules/UserJoined/module.js"),
config: require("../config/UserJoined.json")
}),
Help: this.make_module({
name: "Help",
main_path: "../modules/Help/module.js",
main_class: require("../modules/Help/module.js"),
config: require("../config/Help.json")
}),
TimeToGalacon: this.make_module({
name: "TimeToGalacon",
main_path: "../modules/TimeToGalacon/module.js",
main_class: require("../modules/TimeToGalacon/module.js"),
config: require("../config/TimeToGalacon.json")
}),
Boop: this.make_module({
name: "Boop",
main_path: "../modules/Boop/module.js",
main_class: require("../modules/Boop/module.js"),
config: require("../config/Boop.json")
}),
Bap: this.make_module({
name: "Bap",
main_path: "../modules/Bap/module.js",
main_class: require("../modules/Bap/module.js"),
config: require("../config/Bap.json")
}),
Hug: this.make_module({
name: "Hug",
main_path: "../modules/Hug/module.js",
main_class: require("../modules/Hug/module.js"),
config: require("../config/Hug.json")
}),
Fanta: this.make_module({
name: "Fanta",
main_path: "../modules/Fanta/module.js",
main_class: require("../modules/Fanta/module.js"),
config: require("../config/Fanta.json")
}),
Bizaam: this.make_module({
name: "Bizaam",
main_path: "../modules/Bizaam/module.js",
main_class: require("../modules/Bizaam/module.js"),
config: require("../config/Bizaam.json")
}),
Assfart: this.make_module({
name: "Assfart",
main_path: "../modules/Assfart/module.js",
main_class: require("../modules/Assfart/module.js"),
config: require("../config/Assfart.json")
}),
BestPony: this.make_module({
name: "BestPony",
main_path: "../modules/BestPony/module.js",
main_class: require("../modules/BestPony/module.js"),
config: require("../config/BestPony.json")
}),
WorstPony: this.make_module({
name: "WorstPony",
main_path: "../modules/WorstPony/module.js",
main_class: require("../modules/WorstPony/module.js"),
config: require("../config/WorstPony.json")
}),
MentionCanni: this.make_module({
name: "MentionCanni",
main_path: "../modules/MentionCanni/module.js",
main_class: require("../modules/MentionCanni/module.js"),
config: require("../config/MentionCanni.json")
}),
DevCommands: this.make_module({
name: "DevCommands",
main_path: "../modules/DevCommands/module.js",
main_class: require("../modules/DevCommands/module.js"),
config: require("../config/DevCommands.json")
}),
Solver: this.make_module({
name: "Solver",
main_path: "../modules/Solver/module.js",
main_class: require("../modules/Solver/module.js"),
config: require("../config/Solver.json")
}),
GamerCanni: this.make_module({
name: "GamerCanni",
main_path: "../modules/GamerCanni/module.js",
main_class: require("../modules/GamerCanni/module.js"),
config: require("../config/GamerCanni.json")
}),
Greetings: this.make_module({
name: "Greetings",
main_path: "../modules/Greetings/module.js",
main_class: require("../modules/Greetings/module.js"),
config: require("../config/Greetings.json")
}),
Compliment: this.make_module({
name: "Compliment",
main_path: "../modules/Compliment/module.js",
main_class: require("../modules/Compliment/module.js"),
config: require("../config/Compliment.json")
}),
Hype: this.make_module({
name: "Hype",
main_path: "../modules/Hype/module.js",
main_class: require("../modules/Hype/module.js"),
config: require("../config/Hype.json")
}),
RoutineMessages: this.make_module({
name: "RoutineMessages",
main_path: "../modules/RoutineMessages/module.js",
main_class: require("../modules/RoutineMessages/module.js"),
config: require("../config/RoutineMessages.json")
}),
InterBotCom: this.make_module({
name: "InterBotCom",
main_path: "../modules/InterBotCom/module.js",
main_class: require("../modules/InterBotCom/module.js"),
config: require("../config/InterBotCom.json")
}),
NoMessageProcessor: this.make_module({
name: "NoMessageProcessor",
main_path: "../modules/NoMessageProcessor/module.js",
main_class: require("../modules/NoMessageProcessor/module.js"),
config: require("../config/NoMessageProcessor.json")
})
};
}

/**
Expand Down Expand Up @@ -103,31 +276,63 @@ class Application {
}
}

static registerModule(moduleName) {
const mainModuleFile = this.config.modules_path + "/" + moduleName + "/module.js";

if (!fs.existsSync(mainModuleFile)) {
throw new Error("Missing module.js for module " + moduleName);
}
// static registerModule(moduleName) {
// const mainModuleFile = this.config.modules_path + "/" + moduleName + "/module.js";
//
// if (!fs.existsSync(mainModuleFile)) {
// throw new Error("Missing module.js for module " + moduleName);
// }
//
// const moduleConfig = this.loadModuleConfig(moduleName);
//
// const moduleObj = {
// name: moduleName,
// mainPath: mainModuleFile,
// rootPath: this.config.modules_path + "/" + moduleName,
// config: moduleConfig
// };
//
// const moduleClass = require(mainModuleFile);
// const moduleInstance = new moduleClass(moduleName, moduleConfig, moduleObj);
//
// moduleObj.instance = moduleInstance;
//
// this.moduleObjs.push(moduleObj);
// this.modules[moduleName] = moduleInstance;
//
// return moduleInstance;
// }

const moduleConfig = this.loadModuleConfig(moduleName);
/**
* @template { Module } M
* @template { object } C
*
* @param { object } o
* @param { string } o.name
* @param { string } o.main_path
* @param { new (name: string, config: C) => M } o.main_class
* @param { C } o.config
*/
static make_module({
name,
main_path,
main_class,
config
}) {
main_path = path.resolve(__dirname, main_path);
let root_path = path.dirname(main_path);

const moduleObj = {
name: moduleName,
mainPath: mainModuleFile,
rootPath: this.config.modules_path + "/" + moduleName,
config: moduleConfig
};

const moduleClass = require(mainModuleFile);
const moduleInstance = new moduleClass(moduleName, moduleConfig, moduleObj);

moduleObj.instance = moduleInstance;
name,
mainPath: main_path,
rootPath: root_path,
config,
instance: new main_class(name, config)
}

moduleObj.instance.constructor_pt_2(moduleObj);
this.moduleObjs.push(moduleObj);
this.modules[moduleName] = moduleInstance;

return moduleInstance;
return moduleObj.instance;
}

static initModules() {
Expand Down Expand Up @@ -159,7 +364,6 @@ class Application {
Promise.all(this.moduleObjs.map(m => m.instance.stop()))
.then(() => {
this.moduleObjs = null;
this.modules = null;
resolve();
})
.catch(reject);
Expand Down Expand Up @@ -243,3 +447,7 @@ class Application {
}

module.exports = Application;

/**
* @typedef { import("./Module") } Module
*/
20 changes: 17 additions & 3 deletions lib/Module.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,31 @@
const Application = require("./Application");
const merge = require("merge");

/**
* @typedef {{
* name: string;
* mainPath: string;
* rootPath: string;
* config: object
* }} ModuleConfig
*/

module.exports = class Module {
/**
* @param { string } name
* @param { any } config
* @param { any } moduleConfig
*/
constructor(name, config, moduleConfig) {
constructor(name, config) {
this.name = name;
this.config = merge.recursive({}, config);
this.log = Application.getLogger(this.name);
this.moduleConfig = moduleConfig;
}

/**
* @param { ModuleConfig } module_config
*/
constructor_pt_2(module_config) {
this.moduleConfig = module_config;
}

init() {
Expand Down
47 changes: 1 addition & 46 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"use strict";
// @IMPORTS

const Application = require("./lib/Application");
const stage = (process.env.STAGE || process.env.NODE_ENV || "dev").toLowerCase();

Expand All @@ -23,51 +23,6 @@ Application.configure({
]
});

// resources

const modules = [
// "Activity",
"Discord",
"Overload",
"Ignore",
"Holiday",
"Potato",
"UserJoined",
"Help",
"TimeToGalacon",
"Boop",
"Bap",
"Hug",
"Fanta",
"Bizaam",
"Assfart",
"BestPony",
"WorstPony",
"MentionCanni",
"DevCommands",
"Solver",
"GamerCanni",
"Greetings",
"Compliment",
"Hype",
"RoutineMessages",
"InterBotCom",
"NoMessageProcessor"
];

// remove all disabled modules
const disabledModules = process.env.DISABLED_MODULES ? process.env.DISABLED_MODULES.split(",").map(m => m.trim()) : [];
disabledModules.forEach(module => {
const i = modules.indexOf(module);
i !== -1 && modules.splice(i, 1);
});

// add all enabled modules
const enabledModules = process.env.ENABLED_MODULES ? process.env.ENABLED_MODULES.split(",").map(m => m.trim()) : [];
enabledModules.forEach(module => !modules.includes(module) && modules.push(module));

modules.forEach(module => Application.registerModule(module));

Application.run();

process.on("SIGINT", () => Application.stop());
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
"resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

Expand Down

1 comment on commit 3c80be4

@meadowsys
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deployed from local (flyctl on gha kept failing, although running it locally it had no issues whatsoever)

Please sign in to comment.