TeqFW: Core

Fecha de publicación: 2021-06-25

Una aplicación Teq es primero una aplicación Node.js y, después, una aplicación modular compuesta de plugins Teq que son módulos npm. El núcleo de plataforma tiene tres tareas: arrancar la aplicación y sus comandos de consola, descubrir y conectar plugins, y establecer la arquitectura fundamental.

Bootstrap

El punto de entrada es bin/tequila.mjs. Encuentra la raíz, carga el contenedor DI, mapea fuentes del núcleo, crea configuración bootstrap, obtiene TeqFw_Core_Back_App$, lo inicializa y lo ejecuta. El script pertenece a la aplicación, pero se mantiene prácticamente idéntico de una aplicación Teq a otra.

import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import teq from '@teqfw/core';

const root = join(dirname(fileURLToPath(import.meta.url)), '..');
teq({ path: root }).catch(console.error);

El comportamiento diferente viene de plugins instalados y comandos que aportan, no de reescribir el launcher.

Ciclo de vida

Durante la inicialización, TeqFw_Core_Back_App:

Al ejecutarse realiza el comando pedido —a menudo un servidor web— o imprime la lista de comandos disponibles. También ofrece stop() para cerrar ordenadamente recursos como conexiones de base de datos.

Logger y configuración

El diseño original expone una abstracción de logger común, capaz de trabajar en backend o frontend y enrutar registros a consola, archivo, base o servidor remoto. La configuración local de backend se lee de JSON como cfg/local.json y se inyecta en los objetos que la necesitan. Los secretos deben permanecer en configuración local ignorada o en un entorno seguro de despliegue, nunca en el descriptor del paquete.

Escáner de plugins

Un plugin Teq es un paquete npm con teqfw.json en su raíz. Como mínimo declara namespace y directorio de fuentes:

{
  "autoload": {
    "ns": "Vendor_Project_Plugin",
    "path": "./src"
  }
}

El escáner recorre node_modules, encuentra descriptores, registra los paquetes y añade mapeos namespace-sistema de archivos a DI. Las demás partes acceden a los descriptores mediante ese registro, sin volver a escanear.

Comandos

La aplicación core es en esencia un envoltorio de commander. Los descriptores listan identificadores de módulos que producen DTO de comando:

{ "commands": ["TeqFw_Core_Back_Cli_Version"] }

Un DTO aporta action, descripción, nombre y realm opcional. El realm antepone comandos de un plugin: app más clean se convierte en app-clean.

const command = await container.get(`${factoryName}$`);
const fullName = command.realm ? `${command.realm}-${command.name}` : command.name;
commander.command(fullName).description(command.desc).action(command.action);

Resumen

El plugin Core convierte una colección de módulos npm en una aplicación Teq ejecutable. Descubre plugins, registra namespaces, inicializa logging y configuración local, reúne comandos y ejecuta el seleccionado mediante DI. Así el launcher permanece estable mientras la aplicación crece componiendo plugins.

Fragmentos adicionales de código fuente

{
“path”: “./src”
}
} Сканер плагинов (TeqFw_Core_Back_Scan_Plugin) пробегает по всем подкаталогам в ./node_modules/ в поисках teq-дескрипторов (./teqfw.json) и фиксирует найденные npm-пакеты в качестве teq-плагинов в реестре TeqFw_Core_Back_Scan_Plugin_Registry. После чего core-приложение добавляет найденные namespace’ы и их маппинг на файловую систему в DI-контейнер.
{
“TeqFw_Core_Back_Cli_Version”
]
} В узле commands прописываются идентификаторы es6-модулей, экспортирующих по-умолчанию фабрики для создания таких структур (TeqFw_Core_Back_Api_Dto_Command):
class TeqFw_Core_Back_Api_Dto_Command {
/** @type {Function} */
action;
/** @type {string} */
desc;
/** @type {string} */
name;
/** @type {string} */
realm;
}
export default function Factory(spec) {
// EXTRACT DEPS
/** @type {TeqFw_Core_Defaults} */
const DEF = spec[‘TeqFw_Core_Defaults$’];
/** @type {TeqFw_Core_Back_App.Bootstrap} */
const cfg = spec[‘TeqFw_Core_Back_App#Bootstrap$’];
/** @type {Function|TeqFw_Core_Back_Api_Dto_Command.Factory} */
const fCommand = spec[‘TeqFw_Core_Back_Api_Dto_Command#Factory$’]; // DEFINE INNER FUNCTIONS
const action = async function () {
console.log(Application version: ${cfg.version}.);
}; // COMPOSE RESULT
const res = fCommand.create();
res.realm = DEF.BACK_REALM;
res.name = ‘version’;
res.desc = ‘Get version of the application.’;
res.action = action;
return res;
} Core-приложение добавляет команды в commander при помощи DI-контейнера, который запускает соответствующую фабрику для создания действия (action) и мета-информации для commander’а:
const cmd = await container.get(${factoryName}$);
const fullName = (cmd.realm)
cmd.name;
commander.command(fullName)
.action(cmd.action);