[data-reveal]{opacity:1!important;transform:none!important}
Modules
Core

Modules

Overview

The @antelopejs/interface-core/modules module provides lifecycle events and management functions for AntelopeJS modules. Modules transition through a defined lifecycle, and each transition emits an event that other modules can observe.

Inspect the running modules

Call these functions from a running AntelopeJS module, where the core has attached their implementations. This example reads status without changing the project.

import { ListModules, GetModuleInfo } from "@antelopejs/interface-core/modules";

for (const id of await ListModules()) {
  const info = await GetModuleInfo(id);
  console.log(id, info.status);
}

Use management functions to change what is running now. Use declaration functions to edit what the project loads on its next start. Neither action automatically performs the other.

Import

import {
  Events,
  ListModules,
  GetModuleInfo,
  LoadModule,
  StartModule,
  StopModule,
  DestroyModule,
  ReloadModule,
} from "@antelopejs/interface-core/modules";

Module lifecycle

A module moves through these states:

loaded -> constructed -> active -> constructed -> loaded
                                   (stopped)     (destroyed)
StateDescription
loadedModule code is loaded but no instance exists
constructedModule instance is created but not started
activeModule is fully started and providing services
unknownModule status cannot be determined

Module execution context

This is a loader concern. Application modules normally receive their context from the runtime and do not invent their own owner IDs.

RunWithModuleContext propagates module ownership through synchronous and asynchronous work:

import { RunWithModuleContext } from "@antelopejs/interface-core/modules";

await RunWithModuleContext(
  {
    module: "search-provider",
    owner: "search-provider#42",
  },
  () => constructModule(),
);

module remains the stable public module ID. owner identifies one lifecycle generation and should be unique when old and replacement instances can overlap. Providers capture this full context when attaching callbacks. GetModuleContext returns the active context, or undefined when there is none, and throws ModuleContextInvalidatedError after its owner is destroyed.

Lifecycle events

The Events namespace exposes four EventProxy instances that fire during module lifecycle transitions.

Events.ModuleConstructed

Fires after a module instance is created, before the module is started.

import { Events } from "@antelopejs/interface-core/modules";

Events.ModuleConstructed.register((moduleId: string) => {
  console.log(`Module constructed: ${moduleId}`);
});

Events.ModuleStarted

Fires after a module has been started and is fully operational.

Events.ModuleStarted.register((moduleId: string) => {
  console.log(`Module started: ${moduleId}`);
});

Events.ModuleStopped

Fires after a module has been stopped. The module instance still exists but is no longer active.

Events.ModuleStopped.register((moduleId: string) => {
  console.log(`Module stopped: ${moduleId}`);
});

Events.ModuleDestroyed

Fires after a module instance has been destroyed and all its resources have been released. The system uses this event internally to clean up proxy attachments and event handlers associated with the destroyed module.

Events.ModuleDestroyed.register((moduleId: string) => {
  console.log(`Module destroyed: ${moduleId}`);
});

The event signature remains the module ID. When emitted inside RunWithModuleContext, cleanup targets that context's owner; without an explicit owner it retains the module-level behavior used by earlier releases.

Management functions

These functions are declared as InterfaceFunction proxies. They are available once the core runtime provides their implementation.

ListModules

Returns the identifiers of all loaded modules.

const modules = await ListModules();
// ["auth-module", "database-module", "api-module"]

GetModuleInfo

Returns detailed information about a specific module, including its configuration, status, and file system path.

import type { ModuleInfo } from "@antelopejs/interface-core/modules";

const info: ModuleInfo = await GetModuleInfo("auth-module");
// info.status -> "active"
// info.localPath -> "/path/to/auth-module"
// info.source -> { type: "package", ... }

LoadModule

Loads a new module with the given configuration. Set autostart to true to automatically start the module after loading.

import type { ModuleDefinition } from "@antelopejs/interface-core/modules";

const definition: ModuleDefinition = {
  source: { type: "package", package: "@my/module", version: "1.0.0" },
  config: { key: "value" },
};

await LoadModule("my-module", definition, true);

StartModule

Starts a loaded but inactive module.

await StartModule("my-module");

StopModule

Stops an active module. The module instance remains but stops providing services.

await StopModule("my-module");

DestroyModule

Destroys a stopped module instance. The module code remains loaded.

await DestroyModule("my-module");

ReloadModule

Stops, destroys, unloads, and reloads a module from its source. This is useful for applying updates without restarting the application.

await ReloadModule("my-module");

Declaration functions

These functions read and edit the modules of the project's antelope.config.ts, for a module that installs or removes other modules and wants the change to survive a restart.

ListModuleDeclarations

Returns the modules the configuration file declares at its top level, by key, shorthand entries expanded and disabled ones included.

const declarations = await ListModuleDeclarations();

SaveModuleDeclaration

Writes the given fields of a module's entry, adding the entry when the file has none. Only those fields are rewritten: every other line of the file, comments and expressions included, stays as it was. A field set to undefined or null is removed. The running project does not restart for this write; the caller loads, stops or reloads the module itself.

await LoadModule("@acme/reports", { source }, true);
await SaveModuleDeclaration("@acme/reports", { source, optional: true });

It throws when the file has no modules object it can edit, such as a configuration built by a function.

RemoveModuleDeclaration

Removes a module's entry, leaving the rest of the file as it was and the project running.

await RemoveModuleDeclaration("@acme/reports");

ModuleDefinition

The configuration object for defining a module.

PropertyTypeDescription
source{ type: string } & Record<...>Source location and loading mechanism
configunknownOptional configuration data for the module
importOverridesRecord<string, string[]>Optional runtime import override map with array values
disabledExportsstring[]Optional list of exports to hide from this module

ModuleDefinition is the runtime management contract used by LoadModule and GetModuleInfo. It is not the project-file AntelopeModuleConfig: that type uses ImportOverride[] | Record<string, string> for declarative provider bindings and named connections. The different importOverrides shapes are intentional; do not copy one into the other or cast between them. SaveModuleDeclaration uses the project-file shape. See project configuration for that contract.

ModuleInfo

Extends ModuleDefinition with runtime information.

PropertyTypeDescription
statusstringCurrent lifecycle state of the module
localPathstringFile system path where the module exists

Next steps