@tsplc/debug 0.2.17 → 0.2.18
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/dist/format.js +36 -18
- package/dist/format.js.map +4 -4
- package/dist/index.js +768 -516
- package/dist/index.js.map +20 -17
- package/dist/manifest.js +6 -2
- package/dist/manifest.js.map +3 -3
- package/dist/paths.js +60 -28
- package/dist/paths.js.map +3 -3
- package/package.json +47 -46
- package/src/adapter.ts +43 -36
- package/src/api.ts +126 -123
- package/src/debugger.ts +584 -467
- package/src/errors.ts +3 -0
- package/src/hardware.ts +127 -96
- package/src/http.ts +147 -116
- package/src/index.ts +34 -4
- package/src/jobs.ts +102 -77
- package/src/login-value.ts +165 -0
- package/src/login.ts +233 -253
- package/src/manifest.ts +200 -194
- package/src/opcua.ts +55 -55
- package/src/paths.ts +230 -157
- package/src/requests.ts +86 -0
- package/src/telemetry.ts +104 -90
- package/src/timeline.ts +96 -61
- package/src/trace.ts +41 -31
- package/src/ui/bits.ts +45 -29
- package/src/ui/client.ts +33 -26
- package/src/ui/dom.ts +189 -108
- package/src/ui/format.ts +127 -72
- package/src/ui/hardware.ts +416 -343
- package/src/ui/header.ts +186 -164
- package/src/ui/index.ts +16 -9
- package/src/ui/jobs.ts +263 -214
- package/src/ui/main.ts +52 -48
- package/src/ui/overview.ts +152 -108
- package/src/ui/recent.ts +329 -276
- package/src/ui/requests.ts +69 -73
- package/src/ui/store.ts +236 -198
- package/src/ui/tree.ts +162 -130
- package/src/ui/variables.ts +557 -431
- package/src/watch.ts +22 -17
- package/src/ui/dev.ts +0 -579
- package/src/ui/fixture.ts +0 -548
package/src/ui/overview.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type Health,
|
|
3
|
+
type View,
|
|
4
|
+
deviceHealth,
|
|
5
|
+
deviceHref,
|
|
6
|
+
devicesWithHealth,
|
|
7
|
+
empty,
|
|
8
|
+
h,
|
|
9
|
+
healthBadge,
|
|
10
|
+
} from "./dom.ts";
|
|
2
11
|
import { formatAge, formatClock, formatInterval } from "./format.ts";
|
|
3
12
|
import { isActive, jobRow, jobTable } from "./jobs.ts";
|
|
4
13
|
import { recentEntry } from "./recent.ts";
|
|
@@ -8,116 +17,151 @@ const HEALTH_ORDER: Health[] = ["fault", "stale", "unknown", "ok"];
|
|
|
8
17
|
const RECENT_EVENTS = 12;
|
|
9
18
|
|
|
10
19
|
export const overviewView = (store: Store): View => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
20
|
+
const connection = h("section", { class: "panel" });
|
|
21
|
+
const devices = h("section", { class: "panel" });
|
|
22
|
+
const jobs = h("section", { class: "panel wide" });
|
|
23
|
+
const events = h("section", { class: "panel wide" });
|
|
15
24
|
|
|
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
|
-
|
|
25
|
+
const renderConnection = () => {
|
|
26
|
+
const { session } = store;
|
|
27
|
+
connection.replaceChildren(
|
|
28
|
+
h("h2", {}, "Connection"),
|
|
29
|
+
h(
|
|
30
|
+
"dl",
|
|
31
|
+
{ class: "facts" },
|
|
32
|
+
h("dt", {}, "Values"),
|
|
33
|
+
h(
|
|
34
|
+
"dd",
|
|
35
|
+
{},
|
|
36
|
+
h(
|
|
37
|
+
"span",
|
|
38
|
+
{ class: `st st-${session.connection.state}` },
|
|
39
|
+
session.connection.state,
|
|
40
|
+
),
|
|
41
|
+
` since ${formatClock(session.connection.since)} (${formatAge(store.ageOf(session.connection.since))})`,
|
|
42
|
+
),
|
|
43
|
+
h("dt", {}, "Endpoint"),
|
|
44
|
+
h("dd", { class: "mono" }, session.connection.endpoint),
|
|
45
|
+
session.connection.error && h("dt", {}, "Error"),
|
|
46
|
+
session.connection.error &&
|
|
47
|
+
h("dd", { class: "err" }, session.connection.error),
|
|
48
|
+
h("dt", {}, "Debugger host"),
|
|
49
|
+
h("dd", {}, store.stream === "open" ? "streaming" : `${store.stream}…`),
|
|
50
|
+
h("dt", {}, "Reading"),
|
|
51
|
+
h(
|
|
52
|
+
"dd",
|
|
53
|
+
{},
|
|
54
|
+
`${session.reading.method}, every ${formatInterval(session.reading.intervalMs)}; values older than ${formatInterval(3 * session.reading.intervalMs)} are marked stale`,
|
|
55
|
+
),
|
|
56
|
+
),
|
|
57
|
+
);
|
|
58
|
+
};
|
|
45
59
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
60
|
+
const renderDevices = () => {
|
|
61
|
+
const healths = store.manifest.devices.map((device) => ({
|
|
62
|
+
device,
|
|
63
|
+
health: deviceHealth(store, device),
|
|
64
|
+
}));
|
|
65
|
+
const attention = healths.filter(({ health }) => health.health !== "ok");
|
|
66
|
+
devices.replaceChildren(
|
|
67
|
+
h("h2", {}, h("a", { href: "#/hardware" }, "Devices")),
|
|
68
|
+
h(
|
|
69
|
+
"div",
|
|
70
|
+
{ class: "counts" },
|
|
71
|
+
...HEALTH_ORDER.map((health) =>
|
|
72
|
+
h(
|
|
73
|
+
"div",
|
|
74
|
+
{ class: `count-box h-${health}` },
|
|
75
|
+
h(
|
|
76
|
+
"b",
|
|
77
|
+
{},
|
|
78
|
+
String(
|
|
79
|
+
healths.filter((entry) => entry.health.health === health)
|
|
80
|
+
.length,
|
|
81
|
+
),
|
|
82
|
+
),
|
|
83
|
+
h("span", {}, health),
|
|
84
|
+
),
|
|
85
|
+
),
|
|
86
|
+
),
|
|
87
|
+
...attention.map(({ device, health }) =>
|
|
88
|
+
h(
|
|
89
|
+
"div",
|
|
90
|
+
{ class: "device-line" },
|
|
91
|
+
healthBadge(health),
|
|
92
|
+
" ",
|
|
93
|
+
h(
|
|
94
|
+
"a",
|
|
95
|
+
{
|
|
96
|
+
href: deviceHref(device.id),
|
|
97
|
+
class: "mono",
|
|
98
|
+
},
|
|
99
|
+
device.id,
|
|
100
|
+
),
|
|
101
|
+
h("span", { class: "dim" }, ` ${health.detail}`),
|
|
102
|
+
),
|
|
103
|
+
),
|
|
104
|
+
);
|
|
105
|
+
};
|
|
78
106
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
107
|
+
// The jobs this page reads: the program's own, as the Jobs page shows them by default.
|
|
108
|
+
const shown = new Set(
|
|
109
|
+
store.manifest.jobs.filter((job) => !job.generated).map(({ id }) => id),
|
|
110
|
+
);
|
|
111
|
+
const renderJobs = () => {
|
|
112
|
+
const active = [...store.jobs.values()].filter(
|
|
113
|
+
(job) => shown.has(job.id) && isActive(job),
|
|
114
|
+
);
|
|
115
|
+
jobs.replaceChildren(
|
|
116
|
+
h("h2", {}, h("a", { href: "#/jobs" }, "Active jobs")),
|
|
117
|
+
h("p", { class: "hint" }, "Busy, or failed since they last started."),
|
|
118
|
+
active.length
|
|
119
|
+
? jobTable(active.map((job) => jobRow(store, job)))
|
|
120
|
+
: empty("No job is busy or failed."),
|
|
121
|
+
);
|
|
122
|
+
};
|
|
91
123
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
124
|
+
const renderEvents = () => {
|
|
125
|
+
const recent = store.timeline
|
|
126
|
+
.filter((entry) => entry.kind === "app" || entry.kind === "trace")
|
|
127
|
+
.slice(-RECENT_EVENTS)
|
|
128
|
+
.reverse();
|
|
129
|
+
events.replaceChildren(
|
|
130
|
+
h("h2", {}, h("a", { href: "#/recent" }, "Recent events")),
|
|
131
|
+
...(recent.length
|
|
132
|
+
? recent.map((entry) => recentEntry(store, entry))
|
|
133
|
+
: [empty("The program has reported nothing recently.")]),
|
|
134
|
+
);
|
|
135
|
+
};
|
|
104
136
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
137
|
+
renderConnection();
|
|
138
|
+
renderDevices();
|
|
139
|
+
renderJobs();
|
|
140
|
+
renderEvents();
|
|
141
|
+
store.show({ health: devicesWithHealth(store), jobs: [...shown] });
|
|
142
|
+
return {
|
|
143
|
+
element: h(
|
|
144
|
+
"div",
|
|
145
|
+
{ class: "page overview" },
|
|
146
|
+
connection,
|
|
147
|
+
devices,
|
|
148
|
+
jobs,
|
|
149
|
+
events,
|
|
150
|
+
),
|
|
151
|
+
update(topics) {
|
|
152
|
+
const live = topics.has("session") || topics.has("stream");
|
|
153
|
+
if (live || topics.has("clock")) {
|
|
154
|
+
renderConnection();
|
|
155
|
+
}
|
|
156
|
+
if (live || topics.has("devices")) {
|
|
157
|
+
renderDevices();
|
|
158
|
+
}
|
|
159
|
+
if (live || topics.has("jobs") || topics.has("timeline")) {
|
|
160
|
+
renderJobs();
|
|
161
|
+
}
|
|
162
|
+
if (topics.has("timeline")) {
|
|
163
|
+
renderEvents();
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
};
|
|
123
167
|
};
|