import { blockquoteHandler } from "./blockquote.handler.js"; import { codeBlockHandler } from "./code-block.handler.js"; import { footnoteHandler } from "./footnote.handler.js"; import type { BlockHandler } from "./handler.type.js"; import { headingHandler } from "./heading.handler.js"; import { hrHandler } from "./hr.handler.js"; import { createHtmlHandler } from "./html.handler.js"; import { setHandlerRegistry, setHandlerResolver } from "./identify.js"; import { imageHandler } from "./image.handler.js"; import { listHandler } from "./list.handler.js"; import { paragraphHandler } from "./paragraph.handler.js"; import { createRouterSlotHandler } from "./router-slot.handler.js"; import { tableHandler } from "./table.handler.js"; import { taskListHandler } from "./task-list.handler.js"; import { createWidgetHandler } from "./widget.handler.js"; const handlers: Record = { paragraph: paragraphHandler, heading: headingHandler, "code-block": codeBlockHandler, hr: hrHandler, blockquote: blockquoteHandler, list: listHandler, table: tableHandler, "task-list": taskListHandler, image: imageHandler, footnote: footnoteHandler, }; // Wire the shared registry so identifyBlocks() can find handlers with identify(). setHandlerRegistry(handlers); // Wire the resolver so nested-block handlers (blockquote) can resolve without circular imports. setHandlerResolver(resolveHandler); /** * Resolve handler for a block type. * For unregistered `widget:*`, `html:*`, and `router-slot` types, * creates and caches a default handler. */ export function resolveHandler(type: string): BlockHandler | undefined { if (type in handlers) return handlers[type]; if (type.startsWith("widget:")) { const handler = createWidgetHandler(type.slice(7)); handlers[type] = handler; return handler; } if (type.startsWith("html:")) { const handler = createHtmlHandler(type.slice(5)); handlers[type] = handler; return handler; } if (type === "router-slot") { const handler = createRouterSlotHandler(); handlers[type] = handler; return handler; } return undefined; } /** Get a registered handler without lazy creation. */ export function getHandler(type: string): BlockHandler | undefined { return handlers[type]; } /** List all registered handler type names. */ export function listHandlers(): string[] { return Object.keys(handlers); } /** * Register a custom block handler. * Overwrites any existing handler for the same type. * * @example * ```ts * registerHandler("widget:chart", { * render(raw, attrs) { return ``; }, * serialize(raw) { return "```widget:chart\n" + raw + "\n```"; }, * }); * ``` */ export function registerHandler(type: T, handler: BlockHandler): void { handlers[type] = handler; } /** * Remove a previously registered handler. * Returns `true` if the handler existed, `false` otherwise. */ export function unregisterHandler(type: string): boolean { if (type in handlers) { delete handlers[type]; return true; } return false; }