import { COMPOSER_CONTEXT_KINDS, type KnownComposerContextKind } from "@t3tools/contracts"; export interface ContextPresentationCapability { details: "none" | "tooltip" | "popover"; expanded: "none" | "inline-block" | "modal"; defaultDraftView: "compact" | "expanded"; } export interface ContextPresentationDefinition { kind: KnownComposerContextKind; capabilities: ContextPresentationCapability; } const DEFINITIONS = [ { kind: "image", capabilities: { details: "tooltip", expanded: "modal", defaultDraftView: "compact" }, }, { kind: "file", capabilities: { details: "tooltip", expanded: "modal", defaultDraftView: "compact" }, }, { kind: "terminal", capabilities: { details: "popover", expanded: "none", defaultDraftView: "compact" }, }, { kind: "element", capabilities: { details: "popover", expanded: "none", defaultDraftView: "compact" }, }, { kind: "preview-annotation", capabilities: { details: "popover", expanded: "modal", defaultDraftView: "compact" }, }, { kind: "review-comment", capabilities: { details: "popover", expanded: "none", defaultDraftView: "compact" }, }, { kind: "pull-request", capabilities: { details: "popover", expanded: "none", defaultDraftView: "compact" }, }, { kind: "mention", capabilities: { details: "none", expanded: "none", defaultDraftView: "compact" }, }, { kind: "skill", capabilities: { details: "tooltip", expanded: "none", defaultDraftView: "compact" }, }, { kind: "thread", capabilities: { details: "tooltip", expanded: "none", defaultDraftView: "compact" }, }, { kind: "environment", capabilities: { details: "tooltip", expanded: "none", defaultDraftView: "compact" }, }, ] as const satisfies ReadonlyArray; function buildDefinitionRegistry( definitions: ReadonlyArray, ): ReadonlyMap { const registry = new Map(); for (const definition of definitions) { if (registry.has(definition.kind)) { throw new Error(`Duplicate context presentation definition: ${definition.kind}`); } registry.set(definition.kind, definition); } for (const kind of COMPOSER_CONTEXT_KINDS) { if (!registry.has(kind)) { throw new Error(`Missing context presentation definition: ${kind}`); } } return registry; } const CONTEXT_PRESENTATION_DEFINITIONS = buildDefinitionRegistry(DEFINITIONS); function contextPresentationDefinition( kind: KnownComposerContextKind, ): ContextPresentationDefinition { return CONTEXT_PRESENTATION_DEFINITIONS.get(kind)!; } export interface ContextPresentationHandler { kind: KnownComposerContextKind; canRender?: (record: TRecord, context: TRenderContext) => boolean; render: ( record: TRecord, context: TRenderContext, definition: ContextPresentationDefinition, ) => TResult; } export interface ContextPresentationRegistry { definition(kind: KnownComposerContextKind): ContextPresentationDefinition; render(kind: string, record: TRecord | undefined, context: TRenderContext): TResult; } export function createContextPresentationRegistry(options: { handlers: ReadonlyArray>; requiredKinds?: ReadonlyArray; fallback: (kind: string, record: TRecord | undefined, context: TRenderContext) => TResult; }): ContextPresentationRegistry { const handlers = new Map< KnownComposerContextKind, ContextPresentationHandler >(); for (const handler of options.handlers) { if (handlers.has(handler.kind)) { throw new Error(`Duplicate context presentation handler: ${handler.kind}`); } handlers.set(handler.kind, handler); } for (const kind of options.requiredKinds ?? []) { if (!handlers.has(kind)) { throw new Error(`Missing context presentation handler: ${kind}`); } } return { definition: contextPresentationDefinition, render(kind, record, context) { const handler = handlers.get(kind as KnownComposerContextKind); if (!handler || record === undefined || handler.canRender?.(record, context) === false) { return options.fallback(kind, record, context); } return handler.render(record, context, contextPresentationDefinition(handler.kind)); }, }; }