@tsplc/debug 0.2.17 → 0.2.19
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/api.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ServiceCall } from "@tsplc/server";
|
|
1
2
|
import type { AppRecord } from "@tsplc/server/telemetry";
|
|
2
3
|
import type { DebugManifest, SourceRange } from "./manifest.ts";
|
|
3
4
|
|
|
@@ -11,60 +12,62 @@ export type Quality = "good" | "uncertain" | "bad" | "unavailable";
|
|
|
11
12
|
|
|
12
13
|
/** One value as read. Values of different paths may come from different scans. */
|
|
13
14
|
export interface Sample {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
path: string;
|
|
16
|
+
value: unknown;
|
|
17
|
+
quality: Quality;
|
|
18
|
+
status: string;
|
|
19
|
+
/** When the debugger host received it; the controller reports no time of its own. */
|
|
20
|
+
receivedAt: string;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
/** `unavailable`: nothing to read through, such as no engineering login open. */
|
|
23
|
-
export type ConnectionState =
|
|
24
|
+
export type ConnectionState =
|
|
25
|
+
"connecting" | "connected" | "lost" | "failed" | "unavailable";
|
|
24
26
|
|
|
25
27
|
export interface Session {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
build: {
|
|
29
|
+
manifest: string | null;
|
|
30
|
+
controller: string | null;
|
|
31
|
+
matches: boolean;
|
|
32
|
+
};
|
|
33
|
+
connection: {
|
|
34
|
+
state: ConnectionState;
|
|
35
|
+
since: string;
|
|
36
|
+
endpoint: string;
|
|
37
|
+
error?: string;
|
|
38
|
+
};
|
|
39
|
+
/** How live values are read, such as "engineering login", and how often. */
|
|
40
|
+
reading: { method: string; intervalMs: number };
|
|
41
|
+
/** From the tasks' telemetry batches; `dropped` counts records overwritten before they were sent. */
|
|
42
|
+
tasks: {
|
|
43
|
+
name: string;
|
|
44
|
+
scan: number | null;
|
|
45
|
+
scansPerSecond: number | null;
|
|
46
|
+
dropped: number;
|
|
47
|
+
}[];
|
|
48
|
+
/** PLC clock minus the app server's clock, estimated from telemetry batches. */
|
|
49
|
+
clock: { offsetMs: number; uncertaintyMs: number } | null;
|
|
50
|
+
release?: { id: string; deployedAt: string; operation: string };
|
|
51
|
+
/** The project directory on the host, when served by `tsplc debug`. */
|
|
52
|
+
projectRoot?: string;
|
|
37
53
|
}
|
|
38
54
|
|
|
39
55
|
/** A trace record, decoded through the manifest's event sites. */
|
|
40
56
|
export interface TraceEvent {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
57
|
+
sequence: number;
|
|
58
|
+
task: string;
|
|
59
|
+
scan: number;
|
|
60
|
+
plcTime: number;
|
|
61
|
+
site: number;
|
|
62
|
+
value: unknown;
|
|
63
|
+
/** The site's guard operands, in the site's order. */
|
|
64
|
+
operands: { text: string; path?: string; stable: boolean; value: unknown }[];
|
|
49
65
|
}
|
|
50
66
|
|
|
51
67
|
export type { AppRecord };
|
|
52
68
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
seq: number;
|
|
56
|
-
service: string;
|
|
57
|
-
/** From `x-tsplc-request: <job id>:<sequence>`. */
|
|
58
|
-
job?: number;
|
|
59
|
-
sequence?: number;
|
|
60
|
-
startedAt: string;
|
|
61
|
-
durationMs?: number;
|
|
62
|
-
status: "pending" | "ok" | "error" | "timeout";
|
|
63
|
-
httpStatus?: number;
|
|
64
|
-
error?: string;
|
|
65
|
-
input?: unknown;
|
|
66
|
-
output?: unknown;
|
|
67
|
-
}
|
|
69
|
+
/** One PLC service call, as the app server traced it. */
|
|
70
|
+
export type RequestTrace = ServiceCall;
|
|
68
71
|
|
|
69
72
|
/**
|
|
70
73
|
* A job as last seen. `busy` is null until it is known: from the trace's start and finish
|
|
@@ -72,81 +75,81 @@ export interface RequestTrace {
|
|
|
72
75
|
* is busy and shown.
|
|
73
76
|
*/
|
|
74
77
|
export interface JobState {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
78
|
+
id: number;
|
|
79
|
+
/** Of the `busy` reading; a traced job's is good. */
|
|
80
|
+
quality: Quality;
|
|
81
|
+
busy: boolean | null;
|
|
82
|
+
cancelling?: boolean;
|
|
83
|
+
step?: number;
|
|
84
|
+
current?: { kind: string; range: SourceRange; text: string };
|
|
85
|
+
startedAt?: string;
|
|
86
|
+
elapsedMs?: number;
|
|
87
|
+
request?: { service: string; sequence: number; trace?: RequestTrace };
|
|
88
|
+
/** Busy, but over the number of jobs whose details are read on each poll. */
|
|
89
|
+
unread?: true;
|
|
90
|
+
/** The last failure nothing caught, from the program's `exception` records. */
|
|
91
|
+
failure?: { at: string; code: number; name?: string; source: string };
|
|
89
92
|
}
|
|
90
93
|
|
|
91
94
|
export interface DeviceState {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
95
|
+
id: string;
|
|
96
|
+
/** "unknown" unless the driver's own state was read. */
|
|
97
|
+
health: {
|
|
98
|
+
state: "unknown" | "ok" | "fault" | "stale";
|
|
99
|
+
value?: number;
|
|
100
|
+
name?: string;
|
|
101
|
+
diagnostic?: boolean;
|
|
102
|
+
message?: string;
|
|
103
|
+
quality: Quality;
|
|
104
|
+
};
|
|
105
|
+
assemblies: {
|
|
106
|
+
direction: "input" | "output";
|
|
107
|
+
address?: string;
|
|
108
|
+
bytes: number[] | null;
|
|
109
|
+
quality: Quality;
|
|
110
|
+
}[];
|
|
111
|
+
/** Channels bound to TypeScript I/O paths, by channel id. */
|
|
112
|
+
channels: { id: string; path: string; value: unknown; quality: Quality }[];
|
|
113
|
+
/** The device's hand-configured status symbols, by label. */
|
|
114
|
+
status: Record<string, { value: unknown; quality: Quality }>;
|
|
112
115
|
}
|
|
113
116
|
|
|
114
117
|
/** An entry of the "Recent" view: the server's recent window, merged with the agent's logs. */
|
|
115
118
|
export type TimelineEntry = {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
119
|
+
at: string;
|
|
120
|
+
/** Placed through another clock (the PLC's, or the app server's), so its order is approximate. */
|
|
121
|
+
approximate: boolean;
|
|
122
|
+
source: "plc" | "server" | "agent" | "debugger";
|
|
120
123
|
} & (
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
124
|
+
| { kind: "app"; task: string; sequence: number; record: AppRecord }
|
|
125
|
+
| { kind: "trace"; trace: TraceEvent }
|
|
126
|
+
| { kind: "request"; request: RequestTrace }
|
|
127
|
+
| {
|
|
128
|
+
kind: "deploy";
|
|
129
|
+
release: string;
|
|
130
|
+
operation: string;
|
|
131
|
+
build?: string;
|
|
132
|
+
user?: string;
|
|
133
|
+
host?: string;
|
|
134
|
+
}
|
|
135
|
+
| {
|
|
136
|
+
kind: "audit";
|
|
137
|
+
/** As typed after `tsplc`, such as `force` or `reset cold`. */
|
|
138
|
+
command: string;
|
|
139
|
+
/** Expressions written or forced, with their values; unforced expressions map to "". */
|
|
140
|
+
values: Record<string, string>;
|
|
141
|
+
/** The values read just before a write or force. */
|
|
142
|
+
previous?: Record<string, string>;
|
|
143
|
+
user?: string;
|
|
144
|
+
host?: string;
|
|
145
|
+
release?: string;
|
|
146
|
+
error?: string;
|
|
147
|
+
}
|
|
148
|
+
| { kind: "connection"; state: ConnectionState; error?: string }
|
|
146
149
|
);
|
|
147
150
|
|
|
148
151
|
export interface WatchGroups {
|
|
149
|
-
|
|
152
|
+
groups: Record<string, string[]>;
|
|
150
153
|
}
|
|
151
154
|
|
|
152
155
|
/**
|
|
@@ -154,29 +157,29 @@ export interface WatchGroups {
|
|
|
154
157
|
* `health` devices, and everything of `devices`. Stream query parameters, comma-separated.
|
|
155
158
|
*/
|
|
156
159
|
export interface Interest {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
160
|
+
watch: string[];
|
|
161
|
+
jobs: number[];
|
|
162
|
+
health: string[];
|
|
163
|
+
devices: string[];
|
|
161
164
|
}
|
|
162
165
|
|
|
163
166
|
export interface StreamEvents {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
167
|
+
session: Session;
|
|
168
|
+
sample: Sample;
|
|
169
|
+
job: JobState;
|
|
170
|
+
request: RequestTrace;
|
|
171
|
+
device: DeviceState;
|
|
172
|
+
timeline: TimelineEntry;
|
|
170
173
|
}
|
|
171
174
|
|
|
172
175
|
/** Response bodies by route. Errors are `{ error: string }` with a 4xx or 5xx status. */
|
|
173
176
|
export interface ApiResponses {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
177
|
+
"GET /api/session": Session;
|
|
178
|
+
"GET /api/manifest": DebugManifest;
|
|
179
|
+
"GET /api/values": Sample[];
|
|
180
|
+
"GET /api/jobs": JobState[];
|
|
181
|
+
"GET /api/hardware": DeviceState[];
|
|
182
|
+
"GET /api/timeline": TimelineEntry[];
|
|
183
|
+
"GET /api/watch": WatchGroups;
|
|
184
|
+
"PUT /api/watch": WatchGroups;
|
|
182
185
|
}
|