@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/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
- path: string;
15
- value: unknown;
16
- quality: Quality;
17
- status: string;
18
- /** When the debugger host received it; the controller reports no time of its own. */
19
- receivedAt: string;
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 = "connecting" | "connected" | "lost" | "failed" | "unavailable";
24
+ export type ConnectionState =
25
+ "connecting" | "connected" | "lost" | "failed" | "unavailable";
24
26
 
25
27
  export interface Session {
26
- build: { manifest: string | null; controller: string | null; matches: boolean };
27
- connection: { state: ConnectionState; since: string; endpoint: string; error?: string };
28
- /** How live values are read, such as "engineering login", and how often. */
29
- reading: { method: string; intervalMs: number };
30
- /** From the tasks' telemetry batches; `dropped` counts records overwritten before they were sent. */
31
- tasks: { name: string; scan: number | null; scansPerSecond: number | null; dropped: number }[];
32
- /** PLC clock minus the app server's clock, estimated from telemetry batches. */
33
- clock: { offsetMs: number; uncertaintyMs: number } | null;
34
- release?: { id: string; deployedAt: string; operation: string };
35
- /** The project directory on the host, when served by `tsplc debug`. */
36
- projectRoot?: string;
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
- sequence: number;
42
- task: string;
43
- scan: number;
44
- plcTime: number;
45
- site: number;
46
- value: unknown;
47
- /** The site's guard operands, in the site's order. */
48
- operands: { text: string; path?: string; stable: boolean; value: unknown }[];
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
- export interface RequestTrace {
54
- /** The server's own sequence number. */
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
- id: number;
76
- /** Of the `busy` reading; a traced job's is good. */
77
- quality: Quality;
78
- busy: boolean | null;
79
- cancelling?: boolean;
80
- step?: number;
81
- current?: { kind: string; range: SourceRange; text: string };
82
- startedAt?: string;
83
- elapsedMs?: number;
84
- request?: { service: string; sequence: number; trace?: RequestTrace };
85
- /** Busy, but over the number of jobs whose details are read on each poll. */
86
- unread?: true;
87
- /** The last failure nothing caught, from the program's `exception` records. */
88
- failure?: { at: string; code: number; name?: string; source: string };
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
- id: string;
93
- /** "unknown" unless the driver's own state was read. */
94
- health: {
95
- state: "unknown" | "ok" | "fault" | "stale";
96
- value?: number;
97
- name?: string;
98
- diagnostic?: boolean;
99
- message?: string;
100
- quality: Quality;
101
- };
102
- assemblies: {
103
- direction: "input" | "output";
104
- address?: string;
105
- bytes: number[] | null;
106
- quality: Quality;
107
- }[];
108
- /** Channels bound to TypeScript I/O paths, by channel id. */
109
- channels: { id: string; path: string; value: unknown; quality: Quality }[];
110
- /** The device's hand-configured status symbols, by label. */
111
- status: Record<string, { value: unknown; quality: Quality }>;
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
- at: string;
117
- /** Placed through another clock (the PLC's, or the app server's), so its order is approximate. */
118
- approximate: boolean;
119
- source: "plc" | "server" | "agent" | "debugger";
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
- | { kind: "app"; task: string; sequence: number; record: AppRecord }
122
- | { kind: "trace"; trace: TraceEvent }
123
- | { kind: "request"; request: RequestTrace }
124
- | {
125
- kind: "deploy";
126
- release: string;
127
- operation: string;
128
- build?: string;
129
- user?: string;
130
- host?: string;
131
- }
132
- | {
133
- kind: "audit";
134
- /** As typed after `tsplc`, such as `force` or `reset cold`. */
135
- command: string;
136
- /** Expressions written or forced, with their values; unforced expressions map to "". */
137
- values: Record<string, string>;
138
- /** The values read just before a write or force. */
139
- previous?: Record<string, string>;
140
- user?: string;
141
- host?: string;
142
- release?: string;
143
- error?: string;
144
- }
145
- | { kind: "connection"; state: ConnectionState; error?: string }
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
- groups: Record<string, string[]>;
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
- watch: string[];
158
- jobs: number[];
159
- health: string[];
160
- devices: string[];
160
+ watch: string[];
161
+ jobs: number[];
162
+ health: string[];
163
+ devices: string[];
161
164
  }
162
165
 
163
166
  export interface StreamEvents {
164
- session: Session;
165
- sample: Sample;
166
- job: JobState;
167
- request: RequestTrace;
168
- device: DeviceState;
169
- timeline: TimelineEntry;
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
- "GET /api/session": Session;
175
- "GET /api/manifest": DebugManifest;
176
- "GET /api/values": Sample[];
177
- "GET /api/jobs": JobState[];
178
- "GET /api/hardware": DeviceState[];
179
- "GET /api/timeline": TimelineEntry[];
180
- "GET /api/watch": WatchGroups;
181
- "PUT /api/watch": WatchGroups;
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
  }