@tscircuit/cli 0.1.1630 → 0.1.1631
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/cli/build/build.worker.js +61 -8
- package/dist/cli/main.js +87 -12
- package/dist/cli/snapshot/snapshot.worker.js +61 -8
- package/dist/lib/index.js +23 -1
- package/package.json +1 -1
|
@@ -11984,6 +11984,7 @@ var kleur_default = $;
|
|
|
11984
11984
|
// lib/shared/autorouter-diagnostics.ts
|
|
11985
11985
|
var DEFAULT_DEBUG_DIR = path2.join("dist", "autorouter-debug");
|
|
11986
11986
|
var PROGRESS_LOG_INTERVAL_MS = 1e4;
|
|
11987
|
+
var CIRCUIT_JSON_ID_PATTERN = /\b(?:source|pcb|schematic|subcircuit|cad|simulation)_[a-z0-9_]*_\d+\b/gi;
|
|
11987
11988
|
var parseAutorouterTimeout = (duration) => {
|
|
11988
11989
|
const trimmed = duration.trim();
|
|
11989
11990
|
const match = trimmed.match(/^(\d+(?:\.\d+)?)(ms|s|m)?$/);
|
|
@@ -12086,7 +12087,7 @@ class AutorouterDiagnostics {
|
|
|
12086
12087
|
const previousTraceCount = event.previousTraceCount ?? this.traceCountBySubcircuit.get(subcircuitId) ?? 0;
|
|
12087
12088
|
this.activePhase = {
|
|
12088
12089
|
subcircuitId,
|
|
12089
|
-
componentDisplayName: event.componentDisplayName ??
|
|
12090
|
+
componentDisplayName: event.componentDisplayName ?? "subcircuit",
|
|
12090
12091
|
routingPhaseIndex,
|
|
12091
12092
|
phaseOrdinal,
|
|
12092
12093
|
phaseCount: event.phaseCount,
|
|
@@ -12191,7 +12192,7 @@ class AutorouterDiagnostics {
|
|
|
12191
12192
|
if (!activePhase.hasLoggedStart) {
|
|
12192
12193
|
this.logPhaseStart(activePhase, "failed");
|
|
12193
12194
|
}
|
|
12194
|
-
this.log(` ${this.getPhaseLabel(activePhase)} error after ${this.formatElapsed(elapsedMs)}: ${error.message}`);
|
|
12195
|
+
this.log(` ${this.getPhaseLabel(activePhase)} error after ${this.formatElapsed(elapsedMs)}: ${this.formatUserFacingText(error.message)}`);
|
|
12195
12196
|
}
|
|
12196
12197
|
if (this.shouldDumpFailedInput(activePhase.routingPhaseIndex)) {
|
|
12197
12198
|
this.writeJson(this.getPhaseFileName(activePhase, "input.simple-route.json"), event.simpleRouteJson ?? activePhase.simpleRouteJson ?? {});
|
|
@@ -12267,7 +12268,7 @@ class AutorouterDiagnostics {
|
|
|
12267
12268
|
logPhaseStart(activePhase, reason) {
|
|
12268
12269
|
const reasonText = reason ? ` ${reason}` : "";
|
|
12269
12270
|
this.log([
|
|
12270
|
-
`Autorouting ${
|
|
12271
|
+
`Autorouting ${this.formatUserFacingText(activePhase.componentDisplayName)} ${this.getPhaseLabel(activePhase)}${reasonText} start:`,
|
|
12271
12272
|
`connections=${activePhase.connectionCount},`,
|
|
12272
12273
|
`obstacles=${activePhase.obstacleCount},`,
|
|
12273
12274
|
`previous_traces=${activePhase.previousTraceCount}`,
|
|
@@ -12348,10 +12349,61 @@ class AutorouterDiagnostics {
|
|
|
12348
12349
|
return parts.join(", ");
|
|
12349
12350
|
}
|
|
12350
12351
|
getConnectionNames(simpleRouteJson) {
|
|
12351
|
-
return
|
|
12352
|
-
|
|
12353
|
-
|
|
12354
|
-
|
|
12352
|
+
return [
|
|
12353
|
+
...new Set((simpleRouteJson?.connections ?? []).map((connection) => [
|
|
12354
|
+
connection.rootConnectionName,
|
|
12355
|
+
connection.name,
|
|
12356
|
+
connection.source_trace_id
|
|
12357
|
+
].filter((value) => typeof value === "string").map((value) => this.resolveCircuitJsonId(value)).find((value) => value !== null)).filter((name) => name !== null))
|
|
12358
|
+
];
|
|
12359
|
+
}
|
|
12360
|
+
resolveCircuitJsonId(value) {
|
|
12361
|
+
const circuitJson = this.getCurrentCircuitJson();
|
|
12362
|
+
const element = circuitJson.find((candidate) => Object.entries(candidate).some(([key, candidateValue]) => key.endsWith("_id") && candidateValue === value));
|
|
12363
|
+
if (!element)
|
|
12364
|
+
return value;
|
|
12365
|
+
if (element.type === "source_trace") {
|
|
12366
|
+
if (typeof element.name === "string")
|
|
12367
|
+
return element.name;
|
|
12368
|
+
return this.getTraceSelector(element, circuitJson);
|
|
12369
|
+
}
|
|
12370
|
+
if (element.type === "source_net" && typeof element.name === "string") {
|
|
12371
|
+
return `net.${element.name}`;
|
|
12372
|
+
}
|
|
12373
|
+
if (element.type === "source_port") {
|
|
12374
|
+
return this.getPortSelector(element, circuitJson);
|
|
12375
|
+
}
|
|
12376
|
+
return null;
|
|
12377
|
+
}
|
|
12378
|
+
formatUserFacingText(value) {
|
|
12379
|
+
let formattedValue = value;
|
|
12380
|
+
for (const element of this.getCurrentCircuitJson()) {
|
|
12381
|
+
for (const [key, id] of Object.entries(element)) {
|
|
12382
|
+
if (!key.endsWith("_id") || typeof id !== "string")
|
|
12383
|
+
continue;
|
|
12384
|
+
formattedValue = formattedValue.replaceAll(id, this.resolveCircuitJsonId(id) ?? "internal element");
|
|
12385
|
+
}
|
|
12386
|
+
}
|
|
12387
|
+
return formattedValue.replace(CIRCUIT_JSON_ID_PATTERN, "internal element");
|
|
12388
|
+
}
|
|
12389
|
+
getTraceSelector(trace, circuitJson) {
|
|
12390
|
+
const portIds = trace.connected_source_port_ids;
|
|
12391
|
+
if (!Array.isArray(portIds))
|
|
12392
|
+
return null;
|
|
12393
|
+
const selectors = portIds.map((portId) => typeof portId === "string" ? this.getPortSelectorById(portId, circuitJson) : null).filter((selector) => selector !== null);
|
|
12394
|
+
return selectors.length >= 2 ? selectors.join(" to ") : null;
|
|
12395
|
+
}
|
|
12396
|
+
getPortSelectorById(sourcePortId, circuitJson) {
|
|
12397
|
+
const port = circuitJson.find((element) => element.type === "source_port" && element.source_port_id === sourcePortId);
|
|
12398
|
+
return port ? this.getPortSelector(port, circuitJson) : null;
|
|
12399
|
+
}
|
|
12400
|
+
getPortSelector(port, circuitJson) {
|
|
12401
|
+
const portName = typeof port.most_frequently_referenced_by_name === "string" ? port.most_frequently_referenced_by_name : typeof port.name === "string" ? port.name : null;
|
|
12402
|
+
if (!portName)
|
|
12403
|
+
return null;
|
|
12404
|
+
const component = circuitJson.find((element) => element.type === "source_component" && element.source_component_id === port.source_component_id);
|
|
12405
|
+
const componentName = component && typeof component.name === "string" ? component.name : null;
|
|
12406
|
+
return componentName ? `${componentName}.${portName}` : portName;
|
|
12355
12407
|
}
|
|
12356
12408
|
countErrors(simpleRouteJson) {
|
|
12357
12409
|
const errors = simpleRouteJson?.errors;
|
|
@@ -12359,7 +12411,8 @@ class AutorouterDiagnostics {
|
|
|
12359
12411
|
}
|
|
12360
12412
|
getCurrentCircuitJson() {
|
|
12361
12413
|
try {
|
|
12362
|
-
|
|
12414
|
+
const circuitJson = this.rootCircuit?.db?.toArray?.();
|
|
12415
|
+
return Array.isArray(circuitJson) ? circuitJson : [];
|
|
12363
12416
|
} catch {
|
|
12364
12417
|
return [];
|
|
12365
12418
|
}
|
package/dist/cli/main.js
CHANGED
|
@@ -97764,6 +97764,7 @@ import fs16 from "node:fs";
|
|
|
97764
97764
|
import path16 from "node:path";
|
|
97765
97765
|
var DEFAULT_DEBUG_DIR = path16.join("dist", "autorouter-debug");
|
|
97766
97766
|
var PROGRESS_LOG_INTERVAL_MS = 1e4;
|
|
97767
|
+
var CIRCUIT_JSON_ID_PATTERN = /\b(?:source|pcb|schematic|subcircuit|cad|simulation)_[a-z0-9_]*_\d+\b/gi;
|
|
97767
97768
|
var parseAutorouterTimeout = (duration) => {
|
|
97768
97769
|
const trimmed = duration.trim();
|
|
97769
97770
|
const match = trimmed.match(/^(\d+(?:\.\d+)?)(ms|s|m)?$/);
|
|
@@ -97866,7 +97867,7 @@ class AutorouterDiagnostics {
|
|
|
97866
97867
|
const previousTraceCount = event.previousTraceCount ?? this.traceCountBySubcircuit.get(subcircuitId) ?? 0;
|
|
97867
97868
|
this.activePhase = {
|
|
97868
97869
|
subcircuitId,
|
|
97869
|
-
componentDisplayName: event.componentDisplayName ??
|
|
97870
|
+
componentDisplayName: event.componentDisplayName ?? "subcircuit",
|
|
97870
97871
|
routingPhaseIndex,
|
|
97871
97872
|
phaseOrdinal,
|
|
97872
97873
|
phaseCount: event.phaseCount,
|
|
@@ -97971,7 +97972,7 @@ class AutorouterDiagnostics {
|
|
|
97971
97972
|
if (!activePhase.hasLoggedStart) {
|
|
97972
97973
|
this.logPhaseStart(activePhase, "failed");
|
|
97973
97974
|
}
|
|
97974
|
-
this.log(` ${this.getPhaseLabel(activePhase)} error after ${this.formatElapsed(elapsedMs)}: ${error.message}`);
|
|
97975
|
+
this.log(` ${this.getPhaseLabel(activePhase)} error after ${this.formatElapsed(elapsedMs)}: ${this.formatUserFacingText(error.message)}`);
|
|
97975
97976
|
}
|
|
97976
97977
|
if (this.shouldDumpFailedInput(activePhase.routingPhaseIndex)) {
|
|
97977
97978
|
this.writeJson(this.getPhaseFileName(activePhase, "input.simple-route.json"), event.simpleRouteJson ?? activePhase.simpleRouteJson ?? {});
|
|
@@ -98047,7 +98048,7 @@ class AutorouterDiagnostics {
|
|
|
98047
98048
|
logPhaseStart(activePhase, reason) {
|
|
98048
98049
|
const reasonText = reason ? ` ${reason}` : "";
|
|
98049
98050
|
this.log([
|
|
98050
|
-
`Autorouting ${
|
|
98051
|
+
`Autorouting ${this.formatUserFacingText(activePhase.componentDisplayName)} ${this.getPhaseLabel(activePhase)}${reasonText} start:`,
|
|
98051
98052
|
`connections=${activePhase.connectionCount},`,
|
|
98052
98053
|
`obstacles=${activePhase.obstacleCount},`,
|
|
98053
98054
|
`previous_traces=${activePhase.previousTraceCount}`,
|
|
@@ -98128,10 +98129,61 @@ class AutorouterDiagnostics {
|
|
|
98128
98129
|
return parts.join(", ");
|
|
98129
98130
|
}
|
|
98130
98131
|
getConnectionNames(simpleRouteJson) {
|
|
98131
|
-
return
|
|
98132
|
-
|
|
98133
|
-
|
|
98134
|
-
|
|
98132
|
+
return [
|
|
98133
|
+
...new Set((simpleRouteJson?.connections ?? []).map((connection) => [
|
|
98134
|
+
connection.rootConnectionName,
|
|
98135
|
+
connection.name,
|
|
98136
|
+
connection.source_trace_id
|
|
98137
|
+
].filter((value) => typeof value === "string").map((value) => this.resolveCircuitJsonId(value)).find((value) => value !== null)).filter((name) => name !== null))
|
|
98138
|
+
];
|
|
98139
|
+
}
|
|
98140
|
+
resolveCircuitJsonId(value) {
|
|
98141
|
+
const circuitJson = this.getCurrentCircuitJson();
|
|
98142
|
+
const element = circuitJson.find((candidate) => Object.entries(candidate).some(([key, candidateValue]) => key.endsWith("_id") && candidateValue === value));
|
|
98143
|
+
if (!element)
|
|
98144
|
+
return value;
|
|
98145
|
+
if (element.type === "source_trace") {
|
|
98146
|
+
if (typeof element.name === "string")
|
|
98147
|
+
return element.name;
|
|
98148
|
+
return this.getTraceSelector(element, circuitJson);
|
|
98149
|
+
}
|
|
98150
|
+
if (element.type === "source_net" && typeof element.name === "string") {
|
|
98151
|
+
return `net.${element.name}`;
|
|
98152
|
+
}
|
|
98153
|
+
if (element.type === "source_port") {
|
|
98154
|
+
return this.getPortSelector(element, circuitJson);
|
|
98155
|
+
}
|
|
98156
|
+
return null;
|
|
98157
|
+
}
|
|
98158
|
+
formatUserFacingText(value) {
|
|
98159
|
+
let formattedValue = value;
|
|
98160
|
+
for (const element of this.getCurrentCircuitJson()) {
|
|
98161
|
+
for (const [key, id] of Object.entries(element)) {
|
|
98162
|
+
if (!key.endsWith("_id") || typeof id !== "string")
|
|
98163
|
+
continue;
|
|
98164
|
+
formattedValue = formattedValue.replaceAll(id, this.resolveCircuitJsonId(id) ?? "internal element");
|
|
98165
|
+
}
|
|
98166
|
+
}
|
|
98167
|
+
return formattedValue.replace(CIRCUIT_JSON_ID_PATTERN, "internal element");
|
|
98168
|
+
}
|
|
98169
|
+
getTraceSelector(trace, circuitJson) {
|
|
98170
|
+
const portIds = trace.connected_source_port_ids;
|
|
98171
|
+
if (!Array.isArray(portIds))
|
|
98172
|
+
return null;
|
|
98173
|
+
const selectors = portIds.map((portId) => typeof portId === "string" ? this.getPortSelectorById(portId, circuitJson) : null).filter((selector) => selector !== null);
|
|
98174
|
+
return selectors.length >= 2 ? selectors.join(" to ") : null;
|
|
98175
|
+
}
|
|
98176
|
+
getPortSelectorById(sourcePortId, circuitJson) {
|
|
98177
|
+
const port = circuitJson.find((element) => element.type === "source_port" && element.source_port_id === sourcePortId);
|
|
98178
|
+
return port ? this.getPortSelector(port, circuitJson) : null;
|
|
98179
|
+
}
|
|
98180
|
+
getPortSelector(port, circuitJson) {
|
|
98181
|
+
const portName = typeof port.most_frequently_referenced_by_name === "string" ? port.most_frequently_referenced_by_name : typeof port.name === "string" ? port.name : null;
|
|
98182
|
+
if (!portName)
|
|
98183
|
+
return null;
|
|
98184
|
+
const component = circuitJson.find((element) => element.type === "source_component" && element.source_component_id === port.source_component_id);
|
|
98185
|
+
const componentName = component && typeof component.name === "string" ? component.name : null;
|
|
98186
|
+
return componentName ? `${componentName}.${portName}` : portName;
|
|
98135
98187
|
}
|
|
98136
98188
|
countErrors(simpleRouteJson) {
|
|
98137
98189
|
const errors = simpleRouteJson?.errors;
|
|
@@ -98139,7 +98191,8 @@ class AutorouterDiagnostics {
|
|
|
98139
98191
|
}
|
|
98140
98192
|
getCurrentCircuitJson() {
|
|
98141
98193
|
try {
|
|
98142
|
-
|
|
98194
|
+
const circuitJson = this.rootCircuit?.db?.toArray?.();
|
|
98195
|
+
return Array.isArray(circuitJson) ? circuitJson : [];
|
|
98143
98196
|
} catch {
|
|
98144
98197
|
return [];
|
|
98145
98198
|
}
|
|
@@ -215125,9 +215178,9 @@ var addStartAndEndPortIdsIfMissing = (soup) => {
|
|
|
215125
215178
|
}
|
|
215126
215179
|
}
|
|
215127
215180
|
};
|
|
215128
|
-
var
|
|
215181
|
+
var CIRCUIT_JSON_ID_PATTERN2 = /\b(?:pcb|source|schematic|subcircuit)_[a-z0-9_]+\b/i;
|
|
215129
215182
|
var sanitizeReadableName = (candidate, id2, fallbackLabel) => {
|
|
215130
|
-
if (!candidate || candidate === id2 ||
|
|
215183
|
+
if (!candidate || candidate === id2 || CIRCUIT_JSON_ID_PATTERN2.test(candidate)) {
|
|
215131
215184
|
return fallbackLabel;
|
|
215132
215185
|
}
|
|
215133
215186
|
return candidate;
|
|
@@ -215164,7 +215217,7 @@ var getReadableNameForPort = (circuitJson, pcbPortId) => {
|
|
|
215164
215217
|
return sanitizeReadableName(getReadableNameForPcbPort(circuitJson, pcbPortId) ?? getReadableNameForElement(circuitJson, pcbPortId), pcbPortId, "port");
|
|
215165
215218
|
};
|
|
215166
215219
|
var getReadableNameForElementId = (circuitJson, elementId) => sanitizeReadableName(getReadableNameForElement(circuitJson, elementId), elementId, "element");
|
|
215167
|
-
var containsCircuitJsonId = (message) =>
|
|
215220
|
+
var containsCircuitJsonId = (message) => CIRCUIT_JSON_ID_PATTERN2.test(message);
|
|
215168
215221
|
function checkEachPcbPortConnectedToPcbTraces(circuitJson) {
|
|
215169
215222
|
addStartAndEndPortIdsIfMissing(circuitJson);
|
|
215170
215223
|
const sourceTraces = circuitJson.filter((item) => item.type === "source_trace");
|
|
@@ -264684,6 +264737,28 @@ Publish completed with ${uploadResults.succeeded.length} files uploaded and ${up
|
|
|
264684
264737
|
var debug13 = Debug3("tscircuit:devserver");
|
|
264685
264738
|
var BINARY_FILE_EXTENSIONS2 = new Set([".glb", ".png", ".jpeg", ".jpg"]);
|
|
264686
264739
|
var CONFIG_MODULE_FILENAMES2 = ["tscircuit.config.ts", "tscircuit.config.js"];
|
|
264740
|
+
var CIRCUIT_JSON_ID_PATTERN3 = /\b(?:source|pcb|schematic|subcircuit|cad|simulation)_[a-z0-9_]*_\d+\b/gi;
|
|
264741
|
+
var formatAutorouterDebugEvent = (event) => {
|
|
264742
|
+
const parts = [
|
|
264743
|
+
typeof event.componentDisplayName === "string" ? `component=${event.componentDisplayName}` : null,
|
|
264744
|
+
typeof event.phase === "string" ? `phase=${event.phase}` : null,
|
|
264745
|
+
typeof event.solverName === "string" ? `solver=${event.solverName}` : null,
|
|
264746
|
+
typeof event.connectionCount === "number" ? `connections=${event.connectionCount}` : null,
|
|
264747
|
+
typeof event.obstacleCount === "number" ? `obstacles=${event.obstacleCount}` : null,
|
|
264748
|
+
typeof event.steps === "number" ? `steps=${event.steps}` : null,
|
|
264749
|
+
typeof event.iteration === "number" ? `iteration=${event.iteration}` : null,
|
|
264750
|
+
typeof event.progress === "number" ? `progress=${Math.round(event.progress * 100)}%` : null,
|
|
264751
|
+
typeof event.iterationsPerSecond === "number" ? `iterations_per_second=${Math.round(event.iterationsPerSecond)}` : null,
|
|
264752
|
+
typeof event.elapsedMs === "number" ? `elapsed=${Math.round(event.elapsedMs)}ms` : null
|
|
264753
|
+
].filter((part) => part !== null);
|
|
264754
|
+
const error2 = event.error;
|
|
264755
|
+
const errorMessage = error2 && typeof error2 === "object" && "message" in error2 ? error2.message : typeof error2 === "string" ? error2 : null;
|
|
264756
|
+
if (typeof errorMessage === "string") {
|
|
264757
|
+
parts.push(`error=${errorMessage.replace(CIRCUIT_JSON_ID_PATTERN3, "internal element")}`);
|
|
264758
|
+
}
|
|
264759
|
+
const eventType = typeof event.event_type === "string" ? event.event_type : "autorouting";
|
|
264760
|
+
return `[autorouter] ${eventType}${parts.length > 0 ? ` ${parts.join(" ")}` : ""}`;
|
|
264761
|
+
};
|
|
264687
264762
|
|
|
264688
264763
|
class DevServer {
|
|
264689
264764
|
port;
|
|
@@ -264735,7 +264810,7 @@ class DevServer {
|
|
|
264735
264810
|
this.eventsWatcher.on("*", (event) => {
|
|
264736
264811
|
if (!String(event.event_type).startsWith("autorouting:"))
|
|
264737
264812
|
return;
|
|
264738
|
-
console.log(kleur_default.cyan(
|
|
264813
|
+
console.log(kleur_default.cyan(formatAutorouterDebugEvent(event)));
|
|
264739
264814
|
});
|
|
264740
264815
|
}
|
|
264741
264816
|
this.filesystemWatcher = watch(this.projectDir, {
|
|
@@ -2803,6 +2803,7 @@ import fs from "node:fs";
|
|
|
2803
2803
|
import path from "node:path";
|
|
2804
2804
|
var DEFAULT_DEBUG_DIR = path.join("dist", "autorouter-debug");
|
|
2805
2805
|
var PROGRESS_LOG_INTERVAL_MS = 1e4;
|
|
2806
|
+
var CIRCUIT_JSON_ID_PATTERN = /\b(?:source|pcb|schematic|subcircuit|cad|simulation)_[a-z0-9_]*_\d+\b/gi;
|
|
2806
2807
|
var parseAutorouterTimeout = (duration) => {
|
|
2807
2808
|
const trimmed = duration.trim();
|
|
2808
2809
|
const match = trimmed.match(/^(\d+(?:\.\d+)?)(ms|s|m)?$/);
|
|
@@ -2905,7 +2906,7 @@ class AutorouterDiagnostics {
|
|
|
2905
2906
|
const previousTraceCount = event.previousTraceCount ?? this.traceCountBySubcircuit.get(subcircuitId) ?? 0;
|
|
2906
2907
|
this.activePhase = {
|
|
2907
2908
|
subcircuitId,
|
|
2908
|
-
componentDisplayName: event.componentDisplayName ??
|
|
2909
|
+
componentDisplayName: event.componentDisplayName ?? "subcircuit",
|
|
2909
2910
|
routingPhaseIndex,
|
|
2910
2911
|
phaseOrdinal,
|
|
2911
2912
|
phaseCount: event.phaseCount,
|
|
@@ -3010,7 +3011,7 @@ class AutorouterDiagnostics {
|
|
|
3010
3011
|
if (!activePhase.hasLoggedStart) {
|
|
3011
3012
|
this.logPhaseStart(activePhase, "failed");
|
|
3012
3013
|
}
|
|
3013
|
-
this.log(` ${this.getPhaseLabel(activePhase)} error after ${this.formatElapsed(elapsedMs)}: ${error.message}`);
|
|
3014
|
+
this.log(` ${this.getPhaseLabel(activePhase)} error after ${this.formatElapsed(elapsedMs)}: ${this.formatUserFacingText(error.message)}`);
|
|
3014
3015
|
}
|
|
3015
3016
|
if (this.shouldDumpFailedInput(activePhase.routingPhaseIndex)) {
|
|
3016
3017
|
this.writeJson(this.getPhaseFileName(activePhase, "input.simple-route.json"), event.simpleRouteJson ?? activePhase.simpleRouteJson ?? {});
|
|
@@ -3086,7 +3087,7 @@ class AutorouterDiagnostics {
|
|
|
3086
3087
|
logPhaseStart(activePhase, reason) {
|
|
3087
3088
|
const reasonText = reason ? ` ${reason}` : "";
|
|
3088
3089
|
this.log([
|
|
3089
|
-
`Autorouting ${
|
|
3090
|
+
`Autorouting ${this.formatUserFacingText(activePhase.componentDisplayName)} ${this.getPhaseLabel(activePhase)}${reasonText} start:`,
|
|
3090
3091
|
`connections=${activePhase.connectionCount},`,
|
|
3091
3092
|
`obstacles=${activePhase.obstacleCount},`,
|
|
3092
3093
|
`previous_traces=${activePhase.previousTraceCount}`,
|
|
@@ -3167,10 +3168,61 @@ class AutorouterDiagnostics {
|
|
|
3167
3168
|
return parts.join(", ");
|
|
3168
3169
|
}
|
|
3169
3170
|
getConnectionNames(simpleRouteJson) {
|
|
3170
|
-
return
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3171
|
+
return [
|
|
3172
|
+
...new Set((simpleRouteJson?.connections ?? []).map((connection) => [
|
|
3173
|
+
connection.rootConnectionName,
|
|
3174
|
+
connection.name,
|
|
3175
|
+
connection.source_trace_id
|
|
3176
|
+
].filter((value) => typeof value === "string").map((value) => this.resolveCircuitJsonId(value)).find((value) => value !== null)).filter((name) => name !== null))
|
|
3177
|
+
];
|
|
3178
|
+
}
|
|
3179
|
+
resolveCircuitJsonId(value) {
|
|
3180
|
+
const circuitJson = this.getCurrentCircuitJson();
|
|
3181
|
+
const element = circuitJson.find((candidate) => Object.entries(candidate).some(([key, candidateValue]) => key.endsWith("_id") && candidateValue === value));
|
|
3182
|
+
if (!element)
|
|
3183
|
+
return value;
|
|
3184
|
+
if (element.type === "source_trace") {
|
|
3185
|
+
if (typeof element.name === "string")
|
|
3186
|
+
return element.name;
|
|
3187
|
+
return this.getTraceSelector(element, circuitJson);
|
|
3188
|
+
}
|
|
3189
|
+
if (element.type === "source_net" && typeof element.name === "string") {
|
|
3190
|
+
return `net.${element.name}`;
|
|
3191
|
+
}
|
|
3192
|
+
if (element.type === "source_port") {
|
|
3193
|
+
return this.getPortSelector(element, circuitJson);
|
|
3194
|
+
}
|
|
3195
|
+
return null;
|
|
3196
|
+
}
|
|
3197
|
+
formatUserFacingText(value) {
|
|
3198
|
+
let formattedValue = value;
|
|
3199
|
+
for (const element of this.getCurrentCircuitJson()) {
|
|
3200
|
+
for (const [key, id] of Object.entries(element)) {
|
|
3201
|
+
if (!key.endsWith("_id") || typeof id !== "string")
|
|
3202
|
+
continue;
|
|
3203
|
+
formattedValue = formattedValue.replaceAll(id, this.resolveCircuitJsonId(id) ?? "internal element");
|
|
3204
|
+
}
|
|
3205
|
+
}
|
|
3206
|
+
return formattedValue.replace(CIRCUIT_JSON_ID_PATTERN, "internal element");
|
|
3207
|
+
}
|
|
3208
|
+
getTraceSelector(trace, circuitJson) {
|
|
3209
|
+
const portIds = trace.connected_source_port_ids;
|
|
3210
|
+
if (!Array.isArray(portIds))
|
|
3211
|
+
return null;
|
|
3212
|
+
const selectors = portIds.map((portId) => typeof portId === "string" ? this.getPortSelectorById(portId, circuitJson) : null).filter((selector) => selector !== null);
|
|
3213
|
+
return selectors.length >= 2 ? selectors.join(" to ") : null;
|
|
3214
|
+
}
|
|
3215
|
+
getPortSelectorById(sourcePortId, circuitJson) {
|
|
3216
|
+
const port = circuitJson.find((element) => element.type === "source_port" && element.source_port_id === sourcePortId);
|
|
3217
|
+
return port ? this.getPortSelector(port, circuitJson) : null;
|
|
3218
|
+
}
|
|
3219
|
+
getPortSelector(port, circuitJson) {
|
|
3220
|
+
const portName = typeof port.most_frequently_referenced_by_name === "string" ? port.most_frequently_referenced_by_name : typeof port.name === "string" ? port.name : null;
|
|
3221
|
+
if (!portName)
|
|
3222
|
+
return null;
|
|
3223
|
+
const component = circuitJson.find((element) => element.type === "source_component" && element.source_component_id === port.source_component_id);
|
|
3224
|
+
const componentName = component && typeof component.name === "string" ? component.name : null;
|
|
3225
|
+
return componentName ? `${componentName}.${portName}` : portName;
|
|
3174
3226
|
}
|
|
3175
3227
|
countErrors(simpleRouteJson) {
|
|
3176
3228
|
const errors = simpleRouteJson?.errors;
|
|
@@ -3178,7 +3230,8 @@ class AutorouterDiagnostics {
|
|
|
3178
3230
|
}
|
|
3179
3231
|
getCurrentCircuitJson() {
|
|
3180
3232
|
try {
|
|
3181
|
-
|
|
3233
|
+
const circuitJson = this.rootCircuit?.db?.toArray?.();
|
|
3234
|
+
return Array.isArray(circuitJson) ? circuitJson : [];
|
|
3182
3235
|
} catch {
|
|
3183
3236
|
return [];
|
|
3184
3237
|
}
|
package/dist/lib/index.js
CHANGED
|
@@ -80118,6 +80118,28 @@ Publish completed with ${uploadResults.succeeded.length} files uploaded and ${up
|
|
|
80118
80118
|
var debug2 = Debug2("tscircuit:devserver");
|
|
80119
80119
|
var BINARY_FILE_EXTENSIONS2 = new Set([".glb", ".png", ".jpeg", ".jpg"]);
|
|
80120
80120
|
var CONFIG_MODULE_FILENAMES2 = ["tscircuit.config.ts", "tscircuit.config.js"];
|
|
80121
|
+
var CIRCUIT_JSON_ID_PATTERN = /\b(?:source|pcb|schematic|subcircuit|cad|simulation)_[a-z0-9_]*_\d+\b/gi;
|
|
80122
|
+
var formatAutorouterDebugEvent = (event) => {
|
|
80123
|
+
const parts = [
|
|
80124
|
+
typeof event.componentDisplayName === "string" ? `component=${event.componentDisplayName}` : null,
|
|
80125
|
+
typeof event.phase === "string" ? `phase=${event.phase}` : null,
|
|
80126
|
+
typeof event.solverName === "string" ? `solver=${event.solverName}` : null,
|
|
80127
|
+
typeof event.connectionCount === "number" ? `connections=${event.connectionCount}` : null,
|
|
80128
|
+
typeof event.obstacleCount === "number" ? `obstacles=${event.obstacleCount}` : null,
|
|
80129
|
+
typeof event.steps === "number" ? `steps=${event.steps}` : null,
|
|
80130
|
+
typeof event.iteration === "number" ? `iteration=${event.iteration}` : null,
|
|
80131
|
+
typeof event.progress === "number" ? `progress=${Math.round(event.progress * 100)}%` : null,
|
|
80132
|
+
typeof event.iterationsPerSecond === "number" ? `iterations_per_second=${Math.round(event.iterationsPerSecond)}` : null,
|
|
80133
|
+
typeof event.elapsedMs === "number" ? `elapsed=${Math.round(event.elapsedMs)}ms` : null
|
|
80134
|
+
].filter((part) => part !== null);
|
|
80135
|
+
const error = event.error;
|
|
80136
|
+
const errorMessage = error && typeof error === "object" && "message" in error ? error.message : typeof error === "string" ? error : null;
|
|
80137
|
+
if (typeof errorMessage === "string") {
|
|
80138
|
+
parts.push(`error=${errorMessage.replace(CIRCUIT_JSON_ID_PATTERN, "internal element")}`);
|
|
80139
|
+
}
|
|
80140
|
+
const eventType = typeof event.event_type === "string" ? event.event_type : "autorouting";
|
|
80141
|
+
return `[autorouter] ${eventType}${parts.length > 0 ? ` ${parts.join(" ")}` : ""}`;
|
|
80142
|
+
};
|
|
80121
80143
|
|
|
80122
80144
|
class DevServer {
|
|
80123
80145
|
port;
|
|
@@ -80169,7 +80191,7 @@ class DevServer {
|
|
|
80169
80191
|
this.eventsWatcher.on("*", (event) => {
|
|
80170
80192
|
if (!String(event.event_type).startsWith("autorouting:"))
|
|
80171
80193
|
return;
|
|
80172
|
-
console.log(kleur_default.cyan(
|
|
80194
|
+
console.log(kleur_default.cyan(formatAutorouterDebugEvent(event)));
|
|
80173
80195
|
});
|
|
80174
80196
|
}
|
|
80175
80197
|
this.filesystemWatcher = watch(this.projectDir, {
|