import { type ComponentType } from 'react'; /** Regiones del DocumentEditor/DocumentPage donde se puede contribuir. */ export type DocumentRegion = 'header.fields' | 'party.card' | 'lines.columns' | 'side.panels' | 'body.sections' | 'footer.actions'; export interface DocumentEditorContext { kind: string; model: string; values: Record; mode: 'create' | 'edit' | 'view'; } export interface DocumentContribution

{ /** Id estable `addon.region.name` (dedupe y orden). Re-registrar el mismo id reemplaza. */ id: string; kinds: string[] | '*'; region: DocumentRegion; /** Addon dueño. Si no está instalado, no se renderiza (y el server revalida). */ requiresAddon?: string; /** Mayor = primero. Default 0. */ priority?: number; when?: (ctx: DocumentEditorContext) => boolean; /** Componente o loader perezoso del remote (`() => import('fiscal_mexico/CfdiSection')`). */ component?: ComponentType

; load?: () => Promise<{ default: ComponentType

; }>; } /** * Contribución resuelta: `component` siempre presente (si se registró con * `load`, es un envoltorio lazy + Suspense que no pinta nada mientras carga). */ export type ResolvedDocumentContribution

= DocumentContribution

& { component: ComponentType

; }; export interface DocumentContributionProps { ctx: DocumentEditorContext; setValue: (key: string, value: unknown) => void; issues: { report: (key: string, issue: { severity: 'error' | 'warning'; message: string; }) => void; }; } /** Predicado «¿está instalado?»; `useInstalledAddons` lo arma en React. */ export type IsAddonInstalled = (addonKey: string) => boolean; /** Suscripción para useSyncExternalStore (contribuciones y modales). */ export declare function subscribeContributions(listener: () => void): () => void; /** Versión monotónica: cambia en cada register/dispose. */ export declare function contributionsVersion(): number; export declare function slotIdFor(kind: string, region: DocumentRegion): string; /** * Registra la contribución y la publica en slotRegistry bajo cada `doc::` * (kinds '*' → `doc:*:`). Devuelve el disposer: AddonLoader lo llama al * desmontar o recargar el remote (fiber), así la sección desaparece al desinstalar. * Re-registrar el mismo `id` (recarga en caliente) reemplaza la anterior. */ export declare function registerDocumentContribution

(c: DocumentContribution

, source?: string): () => void; /** * Contribuciones aplicables a `region` para el documento `ctx`, ordenadas por * prioridad (desc) y luego id. Pura: no lee React; `useDocumentContributions` * la envuelve con useInstalledAddons. */ export declare function resolveContributions(ctx: DocumentEditorContext, region: DocumentRegion, isInstalled: IsAddonInstalled): ResolvedDocumentContribution[]; export interface FederatedModal

{ /** Clave `.`, la misma que `modal` en el manifest. */ key: string; addon: string; /** El dispatcher le pasa ActionModalProps (open, onOpenChange, action, model, record…). */ load: () => Promise<{ default: ComponentType

; }>; /** Presente cuando el modal se registró ya cargado (`api.registry.registerModal`). */ component?: ComponentType

; } /** * @deprecated Usa `registerModalComponent({ slug, load, owner })` de * `@asteby/metacore-sdk` o `api.registry.registerModal` desde el plugin. Se * mantiene como alias compatible: escribe en el mismo store. */ export declare function registerFederatedModal(m: FederatedModal): () => void; /** * Modal del slug en el store canónico, o null si no está registrado o su addon * dueño no está instalado. Nunca espera. */ export declare function resolveFederatedModal(key: string, isInstalled: IsAddonInstalled): FederatedModal | null; /** * Componente del modal resuelto: el ya cargado si lo hay; si no, un * `React.lazy` memoizado por registro (no se re-crea en cada render; quien lo * pinta lo envuelve en ``). */ export declare function federatedModalComponent

(m: FederatedModal

): ComponentType

; /** Solo para tests. */ export declare function __resetContributions(): void; //# sourceMappingURL=contributions.d.ts.map