@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/dist/manifest.js
CHANGED
|
@@ -152,7 +152,11 @@ var debugEventSite = z.object({
|
|
|
152
152
|
var debugWriter = z.object({
|
|
153
153
|
output: z.string(),
|
|
154
154
|
target: z.string(),
|
|
155
|
-
sites: z.array(z.object({
|
|
155
|
+
sites: z.array(z.object({
|
|
156
|
+
id: z.number().int(),
|
|
157
|
+
range: sourceRange,
|
|
158
|
+
function: z.number().int()
|
|
159
|
+
}))
|
|
156
160
|
});
|
|
157
161
|
var debugTask = z.object({
|
|
158
162
|
name: z.string(),
|
|
@@ -197,5 +201,5 @@ export {
|
|
|
197
201
|
sourceRange
|
|
198
202
|
};
|
|
199
203
|
|
|
200
|
-
//# debugId=
|
|
204
|
+
//# debugId=04D6881A2315B4F764756E2164756E21
|
|
201
205
|
//# sourceMappingURL=manifest.js.map
|
package/dist/manifest.js.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/manifest.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { z } from \"zod\";\n\n/**\n * What a build tells the debugger: every TypeScript identity it can show, and the target symbol each one reads.\n * TypeScript paths (`program.diverters.binTrackers[10].bin`) are the identity; `target` strings are opaque to\n * everything except the target's adapter (for CODESYS, IEC symbol paths such as `plc_Program.diverters…`).\n * Written by the compiler to `.tsplc/artifacts/st/debug.json` and shipped with each release.\n */\n\n/** A location in the project's own sources: `file` indexes `sources`; lines and columns are 1-based. */\nexport const sourceRange = z.object({\n
|
|
5
|
+
"import { z } from \"zod\";\n\n/**\n * What a build tells the debugger: every TypeScript identity it can show, and the target symbol each one reads.\n * TypeScript paths (`program.diverters.binTrackers[10].bin`) are the identity; `target` strings are opaque to\n * everything except the target's adapter (for CODESYS, IEC symbol paths such as `plc_Program.diverters…`).\n * Written by the compiler to `.tsplc/artifacts/st/debug.json` and shipped with each release.\n */\n\n/** A location in the project's own sources: `file` indexes `sources`; lines and columns are 1-based. */\nexport const sourceRange = z.object({\n\tfile: z.number().int(),\n\tline: z.number().int(),\n\tcolumn: z.number().int(),\n\tendLine: z.number().int(),\n\tendColumn: z.number().int(),\n});\n\nconst json: z.ZodType<unknown> = z.lazy(() =>\n\tz.union([\n\t\tz.string(),\n\t\tz.number(),\n\t\tz.boolean(),\n\t\tz.null(),\n\t\tz.array(json),\n\t\tz.record(z.string(), json),\n\t]),\n);\n\nexport const debugField = z.object({\n\tname: z.string(),\n\ttarget: z.string(),\n\ttype: z.string(),\n\tdeclaration: sourceRange.optional(),\n\t/** Compiler-made storage, such as an async job's `step`; hidden unless asked for. */\n\tgenerated: z.literal(true).optional(),\n});\n\n/** Keys of `types` are opaque ids; scalars use their IEC name, such as `BOOL`. */\nexport const debugType = z.discriminatedUnion(\"kind\", [\n\tz.object({ kind: z.literal(\"scalar\"), iec: z.string() }),\n\tz.object({\n\t\tkind: z.literal(\"enum\"),\n\t\tname: z.string(),\n\t\tmembers: z.record(z.string(), z.number().int()),\n\t}),\n\tz.object({\n\t\tkind: z.literal(\"record\"),\n\t\tname: z.string(),\n\t\tdeclaration: sourceRange.optional(),\n\t\tfields: z.array(debugField),\n\t}),\n\tz.object({\n\t\tkind: z.literal(\"array\"),\n\t\telement: z.string(),\n\t\tlength: z.number().int(),\n\t\t/** The first index; TypeScript paths use the target's own indexes, `lower` to `lower + length - 1`. */\n\t\tlower: z.number().int(),\n\t}),\n]);\n\nexport const debugRoot = z.object({\n\tpath: z.string(),\n\ttarget: z.string(),\n\ttype: z.string(),\n\tdeclaration: sourceRange.optional(),\n\t/** Readable at runtime through the target's adapter; for CODESYS, all stored state is. */\n\treadable: z.boolean(),\n\tgenerated: z.literal(true).optional(),\n});\n\n/** A field the compiler folded away: it has no runtime storage, but its value is known. */\nexport const debugConstant = z.object({\n\tpath: z.string(),\n\ttype: z.string(),\n\tvalue: json,\n\tdeclaration: sourceRange.optional(),\n});\n\nexport const debugIo = z.object({\n\tpath: z.string(),\n\ttarget: z.string(),\n\tdirection: z.enum([\"input\", \"output\"]),\n\ttype: z.string(),\n\tdevice: z.string().optional(),\n\tchannel: z.string().optional(),\n\taddress: z.string().optional(),\n\tinverted: z.literal(true).optional(),\n\tshared: z.literal(true).optional(),\n});\n\nexport const debugChannel = z.object({\n\tid: z.string(),\n\tname: z.string(),\n\tdirection: z.enum([\"input\", \"output\"]),\n\ttype: z.string(),\n\toffsetBits: z.number().int(),\n\tbits: z.number().int(),\n\taddress: z.string().optional(),\n\tunit: z.string().optional(),\n\tdescription: z.string().optional(),\n});\n\nexport const debugDevice = z.object({\n\tid: z.string(),\n\tproduct: z.string().optional(),\n\tvendor: z.string().optional(),\n\tproductCode: z.string().optional(),\n\tnetwork: z\n\t\t.object({ address: z.string(), rpiMs: z.number().optional() })\n\t\t.optional(),\n\tconnection: z.string().optional(),\n\tassemblies: z.array(\n\t\tz.object({\n\t\t\tdirection: z.enum([\"input\", \"output\"]),\n\t\t\tbytes: z.number().int(),\n\t\t\taddress: z.string().optional(),\n\t\t\t/** A byte array over the whole assembly, mapped or not. */\n\t\t\traw: z.string().optional(),\n\t\t}),\n\t),\n\t/**\n\t * Target paths of the driver's own state, such as a generated adapter's `eState`; absent means\n\t * the device's health is unknown.\n\t */\n\thealth: z\n\t\t.object({\n\t\t\tstate: z.string().optional(),\n\t\t\tstates: z.record(z.string(), z.number().int()).optional(),\n\t\t\tdiagnostic: z.string().optional(),\n\t\t\tmessage: z.string().optional(),\n\t\t})\n\t\t.optional(),\n\t/** Status symbols by label: hand-configured ones, and a generated Modbus server's error. */\n\tstatus: z.record(z.string(), z.string()).optional(),\n\tchannels: z.array(debugChannel),\n});\n\n/** A specialized function: one per method per instance, so `reads` resolve to concrete paths. */\nexport const debugFunction = z.object({\n\tid: z.number().int(),\n\tname: z.string(),\n\tdeclaration: sourceRange,\n\t/** The TypeScript path of `this`, for a method specialized to one instance. */\n\tinstance: z.string().optional(),\n\ttask: z.string().optional(),\n\ttarget: z.string(),\n\t/** Member reads in the body whose runtime path is static in this specialization. */\n\treads: z.array(z.object({ range: sourceRange, path: z.string() })),\n});\n\nexport const debugJob = z.object({\n\tid: z.number().int(),\n\tname: z.string(),\n\tdeclaration: sourceRange,\n\tinstance: z.string().optional(),\n\t/** The job's state, with fields `step`, `busy`, `done`, `error` and `cancelling`. */\n\ttarget: z.string(),\n\tsteps: z.array(\n\t\tz.object({\n\t\t\tstep: z.number().int(),\n\t\t\tkind: z.enum([\"await\", \"return\", \"throw\", \"statement\"]),\n\t\t\trange: sourceRange,\n\t\t\ttext: z.string(),\n\t\t}),\n\t),\n\t/**\n\t * The PLC clock in milliseconds when the job last started: the clock of telemetry records'\n\t * `time` and a batch's `now`.\n\t */\n\tstartedAt: z.string().optional(),\n\t/**\n\t * Service calls the job awaits, its nested jobs' included; `sequence` is the request counter sent\n\t * as `x-tsplc-request`, with `job`'s id when a nested job makes the call.\n\t */\n\trequests: z.array(\n\t\tz.object({\n\t\t\tservice: z.string(),\n\t\t\ttarget: z.string(),\n\t\t\tsequence: z.string(),\n\t\t\tjob: z.number().int().optional(),\n\t\t}),\n\t),\n\t/** Made by the compiler, such as a service call's own job; hidden unless asked for. */\n\tgenerated: z.literal(true).optional(),\n});\n\n/**\n * Where `debug.trace` records: an enum state field changing, a decision function returning a\n * different value, or a job starting or finishing. Trace records name their site by `id`.\n */\nexport const debugEventSite = z.object({\n\tid: z.number().int(),\n\tkind: z.enum([\"state\", \"decision\", \"job\"]),\n\t/** For `kind: \"job\"`: the job, and whether it starts or finishes at this site. */\n\tjob: z.number().int().optional(),\n\tphase: z.enum([\"started\", \"finished\"]).optional(),\n\t/** The TypeScript path written, or of the job. */\n\tpath: z.string(),\n\tfunction: z.number().int().optional(),\n\ttype: z.string(),\n\trange: sourceRange,\n\ttext: z.string(),\n\ttask: z.string(),\n\t/**\n\t * Guard values captured in the same scan, at the write: each `if` condition leaf enclosing it.\n\t * `stable` is false when the body between the guard and the write can change the leaf.\n\t */\n\toperands: z.array(\n\t\tz.object({\n\t\t\ttext: z.string(),\n\t\t\trange: sourceRange,\n\t\t\ttype: z.string(),\n\t\t\tpath: z.string().optional(),\n\t\t\tstable: z.boolean(),\n\t\t}),\n\t),\n});\n\n/** The statement that last wrote each output, per scan. */\nexport const debugWriter = z.object({\n\toutput: z.string(),\n\ttarget: z.string(),\n\tsites: z.array(\n\t\tz.object({\n\t\t\tid: z.number().int(),\n\t\t\trange: sourceRange,\n\t\t\tfunction: z.number().int(),\n\t\t}),\n\t),\n});\n\nexport const debugTask = z.object({\n\tname: z.string(),\n\tintervalMs: z.number(),\n\tpriority: z.number().int(),\n});\n\nexport const debugManifest = z.object({\n\tkind: z.literal(\"tsplc-debug\"),\n\tversion: z.literal(1),\n\tbuild: z.object({\n\t\tid: z.string(),\n\t\t/** A variable holding `id`, to tell which build the controller runs. */\n\t\ttarget: z.string(),\n\t\tcompiler: z.string(),\n\t}),\n\t/** Project-relative paths. */\n\tsources: z.array(z.string()),\n\ttypes: z.record(z.string(), debugType),\n\troots: z.array(debugRoot),\n\tconstants: z.array(debugConstant),\n\tio: z.array(debugIo),\n\tdevices: z.array(debugDevice),\n\tfunctions: z.array(debugFunction),\n\tjobs: z.array(debugJob),\n\tevents: z.array(debugEventSite),\n\twriters: z.array(debugWriter),\n\ttasks: z.array(debugTask),\n\t/** Job error codes by number: 1 cancelled, 2 timeout… */\n\terrors: z.record(z.string(), z.string()),\n});\n\nexport type SourceRange = z.infer<typeof sourceRange>;\nexport type DebugType = z.infer<typeof debugType>;\nexport type DebugField = z.infer<typeof debugField>;\nexport type DebugRoot = z.infer<typeof debugRoot>;\nexport type DebugConstant = z.infer<typeof debugConstant>;\nexport type DebugIo = z.infer<typeof debugIo>;\nexport type DebugDevice = z.infer<typeof debugDevice>;\nexport type DebugChannel = z.infer<typeof debugChannel>;\nexport type DebugFunction = z.infer<typeof debugFunction>;\nexport type DebugJob = z.infer<typeof debugJob>;\nexport type DebugEventSite = z.infer<typeof debugEventSite>;\nexport type DebugWriter = z.infer<typeof debugWriter>;\nexport type DebugTask = z.infer<typeof debugTask>;\nexport type DebugManifest = z.infer<typeof debugManifest>;\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";AAAA;AAUO,IAAM,cAAc,EAAE,OAAO;AAAA,
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "04D6881A2315B4F764756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/paths.js
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
// packages/debug/src/paths.ts
|
|
2
|
-
|
|
3
|
-
var
|
|
2
|
+
import { isArrayIndexSegment, symbolPathSegments } from "@tsplc/opcua/contract";
|
|
3
|
+
var anyIndex = "[*]";
|
|
4
|
+
var pathSegments = (path) => path.split(anyIndex).flatMap((part, index) => [
|
|
5
|
+
...index > 0 ? [anyIndex] : [],
|
|
6
|
+
...symbolPathSegments(part)
|
|
7
|
+
]);
|
|
4
8
|
var joinPath = (prefix, segment) => segment.startsWith("[") || !prefix ? `${prefix}${segment}` : `${prefix}.${segment}`;
|
|
5
9
|
var typeOf = (manifest, id) => manifest.types[id] ?? { kind: "scalar", iec: id };
|
|
6
10
|
var createPaths = (manifest) => {
|
|
7
11
|
const typeOfId = (id) => typeOf(manifest, id);
|
|
8
12
|
const bases = new Map([
|
|
9
13
|
...manifest.roots.map(({ path, ...root }) => [path, { kind: "target", path, ...root }]),
|
|
10
|
-
...manifest.io.map(({ path, target, type }) => [
|
|
14
|
+
...manifest.io.map(({ path, target, type }) => [
|
|
15
|
+
path,
|
|
16
|
+
{ kind: "target", path, target, type, readable: true }
|
|
17
|
+
])
|
|
11
18
|
]);
|
|
12
19
|
const constants = new Map(manifest.constants.map(({ path, ...constant }) => [
|
|
13
20
|
path,
|
|
@@ -18,28 +25,32 @@ var createPaths = (manifest) => {
|
|
|
18
25
|
let prefix = "";
|
|
19
26
|
for (const segment of pathSegments(path)) {
|
|
20
27
|
let children = groups.get(prefix);
|
|
21
|
-
if (!children)
|
|
28
|
+
if (!children) {
|
|
22
29
|
groups.set(prefix, children = new Set);
|
|
30
|
+
}
|
|
23
31
|
children.add(segment);
|
|
24
32
|
prefix = joinPath(prefix, segment);
|
|
25
33
|
}
|
|
26
34
|
}
|
|
27
35
|
const resolve = (path) => {
|
|
28
36
|
const constant = constants.get(path);
|
|
29
|
-
if (constant)
|
|
37
|
+
if (constant) {
|
|
30
38
|
return constant;
|
|
39
|
+
}
|
|
31
40
|
const segments = pathSegments(path);
|
|
32
41
|
for (let length = segments.length;length > 0; length--) {
|
|
33
42
|
const base = bases.get(segments.slice(0, length).reduce(joinPath, ""));
|
|
34
|
-
if (!base)
|
|
43
|
+
if (!base) {
|
|
35
44
|
continue;
|
|
45
|
+
}
|
|
36
46
|
let resolved = base;
|
|
37
47
|
for (const segment of segments.slice(length)) {
|
|
38
48
|
const type = typeOfId(resolved.type);
|
|
39
49
|
if (type.kind === "record") {
|
|
40
50
|
const field = type.fields.find(({ name }) => name === segment);
|
|
41
|
-
if (!field)
|
|
51
|
+
if (!field) {
|
|
42
52
|
return;
|
|
53
|
+
}
|
|
43
54
|
resolved = {
|
|
44
55
|
kind: "target",
|
|
45
56
|
path: joinPath(resolved.path, segment),
|
|
@@ -50,32 +61,42 @@ var createPaths = (manifest) => {
|
|
|
50
61
|
...field.declaration && { declaration: field.declaration }
|
|
51
62
|
};
|
|
52
63
|
} else if (type.kind === "array") {
|
|
53
|
-
|
|
54
|
-
|
|
64
|
+
if (!isArrayIndexSegment(segment)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const index = Number(segment.slice(1, -1));
|
|
68
|
+
if (index < type.lower || index >= type.lower + type.length) {
|
|
55
69
|
return;
|
|
70
|
+
}
|
|
56
71
|
resolved = {
|
|
57
72
|
kind: "target",
|
|
58
73
|
path: joinPath(resolved.path, segment),
|
|
59
|
-
target: `${resolved.target}
|
|
74
|
+
target: `${resolved.target}${segment}`,
|
|
60
75
|
type: type.element,
|
|
61
76
|
readable: resolved.readable
|
|
62
77
|
};
|
|
63
|
-
} else
|
|
78
|
+
} else {
|
|
64
79
|
return;
|
|
80
|
+
}
|
|
65
81
|
}
|
|
66
82
|
return resolved;
|
|
67
83
|
}
|
|
68
84
|
};
|
|
69
85
|
const typedChildren = (resolved) => {
|
|
70
86
|
const type = resolved?.kind === "target" ? typeOfId(resolved.type) : undefined;
|
|
71
|
-
if (type?.kind === "record")
|
|
87
|
+
if (type?.kind === "record") {
|
|
72
88
|
return type.fields.map(({ name }) => name);
|
|
73
|
-
|
|
89
|
+
}
|
|
90
|
+
if (type?.kind === "array") {
|
|
74
91
|
return Array.from({ length: type.length }, (_, index) => `[${type.lower + index}]`);
|
|
92
|
+
}
|
|
75
93
|
return [];
|
|
76
94
|
};
|
|
77
95
|
const children = (path) => {
|
|
78
|
-
const names = [
|
|
96
|
+
const names = [
|
|
97
|
+
...typedChildren(resolve(path)),
|
|
98
|
+
...groups.get(path) ?? []
|
|
99
|
+
];
|
|
79
100
|
return [...new Set(names)].map((name) => {
|
|
80
101
|
const child = joinPath(path, name);
|
|
81
102
|
return { name, ...resolve(child) ?? { kind: "group", path: child } };
|
|
@@ -86,43 +107,54 @@ var createPaths = (manifest) => {
|
|
|
86
107
|
const leaves = new Set;
|
|
87
108
|
const add = (path) => {
|
|
88
109
|
leaves.add(path);
|
|
89
|
-
if (leaves.size > limit)
|
|
110
|
+
if (leaves.size > limit) {
|
|
90
111
|
throw new RangeError(`More than ${limit} values match`);
|
|
112
|
+
}
|
|
91
113
|
};
|
|
92
114
|
const below = (node) => {
|
|
93
|
-
if (isLeaf(node))
|
|
115
|
+
if (isLeaf(node)) {
|
|
94
116
|
return add(node.path);
|
|
95
|
-
|
|
96
|
-
|
|
117
|
+
}
|
|
118
|
+
for (const child of children(node.path)) {
|
|
119
|
+
if (!(child.kind === "target" && child.generated)) {
|
|
97
120
|
below(child);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
98
123
|
};
|
|
99
124
|
const match = (prefix, rest, wildcard) => {
|
|
100
125
|
const [head, ...tail] = rest;
|
|
101
126
|
if (head === undefined) {
|
|
102
127
|
const node = resolve(prefix) ?? (groups.has(prefix) ? { kind: "group", path: prefix } : undefined);
|
|
103
|
-
if (node)
|
|
128
|
+
if (node) {
|
|
104
129
|
below(node);
|
|
105
|
-
else if (!wildcard)
|
|
130
|
+
} else if (!wildcard) {
|
|
106
131
|
add(prefix);
|
|
132
|
+
}
|
|
107
133
|
return;
|
|
108
134
|
}
|
|
109
|
-
if (head === "*" || head ===
|
|
110
|
-
for (const child of children(prefix))
|
|
111
|
-
if (!(child.kind === "target" && child.generated) && (head === "*" || child.name.startsWith("[")))
|
|
135
|
+
if (head === "*" || head === anyIndex) {
|
|
136
|
+
for (const child of children(prefix)) {
|
|
137
|
+
if (!(child.kind === "target" && child.generated) && (head === "*" || child.name.startsWith("["))) {
|
|
112
138
|
match(child.path, tail, true);
|
|
113
|
-
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
114
142
|
match(joinPath(prefix, head), tail, wildcard);
|
|
143
|
+
}
|
|
115
144
|
};
|
|
116
|
-
for (const pattern of patterns)
|
|
145
|
+
for (const pattern of patterns) {
|
|
117
146
|
match("", pathSegments(pattern), false);
|
|
147
|
+
}
|
|
118
148
|
return [...leaves];
|
|
119
149
|
};
|
|
120
150
|
const decode = (typeId, raw) => {
|
|
121
151
|
const type = typeOfId(typeId);
|
|
122
|
-
if (type.kind === "enum")
|
|
152
|
+
if (type.kind === "enum") {
|
|
123
153
|
return Object.entries(type.members).find(([, value]) => value === raw)?.[0] ?? raw;
|
|
124
|
-
|
|
154
|
+
}
|
|
155
|
+
if (type.kind === "scalar" && type.iec === "BOOL" && typeof raw === "number") {
|
|
125
156
|
return raw !== 0;
|
|
157
|
+
}
|
|
126
158
|
return raw;
|
|
127
159
|
};
|
|
128
160
|
return { typeOf: typeOfId, resolve, children, isLeaf, expand, decode };
|
|
@@ -134,5 +166,5 @@ export {
|
|
|
134
166
|
typeOf
|
|
135
167
|
};
|
|
136
168
|
|
|
137
|
-
//# debugId=
|
|
169
|
+
//# debugId=851AF08441CF4B4164756E2164756E21
|
|
138
170
|
//# sourceMappingURL=paths.js.map
|
package/dist/paths.js.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/paths.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type { DebugManifest, DebugType, SourceRange } from \"./manifest.ts\";\n\n/**\n * TypeScript paths over a manifest: `program.diverters.binTrackers[10].bin` names a root\n * (`program.diverters`), then record fields and array indexes. Pure, so the browser UI can use it.\n */\n\n/** A path that reads a target, or a constant the compiler folded. */\nexport type ResolvedPath =\n
|
|
5
|
+
"import { isArrayIndexSegment, symbolPathSegments } from \"@tsplc/opcua/contract\";\nimport type { DebugManifest, DebugType, SourceRange } from \"./manifest.ts\";\n\n/**\n * TypeScript paths over a manifest: `program.diverters.binTrackers[10].bin` names a root\n * (`program.diverters`), then record fields and array indexes. Pure, so the browser UI can use it.\n */\n\n/** A path that reads a target, or a constant the compiler folded. */\nexport type ResolvedPath =\n\t| {\n\t\t\tkind: \"target\";\n\t\t\tpath: string;\n\t\t\ttarget: string;\n\t\t\ttype: string;\n\t\t\treadable: boolean;\n\t\t\tgenerated?: true;\n\t\t\tdeclaration?: SourceRange;\n\t }\n\t| {\n\t\t\tkind: \"constant\";\n\t\t\tpath: string;\n\t\t\ttype: string;\n\t\t\tvalue: unknown;\n\t\t\tdeclaration?: SourceRange;\n\t };\n\n/** Roots or constants that share a prefix, such as `program` above `program.diverters`. */\ninterface GroupPath {\n\tkind: \"group\";\n\tpath: string;\n}\n\n/** A child in the instance tree. */\nexport type PathNode = { name: string } & (ResolvedPath | GroupPath);\n\n/** In a pattern, every index of an array. */\nconst anyIndex = \"[*]\";\n\n/** Names and indexes as the controller's symbol paths split them, and `[*]` in patterns. */\nexport const pathSegments = (path: string) =>\n\tpath\n\t\t.split(anyIndex)\n\t\t.flatMap((part, index) => [\n\t\t\t...(index > 0 ? [anyIndex] : []),\n\t\t\t...symbolPathSegments(part),\n\t\t]);\n\nexport const joinPath = (prefix: string, segment: string) =>\n\tsegment.startsWith(\"[\") || !prefix\n\t\t? `${prefix}${segment}`\n\t\t: `${prefix}.${segment}`;\n\n/** Scalar type ids are their IEC names, and may have no entry in `types`. */\nexport const typeOf = (manifest: DebugManifest, id: string): DebugType =>\n\tmanifest.types[id] ?? { kind: \"scalar\", iec: id };\n\nexport const createPaths = (manifest: DebugManifest) => {\n\tconst typeOfId = (id: string) => typeOf(manifest, id);\n\t// I/O bindings are readable symbols with TypeScript paths of their own.\n\tconst bases = new Map<string, Extract<ResolvedPath, { kind: \"target\" }>>([\n\t\t...manifest.roots.map(\n\t\t\t({ path, ...root }) =>\n\t\t\t\t[path, { kind: \"target\" as const, path, ...root }] as const,\n\t\t),\n\t\t...manifest.io.map(\n\t\t\t({ path, target, type }) =>\n\t\t\t\t[\n\t\t\t\t\tpath,\n\t\t\t\t\t{ kind: \"target\" as const, path, target, type, readable: true },\n\t\t\t\t] as const,\n\t\t),\n\t]);\n\tconst constants = new Map(\n\t\tmanifest.constants.map(({ path, ...constant }) => [\n\t\t\tpath,\n\t\t\t{ kind: \"constant\" as const, path, ...constant },\n\t\t]),\n\t);\n\t/** Children of the prefixes of every root and constant path, which are groups unless they resolve. */\n\tconst groups = new Map<string, Set<string>>();\n\tfor (const path of [...bases.keys(), ...constants.keys()]) {\n\t\tlet prefix = \"\";\n\t\tfor (const segment of pathSegments(path)) {\n\t\t\tlet children = groups.get(prefix);\n\t\t\tif (!children) {\n\t\t\t\tgroups.set(prefix, (children = new Set()));\n\t\t\t}\n\t\t\tchildren.add(segment);\n\t\t\tprefix = joinPath(prefix, segment);\n\t\t}\n\t}\n\n\tconst resolve = (path: string): ResolvedPath | undefined => {\n\t\tconst constant = constants.get(path);\n\t\tif (constant) {\n\t\t\treturn constant;\n\t\t}\n\t\tconst segments = pathSegments(path);\n\t\tfor (let length = segments.length; length > 0; length--) {\n\t\t\tconst base = bases.get(segments.slice(0, length).reduce(joinPath, \"\"));\n\t\t\tif (!base) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet resolved: ResolvedPath = base;\n\t\t\tfor (const segment of segments.slice(length)) {\n\t\t\t\tconst type = typeOfId(resolved.type);\n\t\t\t\tif (type.kind === \"record\") {\n\t\t\t\t\tconst field = type.fields.find(({ name }) => name === segment);\n\t\t\t\t\tif (!field) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tresolved = {\n\t\t\t\t\t\tkind: \"target\",\n\t\t\t\t\t\tpath: joinPath(resolved.path, segment),\n\t\t\t\t\t\ttarget: `${resolved.target}.${field.target}`,\n\t\t\t\t\t\ttype: field.type,\n\t\t\t\t\t\treadable: resolved.readable,\n\t\t\t\t\t\t...(field.generated && { generated: true }),\n\t\t\t\t\t\t...(field.declaration && { declaration: field.declaration }),\n\t\t\t\t\t};\n\t\t\t\t} else if (type.kind === \"array\") {\n\t\t\t\t\tif (!isArrayIndexSegment(segment)) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst index = Number(segment.slice(1, -1));\n\t\t\t\t\tif (index < type.lower || index >= type.lower + type.length) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tresolved = {\n\t\t\t\t\t\tkind: \"target\",\n\t\t\t\t\t\tpath: joinPath(resolved.path, segment),\n\t\t\t\t\t\ttarget: `${resolved.target}${segment}`,\n\t\t\t\t\t\ttype: type.element,\n\t\t\t\t\t\treadable: resolved.readable,\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn resolved;\n\t\t}\n\t};\n\n\tconst typedChildren = (resolved: ResolvedPath | undefined) => {\n\t\tconst type =\n\t\t\tresolved?.kind === \"target\" ? typeOfId(resolved.type) : undefined;\n\t\tif (type?.kind === \"record\") {\n\t\t\treturn type.fields.map(({ name }) => name);\n\t\t}\n\t\tif (type?.kind === \"array\") {\n\t\t\treturn Array.from(\n\t\t\t\t{ length: type.length },\n\t\t\t\t(_, index) => `[${type.lower + index}]`,\n\t\t\t);\n\t\t}\n\t\treturn [];\n\t};\n\n\t/** A path's fields or indexes, and the roots and constants below it. */\n\tconst children = (path: string): PathNode[] => {\n\t\tconst names = [\n\t\t\t...typedChildren(resolve(path)),\n\t\t\t...(groups.get(path) ?? []),\n\t\t];\n\t\treturn [...new Set(names)].map((name) => {\n\t\t\tconst child = joinPath(path, name);\n\t\t\treturn { name, ...(resolve(child) ?? { kind: \"group\", path: child }) };\n\t\t});\n\t};\n\n\tconst isLeaf = (node: ResolvedPath | GroupPath) =>\n\t\tnode.kind === \"constant\" ||\n\t\t(node.kind === \"target\" &&\n\t\t\t[\"scalar\", \"enum\"].includes(typeOfId(node.type).kind));\n\n\t/**\n\t * Leaf paths matching `patterns`, where `*` stands for one segment. A pattern naming a record,\n\t * array or group stands for all its leaves; wildcards and expansion skip compiler-made fields.\n\t * Paths that don't resolve are kept, so callers can report them.\n\t */\n\tconst expand = (patterns: readonly string[], limit = 2000) => {\n\t\tconst leaves = new Set<string>();\n\t\tconst add = (path: string) => {\n\t\t\tleaves.add(path);\n\t\t\tif (leaves.size > limit) {\n\t\t\t\tthrow new RangeError(`More than ${limit} values match`);\n\t\t\t}\n\t\t};\n\t\tconst below = (node: ResolvedPath | GroupPath) => {\n\t\t\tif (isLeaf(node)) {\n\t\t\t\treturn add(node.path);\n\t\t\t}\n\t\t\tfor (const child of children(node.path)) {\n\t\t\t\tif (!(child.kind === \"target\" && child.generated)) {\n\t\t\t\t\tbelow(child);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tconst match = (\n\t\t\tprefix: string,\n\t\t\trest: readonly string[],\n\t\t\twildcard: boolean,\n\t\t) => {\n\t\t\tconst [head, ...tail] = rest;\n\t\t\tif (head === undefined) {\n\t\t\t\tconst node: ResolvedPath | GroupPath | undefined =\n\t\t\t\t\tresolve(prefix) ??\n\t\t\t\t\t(groups.has(prefix) ? { kind: \"group\", path: prefix } : undefined);\n\t\t\t\tif (node) {\n\t\t\t\t\tbelow(node);\n\t\t\t\t} else if (!wildcard) {\n\t\t\t\t\tadd(prefix);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (head === \"*\" || head === anyIndex) {\n\t\t\t\tfor (const child of children(prefix)) {\n\t\t\t\t\tif (\n\t\t\t\t\t\t!(child.kind === \"target\" && child.generated) &&\n\t\t\t\t\t\t(head === \"*\" || child.name.startsWith(\"[\"))\n\t\t\t\t\t) {\n\t\t\t\t\t\tmatch(child.path, tail, true);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tmatch(joinPath(prefix, head), tail, wildcard);\n\t\t\t}\n\t\t};\n\t\tfor (const pattern of patterns) {\n\t\t\tmatch(\"\", pathSegments(pattern), false);\n\t\t}\n\t\treturn [...leaves];\n\t};\n\n\t/** A value as TypeScript shows it: enum members by name, BOOL as a boolean. */\n\tconst decode = (typeId: string, raw: unknown) => {\n\t\tconst type = typeOfId(typeId);\n\t\tif (type.kind === \"enum\") {\n\t\t\treturn (\n\t\t\t\tObject.entries(type.members).find(([, value]) => value === raw)?.[0] ??\n\t\t\t\traw\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\ttype.kind === \"scalar\" &&\n\t\t\ttype.iec === \"BOOL\" &&\n\t\t\ttypeof raw === \"number\"\n\t\t) {\n\t\t\treturn raw !== 0;\n\t\t}\n\t\treturn raw;\n\t};\n\n\treturn { typeOf: typeOfId, resolve, children, isLeaf, expand, decode };\n};\n\nexport type Paths = ReturnType<typeof createPaths>;\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "851AF08441CF4B4164756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/package.json
CHANGED
|
@@ -1,48 +1,49 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
2
|
+
"name": "@tsplc/debug",
|
|
3
|
+
"version": "0.2.19",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"description": "Debugger for tsPLC programs: live TypeScript variables, hardware, async jobs, backend requests and the program's recent telemetry.",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/rip-technologies/tsplc.git",
|
|
10
|
+
"directory": "packages/debug"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./src/index.ts",
|
|
15
|
+
"bun": "./src/index.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./manifest": {
|
|
19
|
+
"types": "./src/manifest.ts",
|
|
20
|
+
"bun": "./src/manifest.ts",
|
|
21
|
+
"default": "./dist/manifest.js"
|
|
22
|
+
},
|
|
23
|
+
"./format": {
|
|
24
|
+
"types": "./src/ui/format.ts",
|
|
25
|
+
"bun": "./src/ui/format.ts",
|
|
26
|
+
"default": "./dist/format.js"
|
|
27
|
+
},
|
|
28
|
+
"./paths": {
|
|
29
|
+
"types": "./src/paths.ts",
|
|
30
|
+
"bun": "./src/paths.ts",
|
|
31
|
+
"default": "./dist/paths.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"src",
|
|
37
|
+
"!**/*.test.ts"
|
|
38
|
+
],
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@tsplc/config": "0.2.19",
|
|
44
|
+
"@tsplc/opcua": "0.2.19",
|
|
45
|
+
"@tsplc/server": "0.2.19",
|
|
46
|
+
"zod": "4.3.6",
|
|
47
|
+
"@tsplc/iec": "0.2.19"
|
|
48
|
+
}
|
|
48
49
|
}
|
package/src/adapter.ts
CHANGED
|
@@ -3,31 +3,38 @@ import type { DebugType } from "./manifest.ts";
|
|
|
3
3
|
|
|
4
4
|
/** One target's value, before the debugger names it by TypeScript path and decodes it. */
|
|
5
5
|
export interface TargetSample {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
value: unknown;
|
|
7
|
+
quality: Quality;
|
|
8
|
+
status: string;
|
|
9
|
+
receivedAt: string;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
/** A target to read, with its type in the manifest, which an adapter may need to parse it. */
|
|
13
13
|
export interface TargetRead {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
target: string;
|
|
15
|
+
type: DebugType;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const qualityRank: Record<Quality, number> = {
|
|
18
|
+
const qualityRank: Record<Quality, number> = {
|
|
19
|
+
good: 0,
|
|
20
|
+
uncertain: 1,
|
|
21
|
+
bad: 2,
|
|
22
|
+
unavailable: 3,
|
|
23
|
+
};
|
|
19
24
|
|
|
20
25
|
/** The worst of these qualities; nothing read is unavailable. */
|
|
21
|
-
export const worstQuality = (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
export const worstQuality = (
|
|
27
|
+
samples: readonly (TargetSample | undefined)[],
|
|
28
|
+
): Quality =>
|
|
29
|
+
samples.reduce<Quality>((worst, sample) => {
|
|
30
|
+
const quality = sample?.quality ?? "unavailable";
|
|
31
|
+
return qualityRank[quality] > qualityRank[worst] ? quality : worst;
|
|
32
|
+
}, "good");
|
|
26
33
|
|
|
27
34
|
export interface Connection {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
state: ConnectionState;
|
|
36
|
+
since: string;
|
|
37
|
+
error?: string;
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
/**
|
|
@@ -35,25 +42,25 @@ export interface Connection {
|
|
|
35
42
|
* the manifest (for CODESYS, IEC symbol paths). It never writes.
|
|
36
43
|
*/
|
|
37
44
|
export interface TargetAdapter {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
45
|
+
/** How it reads, for display, such as "engineering login". */
|
|
46
|
+
readonly method: string;
|
|
47
|
+
/** Where it reads, for display. */
|
|
48
|
+
readonly endpoint: string;
|
|
49
|
+
/** How often subscribed targets are read; a value is at most about this old while connected. */
|
|
50
|
+
readonly samplingMs: number;
|
|
51
|
+
connection(): Connection;
|
|
52
|
+
onConnection(listener: (connection: Connection) => void): () => void;
|
|
53
|
+
/** Reads targets now; fails while disconnected. Targets that can't be read come back bad or unavailable. */
|
|
54
|
+
read(targets: readonly TargetRead[]): Promise<Map<string, TargetSample>>;
|
|
55
|
+
/**
|
|
56
|
+
* Calls `listener` with each target's value, about every `intervalMs` (`samplingMs` by
|
|
57
|
+
* default) or on every change, across reconnects, until the returned function is called. While
|
|
58
|
+
* disconnected each target is reported unavailable or bad.
|
|
59
|
+
*/
|
|
60
|
+
subscribe(
|
|
61
|
+
targets: readonly TargetRead[],
|
|
62
|
+
listener: (target: string, sample: TargetSample) => void,
|
|
63
|
+
intervalMs?: number,
|
|
64
|
+
): () => void;
|
|
65
|
+
close(): Promise<void>;
|
|
59
66
|
}
|