| 1 | import { EventEmitter } from "events"; |
| 2 | |
| 3 | export interface CanopyEvent { |
| 4 | type: |
| 5 | | "run:created" |
| 6 | | "run:started" |
| 7 | | "run:completed" |
| 8 | | "run:cancelled" |
| 9 | | "step:started" |
| 10 | | "step:completed" |
| 11 | | "step:skipped" |
| 12 | | "log:append"; |
| 13 | runId: number; |
| 14 | repoId: number; |
| 15 | stepId?: number; |
| 16 | stepIndex?: number; |
| 17 | status?: string; |
| 18 | run?: Record<string, unknown>; |
| 19 | step?: Record<string, unknown>; |
| 20 | log?: { stream: string; content: string; created_at: string }; |
| 21 | ts: string; |
| 22 | } |
| 23 | |
| 24 | export class CanopyEventBus extends EventEmitter { |
| 25 | publish(data: CanopyEvent): void { |
| 26 | this.emit("canopy", data); |
| 27 | } |
| 28 | |
| 29 | subscribe(listener: (data: CanopyEvent) => void): () => void { |
| 30 | this.on("canopy", listener); |
| 31 | return () => this.off("canopy", listener); |
| 32 | } |
| 33 | } |
| 34 | |