Bajo Framework

website·Indexed 31 days ago

https://bajo.app

A 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.

Tokens
11.6K
Snippets
55
Records
85
Agent score
51%

What's inside Bajo

  1. Overview of Bajo Framework capabilities

    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.
  2. Implement a Bajo plugin using the Plugin Factory

    Bajo uses a plugin-based architecture. The main plugin is defined in main/index.js using a factory function. The plugin lifecycle consists of three primary asynchronous methods: init (initialization), start (execution), and exit (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
    }
  3. 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.
  4. 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}/data and 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.
  5. 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 the bajo-cli plugin.
    # Install the CLI plugin
    npm install bajo-cli
    # OR
    yarn add bajo-cli
    1. Add bajo-cli to the data/config/.plugins file.
    2. Launch the application with the -a or --applet switch:
    node index.js -a
    # OR
    bun index.js -a

    To enable logs while in applet mode (which are disabled by default), add the --log-applet switch.

  6. 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.
  7. 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 the main/extend/bajo/hook/ directory, or trigger your own custom hooks using runHook from the app.bajo object.
    // 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')
    }
  8. 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 (like afterBootComplete) or define custom hooks within a plugin's lifecycle using this.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')
    }
  9. Install and enable plugins in Bajo

    To use plugins in the Bajo Framework:

    1. Install the plugin package via npm: npm install {pkgName}.
    2. (Optional) Create a configuration file at {dataDir}/config/{ns}.json to customize settings, where {ns} is the camel-cased version of the plugin's package name.
    3. Add the plugin's package name ({pkgName}) to the {dataDir}/config/.plugins file, listing one package per line.

    To disable a plugin, remove it from the .plugins file or comment it out using a # and restart the application.

    # .plugins file
    bajo-config
    bajo-extra
    bajo-template
  10. 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/hook directory.

    Because colons (:) are not allowed in filenames, Bajo replaces the colon in the hook name with an @ symbol. For example, a hook named main:sayHello must be defined in a file named main@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;
  11. 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.