import type { GridApi } from '../core/grid-api'; import type { GridContext } from '../core/grid-context'; import type { GridPlugin, PluginLayerOptions, RenderWindow, ScrollMetrics } from './plugin.types'; /** What a host needs from the renderer, kept narrow so the coupling is visible. */ export interface PluginRendererSeam { mountPluginLayer(name: string, options?: PluginLayerOptions): HTMLElement; readScrollMetrics(): ScrollMetrics; scheduleRender(): void; setPluginContentWidth(px: number): void; addScrollListener(cb: () => void): () => void; } /** * Owns the lifecycle of a grid's registered plugins. * * Constructed only when `GridOptions.plugins` is non-empty, so a grid without * plugins never allocates one. Its whole job is ordering and blast-radius * containment: plugins run late enough to see a fully built grid, early enough * to be visible to `onReady`, and are torn down before anything they depend on * disappears. * * **Failure policy**, mirroring `EventBus.dispatch` and going one step further: * * - A throw in `init` **quarantines** the plugin. It receives no frames and no * `destroy()` — its constructor ran only partway, so calling teardown on it is * more likely to compound the failure than to clean up. * - A throw in `onRenderWindow` logs **once** and detaches that subscription. At * 60 fps the alternative is an unbounded console flood plus a throw per frame. * - A throw in `destroy` is logged and swallowed, so one plugin cannot prevent * the rest of the grid from tearing down. * * In every case the grid itself keeps working. A plugin is an optional add-on; * it must not be able to take the grid down with it. */ export declare class PluginHost { private readonly ctx; private readonly api; private readonly plugins; private readonly renderer; /** Plugins that initialized cleanly and may receive frames. */ private readonly active; /** Ids that threw during `init` — excluded from frames and teardown. */ private readonly quarantined; /** Ids that have already reported a render-window failure, so we log once. */ private readonly reportedFrameFailures; private readonly windowSubs; private readonly teardowns; private destroyed; constructor(ctx: GridContext, api: GridApi, plugins: readonly GridPlugin[], renderer: PluginRendererSeam); /** * Initializes every registered plugin, in declaration order. * * Duplicate ids are rejected rather than silently tolerated: layers are keyed * by id, so two plugins sharing one would fight over the same element. */ initAll(): void; /** `true` when at least one subscriber exists, so the renderer can skip building a window. */ wantsRenderWindow(): boolean; /** * Delivers one frame's window to every subscriber. * * Iterates a snapshot: a subscriber may unsubscribe during dispatch (its own * or a sibling's), and a failing subscriber is removed mid-walk. */ dispatchRenderWindow(window: RenderWindow): void; /** Tears down every active plugin, in reverse declaration order. */ destroyAll(): void; /** Builds the façade handed to one plugin. */ private createContext; /** Runs `fn`, reporting and containing any throw. Returns whether it succeeded. */ private guard; /** Removes a failing per-frame subscriber, logging only the first failure. */ private detachFrameSub; } //# sourceMappingURL=plugin-host.d.ts.map