feat: enable immediate loading of service overrides during registration (#232)

This commit is contained in:
samanhappy
2025-07-20 20:35:00 +08:00
committed by GitHub
parent 20fd355b87
commit b0b0c93337

View File

@@ -2,12 +2,24 @@ type Class<T> = new (...args: any[]) => T;
interface Service<T> { interface Service<T> {
defaultImpl: Class<T>; defaultImpl: Class<T>;
override?: Class<T>;
} }
const registry = new Map<string, Service<any>>(); const registry = new Map<string, Service<any>>();
const instances = new Map<string, unknown>(); const instances = new Map<string, unknown>();
export function registerService<T>(key: string, entry: Service<T>) { export function registerService<T>(key: string, entry: Service<T>) {
// Try to load override immediately during registration
const overridePath = './' + key + 'x.js';
import(overridePath)
.then((mod) => {
const override = mod[key.charAt(0).toUpperCase() + key.slice(1) + 'x'];
if (typeof override === 'function') {
entry.override = override;
}
})
.catch(() => {}); // Silently ignore if override doesn't exist
registry.set(key, entry); registry.set(key, entry);
} }
@@ -19,17 +31,8 @@ export function getService<T>(key: string): T {
const entry = registry.get(key); const entry = registry.get(key);
if (!entry) throw new Error(`Service not registered for key: ${key.toString()}`); if (!entry) throw new Error(`Service not registered for key: ${key.toString()}`);
let Impl = entry.defaultImpl; // Use override if available, otherwise use default
const Impl = entry.override || entry.defaultImpl;
const overridePath = './' + key + 'x.js';
import(overridePath)
.then((mod) => {
const override = mod[key.charAt(0).toUpperCase() + key.slice(1) + 'x'] ?? Impl.name;
if (typeof override === 'function') {
Impl = override;
}
})
.catch(() => {});
const instance = new Impl(); const instance = new Impl();
instances.set(key, instance); instances.set(key, instance);