@zerotal/monitor 1.8.1 → 1.10.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.
- package/CHANGELOG.md +37 -0
- package/api-surface.md +42 -47
- package/package.json +7 -7
- package/src/MonitorStore.ts +24 -13
- package/src/config.ts +26 -26
- package/src/panel.ts +2 -0
- package/src/ui/MonitorLayout.tsx +1 -0
- package/src/ui/MonitorPage.tsx +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,43 @@ follows the Zerotal monorepo's unified versioning.
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [1.10.0] — 2026-08-30
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **`MonitorStore` options no longer overwrite their own defaults with `undefined`.**
|
|
16
|
+
The constructor applied `?? 100`-style defaults and then spread `...opts` **after**
|
|
17
|
+
them, and object spread copies own properties even when their value is `undefined`.
|
|
18
|
+
So `new MonitorStore({ retentionDays: cfg.retentionDays })` with an unset config put
|
|
19
|
+
`undefined` straight back over the 7, and `prune()` computed a cutoff of
|
|
20
|
+
`Date.now() - undefined * DAY_MS` — `NaN`, which prunes nothing and reports nothing.
|
|
21
|
+
Spreading last is what made every `??` in that constructor decorative.
|
|
22
|
+
|
|
23
|
+
The caller's options now go first and the defaults fill the gaps, which is the
|
|
24
|
+
ordering `Socket`'s constructor already documents at length for the same reason.
|
|
25
|
+
|
|
26
|
+
## [1.9.0] — 2026-08-29
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **The snapshot shape is documented.** **Export JSON** hands you a `MonitorSnapshot` — the whole
|
|
31
|
+
panel for a range, as data — and none of the forty-odd row types it is built from was named
|
|
32
|
+
anywhere. `docs/monitor.md` now maps every field to its row type, which is what you need to
|
|
33
|
+
post one somewhere, diff two of them, or drive an alerting integration off it rather than off
|
|
34
|
+
the built-in thresholds.
|
|
35
|
+
|
|
36
|
+
- **Section contributions can be typed.** `MonitorSection`, `MonitorSectionData`, `MonitorStat`,
|
|
37
|
+
`MonitorTable`, `MonitorTableColumn` and `MonitorRow` are documented. Declaring the host's
|
|
38
|
+
shape locally stays the recommended path — it is what keeps a contributing package free of any
|
|
39
|
+
dependency on the monitor — but a large `resolve` is better served by a typo in a column key
|
|
40
|
+
being a compile error than a blank cell.
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- **INTERNAL: `MonitorLayout`, `MonitorPage` and `MonitorPanelHost` are marked `@internal`.**
|
|
45
|
+
The panel's own shell. Still exported, still working; a contributor pushes a section into the
|
|
46
|
+
host binding rather than constructing any of them.
|
|
47
|
+
|
|
11
48
|
## [1.6.0] — 2026-08-15
|
|
12
49
|
|
|
13
50
|
### Fixed
|
package/api-surface.md
CHANGED
|
@@ -286,37 +286,32 @@ interface ModelStat = {
|
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
interface MonitorConfigShape = {
|
|
289
|
-
accent?: string
|
|
290
|
-
alertCooldownMs?: number
|
|
291
|
-
alertThresholds?: AlertThresholds
|
|
292
|
-
alertWebhook?: string
|
|
293
|
-
alerts?: boolean
|
|
294
|
-
apdexTargetMs?: number
|
|
295
|
-
auth?: (user: unknown) => boolean | Promise<boolean>
|
|
296
|
-
capturePayloads?: boolean
|
|
297
|
-
deploy?: string
|
|
298
|
-
metrics?: boolean
|
|
299
|
-
metricsPath?: string
|
|
300
|
-
path?: string
|
|
301
|
-
payloadMaxBytes?: number
|
|
302
|
-
record?: boolean
|
|
303
|
-
refreshMs?: number
|
|
304
|
-
region?: string
|
|
305
|
-
retentionDays?: number
|
|
306
|
-
retentionMode?: RetentionMode
|
|
307
|
-
sections?: Record<string, boolean>
|
|
308
|
-
slowQueryMs?: number
|
|
309
|
-
slowRequestMs?: number
|
|
310
|
-
snapshotCacheMs?: number
|
|
311
|
-
storage?: string
|
|
312
|
-
subtitle?: string
|
|
313
|
-
title?: string
|
|
314
|
-
zerotalVersion?: string
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
interface MonitorPanelHost = {
|
|
318
|
-
enabled: (id: string) => boolean
|
|
319
|
-
section: (section: MonitorSection) => void
|
|
289
|
+
accent?: string | undefined
|
|
290
|
+
alertCooldownMs?: number | undefined
|
|
291
|
+
alertThresholds?: AlertThresholds | undefined
|
|
292
|
+
alertWebhook?: string | undefined
|
|
293
|
+
alerts?: boolean | undefined
|
|
294
|
+
apdexTargetMs?: number | undefined
|
|
295
|
+
auth?: ((user: unknown) => boolean | Promise<boolean>) | undefined
|
|
296
|
+
capturePayloads?: boolean | undefined
|
|
297
|
+
deploy?: string | undefined
|
|
298
|
+
metrics?: boolean | undefined
|
|
299
|
+
metricsPath?: string | undefined
|
|
300
|
+
path?: string | undefined
|
|
301
|
+
payloadMaxBytes?: number | undefined
|
|
302
|
+
record?: boolean | undefined
|
|
303
|
+
refreshMs?: number | undefined
|
|
304
|
+
region?: string | undefined
|
|
305
|
+
retentionDays?: number | undefined
|
|
306
|
+
retentionMode?: RetentionMode | undefined
|
|
307
|
+
sections?: Record<string, boolean> | undefined
|
|
308
|
+
slowQueryMs?: number | undefined
|
|
309
|
+
slowRequestMs?: number | undefined
|
|
310
|
+
snapshotCacheMs?: number | undefined
|
|
311
|
+
storage?: string | undefined
|
|
312
|
+
subtitle?: string | undefined
|
|
313
|
+
title?: string | undefined
|
|
314
|
+
zerotalVersion?: string | undefined
|
|
320
315
|
}
|
|
321
316
|
|
|
322
317
|
interface MonitorSection = {
|
|
@@ -391,16 +386,16 @@ interface MonitorStat = {
|
|
|
391
386
|
}
|
|
392
387
|
|
|
393
388
|
interface MonitorStoreOptions = {
|
|
394
|
-
apdexTargetMs?: number
|
|
395
|
-
deploy?: string
|
|
396
|
-
region?: string
|
|
397
|
-
retentionDays?: number
|
|
398
|
-
retentionMode?: RetentionMode
|
|
399
|
-
slowQueryMs?: number
|
|
400
|
-
slowRequestMs?: number
|
|
401
|
-
snapshotCacheMs?: number
|
|
402
|
-
storage?: string
|
|
403
|
-
zerotalVersion?: string
|
|
389
|
+
apdexTargetMs?: number | undefined
|
|
390
|
+
deploy?: string | undefined
|
|
391
|
+
region?: string | undefined
|
|
392
|
+
retentionDays?: number | undefined
|
|
393
|
+
retentionMode?: RetentionMode | undefined
|
|
394
|
+
slowQueryMs?: number | undefined
|
|
395
|
+
slowRequestMs?: number | undefined
|
|
396
|
+
snapshotCacheMs?: number | undefined
|
|
397
|
+
storage?: string | undefined
|
|
398
|
+
zerotalVersion?: string | undefined
|
|
404
399
|
}
|
|
405
400
|
|
|
406
401
|
interface MonitorTable = {
|
|
@@ -530,30 +525,30 @@ interface RequestSpan = {
|
|
|
530
525
|
interface ResolvedMonitorConfig = {
|
|
531
526
|
accent: string
|
|
532
527
|
alertCooldownMs: number
|
|
533
|
-
alertThresholds?: AlertThresholds
|
|
534
|
-
alertWebhook?: string
|
|
528
|
+
alertThresholds?: AlertThresholds | undefined
|
|
529
|
+
alertWebhook?: string | undefined
|
|
535
530
|
alerts: boolean
|
|
536
531
|
apdexTargetMs: number
|
|
537
532
|
auth: (user: unknown) => boolean | Promise<boolean>
|
|
538
533
|
capturePayloads: boolean
|
|
539
|
-
deploy?: string
|
|
534
|
+
deploy?: string | undefined
|
|
540
535
|
metrics: boolean
|
|
541
536
|
metricsPath: string
|
|
542
537
|
path: string
|
|
543
538
|
payloadMaxBytes: number
|
|
544
539
|
record: boolean
|
|
545
540
|
refreshMs: number
|
|
546
|
-
region?: string
|
|
541
|
+
region?: string | undefined
|
|
547
542
|
retentionDays: number
|
|
548
543
|
retentionMode: RetentionMode
|
|
549
|
-
sections?: Record<string, boolean>
|
|
544
|
+
sections?: Record<string, boolean> | undefined
|
|
550
545
|
slowQueryMs: number
|
|
551
546
|
slowRequestMs: number
|
|
552
547
|
snapshotCacheMs: number
|
|
553
548
|
storage: string
|
|
554
549
|
subtitle: string
|
|
555
550
|
title: string
|
|
556
|
-
zerotalVersion?: string
|
|
551
|
+
zerotalVersion?: string | undefined
|
|
557
552
|
}
|
|
558
553
|
|
|
559
554
|
interface RouteDetail = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zerotal/monitor",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"maturity": "stable",
|
|
6
6
|
"private": false,
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
"typecheck": "tsc --noEmit"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@zerotal/core": "1.
|
|
34
|
-
"@zerotal/flow-ui": "1.
|
|
35
|
-
"@zerotal/flow": "1.
|
|
33
|
+
"@zerotal/core": "1.10.0",
|
|
34
|
+
"@zerotal/flow-ui": "1.10.0",
|
|
35
|
+
"@zerotal/flow": "1.10.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@zerotal/queue": "1.
|
|
39
|
-
"@zerotal/scheduler": "1.
|
|
40
|
-
"@zerotal/telemetry": "1.
|
|
38
|
+
"@zerotal/queue": "1.10.0",
|
|
39
|
+
"@zerotal/scheduler": "1.10.0",
|
|
40
|
+
"@zerotal/telemetry": "1.10.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@zerotal/queue": "^1.0.0",
|
package/src/MonitorStore.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* A retention policy (`prune`) deletes or archives data past the configured
|
|
13
13
|
* window, and `wipe` clears everything on demand from the panel.
|
|
14
14
|
*/
|
|
15
|
+
import type { Resolved } from "@zerotal/core";
|
|
15
16
|
import { percentile } from "./store/RingBuffer.ts";
|
|
16
17
|
import { MonitorDb } from "./store/MonitorDb.ts";
|
|
17
18
|
import {
|
|
@@ -107,25 +108,25 @@ interface ReqSample {
|
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
export interface MonitorStoreOptions {
|
|
110
|
-
apdexTargetMs?: number;
|
|
111
|
-
slowQueryMs?: number;
|
|
112
|
-
zerotalVersion?: string;
|
|
113
|
-
region?: string;
|
|
114
|
-
deploy?: string;
|
|
111
|
+
apdexTargetMs?: number | undefined;
|
|
112
|
+
slowQueryMs?: number | undefined;
|
|
113
|
+
zerotalVersion?: string | undefined;
|
|
114
|
+
region?: string | undefined;
|
|
115
|
+
deploy?: string | undefined;
|
|
115
116
|
/** SQLite path. `:memory:` (default) for tests; a file path for persistence. */
|
|
116
|
-
storage?: string;
|
|
117
|
+
storage?: string | undefined;
|
|
117
118
|
/** Days of history to keep before pruning. Default: 7. */
|
|
118
|
-
retentionDays?: number;
|
|
119
|
+
retentionDays?: number | undefined;
|
|
119
120
|
/** What to do with data past retention: delete it or move it to the archive. Default: `delete`. */
|
|
120
|
-
retentionMode?: RetentionMode;
|
|
121
|
+
retentionMode?: RetentionMode | undefined;
|
|
121
122
|
/** Requests at/above this many ms count as "slow". Default: 1000. */
|
|
122
|
-
slowRequestMs?: number;
|
|
123
|
+
slowRequestMs?: number | undefined;
|
|
123
124
|
/**
|
|
124
125
|
* Cache built snapshots for this many ms, keyed by range. De-dupes overlapping
|
|
125
126
|
* builds (panel poll + Prometheus scrape + alert loop all hit "live"). Mutating
|
|
126
127
|
* actions invalidate it. Default: 0 (off) — the provider enables it in production.
|
|
127
128
|
*/
|
|
128
|
-
snapshotCacheMs?: number;
|
|
129
|
+
snapshotCacheMs?: number | undefined;
|
|
129
130
|
}
|
|
130
131
|
|
|
131
132
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
@@ -139,22 +140,32 @@ export class MonitorStore {
|
|
|
139
140
|
private readonly _snapTtlMs: number;
|
|
140
141
|
private readonly _snapCache = new Map<MonitorRange, { at: number; snap: MonitorSnapshot }>();
|
|
141
142
|
|
|
142
|
-
private readonly _opts:
|
|
143
|
+
private readonly _opts: Resolved<
|
|
143
144
|
Pick<
|
|
144
145
|
MonitorStoreOptions,
|
|
145
146
|
"apdexTargetMs" | "slowQueryMs" | "slowRequestMs" | "retentionDays" | "retentionMode"
|
|
146
147
|
>
|
|
147
148
|
> &
|
|
148
|
-
|
|
149
|
+
Omit<
|
|
150
|
+
MonitorStoreOptions,
|
|
151
|
+
"apdexTargetMs" | "slowQueryMs" | "slowRequestMs" | "retentionDays" | "retentionMode"
|
|
152
|
+
>;
|
|
149
153
|
|
|
150
154
|
constructor(opts: MonitorStoreOptions = {}) {
|
|
155
|
+
// The caller's options go FIRST, then the defaults fill the gaps — the same
|
|
156
|
+
// ordering, for the same reason, as `Socket`'s constructor documents at length.
|
|
157
|
+
// Object spread copies own properties even when their value is `undefined`, so
|
|
158
|
+
// `new MonitorStore({ retentionDays: cfg.retentionDays })` with an unset config
|
|
159
|
+
// put `undefined` straight back over the 7 and `prune()` then computed a cutoff
|
|
160
|
+
// of `Date.now() - undefined * DAY_MS` — NaN, which deletes nothing and reports
|
|
161
|
+
// nothing. Spreading last is what made the `??` above decorative.
|
|
151
162
|
this._opts = {
|
|
163
|
+
...opts,
|
|
152
164
|
apdexTargetMs: opts.apdexTargetMs ?? 100,
|
|
153
165
|
slowQueryMs: opts.slowQueryMs ?? 100,
|
|
154
166
|
slowRequestMs: opts.slowRequestMs ?? 1000,
|
|
155
167
|
retentionDays: opts.retentionDays ?? 7,
|
|
156
168
|
retentionMode: opts.retentionMode ?? "delete",
|
|
157
|
-
...opts,
|
|
158
169
|
};
|
|
159
170
|
this._snapTtlMs = Math.max(0, opts.snapshotCacheMs ?? 0);
|
|
160
171
|
this._db = new MonitorDb(opts.storage ?? ":memory:");
|
package/src/config.ts
CHANGED
|
@@ -13,91 +13,91 @@ import type { AlertThresholds } from "./alerting.ts";
|
|
|
13
13
|
|
|
14
14
|
export interface MonitorConfigShape {
|
|
15
15
|
/** URL prefix the panel mounts at. Default: `/monitor`. */
|
|
16
|
-
path?: string;
|
|
16
|
+
path?: string | undefined;
|
|
17
17
|
/** Browser tab title / sidebar heading. Default: `Super Panel`. */
|
|
18
|
-
title?: string;
|
|
18
|
+
title?: string | undefined;
|
|
19
19
|
/** Sub-label under the title. Default: `Zerotal Ops`. */
|
|
20
|
-
subtitle?: string;
|
|
20
|
+
subtitle?: string | undefined;
|
|
21
21
|
/**
|
|
22
22
|
* Authorization gate. Receives the authenticated user (or undefined) and
|
|
23
23
|
* must return true to allow access. Default: allow only outside production.
|
|
24
24
|
*/
|
|
25
|
-
auth?: (user: unknown) => boolean | Promise<boolean
|
|
25
|
+
auth?: ((user: unknown) => boolean | Promise<boolean>) | undefined;
|
|
26
26
|
/** Install the recorder middleware to capture live request data. Default: true. */
|
|
27
|
-
record?: boolean;
|
|
27
|
+
record?: boolean | undefined;
|
|
28
28
|
/** Auto-refresh cadence in milliseconds while "Live" is on. Default: 3000. */
|
|
29
|
-
refreshMs?: number;
|
|
29
|
+
refreshMs?: number | undefined;
|
|
30
30
|
/** Apdex satisfaction threshold (T) in ms. Default: 100. */
|
|
31
|
-
apdexTargetMs?: number;
|
|
31
|
+
apdexTargetMs?: number | undefined;
|
|
32
32
|
/** Queries at/above this many ms count as "slow". Default: 100. */
|
|
33
|
-
slowQueryMs?: number;
|
|
33
|
+
slowQueryMs?: number | undefined;
|
|
34
34
|
/** Requests at/above this many ms count as "slow" (Slow Requests widget). Default: 1000. */
|
|
35
|
-
slowRequestMs?: number;
|
|
35
|
+
slowRequestMs?: number | undefined;
|
|
36
36
|
/**
|
|
37
37
|
* Capture request/response headers and bodies on each request (Telescope-style),
|
|
38
38
|
* shown in the request trace. Off by default — it buffers bodies and is
|
|
39
39
|
* privacy-sensitive. Sensitive headers (authorization/cookie) and body keys
|
|
40
40
|
* (password/token/secret/…) are redacted automatically.
|
|
41
41
|
*/
|
|
42
|
-
capturePayloads?: boolean;
|
|
42
|
+
capturePayloads?: boolean | undefined;
|
|
43
43
|
/** Truncate captured request/response bodies to this many bytes. Default: 65536. */
|
|
44
|
-
payloadMaxBytes?: number;
|
|
44
|
+
payloadMaxBytes?: number | undefined;
|
|
45
45
|
/**
|
|
46
46
|
* Cache built snapshots for this many ms, keyed by range, so overlapping reads
|
|
47
47
|
* (panel poll + Prometheus scrape + alert loop) share one build. Mutating actions
|
|
48
48
|
* invalidate it. Default: 1000. Set `0` to always build fresh.
|
|
49
49
|
*/
|
|
50
|
-
snapshotCacheMs?: number;
|
|
50
|
+
snapshotCacheMs?: number | undefined;
|
|
51
51
|
/**
|
|
52
52
|
* SQLite file the panel persists to, so history survives restarts and the
|
|
53
53
|
* 1h/24h/7d ranges trace real data. Default: `storage/monitor.sqlite`. Use
|
|
54
54
|
* `:memory:` for an ephemeral, in-process store.
|
|
55
55
|
*/
|
|
56
|
-
storage?: string;
|
|
56
|
+
storage?: string | undefined;
|
|
57
57
|
/** Days of history to keep before pruning. Default: 7. */
|
|
58
|
-
retentionDays?: number;
|
|
58
|
+
retentionDays?: number | undefined;
|
|
59
59
|
/** What to do with data past retention: `delete` it or `archive` it. Default: `delete`. */
|
|
60
|
-
retentionMode?: RetentionMode;
|
|
60
|
+
retentionMode?: RetentionMode | undefined;
|
|
61
61
|
/**
|
|
62
62
|
* Expose a Prometheus text-exposition endpoint. Default: `false` (opt-in).
|
|
63
63
|
* The endpoint is unauthenticated (a scraper can't satisfy user-auth), so it
|
|
64
64
|
* ships off; enable it only when you protect `metricsPath` at the network
|
|
65
65
|
* layer (firewall/ingress) or scope it to a private interface.
|
|
66
66
|
*/
|
|
67
|
-
metrics?: boolean;
|
|
67
|
+
metrics?: boolean | undefined;
|
|
68
68
|
/** Path for the Prometheus endpoint. Default: `/metrics`. Protect it at the network layer. */
|
|
69
|
-
metricsPath?: string;
|
|
69
|
+
metricsPath?: string | undefined;
|
|
70
70
|
/** Evaluate threshold alerts on a short interval. Default: `true`. */
|
|
71
|
-
alerts?: boolean;
|
|
71
|
+
alerts?: boolean | undefined;
|
|
72
72
|
/** Alert thresholds (error rate, queue backlog, p95, rollbacks). */
|
|
73
|
-
alertThresholds?: AlertThresholds;
|
|
73
|
+
alertThresholds?: AlertThresholds | undefined;
|
|
74
74
|
/**
|
|
75
75
|
* Minimum gap (ms) before the same alert can fire again after it recovers and
|
|
76
76
|
* re-breaches. Stops an oscillating metric from re-paging / re-flooding the feed
|
|
77
77
|
* for one ongoing issue. Default: 30 min. Set `0` to fire on every fresh breach.
|
|
78
78
|
*/
|
|
79
|
-
alertCooldownMs?: number;
|
|
79
|
+
alertCooldownMs?: number | undefined;
|
|
80
80
|
/**
|
|
81
81
|
* Slack-compatible webhook URL. When set, every newly-firing alert is POSTed to
|
|
82
82
|
* it as JSON (`{ text, level, title, detail }`) so alerts page someone instead of
|
|
83
83
|
* only lighting up the panel. Dependency-free (uses `fetch`); delivery is
|
|
84
84
|
* best-effort. For richer routing, register a handler with `onAlert()` instead.
|
|
85
85
|
*/
|
|
86
|
-
alertWebhook?: string;
|
|
86
|
+
alertWebhook?: string | undefined;
|
|
87
87
|
/** Accent colour (hex) for the panel chrome. Default: Zerotal orange. */
|
|
88
|
-
accent?: string;
|
|
88
|
+
accent?: string | undefined;
|
|
89
89
|
/** Version string shown in the System footer. */
|
|
90
|
-
zerotalVersion?: string;
|
|
90
|
+
zerotalVersion?: string | undefined;
|
|
91
91
|
/** Region label shown in the System footer. */
|
|
92
|
-
region?: string;
|
|
92
|
+
region?: string | undefined;
|
|
93
93
|
/** Deploy SHA shown in the System footer. */
|
|
94
|
-
deploy?: string;
|
|
94
|
+
deploy?: string | undefined;
|
|
95
95
|
/**
|
|
96
96
|
* Switch contributed sections off by id — `{ scheduler: false }` keeps the
|
|
97
97
|
* scheduler installed but drops its section from the panel. Anything absent
|
|
98
98
|
* here is on.
|
|
99
99
|
*/
|
|
100
|
-
sections?: Record<string, boolean
|
|
100
|
+
sections?: Record<string, boolean> | undefined;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
export interface ResolvedMonitorConfig extends MonitorConfigShape {
|
package/src/panel.ts
CHANGED
|
@@ -99,6 +99,8 @@ export interface MonitorSection {
|
|
|
99
99
|
*
|
|
100
100
|
* Contributors should declare their own minimal copy of the members they use
|
|
101
101
|
* rather than importing this type, so they depend on this package not at all.
|
|
102
|
+
*
|
|
103
|
+
* @internal
|
|
102
104
|
*/
|
|
103
105
|
export interface MonitorPanelHost {
|
|
104
106
|
/**
|
package/src/ui/MonitorLayout.tsx
CHANGED
package/src/ui/MonitorPage.tsx
CHANGED
|
@@ -121,6 +121,8 @@ const FEED_PER_PAGE = 12;
|
|
|
121
121
|
* `super-panel.html` built on Flow. Eight tabs (Overview, Requests,
|
|
122
122
|
* Exceptions, Queues, Mail, Database, Cache, System) render from a live
|
|
123
123
|
* {@link MonitorSnapshot}; interactions round-trip over the Flow WebSocket.
|
|
124
|
+
*
|
|
125
|
+
* @internal
|
|
124
126
|
*/
|
|
125
127
|
export class MonitorPage extends Component {
|
|
126
128
|
static layout = MonitorLayout;
|