/** * @jorvel/types — Typed federation contracts. * * A "federation contract" is a compile-time description of what a remote * micro-frontend exposes and what event types it publishes/consumes. * * @example * ```ts * // In the remote workspace (e.g. libs/contracts/dashboard.contract.ts) * import { defineFederationContract } from '@jorvel/types'; * * export const dashboardContract = defineFederationContract({ * name: 'dashboard', * exposes: { * './App': null as unknown as import('./src/App').default, * }, * events: { * emits: ['dashboard:action'] as const, * listens: ['shell:ready'] as const, * }, * }); * * export type DashboardContract = typeof dashboardContract; * ``` * * The host then imports `DashboardContract` and can use * `InferExposed` to get the component type * without a runtime import. */ import type { RemoteTarget } from './federation-config.js'; /** * Map of exposed module keys (`"./App"`) to their runtime value type. * * Use `null as unknown as T` for the value when T is a type-only reference * (no runtime value needed at contract definition time). */ export type ExposesMap = Record; /** * Event contract — which events a remote emits and which it listens to. */ export type EventContract = { /** Event keys this remote publishes via `bus.emit(...)`. */ emits: readonly string[]; /** Event keys this remote subscribes to via `bus.on(...)`. */ listens: readonly string[]; }; /** * Full typed federation contract for one remote. * * Use `defineFederationContract()` to create a contract — the helper uses * `` so TypeScript preserves the exact literal * types of `events.emits` and `events.listens`, enabling `InferEmits` and * `InferListens` to produce precise string literal unions. */ export type FederationContract = { /** Module Federation container name. */ name: string; /** * Type-map of exposed modules. * Values carry the TypeScript type of the module's default export * (or named exports via an object type). */ exposes: ExposesMap; /** Optional event contract (emit / listen). */ events?: EventContract; /** Runtime connection info (optional — may be omitted for type-only use). */ remote?: RemoteTarget; }; /** * Identity helper that captures the full concrete type `T` of the contract * literal you pass in, preserving the exact literal tuple types of * `events.emits` and `events.listens`. * * Always use `as const` on the `emits` / `listens` arrays when you want * precise literal-type inference. * * @example * ```ts * export const dashboardContract = defineFederationContract({ * name: 'dashboard', * exposes: { './App': null as unknown as React.ComponentType }, * events: { * emits: ['dashboard:action'] as const, * listens: ['shell:ready'] as const, * }, * }); * * type Emitted = InferEmits; * // => 'dashboard:action' * ``` */ export declare function defineFederationContract(contract: T): T; /** * Extract the type of a specific exposed module from a contract. * * @example * ```ts * type AppComponent = InferExposed; * ``` */ export type InferExposed = C['exposes'][K]; /** * Extract the union of event keys emitted by a contract. * * @example * ```ts * type Emitted = InferEmits; * // => 'dashboard:action' * ``` */ export type InferEmits = C['events'] extends EventContract ? C['events']['emits'][number] : never; /** * Extract the union of event keys listened to by a contract. * * @example * ```ts * type Listened = InferListens; * // => 'shell:ready' * ``` */ export type InferListens = C['events'] extends EventContract ? C['events']['listens'][number] : never; export type ContractViolation = { field: string; expected: string; received: string; }; /** * Structural-only validation. Checks the contract object itself: keys must * start with `./`, the container must look like a real MF container. * * Use this in tests or build-time consistency checks where the remote * container is not actually loaded. */ export declare function validateFederationContractKeys(contract: FederationContract, container: { get: (key: string) => Promise<() => unknown>; } | undefined | null): ContractViolation[]; /** * Runtime validation: actually call `container.get(key)` for each declared * exposed module to verify the remote really exposes them. Returns an array * of violations (empty = valid). * * @example * ```ts * const violations = await validateFederationContract(dashboardContract, remoteContainer); * if (violations.length > 0) { * console.error('Contract violated:', violations); * } * ``` */ export declare function validateFederationContract(contract: FederationContract, container: { get: (key: string) => Promise<() => unknown>; } | undefined | null): Promise; //# sourceMappingURL=federation-contract.d.ts.map