Skip to content

Class: ExtensionCoordinator

Makaio Framework


Makaio Framework / kernel / ExtensionCoordinator

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:68

Manages optional extensions through a unified lifecycle with per-extension state machine, bus observability, and window/tray/CLI surface collection.

Lifecycle flow for each extension:

discovered -> initializing -> [create + init + contributions] -> active
↘ failed (any step fails, contributions rolled back)
↘ skipped (ServiceSkipError from create or init,
or loadEnabled returned false at boot)

Every state transition emits kernel:extension.stateChanged on the bus. Non-critical failures are isolated so remaining extensions continue to start. Critical extension failures abort boot because the host declared them mandatory.

During load, window manifests are registered into windowRegistry, tray entries are collected into trayEntries, and CLI contributions are collected into cliContributions. Static tray entries are bridged to the tray menu bus service after each extension starts so the tray service can be supplied by the same extension graph.

During startAll, each extension’s MakaioExtension.create factory is called with a NodeExtensionContext, followed by service.init(). Storage handlers (if any) are registered via MakaioExtension.storage.registerHandlers when a db instance is provided to the constructor.

new ExtensionCoordinator(bus, options?): ExtensionCoordinator

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:120

IMakaioBus

Bus instance for emitting lifecycle events and serving the list RPC.

ExtensionCoordinatorOptions = {}

Coordinator configuration.

ExtensionCoordinator

readonly windowRegistry: WindowRegistry

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:106

Window registry populated during load.

get cliContributions(): readonly CliContribution[]

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:151

CLI contributions collected from packages during load.

readonly CliContribution[]

Immutable snapshot of all collected CLI contributions.


get trayEntries(): readonly TrayManifest & object[]

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:143

Tray manifest entries collected from packages during load.

readonly TrayManifest & object[]

Immutable snapshot of all collected tray entries.

extensionsWithHttp(): readonly object[]

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:162

Returns extensions that declare HTTP routes. Primarily retained for diagnostics and compatibility with callers that need a snapshot of loaded HTTP surfaces. Runtime route mounting is handled by contribution processors as extensions activate or stop.

readonly object[]

Loaded extensions that have an http field defined.


forEachActiveExtension(callback): void

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:373

Iterate all active extensions in dependency order with their contexts.

Intended for host-owned integration code that needs a snapshot of active packages after the coordinator has completed startup.

(name, pkg, ctx) => void

Called once per active extension with its name, manifest, and a per-extension NodeExtensionContext.

void


forExtension(name, callback): void

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:396

Invoke a callback for a single active extension with its resolved context.

Singular complement to forEachActiveExtension for targeted operations after an extension is re-enabled. No-ops when the extension is not found or not in active state.

string

Name of the extension to target.

(name, pkg, ctx) => void

Called with the extension name, manifest, and a per-extension NodeExtensionContext when the extension is active.

void


getExtension(name): MakaioExtension<NodeExtensionContext> | undefined

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:361

Look up a loaded extension by name.

string

Extension name.

MakaioExtension<NodeExtensionContext> | undefined

The extension, or undefined if not loaded.


getExtensionService<TService>(tokenOrName): TService | undefined

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:349

Retrieve the live service instance for a named extension.

TService = ExtensionService

string | ExtensionToken<TService>

Extension token or extension name string.

TService | undefined

The active service instance, or undefined.


handleSetEnabled(name, enabled): Promise<boolean>

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:444

Handle the kernel:extension.setEnabled RPC by enabling or disabling an extension.

Public so the extracted RPC handler module can call it. Delegates to the shared toggle lifecycle helper.

string

Name of the extension to toggle.

boolean

true to enable, false to disable.

Promise<boolean>

true on success, false when the state machine rejects.


list(): object[]

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:340

Return the current state snapshot for all registered packages.

Array of ExtensionInfo objects reflecting current observable states.


load(packages, configDefaults?): void

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:192

Load extension manifests and build the dependency graph.

Sets all entries to the discovered state and registers the kernel:extension.list, kernel:extension.get, kernel:extension.setEnabled, cli.listContributions, and cli.execute RPC handlers.

Extensions that do not match the coordinator’s runtime surface or declared environment requirements are silently excluded. Dependents of excluded extensions are transitively pruned.

Window manifests are registered into windowRegistry, tray entries are collected into trayEntries, and CLI contributions are collected into cliContributions — all before any services are started.

Single-use: calling this method twice on the same instance throws.

readonly MakaioExtension<NodeExtensionContext>[]

Extension manifests to register.

ReadonlyMap<string, Readonly<Record<string, unknown>>>

Optional map of extension name to default config values sourced from descriptor.json.

void

Error if called more than once, if a dependency cycle is detected, or if dependency sorting fails.


registerContributionProcessor(processor): () => void

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:427

Register an awaited contribution processor.

The processor’s processActivated method is called (and awaited) each time an extension transitions to active — both during startAll and on re-enable via kernel:extension.setEnabled(true).

processStopped (when present) is called before the extension’s service is destroyed during shutdown or kernel:extension.setEnabled(false).

Processors run in registration order during activation and reverse registration order during deactivation. During activation, processor errors cause the extension to transition to failed with rollback of already-activated contributions. During deactivation, errors are caught and logged (best-effort).

ContributionProcessor

Processor to register.

Cleanup function that removes the processor from the registry.

() => void


shutdown(): Promise<void>

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:317

Shut down all active packages in reverse dependency order.

Calls each package’s service destroy() method (if any). Errors are logged but do not stop remaining packages from shutting down.

Safe to call even if startAll was never called.

Promise<void>


startAll(): Promise<void>

Defined in: ../../../packages/kernel/src/extension/extension-coordinator.ts:256

Start all loaded packages in dependency order.

For each package the state machine advances: discovered -> initializing -> active | failed | skipped

Failures are isolated: a package that throws during create or init is set to failed and the error is captured, but remaining packages continue to start unless the package declares critical: true.

Single-use: calling this method twice on the same instance throws.

Promise<void>

Error if called more than once, before load, or when a critical package fails.