@geekmidas/studio 9.0.2 → 10.0.0-alpha.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/package.json +8 -5
- package/CHANGELOG.md +0 -82
- package/src/Studio.ts +0 -367
- package/src/__tests__/Studio.spec.ts +0 -447
- package/src/data/DataBrowser.ts +0 -170
- package/src/data/__tests__/DataBrowser.integration.spec.ts +0 -418
- package/src/data/__tests__/filtering.integration.spec.ts +0 -741
- package/src/data/__tests__/introspection.integration.spec.ts +0 -352
- package/src/data/__tests__/pagination.spec.ts +0 -123
- package/src/data/filtering.ts +0 -191
- package/src/data/index.ts +0 -1
- package/src/data/introspection.ts +0 -220
- package/src/data/pagination.ts +0 -33
- package/src/index.ts +0 -29
- package/src/server/__tests__/hono.integration.spec.ts +0 -619
- package/src/server/hono.ts +0 -427
- package/src/types.ts +0 -278
- package/src/ui-assets.ts +0 -37
- package/tsconfig.json +0 -9
- package/tsdown.config.ts +0 -13
- package/ui/CHANGELOG.md +0 -26
- package/ui/index.html +0 -12
- package/ui/node_modules/.bin/tsc +0 -21
- package/ui/node_modules/.bin/tsserver +0 -21
- package/ui/node_modules/.bin/vite +0 -21
- package/ui/package.json +0 -30
- package/ui/src/App.tsx +0 -100
- package/ui/src/api.ts +0 -213
- package/ui/src/components/FilterPanel.tsx +0 -213
- package/ui/src/components/NavRail.tsx +0 -183
- package/ui/src/components/RowDetail.tsx +0 -119
- package/ui/src/components/StudioHeader.tsx +0 -109
- package/ui/src/components/TableList.tsx +0 -58
- package/ui/src/components/TableView.tsx +0 -564
- package/ui/src/main.tsx +0 -10
- package/ui/src/pages/DashboardPage.tsx +0 -500
- package/ui/src/pages/DatabasePage.tsx +0 -226
- package/ui/src/pages/EndpointDetailsPage.tsx +0 -288
- package/ui/src/pages/ExceptionsPage.tsx +0 -268
- package/ui/src/pages/LogsPage.tsx +0 -228
- package/ui/src/pages/MonitoringPage.tsx +0 -46
- package/ui/src/pages/PerformancePage.tsx +0 -307
- package/ui/src/pages/RequestsPage.tsx +0 -379
- package/ui/src/providers/StudioProvider.tsx +0 -194
- package/ui/src/styles.css +0 -105
- package/ui/src/types.ts +0 -174
- package/ui/src/vite-env.d.ts +0 -1
- package/ui/tsconfig.json +0 -21
- package/ui/tsconfig.tsbuildinfo +0 -1
- package/ui/vite.config.ts +0 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekmidas/studio",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.0-alpha.1",
|
|
4
4
|
"description": "Unified development tools dashboard with database browser and request monitoring",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -35,6 +35,9 @@
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist"
|
|
40
|
+
],
|
|
38
41
|
"repository": {
|
|
39
42
|
"type": "git",
|
|
40
43
|
"url": "https://github.com/geekmidas/toolbox"
|
|
@@ -49,8 +52,8 @@
|
|
|
49
52
|
"peerDependencies": {
|
|
50
53
|
"hono": "^4.0.0",
|
|
51
54
|
"kysely": ">=0.28.2 <0.30.0",
|
|
52
|
-
"@geekmidas/db": "^
|
|
53
|
-
"@geekmidas/telescope": "^
|
|
55
|
+
"@geekmidas/db": "^10.0.0-alpha.1",
|
|
56
|
+
"@geekmidas/telescope": "^10.0.0-alpha.1"
|
|
54
57
|
},
|
|
55
58
|
"peerDependenciesMeta": {
|
|
56
59
|
"@geekmidas/db": {
|
|
@@ -68,8 +71,8 @@
|
|
|
68
71
|
"hono": "^4.7.0",
|
|
69
72
|
"kysely": "~0.29.4",
|
|
70
73
|
"pg": "~8.16.3",
|
|
71
|
-
"@geekmidas/
|
|
72
|
-
"@geekmidas/
|
|
74
|
+
"@geekmidas/db": "^10.0.0-alpha.1",
|
|
75
|
+
"@geekmidas/telescope": "^10.0.0-alpha.1"
|
|
73
76
|
},
|
|
74
77
|
"scripts": {
|
|
75
78
|
"build:ui": "pnpm --filter @geekmidas/studio-ui build && tsx ../ui/scripts/embed-ui.ts dist/ui src/ui-assets.ts"
|
package/CHANGELOG.md
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# @geekmidas/studio
|
|
2
|
-
|
|
3
|
-
## 9.0.2
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
- [#12](https://github.com/geekmidas/toolbox/pull/12) [`d53863a`](https://github.com/geekmidas/toolbox/commit/d53863a84db2e4ab5420e08f79128b637043fc42) Thanks [@geekmidas](https://github.com/geekmidas)! - Align every published package on a single version and keep them in step.
|
|
8
|
-
|
|
9
|
-
All packages now share one version, enforced by a changesets `fixed` group. The
|
|
10
|
-
baseline is 9.0.1 — @geekmidas/client's published version — so nothing moves
|
|
11
|
-
backwards; this release takes the whole set to 9.0.2 together.
|
|
12
|
-
|
|
13
|
-
Independent versions made "which version of the docs applies to me"
|
|
14
|
-
unanswerable: a reader on constructs@7 and cli@2 was on no version at all. One
|
|
15
|
-
number per release makes versioned documentation possible, and lets 9 freeze as
|
|
16
|
-
the current paradigm while the constructs rework is developed against it.
|
|
17
|
-
|
|
18
|
-
Every release now publishes every package, and a major anywhere is a major
|
|
19
|
-
everywhere. Peer ranges get simpler in return.
|
|
20
|
-
|
|
21
|
-
- Updated dependencies [[`d53863a`](https://github.com/geekmidas/toolbox/commit/d53863a84db2e4ab5420e08f79128b637043fc42)]:
|
|
22
|
-
- @geekmidas/db@9.0.2
|
|
23
|
-
- @geekmidas/telescope@9.0.2
|
|
24
|
-
|
|
25
|
-
## 2.0.1
|
|
26
|
-
|
|
27
|
-
### Patch Changes
|
|
28
|
-
|
|
29
|
-
- 🐛 [#11](https://github.com/geekmidas/toolbox/pull/11) [`40f4dc0`](https://github.com/geekmidas/toolbox/commit/40f4dc095911b2223a255029d8f776caf7781309) Thanks [@geekmidas](https://github.com/geekmidas)! - Patch release across all packages to realign published versions with the
|
|
30
|
-
registry. The previous release only published the four packages that had
|
|
31
|
-
version bumps; the remaining packages failed with "cannot publish over the
|
|
32
|
-
previously published versions" because their versions were unchanged.
|
|
33
|
-
- Updated dependencies [[`40f4dc0`](https://github.com/geekmidas/toolbox/commit/40f4dc095911b2223a255029d8f776caf7781309)]:
|
|
34
|
-
- @geekmidas/db@1.1.1
|
|
35
|
-
- @geekmidas/telescope@1.1.1
|
|
36
|
-
|
|
37
|
-
## 2.0.0
|
|
38
|
-
|
|
39
|
-
### Minor Changes
|
|
40
|
-
|
|
41
|
-
- [#9](https://github.com/geekmidas/toolbox/pull/9) [`e31a60a`](https://github.com/geekmidas/toolbox/commit/e31a60a971366180a0e7bec6e7da56d8f36aa21f) Thanks [@geekmidas](https://github.com/geekmidas)! - Support kysely 0.29.
|
|
42
|
-
|
|
43
|
-
kysely 0.29 moved `Migrator` and `FileMigrationProvider` from the root barrel
|
|
44
|
-
(`'kysely'`) to the `'kysely/migration'` subpath. `@geekmidas/testkit`'s
|
|
45
|
-
`PostgresKyselyMigrator` now imports `Migrator` from `'kysely/migration'` and
|
|
46
|
-
its kysely peer becomes `~0.29.4` — consumers must be on kysely 0.29+.
|
|
47
|
-
|
|
48
|
-
The library packages that only declare a kysely _peer_ (`db`, `audit`, `studio`,
|
|
49
|
-
`telescope`) don't touch the moved symbols, so their peer range is _widened_ to
|
|
50
|
-
`>=0.28.2 <0.30.0` — they now support both 0.28 and 0.29 (non-breaking).
|
|
51
|
-
|
|
52
|
-
`@geekmidas/cli`'s scaffolded `test/globalSetup.ts` template now imports
|
|
53
|
-
`FileMigrationProvider` from `'kysely/migration'` so generated projects work on
|
|
54
|
-
kysely 0.29.
|
|
55
|
-
|
|
56
|
-
### Patch Changes
|
|
57
|
-
|
|
58
|
-
- Updated dependencies [[`e31a60a`](https://github.com/geekmidas/toolbox/commit/e31a60a971366180a0e7bec6e7da56d8f36aa21f)]:
|
|
59
|
-
- @geekmidas/db@1.1.0
|
|
60
|
-
- @geekmidas/telescope@1.1.0
|
|
61
|
-
|
|
62
|
-
## 1.0.1
|
|
63
|
-
|
|
64
|
-
### Patch Changes
|
|
65
|
-
|
|
66
|
-
- 🐛 [`d70c6c0`](https://github.com/geekmidas/toolbox/commit/d70c6c0aeb8a79da2473ac77dbd8255a4a2f5651) Thanks [@geekmidas](https://github.com/geekmidas)! - Fix `package.json` exports so TypeScript declarations resolve correctly under NodeNext/Bundler module resolution. Each subpath export now nests `types` inside its `import`/`require` condition, pointing at the `.d.mts` and `.d.cts` files that `tsdown` actually emits (previously the exports referenced non-existent `.d.ts` files, causing type-resolution failures for consumers). Both ESM (`.mjs`) and CJS (`.cjs`) runtime entry points are preserved. Additionally, `@geekmidas/ui` had `import` paths pointing at `.js` files that were never emitted — those are corrected to `.mjs`.
|
|
67
|
-
|
|
68
|
-
- Updated dependencies [[`d70c6c0`](https://github.com/geekmidas/toolbox/commit/d70c6c0aeb8a79da2473ac77dbd8255a4a2f5651)]:
|
|
69
|
-
- @geekmidas/db@1.0.2
|
|
70
|
-
- @geekmidas/telescope@1.0.1
|
|
71
|
-
|
|
72
|
-
## 1.0.0
|
|
73
|
-
|
|
74
|
-
### Major Changes
|
|
75
|
-
|
|
76
|
-
- [`ff7b115`](https://github.com/geekmidas/toolbox/commit/ff7b11599f60f84ac6cdc73714c853ecf786b2e8) Thanks [@geekmidas](https://github.com/geekmidas)! - Version 1 Stable release
|
|
77
|
-
|
|
78
|
-
### Patch Changes
|
|
79
|
-
|
|
80
|
-
- Updated dependencies [[`ff7b115`](https://github.com/geekmidas/toolbox/commit/ff7b11599f60f84ac6cdc73714c853ecf786b2e8)]:
|
|
81
|
-
- @geekmidas/db@1.0.0
|
|
82
|
-
- @geekmidas/telescope@1.0.0
|
package/src/Studio.ts
DELETED
|
@@ -1,367 +0,0 @@
|
|
|
1
|
-
import { Telescope } from '@geekmidas/telescope';
|
|
2
|
-
import { DataBrowser } from './data/DataBrowser';
|
|
3
|
-
import type {
|
|
4
|
-
NormalizedStudioOptions,
|
|
5
|
-
StudioEvent,
|
|
6
|
-
StudioOptions,
|
|
7
|
-
} from './types';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Unified development tools dashboard combining monitoring and database browsing.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```typescript
|
|
14
|
-
* import { Studio, Direction } from '@geekmidas/studio';
|
|
15
|
-
* import { InMemoryStorage } from '@geekmidas/telescope/storage/memory';
|
|
16
|
-
*
|
|
17
|
-
* const studio = new Studio({
|
|
18
|
-
* monitoring: {
|
|
19
|
-
* storage: new InMemoryStorage(),
|
|
20
|
-
* },
|
|
21
|
-
* data: {
|
|
22
|
-
* db: kyselyInstance,
|
|
23
|
-
* cursor: { field: 'id', direction: Direction.Desc },
|
|
24
|
-
* },
|
|
25
|
-
* });
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
export class Studio<DB = unknown> {
|
|
29
|
-
private telescope: Telescope;
|
|
30
|
-
private dataBrowser: DataBrowser<DB>;
|
|
31
|
-
private options: NormalizedStudioOptions<DB>;
|
|
32
|
-
private wsClients = new Set<WebSocket>();
|
|
33
|
-
|
|
34
|
-
constructor(options: StudioOptions<DB>) {
|
|
35
|
-
this.options = this.normalizeOptions(options);
|
|
36
|
-
|
|
37
|
-
// Initialize Telescope internally
|
|
38
|
-
this.telescope = new Telescope({
|
|
39
|
-
storage: this.options.monitoring.storage,
|
|
40
|
-
enabled: this.options.enabled,
|
|
41
|
-
path: `${this.options.path}/monitoring`,
|
|
42
|
-
recordBody: this.options.monitoring.recordBody,
|
|
43
|
-
maxBodySize: this.options.monitoring.maxBodySize,
|
|
44
|
-
ignorePatterns: [
|
|
45
|
-
...this.options.monitoring.ignorePatterns,
|
|
46
|
-
`${this.options.path}/*`, // Ignore Studio's own routes
|
|
47
|
-
],
|
|
48
|
-
pruneAfterHours: this.options.monitoring.pruneAfterHours,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
// Initialize DataBrowser
|
|
52
|
-
this.dataBrowser = new DataBrowser(this.options.data);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// ============================================
|
|
56
|
-
// Public API - Configuration
|
|
57
|
-
// ============================================
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Get the Studio dashboard path.
|
|
61
|
-
*/
|
|
62
|
-
get path(): string {
|
|
63
|
-
return this.options.path;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Check if Studio is enabled.
|
|
68
|
-
*/
|
|
69
|
-
get enabled(): boolean {
|
|
70
|
-
return this.options.enabled;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Get the data browser instance.
|
|
75
|
-
*/
|
|
76
|
-
get data(): DataBrowser<DB> {
|
|
77
|
-
return this.dataBrowser;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Check if body recording is enabled for monitoring.
|
|
82
|
-
*/
|
|
83
|
-
get recordBody(): boolean {
|
|
84
|
-
return this.options.monitoring.recordBody;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Get max body size for monitoring.
|
|
89
|
-
*/
|
|
90
|
-
get maxBodySize(): number {
|
|
91
|
-
return this.options.monitoring.maxBodySize;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// ============================================
|
|
95
|
-
// Public API - Monitoring (delegated to Telescope)
|
|
96
|
-
// ============================================
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Record a request entry.
|
|
100
|
-
*/
|
|
101
|
-
async recordRequest(
|
|
102
|
-
entry: Parameters<Telescope['recordRequest']>[0],
|
|
103
|
-
): Promise<string> {
|
|
104
|
-
return this.telescope.recordRequest(entry);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Record log entries in batch.
|
|
109
|
-
*/
|
|
110
|
-
async log(entries: Parameters<Telescope['log']>[0]): Promise<void> {
|
|
111
|
-
return this.telescope.log(entries);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Log a debug message.
|
|
116
|
-
*/
|
|
117
|
-
async debug(
|
|
118
|
-
message: string,
|
|
119
|
-
context?: Record<string, unknown>,
|
|
120
|
-
requestId?: string,
|
|
121
|
-
): Promise<void> {
|
|
122
|
-
return this.telescope.debug(message, context, requestId);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Log an info message.
|
|
127
|
-
*/
|
|
128
|
-
async info(
|
|
129
|
-
message: string,
|
|
130
|
-
context?: Record<string, unknown>,
|
|
131
|
-
requestId?: string,
|
|
132
|
-
): Promise<void> {
|
|
133
|
-
return this.telescope.info(message, context, requestId);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Log a warning message.
|
|
138
|
-
*/
|
|
139
|
-
async warn(
|
|
140
|
-
message: string,
|
|
141
|
-
context?: Record<string, unknown>,
|
|
142
|
-
requestId?: string,
|
|
143
|
-
): Promise<void> {
|
|
144
|
-
return this.telescope.warn(message, context, requestId);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Log an error message.
|
|
149
|
-
*/
|
|
150
|
-
async error(
|
|
151
|
-
message: string,
|
|
152
|
-
context?: Record<string, unknown>,
|
|
153
|
-
requestId?: string,
|
|
154
|
-
): Promise<void> {
|
|
155
|
-
return this.telescope.error(message, context, requestId);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Record an exception.
|
|
160
|
-
*/
|
|
161
|
-
async exception(error: Error, requestId?: string): Promise<void> {
|
|
162
|
-
return this.telescope.exception(error, requestId);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Get requests from storage.
|
|
167
|
-
*/
|
|
168
|
-
async getRequests(
|
|
169
|
-
options?: Parameters<Telescope['getRequests']>[0],
|
|
170
|
-
): ReturnType<Telescope['getRequests']> {
|
|
171
|
-
return this.telescope.getRequests(options);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Get a single request by ID.
|
|
176
|
-
*/
|
|
177
|
-
async getRequest(id: string): ReturnType<Telescope['getRequest']> {
|
|
178
|
-
return this.telescope.getRequest(id);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Get exceptions from storage.
|
|
183
|
-
*/
|
|
184
|
-
async getExceptions(
|
|
185
|
-
options?: Parameters<Telescope['getExceptions']>[0],
|
|
186
|
-
): ReturnType<Telescope['getExceptions']> {
|
|
187
|
-
return this.telescope.getExceptions(options);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Get a single exception by ID.
|
|
192
|
-
*/
|
|
193
|
-
async getException(id: string): ReturnType<Telescope['getException']> {
|
|
194
|
-
return this.telescope.getException(id);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Get logs from storage.
|
|
199
|
-
*/
|
|
200
|
-
async getLogs(
|
|
201
|
-
options?: Parameters<Telescope['getLogs']>[0],
|
|
202
|
-
): ReturnType<Telescope['getLogs']> {
|
|
203
|
-
return this.telescope.getLogs(options);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Get storage statistics.
|
|
208
|
-
*/
|
|
209
|
-
async getStats(): ReturnType<Telescope['getStats']> {
|
|
210
|
-
return this.telescope.getStats();
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// ============================================
|
|
214
|
-
// Public API - Metrics (delegated to Telescope)
|
|
215
|
-
// ============================================
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Get aggregated request metrics.
|
|
219
|
-
*/
|
|
220
|
-
getMetrics(
|
|
221
|
-
options?: Parameters<Telescope['getMetrics']>[0],
|
|
222
|
-
): ReturnType<Telescope['getMetrics']> {
|
|
223
|
-
return this.telescope.getMetrics(options);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Get metrics grouped by endpoint.
|
|
228
|
-
*/
|
|
229
|
-
getEndpointMetrics(
|
|
230
|
-
options?: Parameters<Telescope['getEndpointMetrics']>[0],
|
|
231
|
-
): ReturnType<Telescope['getEndpointMetrics']> {
|
|
232
|
-
return this.telescope.getEndpointMetrics(options);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Get detailed metrics for a specific endpoint.
|
|
237
|
-
*/
|
|
238
|
-
getEndpointDetails(
|
|
239
|
-
method: string,
|
|
240
|
-
path: string,
|
|
241
|
-
options?: Parameters<Telescope['getEndpointDetails']>[2],
|
|
242
|
-
): ReturnType<Telescope['getEndpointDetails']> {
|
|
243
|
-
return this.telescope.getEndpointDetails(method, path, options);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Get HTTP status code distribution.
|
|
248
|
-
*/
|
|
249
|
-
getStatusDistribution(
|
|
250
|
-
options?: Parameters<Telescope['getStatusDistribution']>[0],
|
|
251
|
-
): ReturnType<Telescope['getStatusDistribution']> {
|
|
252
|
-
return this.telescope.getStatusDistribution(options);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Reset all metrics.
|
|
257
|
-
*/
|
|
258
|
-
resetMetrics(): void {
|
|
259
|
-
this.telescope.resetMetrics();
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// ============================================
|
|
263
|
-
// Public API - WebSocket
|
|
264
|
-
// ============================================
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Add a WebSocket client for real-time updates.
|
|
268
|
-
*/
|
|
269
|
-
addWsClient(ws: WebSocket): void {
|
|
270
|
-
this.wsClients.add(ws);
|
|
271
|
-
// Also add to Telescope for monitoring events
|
|
272
|
-
this.telescope.addWsClient(ws);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Remove a WebSocket client.
|
|
277
|
-
*/
|
|
278
|
-
removeWsClient(ws: WebSocket): void {
|
|
279
|
-
this.wsClients.delete(ws);
|
|
280
|
-
this.telescope.removeWsClient(ws);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Broadcast an event to all connected WebSocket clients.
|
|
285
|
-
*/
|
|
286
|
-
broadcast(event: StudioEvent): void {
|
|
287
|
-
const data = JSON.stringify(event);
|
|
288
|
-
for (const client of this.wsClients) {
|
|
289
|
-
try {
|
|
290
|
-
client.send(data);
|
|
291
|
-
} catch {
|
|
292
|
-
this.wsClients.delete(client);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// ============================================
|
|
298
|
-
// Public API - Lifecycle
|
|
299
|
-
// ============================================
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Check if a path should be ignored for request recording.
|
|
303
|
-
*/
|
|
304
|
-
shouldIgnore(path: string): boolean {
|
|
305
|
-
// Ignore Studio's own routes
|
|
306
|
-
if (path.startsWith(this.options.path)) {
|
|
307
|
-
return true;
|
|
308
|
-
}
|
|
309
|
-
return this.telescope.shouldIgnore(path);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* Manually prune old monitoring entries.
|
|
314
|
-
*/
|
|
315
|
-
async prune(olderThan: Date): Promise<number> {
|
|
316
|
-
return this.telescope.prune(olderThan);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
/**
|
|
320
|
-
* Clean up resources.
|
|
321
|
-
*/
|
|
322
|
-
destroy(): void {
|
|
323
|
-
this.telescope.destroy();
|
|
324
|
-
this.wsClients.clear();
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// ============================================
|
|
328
|
-
// Private Methods
|
|
329
|
-
// ============================================
|
|
330
|
-
|
|
331
|
-
private normalizeOptions(
|
|
332
|
-
options: StudioOptions<DB>,
|
|
333
|
-
): NormalizedStudioOptions<DB> {
|
|
334
|
-
const path = options.path ?? '/__studio';
|
|
335
|
-
|
|
336
|
-
return {
|
|
337
|
-
monitoring: {
|
|
338
|
-
storage: options.monitoring.storage,
|
|
339
|
-
ignorePatterns: options.monitoring.ignorePatterns ?? [],
|
|
340
|
-
recordBody: options.monitoring.recordBody ?? true,
|
|
341
|
-
maxBodySize: options.monitoring.maxBodySize ?? 64 * 1024,
|
|
342
|
-
pruneAfterHours: options.monitoring.pruneAfterHours ?? 24,
|
|
343
|
-
},
|
|
344
|
-
data: {
|
|
345
|
-
db: options.data.db,
|
|
346
|
-
cursor: options.data.cursor,
|
|
347
|
-
tableCursors: options.data.tableCursors ?? {},
|
|
348
|
-
excludeTables: options.data.excludeTables ?? [
|
|
349
|
-
// Kysely
|
|
350
|
-
'kysely_migration',
|
|
351
|
-
'kysely_migration_lock',
|
|
352
|
-
// Prisma
|
|
353
|
-
'_prisma_migrations',
|
|
354
|
-
// Rails/Knex
|
|
355
|
-
'schema_migrations',
|
|
356
|
-
// Generic
|
|
357
|
-
'_migrations',
|
|
358
|
-
'migrations',
|
|
359
|
-
],
|
|
360
|
-
defaultPageSize: Math.min(options.data.defaultPageSize ?? 50, 100),
|
|
361
|
-
showBinaryColumns: options.data.showBinaryColumns ?? false,
|
|
362
|
-
},
|
|
363
|
-
path,
|
|
364
|
-
enabled: options.enabled ?? true,
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
}
|