-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathevents.ts
More file actions
68 lines (61 loc) · 3.05 KB
/
Copy pathevents.ts
File metadata and controls
68 lines (61 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import type { AiErrorKind, ClientTask, GenerationStage, TaskProgress, TaskType } from './responses.js'
/**
* The Server-Sent Event unions the streaming routes actually write today,
* one per stream, discriminated on the literal `type` field.
*
* Each variant is read off the route's `reply.raw.write(...)` call (or, for
* the single-chapter and tasks streams, the subscriber callback it forwards
* verbatim) rather than designed from scratch, so it reflects what really
* goes out on the wire. Prefer importing from here over re-declaring an SSE
* event shape in client/.
*
* Response bodies for non-streaming routes live in shared/responses.ts. This
* file is types only — it compiles away entirely.
*/
/**
* The error event sent verbatim by the create-book, revise-toc, start-book,
* and generate-chapter streams.
*
* `kind` is purely additive and always optional. Every existing client path
* reads `message` and keeps working without it. It carries the failure class
* when the failure came from the AI provider, which is what lets the reader
* route an auth failure to the missing-key dialog instead of showing a
* generic toast that the user cannot act on. A failure with no class, such
* as a parse error the app raised itself, simply omits it.
*/
export type StreamErrorEvent = { type: 'error'; message: string; kind?: AiErrorKind }
/** POST /api/books — table-of-contents generation stream. */
export type CreateBookEvent =
| { type: 'book_created'; bookId: string; title: string; totalChapters: number }
| { type: 'toc'; text: string }
| { type: 'toc_done'; bookId: string; title: string; subtitle?: string; totalChapters: number }
| { type: 'done'; bookId: string; title: string; totalChapters: number }
| StreamErrorEvent
/** POST /api/books/:id/toc/revise — table-of-contents revision stream. */
export type ReviseTocEvent =
| { type: 'toc'; text: string }
| { type: 'toc_revised'; bookId: string; title: string; subtitle?: string; totalChapters: number }
| StreamErrorEvent
/** POST /api/books/:id/start — first-chapter generation stream. */
export type StartBookEvent =
| { type: 'skills_classified' }
| { type: 'chapter'; text: string }
| { type: 'done'; bookId: string }
| StreamErrorEvent
/**
* POST /api/books/:id/generate-next, POST /api/books/:id/chapters/:num/regenerate,
* and GET /api/books/:id/generation-stream (reconnect) — single-chapter
* generation stream. All three forward the same subscriber events verbatim.
*/
export type GenerateChapterEvent =
| { type: 'chapter'; text: string; buffered?: boolean }
| { type: 'stage'; stage: GenerationStage }
| { type: 'done'; chapterNum: number }
| StreamErrorEvent
/** GET /api/tasks/stream — global background-task stream. */
export type TaskEvent =
| { type: 'task_created'; task: ClientTask }
| { type: 'task_progress'; taskId: string; progress: TaskProgress }
| { type: 'task_done'; taskId: string; taskType: TaskType; result?: unknown }
| { type: 'task_error'; taskId: string; taskType: TaskType; error: string }
| { type: 'task_cancelled'; taskId: string }