The Coline App SDK: apps, tools, file types and surfaces that run inside Coline workspaces, and public websites with Coline Sites. TypeScript, with an in-memory test workspace. MIT.
| 6 | emitAmbientEventsInputSchema, |
| 7 | type ColineAppManifest, |
| 8 | type ColineAppManifestInput, |
| 9 | type ColineFileTypeDefinition, |
| 10 | type ColineFileTypeDefinitionInput, |
| 11 | type ColineAppRegistrationPayload, |
| 12 | type EmitAmbientEventsInput, |
| 13 | type EmitAmbientEventsInputInput, |
| 14 | type CreateNotificationInput, |
| 15 | type CreateNotificationInputInput, |
| 16 | type NotificationChannelDefinition, |
| 17 | type NotificationChannelDefinitionInput, |
| 18 | notificationChannelDefinitionSchema, |
| 19 | } from "./manifest"; |
| 20 | import type { |
| 21 | FileRenderContext, |
| 22 | FileRenderResult, |
| 23 | HomeRenderContext, |
| 24 | HomeRenderResult, |
| 25 | IndexSyncContext, |
| 26 | } from "./contexts"; |
| 27 |
| 28 | export type HomeRenderHandler = ( |
| 29 | context: HomeRenderContext, |
| 30 | ) => HomeRenderResult | Promise<HomeRenderResult>; |
| 31 | export type FileRenderHandler = ( |
| 32 | context: FileRenderContext, |
| 33 | ) => FileRenderResult | Promise<FileRenderResult>; |
| 34 | export type IndexSyncHandler = (context: IndexSyncContext) => unknown | Promise<unknown>; |
| 35 |
| 36 | export interface ColineAppDefinition { |
| 37 | manifest: ColineAppManifest; |
| 38 | fileTypes: ColineFileTypeDefinition[]; |
| 39 | notificationChannels: NotificationChannelDefinition[]; |
| 40 | handlers: { |
| 41 | homeRender?: HomeRenderHandler; |
| 42 | fileRender?: FileRenderHandler; |
| 43 | indexSync?: IndexSyncHandler; |
| 44 | }; |
| 45 | } |
| 46 |
| 47 | class ColineAmbientHelper { |
| 48 | emit(input: EmitAmbientEventsInputInput): EmitAmbientEventsInput { |
| 49 | return emitAmbientEventsInputSchema.parse(input); |
| 50 | } |
| 51 | } |
| 52 |
| 53 | export class ColineApp { |
| 54 | readonly manifest: ColineAppManifest; |
| 55 | readonly ambient = new ColineAmbientHelper(); |
| 56 | private readonly fileTypes = new Map<string, ColineFileTypeDefinition>(); |
| 57 | private readonly notificationChannels = new Map<string, NotificationChannelDefinition>(); |
| 58 | private readonly handlers: ColineAppDefinition["handlers"] = {}; |
| 59 |
| 60 | constructor(manifest: ColineAppManifestInput) { |
| 61 | this.manifest = colineAppManifestSchema.parse(manifest); |
| 62 | } |
| 63 |
| 64 | defineFileType(fileType: ColineFileTypeDefinitionInput): this { |
| 65 | const parsed = colineFileTypeSchema.parse(fileType); |
| 66 | this.fileTypes.set(parsed.typeKey, parsed); |
| 67 | return this; |
| 68 | } |
| 69 |
| 70 | defineNotificationChannel(channel: NotificationChannelDefinitionInput): this { |
| 71 | const parsed = notificationChannelDefinitionSchema.parse(channel); |
| 72 | this.notificationChannels.set(parsed.key, parsed); |
| 73 | return this; |
| 74 | } |
| 75 |
| 76 | onHomeRender(handler: HomeRenderHandler): this { |
| 77 | this.handlers.homeRender = handler; |
| 78 | return this; |
| 79 | } |
| 80 |
| 81 | onFileRender(handler: FileRenderHandler): this { |
| 82 | this.handlers.fileRender = handler; |
| 83 | return this; |
| 84 | } |
| 85 |
| 86 | onIndexSync(handler: IndexSyncHandler): this { |
| 87 | this.handlers.indexSync = handler; |
| 88 | return this; |
| 89 | } |
| 90 |
| 91 | getDefinition(): ColineAppDefinition { |
| 92 | const notificationChannels = [...this.notificationChannels.values()]; |
| 93 |
| 94 | return { |
| 95 | manifest: { |
| 96 | ...this.manifest, |
| 97 | notificationChannels, |
| 98 | }, |
| 99 | fileTypes: [...this.fileTypes.values()], |
| 100 | notificationChannels, |
| 101 | handlers: { ...this.handlers }, |
| 102 | }; |
| 103 | } |
| 104 |
| 105 | getRegistrationPayload(version: string): ColineAppRegistrationPayload { |
| 106 | const notificationChannels = [...this.notificationChannels.values()]; |
| 107 |
| 108 | return colineAppRegistrationPayloadSchema.parse({ |
| 109 | version, |
| 110 | manifest: { |
| 111 | ...this.manifest, |
| 112 | notificationChannels, |
| 113 | }, |
| 114 | fileTypes: [...this.fileTypes.values()], |
| 115 | }); |
| 116 | } |
| 117 |
| 118 | createNotification(input: CreateNotificationInputInput): CreateNotificationInput { |
| 119 | return createNotificationInputSchema.parse(input); |
| 120 | } |
| 121 |
| 122 | createAmbientEvents(input: EmitAmbientEventsInputInput): EmitAmbientEventsInput { |
| 123 | return this.ambient.emit(input); |
| 124 | } |
| 125 | } |
| 126 |