@dudousxd/nestjs-telescope-ui 1.12.0 → 1.12.1
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.
- package/CHANGELOG.md +6 -0
- package/package.json +8 -5
- package/skills/telescope-ui-dashboard/SKILL.md +183 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @dudousxd/nestjs-telescope-ui
|
|
2
2
|
|
|
3
|
+
## 1.12.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#29](https://github.com/DavideCarvalho/nestjs-telescope/pull/29) [`a79c3fa`](https://github.com/DavideCarvalho/nestjs-telescope/commit/a79c3fa6f77c8d02a4150325f082d66d9fdc9227) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Ship TanStack Intent agent skills (SKILL.md) inside the package.
|
|
8
|
+
|
|
3
9
|
## 1.12.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dudousxd/nestjs-telescope-ui",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.1",
|
|
4
4
|
"description": "Bundled dashboard + composable React components for @dudousxd/nestjs-telescope.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -36,12 +36,13 @@
|
|
|
36
36
|
"files": [
|
|
37
37
|
"dist/",
|
|
38
38
|
"README.md",
|
|
39
|
-
"CHANGELOG.md"
|
|
39
|
+
"CHANGELOG.md",
|
|
40
|
+
"skills"
|
|
40
41
|
],
|
|
41
42
|
"peerDependencies": {
|
|
42
43
|
"@nestjs/common": ">=11.0.0",
|
|
43
44
|
"@nestjs/core": ">=11.0.0",
|
|
44
|
-
"@dudousxd/nestjs-telescope": "^1.
|
|
45
|
+
"@dudousxd/nestjs-telescope": "^1.13.1"
|
|
45
46
|
},
|
|
46
47
|
"peerDependenciesMeta": {
|
|
47
48
|
"react": {
|
|
@@ -56,6 +57,7 @@
|
|
|
56
57
|
},
|
|
57
58
|
"devDependencies": {
|
|
58
59
|
"@nestjs/common": "^11.0.0",
|
|
60
|
+
"@tanstack/intent": "^0.3.2",
|
|
59
61
|
"@nestjs/core": "^11.0.0",
|
|
60
62
|
"@nestjs/platform-express": "^11.0.0",
|
|
61
63
|
"@nestjs/testing": "^11.0.0",
|
|
@@ -79,7 +81,7 @@
|
|
|
79
81
|
"typescript": "^5.4.0",
|
|
80
82
|
"vite": "^5.4.0",
|
|
81
83
|
"vitest": "^3.0.0",
|
|
82
|
-
"@dudousxd/nestjs-telescope": "1.
|
|
84
|
+
"@dudousxd/nestjs-telescope": "1.13.1"
|
|
83
85
|
},
|
|
84
86
|
"engines": {
|
|
85
87
|
"node": ">=20"
|
|
@@ -90,7 +92,8 @@
|
|
|
90
92
|
"dashboard",
|
|
91
93
|
"ui",
|
|
92
94
|
"observability",
|
|
93
|
-
"react"
|
|
95
|
+
"react",
|
|
96
|
+
"tanstack-intent"
|
|
94
97
|
],
|
|
95
98
|
"scripts": {
|
|
96
99
|
"build": "vite build && tsc -p tsconfig.lib.json && tsc -p tsconfig.server.json",
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: telescope-ui-dashboard
|
|
3
|
+
description: >-
|
|
4
|
+
Serve and embed the nestjs-telescope dashboard with @dudousxd/nestjs-telescope-ui.
|
|
5
|
+
Mount the bundled React SPA via TelescopeUiModule.forRoot({ path?, assetsDir? }) /
|
|
6
|
+
forRootAsync (the path must match TelescopeModule and is static in the async form);
|
|
7
|
+
call the headless API from any frontend with createTelescopeClient({ baseUrl?,
|
|
8
|
+
fetch? }) from the /client subpath; build a custom console with the React
|
|
9
|
+
components, hooks (TelescopeProvider, useTelescopeClient, useEntries, usePulse,
|
|
10
|
+
useTimeseries) from the /react subpath. Use for "show the Telescope dashboard",
|
|
11
|
+
"custom path", "call the Telescope API from React", "embed Telescope components".
|
|
12
|
+
license: MIT
|
|
13
|
+
metadata:
|
|
14
|
+
type: core
|
|
15
|
+
library: "@dudousxd/nestjs-telescope-ui"
|
|
16
|
+
library_version: "1.12.0"
|
|
17
|
+
framework: nestjs
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Dashboard UI & client
|
|
21
|
+
|
|
22
|
+
`@dudousxd/nestjs-telescope-ui` serves a bundled React SPA from a NestJS module —
|
|
23
|
+
no frontend dependency is imposed on your app. It also ships a framework-agnostic
|
|
24
|
+
`createTelescopeClient` (`/client`) and composable React components/hooks
|
|
25
|
+
(`/react`) for building your own console.
|
|
26
|
+
|
|
27
|
+
## Setup
|
|
28
|
+
|
|
29
|
+
Import the UI module alongside the core module. The `path` must match
|
|
30
|
+
`TelescopeModule` (default `telescope`):
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { Module } from '@nestjs/common';
|
|
34
|
+
import { TelescopeModule } from '@dudousxd/nestjs-telescope';
|
|
35
|
+
import { TelescopeUiModule } from '@dudousxd/nestjs-telescope-ui';
|
|
36
|
+
|
|
37
|
+
@Module({
|
|
38
|
+
imports: [
|
|
39
|
+
TelescopeModule.forRoot({ enabled: true, authorizer: () => true }),
|
|
40
|
+
TelescopeUiModule.forRoot(), // dashboard at /telescope
|
|
41
|
+
],
|
|
42
|
+
})
|
|
43
|
+
export class AppModule {}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Source: `packages/ui/src/server/telescope-ui.module.ts`,
|
|
47
|
+
`packages/ui/src/server/telescope-ui.options.ts` (`TelescopeUiModuleOptions`).
|
|
48
|
+
|
|
49
|
+
## Core patterns
|
|
50
|
+
|
|
51
|
+
### Pattern 1 — a custom mount path
|
|
52
|
+
|
|
53
|
+
Set the same `path` on BOTH modules. In `forRootAsync` the `path` is a static
|
|
54
|
+
sibling of `useFactory`, not returned from it.
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
TelescopeModule.forRoot({ path: 'observability', enabled: true, authorizer: () => true });
|
|
58
|
+
TelescopeUiModule.forRoot({ path: 'observability' }); // dashboard now at /observability
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
// async form: path stays static
|
|
63
|
+
TelescopeUiModule.forRootAsync({
|
|
64
|
+
path: 'observability',
|
|
65
|
+
useFactory: () => ({}),
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Source: `packages/ui/src/server/telescope-ui.module.ts`,
|
|
70
|
+
`packages/ui/src/server/telescope-ui.options.ts`.
|
|
71
|
+
|
|
72
|
+
### Pattern 2 — call the headless API with the client
|
|
73
|
+
|
|
74
|
+
`createTelescopeClient` (from the `/client` subpath) is a typed wrapper over the
|
|
75
|
+
JSON API, usable in any frontend. `baseUrl` defaults to
|
|
76
|
+
`window.__TELESCOPE_BASE__ + '/api'`, else `/telescope/api`.
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { createTelescopeClient } from '@dudousxd/nestjs-telescope-ui/client';
|
|
80
|
+
|
|
81
|
+
const client = createTelescopeClient({ baseUrl: '/observability/api' });
|
|
82
|
+
const page = await client.entries({ type: 'exception' });
|
|
83
|
+
const detail = await client.entry(page.data[0].id); // entry + its correlated batch
|
|
84
|
+
const pulse = await client.pulse('1h');
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Source: `packages/ui/src/client/telescope-client.ts` (`createTelescopeClient`,
|
|
88
|
+
`TelescopeClient`, `TelescopeClientOptions`).
|
|
89
|
+
|
|
90
|
+
### Pattern 3 — build a custom console with React hooks
|
|
91
|
+
|
|
92
|
+
Wrap your tree in `TelescopeProvider`, then read with the query hooks from the
|
|
93
|
+
`/react` subpath.
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import {
|
|
97
|
+
TelescopeProvider,
|
|
98
|
+
useEntries,
|
|
99
|
+
usePulse,
|
|
100
|
+
} from '@dudousxd/nestjs-telescope-ui/react';
|
|
101
|
+
import { createTelescopeClient } from '@dudousxd/nestjs-telescope-ui/client';
|
|
102
|
+
|
|
103
|
+
function ExceptionList() {
|
|
104
|
+
const { data } = useEntries({ type: 'exception' });
|
|
105
|
+
return <ul>{data?.data.map((e) => <li key={e.id}>{e.id}</li>)}</ul>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function App() {
|
|
109
|
+
return (
|
|
110
|
+
<TelescopeProvider client={createTelescopeClient({ baseUrl: '/telescope/api' })}>
|
|
111
|
+
<ExceptionList />
|
|
112
|
+
</TelescopeProvider>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Source: `packages/ui/src/react/telescope-context.tsx` (`TelescopeProvider`,
|
|
118
|
+
`useTelescopeClient`), `packages/ui/src/react/use-telescope-queries.ts`
|
|
119
|
+
(`useEntries`, `usePulse`, `useTimeseries`).
|
|
120
|
+
|
|
121
|
+
## Common mistakes
|
|
122
|
+
|
|
123
|
+
### Mistake 1 — mismatched paths between the two modules
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
// Wrong — the SPA loads but its API calls 404: core API is at /observability/api,
|
|
127
|
+
// the dashboard probes /telescope/api.
|
|
128
|
+
TelescopeModule.forRoot({ path: 'observability', enabled: true, authorizer: () => true });
|
|
129
|
+
TelescopeUiModule.forRoot(); // defaults to 'telescope'
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
// Correct — both modules share the same path.
|
|
134
|
+
TelescopeModule.forRoot({ path: 'observability', enabled: true, authorizer: () => true });
|
|
135
|
+
TelescopeUiModule.forRoot({ path: 'observability' });
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Mechanism: the UI controller injects the mount base so the SPA derives its API base
|
|
139
|
+
from it; if the core API lives elsewhere every request misses. Source:
|
|
140
|
+
`packages/ui/src/server/telescope-ui.options.ts`,
|
|
141
|
+
`packages/ui/src/client/telescope-client.ts` (`defaultBaseUrl`).
|
|
142
|
+
|
|
143
|
+
### Mistake 2 — importing components from the package root
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
// Wrong — the root export is the NestJS server module, not React; this fails.
|
|
147
|
+
import { TelescopeProvider } from '@dudousxd/nestjs-telescope-ui';
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
// Correct — React surface lives under /react, the client under /client.
|
|
152
|
+
import { TelescopeProvider } from '@dudousxd/nestjs-telescope-ui/react';
|
|
153
|
+
import { createTelescopeClient } from '@dudousxd/nestjs-telescope-ui/client';
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Mechanism: the package has three entry points — `.` (server module), `./react`,
|
|
157
|
+
and `./client` — so frontend code must import from the subpaths. Source:
|
|
158
|
+
`packages/ui/package.json` (`exports`), `packages/ui/src/react/index.ts`.
|
|
159
|
+
|
|
160
|
+
### Mistake 3 — using a query hook outside `TelescopeProvider`
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
// Wrong — useEntries calls useTelescopeClient, which throws with no provider.
|
|
164
|
+
function App() {
|
|
165
|
+
const { data } = useEntries(); // Error: must be used within a TelescopeProvider
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
// Correct — wrap the tree in TelescopeProvider first.
|
|
172
|
+
function Root() {
|
|
173
|
+
return (
|
|
174
|
+
<TelescopeProvider>
|
|
175
|
+
<App />
|
|
176
|
+
</TelescopeProvider>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Mechanism: the hooks resolve the client from React context; `useTelescopeClient`
|
|
182
|
+
throws "must be used within a TelescopeProvider" when the context is missing.
|
|
183
|
+
Source: `packages/ui/src/react/telescope-context.tsx` (`useTelescopeClient`).
|