70 lines
1.7 KiB
TypeScript
70 lines
1.7 KiB
TypeScript
const services: Record<string, unknown> = {};
|
|
|
|
/**
|
|
* Registra un objeto de servicio (API) bajo un nombre.
|
|
*/
|
|
export function registerService(name: string, api: unknown) {
|
|
console.debug(`Registering service: ${name}`);
|
|
if (services[name]) {
|
|
throw new Error(`❌ Servicio "${name}" ya fue registrado.`);
|
|
}
|
|
services[name] = api;
|
|
}
|
|
|
|
/**
|
|
* Recupera un servicio registrado bajo un "scope".
|
|
*
|
|
* getService("customers:repository")
|
|
* Debe declarar: dependencies: ["customers"]
|
|
*
|
|
* El "scope" puede ser "self" para recuperar
|
|
* los servicios propios registrados.
|
|
*
|
|
* getService("self:repository")
|
|
*/
|
|
export function getServiceScoped<T = unknown>(
|
|
requesterModule: string,
|
|
allowedDeps: readonly string[],
|
|
name: string
|
|
): T {
|
|
const [serviceModule, ...key] = name.split(":");
|
|
|
|
if (serviceModule === "self") {
|
|
return getService<T>(`${requesterModule}:${key.join(":")}`);
|
|
}
|
|
|
|
if (!allowedDeps.includes(serviceModule)) {
|
|
throw new Error(
|
|
`❌ Module "${requesterModule}" tried to access service "${name}" ` +
|
|
`without declaring dependency on "${serviceModule}"`
|
|
);
|
|
}
|
|
|
|
return getService<T>(name);
|
|
}
|
|
|
|
/**
|
|
* Recupera un servicio registrado, con tipado opcional.
|
|
*/
|
|
function getService<T = unknown>(name: string): T {
|
|
const service = services[name];
|
|
if (!service) {
|
|
throw new Error(`❌ Servicio "${name}" no encontrado.`);
|
|
}
|
|
return service as T;
|
|
}
|
|
|
|
/**
|
|
* Permite saber si un servicio fue registrado.
|
|
*/
|
|
export function hasService(name: string): boolean {
|
|
return !!services[name];
|
|
}
|
|
|
|
/**
|
|
* Devuelve todos los servicios (para depuración o tests).
|
|
*/
|
|
export function listServices(): string[] {
|
|
return Object.keys(services);
|
|
}
|