Bajo Framework
website·Indexed 31 days ago
https://bajo.appA framework for rapid application development featuring a plugin-based ecosystem and system hooks. Documentation covers v2.0.x, including installation, configuration, system architecture, and plugin development.
What's inside Bajo
- Bajo Framework (v2.0.x) is a universal, open-source (MIT Licensed) framework designed for building a wide range of applications, including CLI tools, web servers, and messaging systems. It utilizes an ES6 module-based architecture supporting both static and dynamic imports, ensuring clear encapsulation and scoping.
Implement a Bajo plugin using the Plugin Factory
Bajo uses a plugin-based architecture. The main plugin is defined in
main/index.jsusing a factory function. The plugin lifecycle consists of three primary asynchronous methods:init(initialization),start(execution), andexit(cleanup).Plugins are configured via JSON files at
{dataDir}/config/{pluginName}.json. Default configuration values should be defined in the plugin's constructor to ensure they are merged correctly with the JSON config.// main/index.js async function factory (pkgName) { const me = this return class Main extends this.app.pluginClass.base { constructor () { super(pkgName, me.app) // Define default config here this.config = { firstName: 'John', lastName: 'Doe', age: 50 } } init = async () => { // Values from data/config/main.json are merged into this.config this.firstName = this.config.firstName this.lastName = this.config.lastName this.age = this.config.age } start = async () => { this.log.info('First name: %s, Last name: %s, age: %d', this.firstName, this.lastName, this.age) } exit = async () => { this.log.warn('Program aborted') } } } export default factory// data/config/main.json { "firstName": "Tanjiro", "lastName": "Kamado", "age": 15 }Bajo Framework Overview
Bajo Framework (v2.0.x) is a universal, open-source (MIT Licensed) framework designed for rapid development of large-scale applications, including CLI tools, web servers, and messaging systems. It utilizes a modular 'LEGO-like' architecture where developers select and configure only the necessary plugins for their specific needs.Understand Bajo framework terminology
Bajo uses specific terms to describe the project environment and plugin architecture:
{appDir}: The root project directory containing the application code.{dataDir}: The directory for all data and configuration; defaults to{appDir}/dataand is created automatically if missing.{tmpDir}: The temporary directory, defaulting to the OS temporary directory.{pkgName}: The plugin's npm package name.{ns}: The plugin namespace (the camel-cased version of the package name).{mainNs}: The special 'main' namespace and directory within{appDir}where application-specific code resides.
Run Bajo in Applet Mode
Applets are small tools embedded in plugins that run independently of the main program but share resources and config objects. To use applet mode, you must install thebajo-cliplugin.# Install the CLI plugin npm install bajo-cli # OR yarn add bajo-cli- Add
bajo-clito thedata/config/.pluginsfile. - Launch the application with the
-aor--appletswitch:
node index.js -a # OR bun index.js -aTo enable logs while in applet mode (which are disabled by default), add the
--log-appletswitch.- Add
Organize the Bajo application directory structure
A typical Bajo application follows this structure:
{appDir}/main/: The application code directory (the{mainNs}plugin). It is always available, starts last, and is created automatically if missing.index.js: The factory function for the main plugin.extend/: Directory for extending other plugins.
{dataDir}/(Default:{appDir}/data): The only directory where Bajo is permitted to write data.config/: Contains configuration files..plugins: Defines which plugins to load.bajo.json: Global settings.{ns}.json: Plugin-specific configuration files.
plugins/: Plugin data storage.
index.js: The main entry point for the application.package.json: Project dependencies and metadata.
Use the Bajo Hook system to extend functionality
Bajo's hook system allows developers to inject custom code into specific lifecycle events. You can tap into existing system hooks by creating files in themain/extend/bajo/hook/directory, or trigger your own custom hooks usingrunHookfrom theapp.bajoobject.// Example: Tapping into a system hook // File: main/extend/bajo/hook/afterBootComplete.js async function afterBootComplete () { this.log.info('Hook after boot complete') } export default afterBootComplete// Example: Triggering a custom hook in a plugin init = async () => { const { runHook } = this.app.bajo // ... initialization logic ... await runHook('main:myHook') }Use the Bajo Hook system to extend functionality
Bajo allows developers to 'tap' into system events using hooks. You can either use built-in hooks (likeafterBootComplete) or define custom hooks within a plugin's lifecycle usingthis.app.bajo.runHook('hookName').// Example: Tapping a built-in hook // File: main/extend/bajo/hook/afterBootComplete.js async function afterBootComplete () { this.log.info('Hook after boot complete') } export default afterBootComplete // Example: Triggering a custom hook in a plugin init = async () => { const { runHook } = this.app.bajo // ... initialization logic ... await runHook('main:myHook') }Hire professional services for Bajo Framework projects
Professional assistance and services for projects based on the Bajo Framework are available through the maintainer's GitHub profile.Install and enable plugins in Bajo
To use plugins in the Bajo Framework:
- Install the plugin package via npm:
npm install {pkgName}. - (Optional) Create a configuration file at
{dataDir}/config/{ns}.jsonto customize settings, where{ns}is the camel-cased version of the plugin's package name. - Add the plugin's package name (
{pkgName}) to the{dataDir}/config/.pluginsfile, listing one package per line.
To disable a plugin, remove it from the
.pluginsfile or comment it out using a#and restart the application.# .plugins file bajo-config bajo-extra bajo-template- Install the plugin package via npm:
Create a hook handler file
Bajo automatically scans for hook files during the boot process. To create a handler for a hook, place a file in the
{appDir}/main/extend/bajo/hookdirectory.Because colons (
:) are not allowed in filenames, Bajo replaces the colon in the hook name with an@symbol. For example, a hook namedmain:sayHellomust be defined in a file namedmain@sayHello.js.// File: {appDir}/main/extend/bajo/hook/main@sayHello.js async function sayHello (...params) { const [mainChar, friend, payload] = params; console.log(mainChar, friend, payload); } export default sayHello;Verify Bajo runtime requirements
Bajo is a pure ES6 framework that relies heavily on dynamic imports. It has the following runtime constraints:
- Node.js: Version 20 or higher is required (latest stable recommended).
- Bun: Supported and compatible.
- Deno: Not supported due to reliance on Node.js-specific libraries.
- Hardware: A fast disk (SSD) and sufficient RAM are highly recommended for performance when loading many plugins.