Modules
Module Structure
A module is a standard npm package with an antelopeJs field in its package.json. This field tells the core what the module implements, where to find its compiled output, and how to resolve its internal imports.
{
"name": "my-module",
"antelopeJs": {
"implements": ["@antelopejs/interface-example"],
"baseUrl": "dist",
"paths": { "@/*": ["*"] },
"moduleAliases": {},
"defaultConfig": {}
}
}
The implements array lists the interface packages this module provides. The baseUrl points to the compiled output directory. The paths field configures TypeScript-style path aliases, and defaultConfig provides fallback configuration values.
Entry Point
The module entry point (src/index.ts, compiled to dist/index.js) exports lifecycle functions. The core calls these functions in order as the module transitions through its lifecycle states.
import { ImplementInterface } from "@antelopejs/interface-core";
export async function construct(config: unknown): Promise<void> {
// Initialize resources, connect to databases
// Register interface implementations
}
export function start(): void {
// Module is fully active, all interfaces available
}
export async function stop(): Promise<void> {
// Gracefully stop operations
}
export async function destroy(): Promise<void> {
// Clean up resources
}
The construct function receives the module's configuration object. Use it to set up database connections, register interface implementations, and prepare internal state. The start function runs after all modules have been constructed and interfaces are resolved.
Lifecycle States
Every module passes through a defined sequence of states. The core manages these transitions and ensures they happen in the correct order.
| State | Description |
|---|---|
loaded | Module files have been resolved and loaded into memory. |
constructed | The construct() function has completed successfully. |
active | The start() function has completed and the module is serving its interfaces. |
The full lifecycle flows in one direction: loaded → constructed → active → (stop) → (destroy). The stop and destroy phases reverse the startup sequence, giving each module a chance to release resources gracefully.
Module Events
Other modules can listen for lifecycle transitions. The core emits events whenever a module changes state, enabling coordination between modules that need to react to each other's availability.
import { Events } from "@antelopejs/interface-core/modules";
Events.ModuleConstructed.register((moduleId: string) => {
// Fires after a module completes construct()
});
Events.ModuleStarted.register((moduleId: string) => {
// Fires after a module completes start()
});
Events.ModuleStopped.register((moduleId: string) => {
// Fires after a module completes stop()
});
Events.ModuleDestroyed.register((moduleId: string) => {
// Fires after a module completes destroy()
});
Module Management Functions
The core provides functions to inspect and control modules at runtime. These functions are available from @antelopejs/interface-core/modules and operate on module IDs as defined in your project configuration.
Listing and Inspecting Modules
Retrieve the list of loaded modules or query detailed information about a specific module. Both functions return promises and accept module IDs as defined in your project configuration.
import { ListModules, GetModuleInfo } from "@antelopejs/interface-core/modules";
// List all loaded module IDs
const modules = await ListModules();
// Get detailed info about a module
const info = await GetModuleInfo("my-module");
// info.status: "loaded" | "constructed" | "active" | "unknown"
// info.source, info.config, info.importOverrides, info.disabledExports, info.localPath
Loading Modules Dynamically
Add new modules to a running application without restarting. The third argument controls whether the module starts immediately after loading.
import { LoadModule } from "@antelopejs/interface-core/modules";
await LoadModule("new-module", {
source: { type: "package", package: "@scope/module", version: "1.0.0" },
config: { /* module config */ }
}, true); // true = autostart
Lifecycle Control
Start, stop, destroy, or perform Hot Module Reloading (HMR) on individual modules. These functions give you fine-grained control over the module lifecycle at runtime.
import { StartModule, StopModule, DestroyModule, ReloadModule } from "@antelopejs/interface-core/modules";
await StartModule("my-module");
await StopModule("my-module");
await DestroyModule("my-module");
await ReloadModule("my-module"); // HMR
ReloadModule performs a stop-destroy-load-start cycle in a single call. During development, the --watch flag on ajs project dev triggers this automatically when source files change.Interfaces
Interfaces define the contracts that modules use to communicate — declaring functions, events, and registrations without tying them to any specific implementation.
Proxies
Proxies are the communication backbone of Antelopejs — AsyncProxy for function calls, EventProxy for broadcasting, and RegisteringProxy for registration systems.