refactor: Move runtime config and router fix to proper Ember initializers

Refactored app.js boot sequence to follow Ember conventions:

1. Created app/initializers/load-runtime-config.js
   - Loads fleetbase.config.json before application boots
   - Uses deferReadiness/advanceReadiness pattern
   - Runs before all other initializers
   - Added performance timing with debug logging

2. Created app/instance-initializers/apply-router-fix.js
   - Applies router refresh bug fix patch
   - Runs as instance-initializer (needs app instance)
   - Runs before extension loading
   - Added performance timing with debug logging

3. Refactored app/app.js
   - Removed custom ready() hook
   - Removed document.addEventListener('DOMContentLoaded')
   - Removed manual deferReadiness/boot calls
   - Now uses standard Ember boot sequence
   - Clean, minimal implementation

Benefits:
- Follows Ember conventions and best practices
- Proper initialization order guaranteed
- Performance monitoring for boot phases
- Easier to debug and maintain
- No custom boot logic needed

Boot sequence:
1. load-runtime-config initializer (runs first)
2. Other initializers (socketcluster, etc.)
3. apply-router-fix instance-initializer
4. load-extensions instance-initializer
5. Other instance-initializers
6. Application ready
This commit is contained in:
roncodes
2025-11-27 23:12:14 -05:00
parent ca3050905d
commit 5726eb974f
3 changed files with 81 additions and 21 deletions

View File

@@ -2,10 +2,6 @@ import Application from '@ember/application';
import Resolver from 'ember-resolver';
import loadInitializers from 'ember-load-initializers';
import config from '@fleetbase/console/config/environment';
import loadExtensions from '@fleetbase/ember-core/utils/load-extensions';
import mapEngines from '@fleetbase/ember-core/utils/map-engines';
import loadRuntimeConfig from '@fleetbase/console/utils/runtime-config';
import applyRouterFix from './utils/router-refresh-patch';
export default class App extends Application {
modulePrefix = config.modulePrefix;
@@ -13,22 +9,7 @@ export default class App extends Application {
Resolver = Resolver;
extensions = [];
engines = {};
async ready() {
console.log('[app.ready] Has been called!');
applyRouterFix(this);
// Extensions are now loaded in the initialize-universe initializer
// This hook can be used for other ready-time setup if needed
console.log('[app.ready] Application ready with extensions:', this.extensions);
}
}
document.addEventListener('DOMContentLoaded', async () => {
await loadRuntimeConfig();
loadInitializers(App, config.modulePrefix);
const Fleetbase = App.create();
Fleetbase.deferReadiness();
Fleetbase.boot();
});
// Load all initializers (including our new load-runtime-config initializer)
loadInitializers(App, config.modulePrefix);

View File

@@ -0,0 +1,40 @@
import loadRuntimeConfig from '@fleetbase/console/utils/runtime-config';
import { debug } from '@ember/debug';
/**
* Load Runtime Config Initializer
*
* Loads runtime configuration from fleetbase.config.json before the application boots.
* This must run first to ensure all config is available for other initializers.
*
* Uses `before` to ensure it runs before any other initializers.
*
* @export
* @param {Application} application
*/
export function initialize(application) {
const startTime = performance.now();
debug('[Initializer:load-runtime-config] Loading runtime configuration...');
// Defer readiness until config is loaded
application.deferReadiness();
loadRuntimeConfig()
.then(() => {
const endTime = performance.now();
debug(`[Initializer:load-runtime-config] Runtime config loaded in ${(endTime - startTime).toFixed(2)}ms`);
application.advanceReadiness();
})
.catch((error) => {
console.error('[Initializer:load-runtime-config] Failed to load runtime config:', error);
// Still advance readiness to prevent hanging
application.advanceReadiness();
});
}
export default {
name: 'load-runtime-config',
initialize,
// Run before everything else
before: 'load-socketcluster-client'
};

View File

@@ -0,0 +1,39 @@
import applyRouterFix from '@fleetbase/console/utils/router-refresh-patch';
import { debug } from '@ember/debug';
/**
* Apply Router Fix Instance Initializer
*
* Applies the Fleetbase router refresh bug fix patch.
* This patches the Ember router to handle dynamic segments correctly
* when refreshing routes with query parameters.
*
* Runs as an instance-initializer because it needs access to the
* application instance and router service.
*
* Bug: https://github.com/emberjs/ember.js/issues/19260
*
* @export
* @param {ApplicationInstance} appInstance
*/
export function initialize(appInstance) {
const startTime = performance.now();
debug('[InstanceInitializer:apply-router-fix] Applying router refresh bug fix...');
try {
const application = appInstance.application;
applyRouterFix(application);
const endTime = performance.now();
debug(`[InstanceInitializer:apply-router-fix] Router fix applied in ${(endTime - startTime).toFixed(2)}ms`);
} catch (error) {
console.error('[InstanceInitializer:apply-router-fix] Failed to apply router fix:', error);
}
}
export default {
name: 'apply-router-fix',
initialize,
// Run before extension loading to ensure router is patched early
before: 'load-extensions'
};