From 3649dff9aa14bd2f9e4ab4253d14561cc3d6e1c2 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Mon, 28 Oct 2024 15:09:26 -0400 Subject: [PATCH] dev: add module lib installation to useapi --- src/backend/src/CoreModule.js | 11 +++++-- src/backend/src/Kernel.js | 61 ++++++++++++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/backend/src/CoreModule.js b/src/backend/src/CoreModule.js index b54c8d11..52d5cd01 100644 --- a/src/backend/src/CoreModule.js +++ b/src/backend/src/CoreModule.js @@ -24,11 +24,13 @@ const { Context } = require('./util/context'); class CoreModule extends AdvancedBase { + dirname () { return __dirname; } async install (context) { const services = context.get('services'); const app = context.get('app'); const useapi = context.get('useapi'); - await install({ services, app, useapi }); + const modapi = context.get('modapi'); + await install({ services, app, useapi, modapi }); } // Some services were created before the BaseService @@ -44,7 +46,10 @@ class CoreModule extends AdvancedBase { module.exports = CoreModule; -const install = async ({ services, app, useapi }) => { +/** + * @footgun - real install method is defined above + */ +const install = async ({ services, app, useapi, modapi }) => { const config = require('./config'); useapi.withuse(() => { @@ -63,6 +68,8 @@ const install = async ({ services, app, useapi }) => { const LibTypeTagged = require('./libraries/LibTypeTagged'); services.registerService('lib-type-tagged', LibTypeTagged); }); + + modapi.libdir('lib.core', './util'); // === SERVICES === diff --git a/src/backend/src/Kernel.js b/src/backend/src/Kernel.js index d5028d48..881b922e 100644 --- a/src/backend/src/Kernel.js +++ b/src/backend/src/Kernel.js @@ -135,9 +135,14 @@ class Kernel extends AdvancedBase { const { services } = this; // Internal modules - for ( const module of this.modules ) { - services.registerModule(module.constructor.name, module); - await module.install(Context.get()); + for ( const module_ of this.modules ) { + services.registerModule(module_.constructor.name, module_); + const mod_context = this._create_mod_context(Context.get(), { + name: module_.constructor.name, + ['module']: module_, + external: false, + }); + await module_.install(mod_context); } // External modules @@ -209,6 +214,8 @@ class Kernel extends AdvancedBase { const path_ = require('path'); const fs = require('fs'); + const mod_install_root_context = Context.get(); + const mod_paths = this.environment.mod_paths; for ( const mods_dirpath of mod_paths ) { const mod_dirnames = fs.readdirSync(mods_dirpath); @@ -226,14 +233,60 @@ class Kernel extends AdvancedBase { continue; } + const mod_context = this._create_mod_context(mod_install_root_context, { + name: mod_class.name ?? mod_dirname, + ['module']: mod, + external: true, + mod_path, + }); + if ( mod.install ) { this.useapi.awithuse(async () => { - await mod.install(Context.get()); + await mod.install(mod_context); }); } } } } + + _create_mod_context (parent, options) { + const path_ = require('path'); + const fs = require('fs'); + + const modapi = {}; + + let mod_path = options.mod_path; + if ( ! mod_path && options.module.dirname ) { + mod_path = options.module.dirname(); + } + + if ( mod_path ) { + modapi.libdir = (prefix, directory) => { + const fullpath = path_.join(mod_path, directory); + const fsitems = fs.readdirSync(fullpath); + for ( const item of fsitems ) { + if ( ! item.endsWith('.js') ) { + continue; + } + const stat = fs.statSync(path_.join(fullpath, item)); + if ( ! stat.isFile() ) { + continue; + } + + const name = item.slice(0, -3); + const path = path_.join(fullpath, item); + let lib = require(path); + + // TODO: This context can be made dynamic by adding a + // getter-like behavior to useapi. + this.useapi.def(`${prefix}.${name}`, lib); + } + } + } + const mod_context = parent.sub({ modapi }, `mod:${options.name}`); + return mod_context; + + } } module.exports = { Kernel };