UNPKG

dockview-core

Version:

Zero dependency layout manager supporting tabs, groups, grids and splitviews for vanilla TypeScript

111 lines (110 loc) 5.14 kB
/** * Internal module system for dockview. * * Modules are feature bundles that register services into the dockview * component. `registerModules(...)` is the one public entry point — it lets a * sibling package contribute modules that `DockviewComponent` picks up at * construction. The richer opt-in surface (a per-component `modules` option, * framework wrappers) is still reserved for a future version; the module * authoring API (`defineModule`, the service contracts) remains internal. */ import { IDisposable } from '../lifecycle'; import { IFloatingGroupService } from './floatingGroupService'; import { IPopoutWindowService } from './popoutWindowService'; import { IWatermarkService } from './watermarkService'; import { IEdgeGroupService } from './edgeGroupService'; import { IRootDropTargetService } from './rootDropTargetService'; import { IHeaderActionsService } from './headerActionsService'; import { ILiveRegionService } from './liveRegionService'; import { IAccessibilityService, IAdvancedDnDService, IContextMenuService, IKeyboardDockingService, ITabGroupChipsService } from './moduleContracts'; export interface ServiceCollection { floatingGroupService?: IFloatingGroupService; popoutWindowService?: IPopoutWindowService; watermarkService?: IWatermarkService; edgeGroupService?: IEdgeGroupService; tabGroupChipsService?: ITabGroupChipsService; contextMenuService?: IContextMenuService; rootDropTargetService?: IRootDropTargetService; headerActionsService?: IHeaderActionsService; advancedDnDService?: IAdvancedDnDService; liveRegionService?: ILiveRegionService; accessibilityService?: IAccessibilityService; keyboardDockingService?: IKeyboardDockingService; } export interface DockviewModule<THost = unknown> { moduleName: string; services?: Record<string, (host: THost) => unknown>; /** * Optional post-construct hook called once after the host is fully * constructed and all module services are instantiated. Use this to * subscribe to host events — the returned disposable runs at host * teardown. Components don't need to call into the service from event * handlers; the module owns its own reactivity. */ init?: (host: THost, services: ServiceCollection) => IDisposable; dependsOn?: DockviewModule<any>[]; } /** * Typed helper for defining a module. Enforces that the factory's return * type matches the slot in ServiceCollection at compile time, replacing * the manual cast each module file would otherwise need. */ export declare function defineModule<K extends keyof ServiceCollection, THost>(config: { name: string; serviceKey: K; create: (host: THost) => NonNullable<ServiceCollection[K]>; init?: (host: THost, service: NonNullable<ServiceCollection[K]>) => IDisposable; dependsOn?: DockviewModule<any>[]; }): DockviewModule<THost>; /** * For tests — clears the once-per-key dedup cache used by `assertModule`. */ export declare function _resetMissingModuleWarnings(): void; /** * Returns the service if its module is registered, otherwise logs a * deduplicated console error and returns `undefined`. Modelled on AG Grid's * `assertModuleRegistered`: missing modules never throw — they degrade the * affected feature to a no-op so consuming applications don't crash in * production. * * Use at public-API entry points where the caller wants to surface which * module is missing. For internal/lifecycle paths, plain `?.` chaining on * the service slot is preferred — no log, just a silent no-op. */ export declare function assertModule<T>(service: T | undefined, moduleName: string, context?: string): T | undefined; export declare class ModuleRegistry<THost> implements IDisposable { private readonly _modules; private readonly _services; private readonly _initDisposables; get services(): ServiceCollection; register<H>(module: DockviewModule<H>): void; initialize(host: THost): void; postConstruct(host: THost): void; has(moduleName: string): boolean; dispose(): void; } /** * Register modules globally. Idempotent per `moduleName` — registering the * same module twice is a no-op. Intended to be called once at import time by * the package that bundles a given set of modules. */ export declare function registerModules(modules: DockviewModule<any>[]): void; /** * Returns the globally-registered modules (a copy). `DockviewComponent` reads * this to extend its built-in module set. */ export declare function getRegisteredModules(): DockviewModule<any>[]; /** * For tests — clears the global module registry. */ export declare function clearRegisteredModules(): void; /** * Called once by the `dockview` package on import, solely so `dockview-core` * can warn when it is used directly (see above). Not used for anything else. */ export declare function markDockviewPackageLoaded(): void; /** * Whether the `dockview` package has been loaded in this process. Used only to * gate the "don't use dockview-core directly" developer warning. */ export declare function isDockviewPackageLoaded(): boolean;