@tsplc/debug 0.0.0-stage → 0.2.16
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 +121 -0
- package/dist/format.js.map +11 -0
- package/dist/index.js +1681 -0
- package/dist/index.js.map +24 -0
- package/dist/manifest.js +201 -0
- package/dist/manifest.js.map +10 -0
- package/dist/paths.js +138 -0
- package/dist/paths.js.map +10 -0
- package/package.json +46 -4
- package/src/adapter.ts +59 -0
- package/src/api.ts +183 -0
- package/src/debugger.ts +509 -0
- package/src/hardware.ts +125 -0
- package/src/http.ts +155 -0
- package/src/index.ts +8 -0
- package/src/jobs.ts +115 -0
- package/src/login.ts +284 -0
- package/src/manifest.ts +271 -0
- package/src/opcua.ts +69 -0
- package/src/paths.ts +185 -0
- package/src/telemetry.ts +110 -0
- package/src/timeline.ts +78 -0
- package/src/trace.ts +45 -0
- package/src/ui/bits.ts +41 -0
- package/src/ui/client.ts +48 -0
- package/src/ui/dev.ts +579 -0
- package/src/ui/dom.ts +168 -0
- package/src/ui/fixture.ts +548 -0
- package/src/ui/format.ts +125 -0
- package/src/ui/hardware.ts +368 -0
- package/src/ui/header.ts +179 -0
- package/src/ui/index.ts +20 -0
- package/src/ui/jobs.ts +249 -0
- package/src/ui/main.ts +74 -0
- package/src/ui/overview.ts +123 -0
- package/src/ui/page.ts +178 -0
- package/src/ui/recent.ts +322 -0
- package/src/ui/requests.ts +81 -0
- package/src/ui/store.ts +227 -0
- package/src/ui/tree.ts +156 -0
- package/src/ui/variables.ts +469 -0
- package/src/watch.ts +32 -0
- package/README.md +0 -3
package/dist/format.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// packages/debug/src/paths.ts
|
|
2
|
+
var typeOf = (manifest, id) => manifest.types[id] ?? { kind: "scalar", iec: id };
|
|
3
|
+
|
|
4
|
+
// packages/debug/src/ui/format.ts
|
|
5
|
+
var valueStateLabels = {
|
|
6
|
+
live: "good",
|
|
7
|
+
uncertain: "uncertain",
|
|
8
|
+
bad: "bad",
|
|
9
|
+
stale: "stale",
|
|
10
|
+
unavailable: "unavailable",
|
|
11
|
+
constant: "constant"
|
|
12
|
+
};
|
|
13
|
+
var valueState = (quality, ageMs, context) => {
|
|
14
|
+
if (quality === "unavailable")
|
|
15
|
+
return "unavailable";
|
|
16
|
+
if (!context.connected || ageMs > 3 * context.intervalMs)
|
|
17
|
+
return "stale";
|
|
18
|
+
if (quality === "bad")
|
|
19
|
+
return "bad";
|
|
20
|
+
if (quality === "uncertain")
|
|
21
|
+
return "uncertain";
|
|
22
|
+
return "live";
|
|
23
|
+
};
|
|
24
|
+
var formatAge = (ms) => {
|
|
25
|
+
if (ms < 1000)
|
|
26
|
+
return "now";
|
|
27
|
+
if (ms < 60000)
|
|
28
|
+
return `${Math.floor(ms / 1000)} s ago`;
|
|
29
|
+
if (ms < 3600000)
|
|
30
|
+
return `${Math.floor(ms / 60000)} min ago`;
|
|
31
|
+
return `${Math.floor(ms / 3600000)} h ago`;
|
|
32
|
+
};
|
|
33
|
+
var formatDuration = (ms) => {
|
|
34
|
+
if (ms < 1000)
|
|
35
|
+
return `${Math.round(ms)} ms`;
|
|
36
|
+
if (ms < 60000)
|
|
37
|
+
return `${(ms / 1000).toFixed(1)} s`;
|
|
38
|
+
return `${Math.floor(ms / 60000)} min ${Math.floor(ms % 60000 / 1000)} s`;
|
|
39
|
+
};
|
|
40
|
+
var formatInterval = (ms) => ms < 1000 ? `${ms} ms` : `${ms / 1000} s`;
|
|
41
|
+
var formatClock = (iso) => {
|
|
42
|
+
const date = new Date(iso);
|
|
43
|
+
const pad = (value, width = 2) => String(value).padStart(width, "0");
|
|
44
|
+
return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}.${pad(date.getMilliseconds(), 3)}`;
|
|
45
|
+
};
|
|
46
|
+
var formatReadAt = (iso) => `read ${formatClock(iso).slice(0, 8)}`;
|
|
47
|
+
var formatScalar = (value) => {
|
|
48
|
+
if (typeof value === "boolean")
|
|
49
|
+
return value ? "TRUE" : "FALSE";
|
|
50
|
+
if (typeof value === "number")
|
|
51
|
+
return Number.isInteger(value) ? String(value) : String(Number(value.toPrecision(6)));
|
|
52
|
+
if (typeof value === "string")
|
|
53
|
+
return JSON.stringify(value);
|
|
54
|
+
if (value === null || value === undefined)
|
|
55
|
+
return "—";
|
|
56
|
+
return JSON.stringify(value);
|
|
57
|
+
};
|
|
58
|
+
var formatValue = (manifest, typeId, value) => {
|
|
59
|
+
const type = typeOf(manifest, typeId);
|
|
60
|
+
if (type.kind !== "enum")
|
|
61
|
+
return formatScalar(value);
|
|
62
|
+
if (typeof value === "string" && Object.hasOwn(type.members, value))
|
|
63
|
+
return value;
|
|
64
|
+
if (typeof value !== "number")
|
|
65
|
+
return formatScalar(value);
|
|
66
|
+
const member = Object.entries(type.members).find(([, number]) => number === value)?.[0];
|
|
67
|
+
return member ?? `${value} (not a ${type.name})`;
|
|
68
|
+
};
|
|
69
|
+
var typeLabel = (manifest, typeId) => {
|
|
70
|
+
const type = typeOf(manifest, typeId);
|
|
71
|
+
switch (type.kind) {
|
|
72
|
+
case "scalar":
|
|
73
|
+
return type.iec;
|
|
74
|
+
case "enum":
|
|
75
|
+
case "record":
|
|
76
|
+
return type.name;
|
|
77
|
+
case "array":
|
|
78
|
+
return `${typeLabel(manifest, type.element)}[${type.length}]`;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
var PROPERTY_TEXT = 16;
|
|
82
|
+
var formatProperties = (properties) => Object.entries(properties).map(([key, value]) => {
|
|
83
|
+
const text = typeof value === "string" ? value : formatScalar(value);
|
|
84
|
+
return `${key}=${text.length > PROPERTY_TEXT ? `${text.slice(0, PROPERTY_TEXT)}…` : text}`;
|
|
85
|
+
}).join(" ");
|
|
86
|
+
var fileHref = (projectRoot, file, line, column) => {
|
|
87
|
+
if (projectRoot === undefined)
|
|
88
|
+
return;
|
|
89
|
+
const root = projectRoot.replaceAll("\\", "/").replace(/\/$/, "");
|
|
90
|
+
const absolute = `${root}/${file}`.replace(/^\/?/, "/");
|
|
91
|
+
return `vscode://file${absolute}:${line}:${column}`;
|
|
92
|
+
};
|
|
93
|
+
var sourceLocation = (manifest, projectRoot, range) => {
|
|
94
|
+
const file = manifest.sources[range.file] ?? `source ${range.file}`;
|
|
95
|
+
const href = fileHref(projectRoot, file, range.line, range.column);
|
|
96
|
+
return { label: `${file}:${range.line}`, ...href && { href } };
|
|
97
|
+
};
|
|
98
|
+
var recordLocation = (projectRoot, source) => {
|
|
99
|
+
const [, file = source, line] = /^(.*):(\d+)$/.exec(source) ?? [];
|
|
100
|
+
const label = `${file.slice(file.lastIndexOf("/") + 1)}${line ? `:${line}` : ""}`;
|
|
101
|
+
const href = line === undefined ? undefined : fileHref(projectRoot, file, Number(line), 1);
|
|
102
|
+
return { label, ...href && { href } };
|
|
103
|
+
};
|
|
104
|
+
export {
|
|
105
|
+
formatAge,
|
|
106
|
+
formatClock,
|
|
107
|
+
formatDuration,
|
|
108
|
+
formatInterval,
|
|
109
|
+
formatProperties,
|
|
110
|
+
formatReadAt,
|
|
111
|
+
formatScalar,
|
|
112
|
+
formatValue,
|
|
113
|
+
recordLocation,
|
|
114
|
+
sourceLocation,
|
|
115
|
+
typeLabel,
|
|
116
|
+
valueState,
|
|
117
|
+
valueStateLabels
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
//# debugId=78E800313C3FB5FD64756E2164756E21
|
|
121
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/paths.ts", "../src/ui/format.ts"],
|
|
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 | {\n kind: \"target\";\n path: string;\n target: string;\n type: string;\n readable: boolean;\n generated?: true;\n declaration?: SourceRange;\n }\n | { kind: \"constant\"; path: string; type: string; value: unknown; declaration?: SourceRange };\n\n/** Roots or constants that share a prefix, such as `program` above `program.diverters`. */\ninterface GroupPath {\n kind: \"group\";\n path: string;\n}\n\n/** A child in the instance tree. */\nexport type PathNode = { name: string } & (ResolvedPath | GroupPath);\n\nconst segmentPattern = /[^.[\\]]+|\\[(?:-?\\d+|\\*)\\]/g;\n\nexport const pathSegments = (path: string) => path.match(segmentPattern) ?? [];\n\nexport const joinPath = (prefix: string, segment: string) =>\n segment.startsWith(\"[\") || !prefix ? `${prefix}${segment}` : `${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 manifest.types[id] ?? { kind: \"scalar\", iec: id };\n\nexport const createPaths = (manifest: DebugManifest) => {\n const typeOfId = (id: string) => typeOf(manifest, id);\n // I/O bindings are readable symbols with TypeScript paths of their own.\n const bases = new Map<string, Extract<ResolvedPath, { kind: \"target\" }>>([\n ...manifest.roots.map(\n ({ path, ...root }) => [path, { kind: \"target\" as const, path, ...root }] as const,\n ),\n ...manifest.io.map(\n ({ path, target, type }) =>\n [path, { kind: \"target\" as const, path, target, type, readable: true }] as const,\n ),\n ]);\n const constants = new Map(\n manifest.constants.map(({ path, ...constant }) => [\n path,\n { kind: \"constant\" as const, path, ...constant },\n ]),\n );\n /** Children of the prefixes of every root and constant path, which are groups unless they resolve. */\n const groups = new Map<string, Set<string>>();\n for (const path of [...bases.keys(), ...constants.keys()]) {\n let prefix = \"\";\n for (const segment of pathSegments(path)) {\n let children = groups.get(prefix);\n if (!children) groups.set(prefix, (children = new Set()));\n children.add(segment);\n prefix = joinPath(prefix, segment);\n }\n }\n\n const resolve = (path: string): ResolvedPath | undefined => {\n const constant = constants.get(path);\n if (constant) return constant;\n const segments = pathSegments(path);\n for (let length = segments.length; length > 0; length--) {\n const base = bases.get(segments.slice(0, length).reduce(joinPath, \"\"));\n if (!base) continue;\n let resolved: ResolvedPath = base;\n for (const segment of segments.slice(length)) {\n const type = typeOfId(resolved.type);\n if (type.kind === \"record\") {\n const field = type.fields.find(({ name }) => name === segment);\n if (!field) return;\n resolved = {\n kind: \"target\",\n path: joinPath(resolved.path, segment),\n target: `${resolved.target}.${field.target}`,\n type: field.type,\n readable: resolved.readable,\n ...(field.generated && { generated: true }),\n ...(field.declaration && { declaration: field.declaration }),\n };\n } else if (type.kind === \"array\") {\n const index = /^\\[(-?\\d+)\\]$/.exec(segment)?.[1];\n if (\n index === undefined ||\n Number(index) < type.lower ||\n Number(index) >= type.lower + type.length\n )\n return;\n resolved = {\n kind: \"target\",\n path: joinPath(resolved.path, segment),\n target: `${resolved.target}[${index}]`,\n type: type.element,\n readable: resolved.readable,\n };\n } else return;\n }\n return resolved;\n }\n };\n\n const typedChildren = (resolved: ResolvedPath | undefined) => {\n const type = resolved?.kind === \"target\" ? typeOfId(resolved.type) : undefined;\n if (type?.kind === \"record\") return type.fields.map(({ name }) => name);\n if (type?.kind === \"array\")\n return Array.from({ length: type.length }, (_, index) => `[${type.lower + index}]`);\n return [];\n };\n\n /** A path's fields or indexes, and the roots and constants below it. */\n const children = (path: string): PathNode[] => {\n const names = [...typedChildren(resolve(path)), ...(groups.get(path) ?? [])];\n return [...new Set(names)].map((name) => {\n const child = joinPath(path, name);\n return { name, ...(resolve(child) ?? { kind: \"group\", path: child }) };\n });\n };\n\n const isLeaf = (node: ResolvedPath | GroupPath) =>\n node.kind === \"constant\" ||\n (node.kind === \"target\" && [\"scalar\", \"enum\"].includes(typeOfId(node.type).kind));\n\n /**\n * Leaf paths matching `patterns`, where `*` stands for one segment. A pattern naming a record,\n * array or group stands for all its leaves; wildcards and expansion skip compiler-made fields.\n * Paths that don't resolve are kept, so callers can report them.\n */\n const expand = (patterns: readonly string[], limit = 2000) => {\n const leaves = new Set<string>();\n const add = (path: string) => {\n leaves.add(path);\n if (leaves.size > limit) throw new RangeError(`More than ${limit} values match`);\n };\n const below = (node: ResolvedPath | GroupPath) => {\n if (isLeaf(node)) return add(node.path);\n for (const child of children(node.path))\n if (!(child.kind === \"target\" && child.generated)) below(child);\n };\n const match = (prefix: string, rest: readonly string[], wildcard: boolean) => {\n const [head, ...tail] = rest;\n if (head === undefined) {\n const node: ResolvedPath | GroupPath | undefined =\n resolve(prefix) ?? (groups.has(prefix) ? { kind: \"group\", path: prefix } : undefined);\n if (node) below(node);\n else if (!wildcard) add(prefix);\n return;\n }\n if (head === \"*\" || head === \"[*]\") {\n for (const child of children(prefix))\n if (\n !(child.kind === \"target\" && child.generated) &&\n (head === \"*\" || child.name.startsWith(\"[\"))\n )\n match(child.path, tail, true);\n } else match(joinPath(prefix, head), tail, wildcard);\n };\n for (const pattern of patterns) match(\"\", pathSegments(pattern), false);\n return [...leaves];\n };\n\n /** A value as TypeScript shows it: enum members by name, BOOL as a boolean. */\n const decode = (typeId: string, raw: unknown) => {\n const type = typeOfId(typeId);\n if (type.kind === \"enum\")\n return Object.entries(type.members).find(([, value]) => value === raw)?.[0] ?? raw;\n if (type.kind === \"scalar\" && type.iec === \"BOOL\" && typeof raw === \"number\") return raw !== 0;\n return raw;\n };\n\n return { typeOf: typeOfId, resolve, children, isLeaf, expand, decode };\n};\n\nexport type Paths = ReturnType<typeof createPaths>;\n",
|
|
6
|
+
"import type { Quality } from \"../api.ts\";\nimport type { DebugManifest, SourceRange } from \"../manifest.ts\";\nimport { typeOf } from \"../paths.ts\";\n\n/** How a value is shown: each state has its own styling and label, so none passes for live. */\nexport type ValueState = \"live\" | \"uncertain\" | \"bad\" | \"stale\" | \"unavailable\" | \"constant\";\n\nexport const valueStateLabels: Record<ValueState, string> = {\n live: \"good\",\n uncertain: \"uncertain\",\n bad: \"bad\",\n stale: \"stale\",\n unavailable: \"unavailable\",\n constant: \"constant\",\n};\n\n/** A sample is stale when the controller connection is down or the sample is older than three sample intervals. */\nexport const valueState = (\n quality: Quality,\n ageMs: number,\n context: { connected: boolean; intervalMs: number },\n): ValueState => {\n if (quality === \"unavailable\") return \"unavailable\";\n if (!context.connected || ageMs > 3 * context.intervalMs) return \"stale\";\n if (quality === \"bad\") return \"bad\";\n if (quality === \"uncertain\") return \"uncertain\";\n return \"live\";\n};\n\nexport const formatAge = (ms: number) => {\n if (ms < 1000) return \"now\";\n if (ms < 60_000) return `${Math.floor(ms / 1000)} s ago`;\n if (ms < 3_600_000) return `${Math.floor(ms / 60_000)} min ago`;\n return `${Math.floor(ms / 3_600_000)} h ago`;\n};\n\nexport const formatDuration = (ms: number) => {\n if (ms < 1000) return `${Math.round(ms)} ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)} s`;\n return `${Math.floor(ms / 60_000)} min ${Math.floor((ms % 60_000) / 1000)} s`;\n};\n\n/** How often values are read: `250 ms`, `1 s`, `1.5 s`. */\nexport const formatInterval = (ms: number) => (ms < 1000 ? `${ms} ms` : `${ms / 1000} s`);\n\n/** Local time of day with milliseconds, for ordering events by eye. */\nexport const formatClock = (iso: string) => {\n const date = new Date(iso);\n const pad = (value: number, width = 2) => String(value).padStart(width, \"0\");\n return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}.${pad(date.getMilliseconds(), 3)}`;\n};\n\n/** When a value was read, to the second: `read 14:03:27`. */\nexport const formatReadAt = (iso: string) => `read ${formatClock(iso).slice(0, 8)}`;\n\n/** A value of unknown type: booleans as IEC literals, strings quoted. */\nexport const formatScalar = (value: unknown): string => {\n if (typeof value === \"boolean\") return value ? \"TRUE\" : \"FALSE\";\n if (typeof value === \"number\")\n return Number.isInteger(value) ? String(value) : String(Number(value.toPrecision(6)));\n if (typeof value === \"string\") return JSON.stringify(value);\n if (value === null || value === undefined) return \"—\";\n return JSON.stringify(value);\n};\n\n/** A value in the program's terms: enum members by name, whether the host decoded them already or not. */\nexport const formatValue = (manifest: DebugManifest, typeId: string, value: unknown): string => {\n const type = typeOf(manifest, typeId);\n if (type.kind !== \"enum\") return formatScalar(value);\n if (typeof value === \"string\" && Object.hasOwn(type.members, value)) return value;\n if (typeof value !== \"number\") return formatScalar(value);\n const member = Object.entries(type.members).find(([, number]) => number === value)?.[0];\n return member ?? `${value} (not a ${type.name})`;\n};\n\nexport const typeLabel = (manifest: DebugManifest, typeId: string): string => {\n const type = typeOf(manifest, typeId);\n switch (type.kind) {\n case \"scalar\":\n return type.iec;\n case \"enum\":\n case \"record\":\n return type.name;\n case \"array\":\n return `${typeLabel(manifest, type.element)}[${type.length}]`;\n }\n};\n\nconst PROPERTY_TEXT = 16;\n\n/** A record's properties as `barcode=CON-MD3-884… scanner=3`, long strings cut short. */\nexport const formatProperties = (properties: Record<string, unknown>) =>\n Object.entries(properties)\n .map(([key, value]) => {\n const text = typeof value === \"string\" ? value : formatScalar(value);\n return `${key}=${text.length > PROPERTY_TEXT ? `${text.slice(0, PROPERTY_TEXT)}…` : text}`;\n })\n .join(\" \");\n\n/** A VS Code link to a project file, when the project root on the debugger host is known. */\nconst fileHref = (projectRoot: string | undefined, file: string, line: number, column: number) => {\n if (projectRoot === undefined) return undefined;\n const root = projectRoot.replaceAll(\"\\\\\", \"/\").replace(/\\/$/, \"\");\n const absolute = `${root}/${file}`.replace(/^\\/?/, \"/\");\n return `vscode://file${absolute}:${line}:${column}`;\n};\n\n/** `file:line`, and a VS Code link when the project root on the debugger host is known. */\nexport const sourceLocation = (\n manifest: DebugManifest,\n projectRoot: string | undefined,\n range: SourceRange,\n) => {\n const file = manifest.sources[range.file] ?? `source ${range.file}`;\n const href = fileHref(projectRoot, file, range.line, range.column);\n return { label: `${file}:${range.line}`, ...(href && { href }) };\n};\n\n/** A record's project-relative `file:line` as `basename:line`, with the same VS Code link. */\nexport const recordLocation = (projectRoot: string | undefined, source: string) => {\n const [, file = source, line] = /^(.*):(\\d+)$/.exec(source) ?? [];\n const label = `${file.slice(file.lastIndexOf(\"/\") + 1)}${line ? `:${line}` : \"\"}`;\n const href = line === undefined ? undefined : fileHref(projectRoot, file, Number(line), 1);\n return { label, ...(href && { href }) };\n};\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "78E800313C3FB5FD64756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|