import { colineAppManifestSchema, colineAppRegistrationPayloadSchema, colineFileTypeSchema, type ColineAppManifest, type ColineFileTypeDefinition, type ColineFileTypeDefinitionInput, type ColineAppRegistrationPayload, } from "./manifest"; type UnknownPayload = Record; export interface HomeRenderContext extends UnknownPayload {} export interface FileRenderContext extends UnknownPayload { fileId?: string; } export interface IndexSyncContext extends UnknownPayload { workspaceId?: string; } export type HomeRenderHandler = (context: HomeRenderContext) => unknown | Promise; export type FileRenderHandler = (context: FileRenderContext) => unknown | Promise; export type IndexSyncHandler = (context: IndexSyncContext) => unknown | Promise; export interface ColineAppDefinition { manifest: ColineAppManifest; fileTypes: ColineFileTypeDefinition[]; handlers: { homeRender?: HomeRenderHandler; fileRender?: FileRenderHandler; indexSync?: IndexSyncHandler; }; } export class ColineApp { readonly manifest: ColineAppManifest; private readonly fileTypes = new Map(); private readonly handlers: ColineAppDefinition["handlers"] = {}; constructor(manifest: ColineAppManifest) { this.manifest = colineAppManifestSchema.parse(manifest); } defineFileType(fileType: ColineFileTypeDefinitionInput): this { const parsed = colineFileTypeSchema.parse(fileType); this.fileTypes.set(parsed.typeKey, parsed); return this; } onHomeRender(handler: HomeRenderHandler): this { this.handlers.homeRender = handler; return this; } onFileRender(handler: FileRenderHandler): this { this.handlers.fileRender = handler; return this; } onIndexSync(handler: IndexSyncHandler): this { this.handlers.indexSync = handler; return this; } getDefinition(): ColineAppDefinition { return { manifest: this.manifest, fileTypes: [...this.fileTypes.values()], handlers: { ...this.handlers }, }; } getRegistrationPayload(version: string): ColineAppRegistrationPayload { return colineAppRegistrationPayloadSchema.parse({ version, manifest: this.manifest, fileTypes: [...this.fileTypes.values()], }); } }