Files
flights_web/src/mf/remote-loader.ts
T

59 lines
1.6 KiB
TypeScript

import {
init,
loadRemote,
registerRemotes,
} from "@module-federation/enhanced/runtime";
export interface RemoteModuleRef<T = unknown> {
name: string;
module: string;
/** Phantom marker to preserve the generic parameter through the type system. */
readonly __type?: T;
}
export interface RemoteEntry {
name: string;
entry: string;
}
let initialized = false;
const HOST_NAME = "aeroflot_flights_host" as const;
/**
* Registers a remote with the MF runtime. On the first call, this also calls
* `init()` to bootstrap the MF runtime with the host identity. Subsequent
* calls use `registerRemotes()` to add remotes without re-initializing.
*/
export function registerRemote(entry: RemoteEntry): void {
if (!initialized) {
init({
name: HOST_NAME,
remotes: [entry],
});
initialized = true;
return;
}
registerRemotes([entry]);
}
/**
* Loads an exposed module from a previously registered remote. The `name` +
* `module` fields are concatenated into MF's `remote/module` lookup key.
*
* Throws if the runtime returns a null/undefined module, which usually means
* the remote manifest does not actually expose the requested path.
*/
export async function loadRemoteModule<T>(ref: RemoteModuleRef<T>): Promise<T> {
const key = `${ref.name}/${ref.module.replace(/^\.\//, "")}`;
const result = await loadRemote<T>(key);
if (result === null || result === undefined) {
throw new Error(`Remote module ${key} loaded as null/undefined`);
}
return result;
}
/** Test-only: resets the one-shot init flag. */
export function __resetRemoteLoaderForTests(): void {
initialized = false;
}