GeoLeaf Core API - v3.19.0
    Preparing search index...

    Lifecycle contract for a GeoLeaf module that participates in boot.

    Modules are registered with IModuleRegistry.register() and initialised in dependency order by IModuleRegistry.init(). Each module must implement init() and destroy(), and declare its dependencies so the registry can resolve the correct initialisation order.

    Dependency declaration rules:

    • List only direct dependencies (not transitive).
    • Reference dependencies by their id string.
    • Circular dependencies are detected at registration time and throw a GeoLeafError with the full dependency cycle path in the message.

    ⚠️ An edge declares a RANK, not only a data read — and the rank is observable. The in-core capabilities all declare ["geojson"] while most of their init() bodies read no geojson state at all (measured, module by module). The edge still does load-bearing work: it places the capability in the LATE init wave — after config has merged the profile, after core-map, after ui has mounted its controls, and before ThemeEngineModule, whose init() is what dispatches geoleaf:theme:applied (and through the reveal, geoleaf:app:ready). On a profile without a default theme, the boot dispatches geoleaf:app:ready once registry.init() has returned — after every module either way. (It used to fire from inside ui's init(), i.e. BEFORE this wave, and the capabilities that mount on it never did.) Removing an edge moves the module to the FIRST wave, which visibly reorders map controls (stacking follows insertion), changes introspection ranks, and re-times every listener armed at init relative to the kernel emitters. Do not delete an edge because its init "reads nothing" — that was measured true for thirteen of fourteen, and deleting was still the wrong gesture. Change an edge only with the boot sequence of a shipped bundle in front of you, and re-verify at execution: no gate guards this order.

    ⚠ Classes implement THIS interface, never the ICoreModule union — TypeScript's implements clause rejects union types.

    class ExampleModule implements ILifecycleModule {
    readonly id = 'example';
    readonly dependencies = ['geojson'] as const;
    readonly ui: IModuleUISlot = { … };

    async init(adapter: IMapAdapter, config: IGeoLeafConfig): Promise<void> {
    // … setup
    }

    destroy(): void {
    // … cleanup
    }
    }
    interface ILifecycleModule {
        id: string;
        dependencies: readonly string[];
        ui?: IModuleUISlot;
        init(adapter: IMapAdapter, config: IGeoLeafConfig): void | Promise<void>;
        destroy(): void;
    }

    Implemented by

    Index
    id: string

    Unique module identifier within the GeoLeaf instance.

    The registry enforces uniqueness — registering two modules with the same id throws a GeoLeafError. Use lowercase kebab-case.

    `'geojson'`, `'route'`, `'legend'`, `'layer-manager'`
    
    dependencies: readonly string[]

    IDs of modules that must be fully initialised before this module's init() is called.

    The registry resolves a topological order from these declarations. An empty array means this module has no dependencies.

    Use as const in implementing classes for best type inference:

    readonly dependencies = ['poi', 'ui'] as const;
    

    Optional UI slot declaration.

    Declare this when the module contributes UI to the mobile toolbar pill or the desktop filter panel. The registry collects all slots via getUISlots() and passes them to the UI orchestrator.

    • Initialises the module.

      Called by the registry after all declared dependencies are ready. Guaranteed postconditions at call time:

      • adapter.isReady() returns true
      • config.isLoaded() returns true
      • All modules listed in dependencies have completed their init()

      Returning void (synchronous) is allowed for modules that do not perform async work. The registry handles both with Promise.resolve().

      Parameters

      Returns void | Promise<void>

    • Tears down the module and releases all resources.

      Must remove every event listener, DOM node, and layer reference created during init(). After destroy(), the module must be safe to garbage collect.

      Called by the registry in reverse dependency order (dependants are destroyed before their dependencies).

      Returns void