FleetbaseFleetbase

Overview

The UniverseService is the central extensibility facade in @fleetbase/ember-core. It exposes five sub-services for menus, registries, widgets, hooks, and engines — and is the single entry point your extension uses to plug into the console.

Universe Service

The UniverseService is the central extensibility facade in @fleetbase/ember-core. It is the entry point your extension uses to register everything: menu items, components, widgets, hooks, registries, and engine integrations.

You access it through the setupExtension(app, universe) hook in your addon/extension.js:

// addon/extension.js
import { MenuItem, ExtensionComponent } from '@fleetbase/ember-core/contracts';

export default {
    setupExtension(app, universe) {
        const menuService     = universe.getService('menu');
        const registryService = universe.getService('registry');
        const widgetService   = universe.getService('widget');
        const hookService     = universe.getService('hook');

        // … register your contributions
    },
};

For the full extension-registration lifecycle, see Extension Registration.

Five Sub-Services

UniverseService is a façade — most functionality lives in five specialized sub-services that you reach via universe.getService(...):

ServiceWhat it doesPage
menuHeader items, settings, admin panels, organization & user dropdowns, custom registriesMenu Service
registryCreate & query registries; register renderable components, components, services, helpersRegistry Service
widgetDashboard widgets and dashboardsWidget Service
hookLifecycle hooks (application:before-model, console:after-model, etc.)Hook Service
extension-managerEngine loading & cross-engine integrationExtension Manager

getService() Name Resolution

getService() accepts several forms — they all resolve to the same sub-service:

You can writeResolves to
'menu', 'menus'universe/menu-service
'menu-service', 'menuService'universe/menu-service
'universe/menu-service'universe/menu-service
'registry', 'registry-service'universe/registry-service
'widget', 'widgets', 'widget-service'universe/widget-service
'hook', 'hooks', 'hook-service'universe/hook-service

The kebab-case short form ('menu', 'widget', etc.) is the canonical idiom in real addon/extension.js files — that's what every modern extension uses.

Engine Lifecycle Methods

Beyond the sub-services, UniverseService exposes a handful of engine-loading helpers directly:

MethodPurpose
universe.whenEngineLoaded(name, cb)Run cb(engineInstance, universe, app) when the engine has booted. If it's already loaded, runs immediately. The recommended way to do cross-engine work
universe.ensureEngineLoaded(name)Force-load an engine (returns a Promise<EngineInstance>)
universe.onEngineLoaded(name, cb)Event-only listener — does not fire if the engine is already loaded. Prefer whenEngineLoaded
universe.getEngineInstance(name)Returns the loaded engine instance, or null
universe.getServiceFromEngine(engineName, serviceName, options?)Look up a service inside another engine
universe.extensionManager.isInstalled(name)Whether an extension is installed in this Fleetbase deployment

These all delegate to the Extension Manager.

Façade Convenience Methods

For backward compatibility, UniverseService itself exposes thin pass-through methods that delegate to the sub-services. For example:

  • universe.registerHeaderMenuItem(...)menuService.registerHeaderMenuItem(...)
  • universe.registerHook(...)hookService.registerHook(...)
  • universe.createRegistry(...)registryService.createRegistry(...)
  • universe.registerRenderableComponent(...)registryService.registerRenderableComponent(...)

Prefer the sub-service form (universe.getService('menu').registerHeaderMenuItem(...)) — it's the canonical idiom, makes the intent explicit, and avoids deprecated façade aliases like registerDashboardWidgets.

A Complete addon/extension.js

A representative example combining several sub-services:

// addon/extension.js
import { MenuItem, Widget, ExtensionComponent, Hook } from '@fleetbase/ember-core/contracts';

export default {
    setupExtension(app, universe) {
        const menuService     = universe.getService('menu');
        const registryService = universe.getService('registry');
        const widgetService   = universe.getService('widget');
        const hookService     = universe.getService('hook');

        // 1. Top-level header item
        menuService.registerHeaderMenuItem('My Extension', 'console.my-extension', {
            icon: 'puzzle-piece',
            description: 'My custom logistics feature.',
        });

        // 2. Settings item
        menuService.registerSettingsMenuItem(
            new MenuItem({
                title: 'My Extension',
                slug: 'my-extension',
                icon: 'gear',
                component: new ExtensionComponent('@my-org/my-extension-engine', 'settings'),
            })
        );

        // 3. Inject a component into another extension's slot
        registryService.registerRenderableComponent(
            'fleet-ops:component:order:details',
            new ExtensionComponent('@my-org/my-extension-engine', 'my-order-tab')
        );

        // 4. Register a dashboard widget
        widgetService.registerWidgets('dashboard', [
            new Widget({
                id: 'my-extension-stats',
                name: 'My Stats',
                icon: 'chart-line',
                component: new ExtensionComponent('@my-org/my-extension-engine', 'widget/my-stats'),
                grid_options: { w: 6, h: 6, minW: 4, minH: 4 },
            }),
        ]);

        // 5. Hook into the console boot
        hookService.registerHook(
            new Hook('console:after-model', (session, router) => {
                // do something after the user is authenticated
            })
        );
    },
};

Real-World References

ExtensionPattern shownSource
StorefrontHeader menu with shortcuts, dashboard widget, registry componentsstorefront/addon/extension.js
Fleet-OpsHeader item with shortcuts, admin panel, custom registries (40+), widgetfleetops/addon/extension.js
VROOMwhenEngineLoaded to register a route-optimization provider into Fleet-Opsvroom/addon/extension.js
ValhallawhenEngineLoaded to register a routing engine into Fleet-Opsvalhalla/addon/extension.js
PalletHeader menu, settings registriespallet/addon/extension.js
LedgerCustom dashboard, multiple widgets, Fleet-Ops order-details tabledger/addon/extension.js

Source

FileDescription
addon/services/universe.jsThe UniverseService façade
addon/services/universe/All five sub-services
addon/contracts/MenuItem, Widget, Hook, ExtensionComponent, etc.
Overview | Fleetbase