import type { ExtensionProcessDefinition, ProcessWatcherAPI, ProcessWatcherDefinition, } from "./extension-api.js"; import { cloneMap, registerUnique } from "./registry-utils.js"; /** @public */ export interface BuiltProcessWatcherDefinition { /** @public */ watchers: ReadonlyMap>; } function validateWatcherDefinition( def: ProcessWatcherDefinition, ): void { if (!def.id.trim()) { throw new Error("Process watcher id is required"); } if (!def.label.trim()) { throw new Error(`Process watcher '${def.id}' must define a non-empty label`); } if (!def.description.trim()) { throw new Error(`Process watcher '${def.id}' must define a non-empty description`); } if (!def.source || def.source.id.trim() === "") { throw new Error(`Process watcher '${def.id}' must define a watcher source`); } } /** @internal */ export function createProcessWatcherBuilder(): ProcessWatcherAPI & { /** @internal */ getDefinition(): BuiltProcessWatcherDefinition; } { const watchers = new Map>(); return { watcher( def: ProcessWatcherDefinition, ) { registerUnique( watchers, def.id, def as unknown as ProcessWatcherDefinition, { duplicateMessage: `Process watcher '${def.id}' is already registered`, validate: validateWatcherDefinition, }, ); }, getDefinition() { return { watchers: cloneMap(watchers), }; }, }; } /** @public */ export function buildProcessWatchers( process: ExtensionProcessDefinition, ): BuiltProcessWatcherDefinition | undefined { if (!process.watchers) { return undefined; } const builder = createProcessWatcherBuilder(); process.watchers(builder); return builder.getDefinition(); }