@galdor/dashboard 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Embedded observability dashboard for galdor.
3
+ *
4
+ * A self-contained web UI served over either {@link Bun.serve} (under Bun) or
5
+ * `node:http` (under Node), chosen at runtime by {@link startDashboard}. It reads
6
+ * the SQLite span store that the CLI and exporter write to and renders a full
7
+ * trace explorer:
8
+ *
9
+ * - `GET /` run list with a live (SSE) tail
10
+ * - `GET /runs/:id` run detail: timeline, span tree, graph topology
11
+ * - `GET /runs/:id/steps` step-by-step walkthrough of the run
12
+ * - `GET /runs/:id/spans/:spanId` one span: metadata, attributes, captured messages
13
+ * - `GET /api/runs` JSON run summaries
14
+ * - `GET /api/runs/:id/spans` JSON spans for a run
15
+ * - `GET /api/runs/:id/spans/:spanId`JSON for a single span
16
+ * - `GET /api/runs/:id/graph` JSON graph topology recorded for a run
17
+ * - `GET /api/orphans` orphan-span count
18
+ * - `GET /events` Server-Sent Events live-tail of the run list
19
+ *
20
+ * All HTML, CSS, and the one small client script are inlined in this module —
21
+ * the interactive timeline and graph are rendered server-side as SVG, so the UI
22
+ * works without any client-side framework and ships as a single importable unit.
23
+ *
24
+ * @see {@link startDashboard} to launch the server.
25
+ * @see {@link createHandler} to obtain the request handler on its own.
26
+ */
27
+ import { Store } from "@galdor/core/store";
28
+ /**
29
+ * Configuration for {@link startDashboard}.
30
+ *
31
+ * Provide either a {@link DashboardOptions.store | store} to serve from an
32
+ * already-open {@link Store}, or a {@link DashboardOptions.dbPath | dbPath} to
33
+ * open one on demand.
34
+ */
35
+ export interface DashboardOptions {
36
+ /** Path to the span database; `":memory:"` for tests, or a file path for the real store. */
37
+ dbPath?: string;
38
+ /** An already-open {@link Store} to serve from. Takes precedence over {@link DashboardOptions.dbPath | dbPath}. */
39
+ store?: Store;
40
+ /** Listen host. Defaults to `127.0.0.1` (loopback only). */
41
+ hostname?: string;
42
+ /** Listen port. Defaults to `7777`; pass `0` to bind an ephemeral port. */
43
+ port?: number;
44
+ /**
45
+ * Extra `Host`-header hostnames to accept beyond localhost and IP literals
46
+ * (DNS-rebinding guard). Set only when serving behind a trusted proxy under a
47
+ * custom DNS name. See {@link HandlerOptions.allowedHosts}.
48
+ */
49
+ allowedHosts?: string[];
50
+ }
51
+ /** Options for {@link createHandler}. */
52
+ export interface HandlerOptions {
53
+ /**
54
+ * Extra `Host`-header hostnames to accept beyond localhost and IP literals.
55
+ * Set this only when fronting the dashboard with a custom DNS name behind a
56
+ * trusted proxy; by default a domain-name Host is rejected as a
57
+ * DNS-rebinding attempt.
58
+ */
59
+ allowedHosts?: string[];
60
+ }
61
+ /**
62
+ * Build the dashboard request handler bound to a span store.
63
+ *
64
+ * The returned function routes requests to the HTML pages, JSON endpoints, and
65
+ * the SSE live-tail described in the module overview, and answers `404` for any
66
+ * unmatched path. Use it directly when embedding the dashboard in an existing
67
+ * server, or let {@link startDashboard} wire it into {@link Bun.serve} for you.
68
+ *
69
+ * Requests whose `Host` header is a domain name (rather than `localhost` or an
70
+ * IP literal) are rejected with `403` as a DNS-rebinding guard; extend the
71
+ * allowlist via {@link HandlerOptions.allowedHosts}.
72
+ *
73
+ * @param store - The {@link Store} whose runs and spans are served.
74
+ * @param opts - Optional {@link HandlerOptions}.
75
+ * @returns A fetch handler that maps a {@link Request} to a {@link Response}.
76
+ * @example
77
+ * ```ts
78
+ * const handler = createHandler(Store.openExisting("spans.db"));
79
+ * const res = handler(new Request("http://127.0.0.1/api/runs"));
80
+ * ```
81
+ */
82
+ export declare function createHandler(store: Store, opts?: HandlerOptions): (req: Request) => Response | Promise<Response>;
83
+ /**
84
+ * A running dashboard server, exposed uniformly across runtimes.
85
+ *
86
+ * Both the Bun and Node backends return a value matching this shape so callers
87
+ * and tests can stay runtime-agnostic.
88
+ */
89
+ export interface DashboardServer {
90
+ /**
91
+ * The bound listen port. When an ephemeral port (`0`) was requested, the
92
+ * OS-assigned port is only known once the server is listening — await
93
+ * {@link DashboardServer.ready} before reading `.port` in that case. For a
94
+ * fixed port it is valid immediately.
95
+ */
96
+ port: number;
97
+ /** The bound listen host. */
98
+ hostname: string;
99
+ /**
100
+ * Resolves once the server is accepting connections. Await it before reading
101
+ * {@link DashboardServer.port} when an ephemeral port (`0`) was requested.
102
+ */
103
+ ready: Promise<void>;
104
+ /**
105
+ * Shut the server down.
106
+ *
107
+ * @param force - When `true`, also tear down active connections (e.g. open
108
+ * Server-Sent Events streams) so the listener can close promptly.
109
+ */
110
+ stop(force?: boolean): void;
111
+ }
112
+ /**
113
+ * Start the dashboard HTTP server.
114
+ *
115
+ * Serves from {@link DashboardOptions.store} when provided, otherwise opens the
116
+ * store at {@link DashboardOptions.dbPath} (defaulting to an in-memory store).
117
+ *
118
+ * The transport is chosen by runtime: on Bun the server is backed by
119
+ * {@link Bun.serve}; on Node it is backed by `node:http`, with an adapter that
120
+ * converts each incoming request into a Web {@link Request}, runs the same
121
+ * {@link createHandler} handler, and streams the Web {@link Response} back —
122
+ * including unbounded Server-Sent Events bodies. Either way the return value
123
+ * conforms to {@link DashboardServer}.
124
+ *
125
+ * @param opts - Server and store {@link DashboardOptions | options}.
126
+ * @returns The running {@link DashboardServer}; call `.stop()` to shut it down.
127
+ * @example
128
+ * ```ts
129
+ * const server = startDashboard({ dbPath: "spans.db", port: 7777 });
130
+ * // ...later
131
+ * server.stop();
132
+ * ```
133
+ */
134
+ export declare function startDashboard(opts?: DashboardOptions): DashboardServer;
135
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAMH,OAAO,EAAoE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AA4D7G;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4FAA4F;IAC5F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mHAAmH;IACnH,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAmGD,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,GAAE,cAAmB,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkFrH;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACrB;;;;;OAKG;IACH,IAAI,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,cAAc,CAAC,IAAI,GAAE,gBAAqB,GAAG,eAAe,CAuB3E"}