@tscircuit/cli 0.1.1628 → 0.1.1629
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 +676 -265
- package/dist/cli/main.js +1749 -1292
- package/dist/cli/snapshot/snapshot.worker.js +484 -77
- package/dist/lib/index.js +12 -2
- package/package.json +1 -1
|
@@ -2485,8 +2485,8 @@ export default {
|
|
|
2485
2485
|
import { parentPort } from "node:worker_threads";
|
|
2486
2486
|
|
|
2487
2487
|
// lib/shared/process-snapshot-file.ts
|
|
2488
|
-
import
|
|
2489
|
-
import
|
|
2488
|
+
import fs7 from "node:fs";
|
|
2489
|
+
import path6 from "node:path";
|
|
2490
2490
|
|
|
2491
2491
|
// node_modules/circuit-json-to-3d-png/dist/index.js
|
|
2492
2492
|
function normalizeDir(dir) {
|
|
@@ -2776,8 +2776,8 @@ function init(open, close) {
|
|
|
2776
2776
|
var kleur_default = $;
|
|
2777
2777
|
|
|
2778
2778
|
// lib/shared/generate-circuit-json.tsx
|
|
2779
|
-
import
|
|
2780
|
-
import
|
|
2779
|
+
import fs4 from "node:fs";
|
|
2780
|
+
import path4 from "node:path";
|
|
2781
2781
|
import { pathToFileURL } from "node:url";
|
|
2782
2782
|
import Debug from "debug";
|
|
2783
2783
|
|
|
@@ -2798,14 +2798,416 @@ var abbreviateStringifyObject = (obj) => {
|
|
|
2798
2798
|
// lib/shared/generate-circuit-json.tsx
|
|
2799
2799
|
var import_make_vfs = __toESM(require_dist(), 1);
|
|
2800
2800
|
|
|
2801
|
-
// lib/shared/
|
|
2802
|
-
import { createRequire as createRequire2 } from "node:module";
|
|
2801
|
+
// lib/shared/autorouter-diagnostics.ts
|
|
2803
2802
|
import fs from "node:fs";
|
|
2804
2803
|
import path from "node:path";
|
|
2804
|
+
var DEFAULT_DEBUG_DIR = path.join("dist", "autorouter-debug");
|
|
2805
|
+
var PROGRESS_LOG_INTERVAL_MS = 1e4;
|
|
2806
|
+
var parseAutorouterTimeout = (duration) => {
|
|
2807
|
+
const trimmed = duration.trim();
|
|
2808
|
+
const match = trimmed.match(/^(\d+(?:\.\d+)?)(ms|s|m)?$/);
|
|
2809
|
+
if (!match) {
|
|
2810
|
+
throw new Error(`Invalid --autorouter-timeout value "${duration}". Use values like "120s", "2m", or "5000ms".`);
|
|
2811
|
+
}
|
|
2812
|
+
const value = Number.parseFloat(match[1]);
|
|
2813
|
+
const unit = match[2] ?? "ms";
|
|
2814
|
+
const multiplier = unit === "m" ? 60000 : unit === "s" ? 1000 : 1;
|
|
2815
|
+
const timeoutMs = Math.round(value * multiplier);
|
|
2816
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
2817
|
+
throw new Error("--autorouter-timeout must be greater than zero");
|
|
2818
|
+
}
|
|
2819
|
+
return timeoutMs;
|
|
2820
|
+
};
|
|
2821
|
+
var parseAutorouterDumpSrjMode = (value) => {
|
|
2822
|
+
if (value === undefined || value === false)
|
|
2823
|
+
return;
|
|
2824
|
+
if (value === true || value === "")
|
|
2825
|
+
return "failed";
|
|
2826
|
+
if (value === "all" || value === "failed")
|
|
2827
|
+
return value;
|
|
2828
|
+
const phaseMatch = value.match(/^phase:(\d+)$/);
|
|
2829
|
+
if (phaseMatch)
|
|
2830
|
+
return `phase:${Number.parseInt(phaseMatch[1], 10)}`;
|
|
2831
|
+
throw new Error(`Invalid --autorouter-dump-srj value "${value}". Use "all", "failed", or "phase:<index>".`);
|
|
2832
|
+
};
|
|
2833
|
+
|
|
2834
|
+
class AutorouterPhaseTimeoutError extends Error {
|
|
2835
|
+
debugArtifactPath;
|
|
2836
|
+
constructor(message, debugArtifactPath) {
|
|
2837
|
+
super(message);
|
|
2838
|
+
this.name = "AutorouterPhaseTimeoutError";
|
|
2839
|
+
this.debugArtifactPath = debugArtifactPath;
|
|
2840
|
+
}
|
|
2841
|
+
}
|
|
2842
|
+
|
|
2843
|
+
class AutorouterDiagnostics {
|
|
2844
|
+
options;
|
|
2845
|
+
phaseOrdinalBySubcircuit = new Map;
|
|
2846
|
+
traceCountBySubcircuit = new Map;
|
|
2847
|
+
activePhase = null;
|
|
2848
|
+
completedPhaseTraces = [];
|
|
2849
|
+
summary = [];
|
|
2850
|
+
rootCircuit;
|
|
2851
|
+
constructor(options = {}) {
|
|
2852
|
+
this.options = {
|
|
2853
|
+
...options,
|
|
2854
|
+
debugDir: options.debugDir ?? DEFAULT_DEBUG_DIR,
|
|
2855
|
+
log: options.log ?? console.log
|
|
2856
|
+
};
|
|
2857
|
+
}
|
|
2858
|
+
get isActive() {
|
|
2859
|
+
return Boolean(this.options.enabled || this.options.timeoutMs || this.options.dumpSrj || this.options.logOnError || this.options.longRunningLogThresholdMs);
|
|
2860
|
+
}
|
|
2861
|
+
attachToRootCircuit(rootCircuit) {
|
|
2862
|
+
if (!this.isActive)
|
|
2863
|
+
return;
|
|
2864
|
+
this.rootCircuit = rootCircuit;
|
|
2865
|
+
rootCircuit.on?.("autorouting:start", (event) => this.handleStart(event));
|
|
2866
|
+
rootCircuit.on?.("autorouting:progress", (event) => this.handleProgress(event));
|
|
2867
|
+
rootCircuit.on?.("autorouting:end", (event) => this.handleEnd(event));
|
|
2868
|
+
rootCircuit.on?.("autorouting:error", (event) => this.handleError(event));
|
|
2869
|
+
}
|
|
2870
|
+
checkTimeout() {
|
|
2871
|
+
this.checkLongRunning();
|
|
2872
|
+
if (!this.options.timeoutMs || !this.activePhase)
|
|
2873
|
+
return;
|
|
2874
|
+
const elapsedMs = performance.now() - this.activePhase.startedAt;
|
|
2875
|
+
if (elapsedMs < this.options.timeoutMs)
|
|
2876
|
+
return;
|
|
2877
|
+
const artifactPath = this.writeTimeoutArtifact(this.activePhase, elapsedMs);
|
|
2878
|
+
const phaseLabel = this.getPhaseLabel(this.activePhase);
|
|
2879
|
+
const message = `Autorouter timeout after ${this.formatElapsed(elapsedMs)} in ${phaseLabel}.`;
|
|
2880
|
+
this.log(kleur_default.red(message));
|
|
2881
|
+
this.log(`Wrote debug artifact: ${path.relative(process.cwd(), artifactPath)}`);
|
|
2882
|
+
throw new AutorouterPhaseTimeoutError(message, artifactPath);
|
|
2883
|
+
}
|
|
2884
|
+
finalize(circuitJson) {
|
|
2885
|
+
if (!this.isActive || this.summary.length === 0 || !this.options.enabled && !this.options.dumpSrj) {
|
|
2886
|
+
return;
|
|
2887
|
+
}
|
|
2888
|
+
this.writeJson("board.meta.json", {
|
|
2889
|
+
type: "autorouter_debug_summary",
|
|
2890
|
+
generatedAt: new Date().toISOString(),
|
|
2891
|
+
phaseCount: this.summary.length,
|
|
2892
|
+
phases: this.summary,
|
|
2893
|
+
circuitJsonElementCount: circuitJson?.length
|
|
2894
|
+
});
|
|
2895
|
+
}
|
|
2896
|
+
handleStart(event) {
|
|
2897
|
+
const simpleRouteJson = event.simpleRouteJson;
|
|
2898
|
+
const subcircuitId = event.subcircuit_id ?? event.subcircuitId ?? "unknown-subcircuit";
|
|
2899
|
+
const previousOrdinal = this.phaseOrdinalBySubcircuit.get(subcircuitId) ?? 0;
|
|
2900
|
+
const phaseOrdinal = event.phaseOrdinal ?? previousOrdinal + 1;
|
|
2901
|
+
this.phaseOrdinalBySubcircuit.set(subcircuitId, phaseOrdinal);
|
|
2902
|
+
const routingPhaseIndex = event.routingPhaseIndex ?? phaseOrdinal - 1;
|
|
2903
|
+
const connectionCount = event.connectionCount ?? simpleRouteJson?.connections?.length ?? 0;
|
|
2904
|
+
const obstacleCount = event.obstacleCount ?? simpleRouteJson?.obstacles?.length ?? 0;
|
|
2905
|
+
const previousTraceCount = event.previousTraceCount ?? this.traceCountBySubcircuit.get(subcircuitId) ?? 0;
|
|
2906
|
+
this.activePhase = {
|
|
2907
|
+
subcircuitId,
|
|
2908
|
+
componentDisplayName: event.componentDisplayName ?? subcircuitId,
|
|
2909
|
+
routingPhaseIndex,
|
|
2910
|
+
phaseOrdinal,
|
|
2911
|
+
phaseCount: event.phaseCount,
|
|
2912
|
+
connectionCount,
|
|
2913
|
+
obstacleCount,
|
|
2914
|
+
previousTraceCount,
|
|
2915
|
+
startedAt: performance.now(),
|
|
2916
|
+
startedAtIso: new Date().toISOString(),
|
|
2917
|
+
simpleRouteJson,
|
|
2918
|
+
routerDescription: this.formatRouter(event),
|
|
2919
|
+
lastProgressLogAt: 0,
|
|
2920
|
+
hasLoggedStart: false,
|
|
2921
|
+
longRunningLoggingStarted: false
|
|
2922
|
+
};
|
|
2923
|
+
if (this.options.enabled) {
|
|
2924
|
+
this.logPhaseStart(this.activePhase);
|
|
2925
|
+
}
|
|
2926
|
+
if (this.shouldDumpInput(routingPhaseIndex)) {
|
|
2927
|
+
this.writeJson(this.getPhaseFileName(this.activePhase, "input.simple-route.json"), simpleRouteJson ?? {});
|
|
2928
|
+
}
|
|
2929
|
+
}
|
|
2930
|
+
handleProgress(event) {
|
|
2931
|
+
if (!this.activePhase)
|
|
2932
|
+
return;
|
|
2933
|
+
const now = performance.now();
|
|
2934
|
+
this.activePhase.lastProgress = event;
|
|
2935
|
+
if (!this.shouldLogPhaseDetails(this.activePhase))
|
|
2936
|
+
return;
|
|
2937
|
+
if (this.activePhase.lastProgressLogAt > 0 && now - this.activePhase.lastProgressLogAt < PROGRESS_LOG_INTERVAL_MS) {
|
|
2938
|
+
return;
|
|
2939
|
+
}
|
|
2940
|
+
this.activePhase.lastProgressLogAt = now;
|
|
2941
|
+
this.logProgress(this.activePhase, event, now);
|
|
2942
|
+
}
|
|
2943
|
+
handleEnd(event) {
|
|
2944
|
+
const activePhase = this.matchActivePhase(event);
|
|
2945
|
+
if (!activePhase)
|
|
2946
|
+
return;
|
|
2947
|
+
const elapsedMs = performance.now() - activePhase.startedAt;
|
|
2948
|
+
const outputSrj = event.simpleRouteJson;
|
|
2949
|
+
const outputTraceCount = outputSrj?.traces?.length ?? 0;
|
|
2950
|
+
const outputJumperCount = outputSrj?.jumpers?.length ?? 0;
|
|
2951
|
+
const errorCount = this.countErrors(outputSrj);
|
|
2952
|
+
const cumulativeTraceCount = activePhase.previousTraceCount + outputTraceCount;
|
|
2953
|
+
this.traceCountBySubcircuit.set(activePhase.subcircuitId, cumulativeTraceCount);
|
|
2954
|
+
this.completedPhaseTraces.push(...outputSrj?.traces ?? []);
|
|
2955
|
+
this.summary.push({
|
|
2956
|
+
subcircuit_id: activePhase.subcircuitId,
|
|
2957
|
+
componentDisplayName: activePhase.componentDisplayName,
|
|
2958
|
+
routingPhaseIndex: activePhase.routingPhaseIndex,
|
|
2959
|
+
phaseOrdinal: activePhase.phaseOrdinal,
|
|
2960
|
+
phaseCount: activePhase.phaseCount,
|
|
2961
|
+
connectionCount: activePhase.connectionCount,
|
|
2962
|
+
obstacleCount: activePhase.obstacleCount,
|
|
2963
|
+
previousTraceCount: activePhase.previousTraceCount,
|
|
2964
|
+
outputTraceCount,
|
|
2965
|
+
outputJumperCount,
|
|
2966
|
+
errorCount,
|
|
2967
|
+
elapsedMs: Math.round(elapsedMs),
|
|
2968
|
+
startedAt: activePhase.startedAtIso,
|
|
2969
|
+
completedAt: new Date().toISOString()
|
|
2970
|
+
});
|
|
2971
|
+
if (this.shouldLogPhaseDetails(activePhase) || this.didCrossLongRunningThreshold(activePhase, elapsedMs)) {
|
|
2972
|
+
if (!activePhase.hasLoggedStart) {
|
|
2973
|
+
this.startLongRunningLogging(activePhase, elapsedMs);
|
|
2974
|
+
}
|
|
2975
|
+
this.logPhaseEnd(activePhase, {
|
|
2976
|
+
outputTraceCount,
|
|
2977
|
+
outputJumperCount,
|
|
2978
|
+
errorCount,
|
|
2979
|
+
elapsedMs
|
|
2980
|
+
});
|
|
2981
|
+
}
|
|
2982
|
+
if (this.shouldDumpSuccessfulOutput(activePhase.routingPhaseIndex)) {
|
|
2983
|
+
this.writeJson(this.getPhaseFileName(activePhase, "output.traces.json"), outputSrj?.traces ?? []);
|
|
2984
|
+
}
|
|
2985
|
+
if (this.activePhase === activePhase) {
|
|
2986
|
+
this.activePhase = null;
|
|
2987
|
+
}
|
|
2988
|
+
}
|
|
2989
|
+
handleError(event) {
|
|
2990
|
+
const activePhase = this.matchActivePhase(event);
|
|
2991
|
+
if (!activePhase)
|
|
2992
|
+
return;
|
|
2993
|
+
const elapsedMs = performance.now() - activePhase.startedAt;
|
|
2994
|
+
const error = this.serializeError(event.error);
|
|
2995
|
+
this.summary.push({
|
|
2996
|
+
subcircuit_id: activePhase.subcircuitId,
|
|
2997
|
+
componentDisplayName: activePhase.componentDisplayName,
|
|
2998
|
+
routingPhaseIndex: activePhase.routingPhaseIndex,
|
|
2999
|
+
phaseOrdinal: activePhase.phaseOrdinal,
|
|
3000
|
+
phaseCount: activePhase.phaseCount,
|
|
3001
|
+
connectionCount: activePhase.connectionCount,
|
|
3002
|
+
obstacleCount: activePhase.obstacleCount,
|
|
3003
|
+
previousTraceCount: activePhase.previousTraceCount,
|
|
3004
|
+
elapsedMs: Math.round(elapsedMs),
|
|
3005
|
+
error,
|
|
3006
|
+
startedAt: activePhase.startedAtIso,
|
|
3007
|
+
completedAt: new Date().toISOString()
|
|
3008
|
+
});
|
|
3009
|
+
if (this.options.enabled || this.options.logOnError) {
|
|
3010
|
+
if (!activePhase.hasLoggedStart) {
|
|
3011
|
+
this.logPhaseStart(activePhase, "failed");
|
|
3012
|
+
}
|
|
3013
|
+
this.log(` ${this.getPhaseLabel(activePhase)} error after ${this.formatElapsed(elapsedMs)}: ${error.message}`);
|
|
3014
|
+
}
|
|
3015
|
+
if (this.shouldDumpFailedInput(activePhase.routingPhaseIndex)) {
|
|
3016
|
+
this.writeJson(this.getPhaseFileName(activePhase, "input.simple-route.json"), event.simpleRouteJson ?? activePhase.simpleRouteJson ?? {});
|
|
3017
|
+
this.writeJson(this.getPhaseFileName(activePhase, "error.json"), {
|
|
3018
|
+
type: "autorouter_phase_error",
|
|
3019
|
+
subcircuit_id: activePhase.subcircuitId,
|
|
3020
|
+
routingPhaseIndex: activePhase.routingPhaseIndex,
|
|
3021
|
+
phaseOrdinal: activePhase.phaseOrdinal,
|
|
3022
|
+
phaseCount: activePhase.phaseCount,
|
|
3023
|
+
elapsedMs: Math.round(elapsedMs),
|
|
3024
|
+
connectionCount: activePhase.connectionCount,
|
|
3025
|
+
obstacleCount: activePhase.obstacleCount,
|
|
3026
|
+
previousTraceCount: activePhase.previousTraceCount,
|
|
3027
|
+
error
|
|
3028
|
+
});
|
|
3029
|
+
}
|
|
3030
|
+
if (this.activePhase === activePhase) {
|
|
3031
|
+
this.activePhase = null;
|
|
3032
|
+
}
|
|
3033
|
+
}
|
|
3034
|
+
writeTimeoutArtifact(activePhase, elapsedMs) {
|
|
3035
|
+
const inputFile = this.getPhaseFileName(activePhase, "input.simple-route.json");
|
|
3036
|
+
const previousTracesFile = this.getPhaseFileName(activePhase, "previous-output.traces.json");
|
|
3037
|
+
const timeoutFile = this.getPhaseFileName(activePhase, "timeout.json");
|
|
3038
|
+
const boardFile = "board.source-and-pcb.circuit.json";
|
|
3039
|
+
this.writeJson(inputFile, activePhase.simpleRouteJson ?? {});
|
|
3040
|
+
this.writeJson(previousTracesFile, this.completedPhaseTraces);
|
|
3041
|
+
this.writeJson(boardFile, this.getCurrentCircuitJson());
|
|
3042
|
+
return this.writeJson(timeoutFile, {
|
|
3043
|
+
type: "autorouter_phase_timeout",
|
|
3044
|
+
subcircuit_id: activePhase.subcircuitId,
|
|
3045
|
+
componentDisplayName: activePhase.componentDisplayName,
|
|
3046
|
+
routingPhaseIndex: activePhase.routingPhaseIndex,
|
|
3047
|
+
phaseOrdinal: activePhase.phaseOrdinal,
|
|
3048
|
+
phaseCount: activePhase.phaseCount,
|
|
3049
|
+
elapsedMs: Math.round(elapsedMs),
|
|
3050
|
+
connectionCount: activePhase.connectionCount,
|
|
3051
|
+
obstacleCount: activePhase.obstacleCount,
|
|
3052
|
+
previousTraceCount: activePhase.previousTraceCount,
|
|
3053
|
+
autorouter: {
|
|
3054
|
+
kind: "default-or-core"
|
|
3055
|
+
},
|
|
3056
|
+
files: {
|
|
3057
|
+
inputSimpleRouteJson: inputFile,
|
|
3058
|
+
previousOutputTraces: previousTracesFile,
|
|
3059
|
+
boardCircuitJson: boardFile
|
|
3060
|
+
},
|
|
3061
|
+
lastProgress: activePhase.lastProgress
|
|
3062
|
+
});
|
|
3063
|
+
}
|
|
3064
|
+
checkLongRunning() {
|
|
3065
|
+
if (!this.activePhase)
|
|
3066
|
+
return;
|
|
3067
|
+
const elapsedMs = performance.now() - this.activePhase.startedAt;
|
|
3068
|
+
if (!this.didCrossLongRunningThreshold(this.activePhase, elapsedMs))
|
|
3069
|
+
return;
|
|
3070
|
+
this.startLongRunningLogging(this.activePhase, elapsedMs);
|
|
3071
|
+
}
|
|
3072
|
+
didCrossLongRunningThreshold(activePhase, elapsedMs) {
|
|
3073
|
+
return Boolean(!this.options.enabled && this.options.longRunningLogThresholdMs && !activePhase.longRunningLoggingStarted && elapsedMs >= this.options.longRunningLogThresholdMs);
|
|
3074
|
+
}
|
|
3075
|
+
startLongRunningLogging(activePhase, elapsedMs) {
|
|
3076
|
+
activePhase.longRunningLoggingStarted = true;
|
|
3077
|
+
this.log(kleur_default.yellow(`Autorouting ${this.getPhaseLabel(activePhase)} has been running for ${this.formatElapsed(elapsedMs)}; enabling phase diagnostics. Re-run with --autorouter-debug for full autorouter logs from the start.`));
|
|
3078
|
+
this.logPhaseStart(activePhase, "long-running");
|
|
3079
|
+
if (activePhase.lastProgress) {
|
|
3080
|
+
this.logProgress(activePhase, activePhase.lastProgress, performance.now());
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
shouldLogPhaseDetails(activePhase) {
|
|
3084
|
+
return Boolean(this.options.enabled || activePhase.longRunningLoggingStarted);
|
|
3085
|
+
}
|
|
3086
|
+
logPhaseStart(activePhase, reason) {
|
|
3087
|
+
const reasonText = reason ? ` ${reason}` : "";
|
|
3088
|
+
this.log([
|
|
3089
|
+
`Autorouting ${activePhase.componentDisplayName} (${activePhase.subcircuitId}) ${this.getPhaseLabel(activePhase)}${reasonText} start:`,
|
|
3090
|
+
`connections=${activePhase.connectionCount},`,
|
|
3091
|
+
`obstacles=${activePhase.obstacleCount},`,
|
|
3092
|
+
`previous_traces=${activePhase.previousTraceCount}`,
|
|
3093
|
+
activePhase.routerDescription ? `, ${activePhase.routerDescription}` : ""
|
|
3094
|
+
].join(" "));
|
|
3095
|
+
const connectionNames = this.getConnectionNames(activePhase.simpleRouteJson);
|
|
3096
|
+
if (connectionNames.length > 0) {
|
|
3097
|
+
this.log(` connections: ${connectionNames.join(", ")}`);
|
|
3098
|
+
}
|
|
3099
|
+
activePhase.hasLoggedStart = true;
|
|
3100
|
+
}
|
|
3101
|
+
logProgress(activePhase, event, now) {
|
|
3102
|
+
const elapsedMs = event.elapsedMs ?? now - activePhase.startedAt;
|
|
3103
|
+
const details = [
|
|
3104
|
+
event.solverName ? `solver=${event.solverName}` : null,
|
|
3105
|
+
event.phase ? `solver_phase=${event.phase}` : null,
|
|
3106
|
+
event.iteration !== undefined ? `iter=${event.iteration}` : event.steps !== undefined ? `steps=${event.steps}` : null,
|
|
3107
|
+
event.progress !== undefined ? `progress=${Math.round(event.progress * 100)}%` : null,
|
|
3108
|
+
event.iterationsPerSecond !== undefined ? `iterations_per_second=${Math.round(event.iterationsPerSecond)}` : null,
|
|
3109
|
+
`elapsed=${this.formatElapsed(elapsedMs)}`
|
|
3110
|
+
].filter(Boolean);
|
|
3111
|
+
this.log(` ${this.getPhaseLabel(activePhase)} progress: ${details.join(" ")}`);
|
|
3112
|
+
}
|
|
3113
|
+
logPhaseEnd(activePhase, {
|
|
3114
|
+
outputTraceCount,
|
|
3115
|
+
outputJumperCount,
|
|
3116
|
+
errorCount,
|
|
3117
|
+
elapsedMs
|
|
3118
|
+
}) {
|
|
3119
|
+
this.log(` ${this.getPhaseLabel(activePhase)} done: routed_traces=${outputTraceCount}, jumpers=${outputJumperCount}, errors=${errorCount}, elapsed=${this.formatElapsed(elapsedMs)}`);
|
|
3120
|
+
}
|
|
3121
|
+
matchActivePhase(event) {
|
|
3122
|
+
if (!this.activePhase)
|
|
3123
|
+
return null;
|
|
3124
|
+
const subcircuitId = event.subcircuit_id ?? event.subcircuitId;
|
|
3125
|
+
if (subcircuitId && subcircuitId !== this.activePhase.subcircuitId) {
|
|
3126
|
+
return null;
|
|
3127
|
+
}
|
|
3128
|
+
return this.activePhase;
|
|
3129
|
+
}
|
|
3130
|
+
shouldDumpInput(routingPhaseIndex) {
|
|
3131
|
+
return this.options.dumpSrj === "all" || this.options.dumpSrj === `phase:${routingPhaseIndex}`;
|
|
3132
|
+
}
|
|
3133
|
+
shouldDumpSuccessfulOutput(routingPhaseIndex) {
|
|
3134
|
+
return this.options.dumpSrj === "all" || this.options.dumpSrj === `phase:${routingPhaseIndex}`;
|
|
3135
|
+
}
|
|
3136
|
+
shouldDumpFailedInput(routingPhaseIndex) {
|
|
3137
|
+
return this.options.dumpSrj === "all" || this.options.dumpSrj === "failed" || this.options.dumpSrj === `phase:${routingPhaseIndex}`;
|
|
3138
|
+
}
|
|
3139
|
+
writeJson(fileName, value) {
|
|
3140
|
+
const debugDir = path.resolve(this.options.debugDir ?? DEFAULT_DEBUG_DIR);
|
|
3141
|
+
fs.mkdirSync(debugDir, { recursive: true });
|
|
3142
|
+
const filePath = path.join(debugDir, fileName);
|
|
3143
|
+
fs.writeFileSync(filePath, JSON.stringify(value, null, 2));
|
|
3144
|
+
return filePath;
|
|
3145
|
+
}
|
|
3146
|
+
getPhaseFileName(activePhase, suffix) {
|
|
3147
|
+
const phaseNumber = activePhase.routingPhaseIndex;
|
|
3148
|
+
return `phase-${phaseNumber}.${suffix}`;
|
|
3149
|
+
}
|
|
3150
|
+
getPhaseLabel(activePhase) {
|
|
3151
|
+
if (activePhase.phaseCount) {
|
|
3152
|
+
return `phase ${activePhase.phaseOrdinal}/${activePhase.phaseCount}`;
|
|
3153
|
+
}
|
|
3154
|
+
return `phase ${activePhase.phaseOrdinal}`;
|
|
3155
|
+
}
|
|
3156
|
+
formatElapsed(elapsedMs) {
|
|
3157
|
+
if (elapsedMs < 1000)
|
|
3158
|
+
return `${Math.round(elapsedMs)}ms`;
|
|
3159
|
+
return `${(elapsedMs / 1000).toFixed(1)}s`;
|
|
3160
|
+
}
|
|
3161
|
+
formatRouter(event) {
|
|
3162
|
+
const parts = [
|
|
3163
|
+
event.autorouterName ? `router=${event.autorouterName}` : null,
|
|
3164
|
+
event.autorouterVersion ? `version=${event.autorouterVersion}` : null,
|
|
3165
|
+
event.effort !== undefined ? `effort=${event.effort}` : null
|
|
3166
|
+
].filter(Boolean);
|
|
3167
|
+
return parts.join(", ");
|
|
3168
|
+
}
|
|
3169
|
+
getConnectionNames(simpleRouteJson) {
|
|
3170
|
+
return (simpleRouteJson?.connections ?? []).map((connection) => {
|
|
3171
|
+
const name = connection.name ?? connection.rootConnectionName ?? connection.source_trace_id;
|
|
3172
|
+
return typeof name === "string" ? name : null;
|
|
3173
|
+
}).filter((name) => Boolean(name));
|
|
3174
|
+
}
|
|
3175
|
+
countErrors(simpleRouteJson) {
|
|
3176
|
+
const errors = simpleRouteJson?.errors;
|
|
3177
|
+
return Array.isArray(errors) ? errors.length : 0;
|
|
3178
|
+
}
|
|
3179
|
+
getCurrentCircuitJson() {
|
|
3180
|
+
try {
|
|
3181
|
+
return this.rootCircuit?.db?.toArray?.() ?? [];
|
|
3182
|
+
} catch {
|
|
3183
|
+
return [];
|
|
3184
|
+
}
|
|
3185
|
+
}
|
|
3186
|
+
serializeError(error) {
|
|
3187
|
+
if (error instanceof Error) {
|
|
3188
|
+
return { message: error.message, stack: error.stack };
|
|
3189
|
+
}
|
|
3190
|
+
if (typeof error === "string") {
|
|
3191
|
+
return { message: error };
|
|
3192
|
+
}
|
|
3193
|
+
return {
|
|
3194
|
+
message: error?.message ?? "Unknown autorouting error",
|
|
3195
|
+
stack: error?.stack
|
|
3196
|
+
};
|
|
3197
|
+
}
|
|
3198
|
+
log(message) {
|
|
3199
|
+
this.options.log(message);
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
|
|
3203
|
+
// lib/shared/importFromUserLand.ts
|
|
3204
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
3205
|
+
import fs2 from "node:fs";
|
|
3206
|
+
import path2 from "node:path";
|
|
2805
3207
|
async function importFromUserLand(moduleName) {
|
|
2806
|
-
const userModulePath =
|
|
2807
|
-
if (
|
|
2808
|
-
const userRequire = createRequire2(
|
|
3208
|
+
const userModulePath = path2.join(process.cwd(), "node_modules", moduleName);
|
|
3209
|
+
if (fs2.existsSync(userModulePath)) {
|
|
3210
|
+
const userRequire = createRequire2(path2.join(process.cwd(), "noop.js"));
|
|
2809
3211
|
try {
|
|
2810
3212
|
const resolvedUserPath = userRequire.resolve(moduleName);
|
|
2811
3213
|
return await import(resolvedUserPath);
|
|
@@ -2828,8 +3230,8 @@ async function importFromUserLand(moduleName) {
|
|
|
2828
3230
|
}
|
|
2829
3231
|
|
|
2830
3232
|
// lib/shared/register-static-asset-loaders.ts
|
|
2831
|
-
import
|
|
2832
|
-
import
|
|
3233
|
+
import fs3 from "node:fs";
|
|
3234
|
+
import path3 from "node:path";
|
|
2833
3235
|
var STATIC_ASSET_EXTENSIONS = [
|
|
2834
3236
|
".glb",
|
|
2835
3237
|
".gltf",
|
|
@@ -2854,15 +3256,15 @@ var TEXT_STATIC_ASSET_EXTENSIONS = new Set([
|
|
|
2854
3256
|
".kicad_sch"
|
|
2855
3257
|
]);
|
|
2856
3258
|
var readFileContentForStaticLoader = (filePath) => {
|
|
2857
|
-
const ext =
|
|
3259
|
+
const ext = path3.extname(filePath).toLowerCase();
|
|
2858
3260
|
if (TEXT_STATIC_ASSET_EXTENSIONS.has(ext)) {
|
|
2859
|
-
return
|
|
3261
|
+
return fs3.readFileSync(filePath, "utf-8");
|
|
2860
3262
|
}
|
|
2861
|
-
const buffer =
|
|
3263
|
+
const buffer = fs3.readFileSync(filePath);
|
|
2862
3264
|
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
2863
3265
|
};
|
|
2864
3266
|
var getStaticFileLoader = (filePath) => {
|
|
2865
|
-
const extWithDot =
|
|
3267
|
+
const extWithDot = path3.extname(filePath).toLowerCase();
|
|
2866
3268
|
const ext = extWithDot.replace(/^\./, "");
|
|
2867
3269
|
return activePlatformConfig?.staticFileLoaderMap?.[ext] ?? activePlatformConfig?.staticFileLoaderMap?.[extWithDot];
|
|
2868
3270
|
};
|
|
@@ -2876,12 +3278,12 @@ var normalizeStaticFileLoaderResult = (result) => {
|
|
|
2876
3278
|
};
|
|
2877
3279
|
};
|
|
2878
3280
|
var getBaseUrlFromTsConfig = () => {
|
|
2879
|
-
const tsconfigPath =
|
|
3281
|
+
const tsconfigPath = path3.join(process.cwd(), "tsconfig.json");
|
|
2880
3282
|
try {
|
|
2881
|
-
if (!
|
|
3283
|
+
if (!fs3.existsSync(tsconfigPath)) {
|
|
2882
3284
|
return null;
|
|
2883
3285
|
}
|
|
2884
|
-
const tsconfigContent =
|
|
3286
|
+
const tsconfigContent = fs3.readFileSync(tsconfigPath, "utf-8");
|
|
2885
3287
|
const tsconfig = JSON.parse(tsconfigContent);
|
|
2886
3288
|
if (tsconfig.compilerOptions?.baseUrl) {
|
|
2887
3289
|
return tsconfig.compilerOptions.baseUrl;
|
|
@@ -2908,8 +3310,8 @@ var registerStaticAssetLoaders = (platformConfig) => {
|
|
|
2908
3310
|
loader: "object"
|
|
2909
3311
|
};
|
|
2910
3312
|
}
|
|
2911
|
-
const baseDir = baseUrl ?
|
|
2912
|
-
const relativePath =
|
|
3313
|
+
const baseDir = baseUrl ? path3.resolve(process.cwd(), baseUrl) : process.cwd();
|
|
3314
|
+
const relativePath = path3.relative(baseDir, args.path).split(path3.sep).join("/");
|
|
2913
3315
|
const pathStr = `./${relativePath}`;
|
|
2914
3316
|
return {
|
|
2915
3317
|
exports: {
|
|
@@ -2948,7 +3350,8 @@ async function generateCircuitJson({
|
|
|
2948
3350
|
saveToFile = false,
|
|
2949
3351
|
platformConfig,
|
|
2950
3352
|
injectedProps,
|
|
2951
|
-
onAsyncEffectStatus
|
|
3353
|
+
onAsyncEffectStatus,
|
|
3354
|
+
autorouterDiagnostics: autorouterDiagnosticsOptions
|
|
2952
3355
|
}) {
|
|
2953
3356
|
debug(`Generating circuit JSON for ${filePath}`);
|
|
2954
3357
|
const React = await importFromUserLand("react");
|
|
@@ -2958,12 +3361,14 @@ async function generateCircuitJson({
|
|
|
2958
3361
|
const runner = new userLandTscircuit.RootCircuit({
|
|
2959
3362
|
platform: platformConfig
|
|
2960
3363
|
});
|
|
2961
|
-
const
|
|
2962
|
-
|
|
3364
|
+
const autorouterDiagnostics = new AutorouterDiagnostics(autorouterDiagnosticsOptions);
|
|
3365
|
+
autorouterDiagnostics.attachToRootCircuit(runner);
|
|
3366
|
+
const absoluteFilePath = path4.isAbsolute(filePath) ? filePath : path4.resolve(process.cwd(), filePath);
|
|
3367
|
+
const projectDir = path4.dirname(absoluteFilePath);
|
|
2963
3368
|
const resolvedOutputDir = outputDir ?? projectDir;
|
|
2964
|
-
const relativeComponentPath =
|
|
2965
|
-
const baseFileName = outputFileName ||
|
|
2966
|
-
const outputPath =
|
|
3369
|
+
const relativeComponentPath = path4.relative(projectDir, absoluteFilePath);
|
|
3370
|
+
const baseFileName = outputFileName || path4.basename(absoluteFilePath).replace(/\.[^.]+$/, "");
|
|
3371
|
+
const outputPath = path4.join(resolvedOutputDir, `${baseFileName}.circuit.json`);
|
|
2967
3372
|
debug(`Project directory: ${projectDir}`);
|
|
2968
3373
|
debug(`Relative component path: ${relativeComponentPath}`);
|
|
2969
3374
|
debug(`Output path: ${outputPath}`);
|
|
@@ -2983,7 +3388,7 @@ async function generateCircuitJson({
|
|
|
2983
3388
|
return false;
|
|
2984
3389
|
if (normalizedFilePath.match(/^\.[^/]/))
|
|
2985
3390
|
return false;
|
|
2986
|
-
if (!ALLOWED_FILE_EXTENSIONS.includes(
|
|
3391
|
+
if (!ALLOWED_FILE_EXTENSIONS.includes(path4.extname(normalizedFilePath)))
|
|
2987
3392
|
return false;
|
|
2988
3393
|
return true;
|
|
2989
3394
|
},
|
|
@@ -3010,14 +3415,16 @@ async function generateCircuitJson({
|
|
|
3010
3415
|
loggedAsyncEffectNames.add(asyncEffectName);
|
|
3011
3416
|
onAsyncEffectStatus?.(asyncEffectName);
|
|
3012
3417
|
}
|
|
3418
|
+
autorouterDiagnostics.checkTimeout();
|
|
3013
3419
|
await new Promise((resolve2) => setTimeout(resolve2, 100));
|
|
3014
3420
|
runner.render();
|
|
3015
3421
|
}
|
|
3016
3422
|
runner.emit("renderComplete");
|
|
3017
3423
|
const circuitJson = await runner.getCircuitJson();
|
|
3424
|
+
autorouterDiagnostics.finalize(circuitJson);
|
|
3018
3425
|
if (saveToFile) {
|
|
3019
3426
|
debug(`Saving circuit JSON to ${outputPath}`);
|
|
3020
|
-
|
|
3427
|
+
fs4.writeFileSync(outputPath, JSON.stringify(circuitJson, null, 2));
|
|
3021
3428
|
}
|
|
3022
3429
|
return {
|
|
3023
3430
|
circuitJson,
|
|
@@ -3028,28 +3435,28 @@ async function generateCircuitJson({
|
|
|
3028
3435
|
|
|
3029
3436
|
// lib/shared/get-platform-config-with-cli-defaults.ts
|
|
3030
3437
|
import { createHash } from "node:crypto";
|
|
3031
|
-
import
|
|
3032
|
-
import
|
|
3438
|
+
import fs5 from "node:fs";
|
|
3439
|
+
import path5 from "node:path";
|
|
3033
3440
|
import { getPlatformConfig } from "@tscircuit/eval/platform-config";
|
|
3034
|
-
function createLocalCacheEngine(cacheDir =
|
|
3441
|
+
function createLocalCacheEngine(cacheDir = path5.join(process.cwd(), ".tscircuit", "cache")) {
|
|
3035
3442
|
return {
|
|
3036
3443
|
getItem: (key) => {
|
|
3037
3444
|
try {
|
|
3038
3445
|
const hash = createHash("md5").update(key).digest("hex");
|
|
3039
3446
|
const keyWithSafeCharacters = key.replace(/[^a-zA-Z0-9]/g, "_");
|
|
3040
|
-
const filePath =
|
|
3041
|
-
return
|
|
3447
|
+
const filePath = path5.join(cacheDir, `${keyWithSafeCharacters.slice(keyWithSafeCharacters.length - 10, keyWithSafeCharacters.length)}-${hash}.json`);
|
|
3448
|
+
return fs5.readFileSync(filePath, "utf-8");
|
|
3042
3449
|
} catch {
|
|
3043
3450
|
return null;
|
|
3044
3451
|
}
|
|
3045
3452
|
},
|
|
3046
3453
|
setItem: (key, value) => {
|
|
3047
3454
|
try {
|
|
3048
|
-
|
|
3455
|
+
fs5.mkdirSync(cacheDir, { recursive: true });
|
|
3049
3456
|
const hash = createHash("md5").update(key).digest("hex");
|
|
3050
3457
|
const keyWithSafeCharacters = key.replace(/[^a-zA-Z0-9]/g, "_");
|
|
3051
|
-
const filePath =
|
|
3052
|
-
|
|
3458
|
+
const filePath = path5.join(cacheDir, `${keyWithSafeCharacters.slice(keyWithSafeCharacters.length - 10, keyWithSafeCharacters.length)}-${hash}.json`);
|
|
3459
|
+
fs5.writeFileSync(filePath, value);
|
|
3053
3460
|
} catch {}
|
|
3054
3461
|
}
|
|
3055
3462
|
};
|
|
@@ -3065,15 +3472,15 @@ function getPlatformConfigWithCliDefaults(userConfig) {
|
|
|
3065
3472
|
loadFromUrl: async (url) => {
|
|
3066
3473
|
let fetchUrl = url;
|
|
3067
3474
|
if (url.startsWith("./") || url.startsWith("../")) {
|
|
3068
|
-
const absolutePath =
|
|
3475
|
+
const absolutePath = path5.resolve(process.cwd(), url);
|
|
3069
3476
|
fetchUrl = `file://${absolutePath}`;
|
|
3070
3477
|
} else if (url.startsWith("/")) {
|
|
3071
|
-
if (
|
|
3478
|
+
if (fs5.existsSync(url)) {
|
|
3072
3479
|
fetchUrl = `file://${url}`;
|
|
3073
3480
|
} else {
|
|
3074
3481
|
const relativePath = `.${url}`;
|
|
3075
|
-
const absolutePath =
|
|
3076
|
-
if (
|
|
3482
|
+
const absolutePath = path5.resolve(process.cwd(), relativePath);
|
|
3483
|
+
if (fs5.existsSync(absolutePath)) {
|
|
3077
3484
|
fetchUrl = `file://${absolutePath}`;
|
|
3078
3485
|
} else {
|
|
3079
3486
|
fetchUrl = `file://${url}`;
|
|
@@ -3146,7 +3553,7 @@ var getSimulationSvgAssetsFromCircuitJson = (circuitJson) => {
|
|
|
3146
3553
|
|
|
3147
3554
|
// lib/shared/compare-images.ts
|
|
3148
3555
|
import looksSame from "@tscircuit/image-utils/looks-same";
|
|
3149
|
-
import
|
|
3556
|
+
import fs6 from "node:fs/promises";
|
|
3150
3557
|
var compareAndCreateDiff = async (buffer1, buffer2, diffPath, createDiff = true) => {
|
|
3151
3558
|
const b1 = Buffer.from(buffer1);
|
|
3152
3559
|
const b2 = Buffer.from(buffer2);
|
|
@@ -3162,9 +3569,9 @@ var compareAndCreateDiff = async (buffer1, buffer2, diffPath, createDiff = true)
|
|
|
3162
3569
|
highlightColor: "#ff00ff",
|
|
3163
3570
|
tolerance: 2
|
|
3164
3571
|
});
|
|
3165
|
-
await
|
|
3572
|
+
await fs6.writeFile(diffPath, diffBuffer);
|
|
3166
3573
|
} else {
|
|
3167
|
-
await
|
|
3574
|
+
await fs6.writeFile(diffPath, buffer2);
|
|
3168
3575
|
}
|
|
3169
3576
|
}
|
|
3170
3577
|
return { equal };
|
|
@@ -3193,7 +3600,7 @@ var processSnapshotFile = async ({
|
|
|
3193
3600
|
cameraPreset,
|
|
3194
3601
|
pcbLayer
|
|
3195
3602
|
}) => {
|
|
3196
|
-
const relativeFilePath =
|
|
3603
|
+
const relativeFilePath = path6.relative(projectDir, file);
|
|
3197
3604
|
const successPaths = [];
|
|
3198
3605
|
const warningMessages = [];
|
|
3199
3606
|
const mismatches = [];
|
|
@@ -3204,7 +3611,7 @@ var processSnapshotFile = async ({
|
|
|
3204
3611
|
let simulationSvgAssets;
|
|
3205
3612
|
try {
|
|
3206
3613
|
if (isCircuitJsonFile(file)) {
|
|
3207
|
-
const parsed = JSON.parse(
|
|
3614
|
+
const parsed = JSON.parse(fs7.readFileSync(file, "utf-8"));
|
|
3208
3615
|
circuitJson = Array.isArray(parsed) ? parsed : [];
|
|
3209
3616
|
} else {
|
|
3210
3617
|
const platformConfigWithCliDefaults = getPlatformConfigWithCliDefaults(platformConfig);
|
|
@@ -3288,12 +3695,12 @@ var processSnapshotFile = async ({
|
|
|
3288
3695
|
} catch (error) {
|
|
3289
3696
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3290
3697
|
if (errorMessage.includes("No pcb_board found in circuit JSON")) {
|
|
3291
|
-
const fileDir =
|
|
3292
|
-
const relativeDir =
|
|
3293
|
-
const snapDir2 = snapshotsDirName ?
|
|
3294
|
-
const base2 =
|
|
3295
|
-
const snap3dPath =
|
|
3296
|
-
const existing3dSnapshot =
|
|
3698
|
+
const fileDir = path6.dirname(file);
|
|
3699
|
+
const relativeDir = path6.relative(projectDir, fileDir);
|
|
3700
|
+
const snapDir2 = snapshotsDirName ? path6.join(projectDir, snapshotsDirName, relativeDir) : path6.join(fileDir, "__snapshots__");
|
|
3701
|
+
const base2 = path6.basename(file).replace(/\.[^.]+$/, "");
|
|
3702
|
+
const snap3dPath = path6.join(snapDir2, `${base2}-3d.snap.png`);
|
|
3703
|
+
const existing3dSnapshot = fs7.existsSync(snap3dPath);
|
|
3297
3704
|
if (existing3dSnapshot) {
|
|
3298
3705
|
return {
|
|
3299
3706
|
ok: false,
|
|
@@ -3304,7 +3711,7 @@ var processSnapshotFile = async ({
|
|
|
3304
3711
|
errorMessage: kleur_default.red(`
|
|
3305
3712
|
❌ Failed to generate 3D snapshot for ${relativeFilePath}:
|
|
3306
3713
|
`) + kleur_default.red(` No pcb_board found in circuit JSON
|
|
3307
|
-
`) + kleur_default.red(` Existing snapshot: ${
|
|
3714
|
+
`) + kleur_default.red(` Existing snapshot: ${path6.relative(projectDir, snap3dPath)}
|
|
3308
3715
|
`)
|
|
3309
3716
|
};
|
|
3310
3717
|
}
|
|
@@ -3325,9 +3732,9 @@ var processSnapshotFile = async ({
|
|
|
3325
3732
|
}
|
|
3326
3733
|
}
|
|
3327
3734
|
}
|
|
3328
|
-
const snapDir = snapshotsDirName ?
|
|
3329
|
-
|
|
3330
|
-
const base =
|
|
3735
|
+
const snapDir = snapshotsDirName ? path6.join(projectDir, snapshotsDirName, path6.relative(projectDir, path6.dirname(file))) : path6.join(path6.dirname(file), "__snapshots__");
|
|
3736
|
+
fs7.mkdirSync(snapDir, { recursive: true });
|
|
3737
|
+
const base = path6.basename(file).replace(/\.[^.]+$/, "");
|
|
3331
3738
|
const snapshots = [];
|
|
3332
3739
|
if (!simulationOnly && (pcbOnly || !schematicOnly)) {
|
|
3333
3740
|
let pcbSnapshotType = "pcb";
|
|
@@ -3361,17 +3768,17 @@ var processSnapshotFile = async ({
|
|
|
3361
3768
|
for (const snapshot of snapshots) {
|
|
3362
3769
|
const { type } = snapshot;
|
|
3363
3770
|
const is3d = type === "3d";
|
|
3364
|
-
const snapPath =
|
|
3365
|
-
const existing =
|
|
3771
|
+
const snapPath = path6.join(snapDir, `${base}-${type}.snap.${is3d ? "png" : "svg"}`);
|
|
3772
|
+
const existing = fs7.existsSync(snapPath);
|
|
3366
3773
|
const newContentBuffer = snapshot.isBinary ? snapshot.content : Buffer.from(snapshot.content, "utf8");
|
|
3367
3774
|
const newContentForFile = snapshot.content;
|
|
3368
3775
|
if (!existing) {
|
|
3369
|
-
|
|
3370
|
-
successPaths.push(
|
|
3776
|
+
fs7.writeFileSync(snapPath, newContentForFile);
|
|
3777
|
+
successPaths.push(path6.relative(projectDir, snapPath));
|
|
3371
3778
|
didUpdate = true;
|
|
3372
3779
|
continue;
|
|
3373
3780
|
}
|
|
3374
|
-
const oldContentBuffer =
|
|
3781
|
+
const oldContentBuffer = fs7.readFileSync(snapPath);
|
|
3375
3782
|
let equal;
|
|
3376
3783
|
let diffPath;
|
|
3377
3784
|
if (createDiff) {
|
|
@@ -3383,16 +3790,16 @@ var processSnapshotFile = async ({
|
|
|
3383
3790
|
}
|
|
3384
3791
|
if (update) {
|
|
3385
3792
|
if (!forceUpdate && equal) {
|
|
3386
|
-
successPaths.push(
|
|
3793
|
+
successPaths.push(path6.relative(projectDir, snapPath));
|
|
3387
3794
|
} else {
|
|
3388
|
-
|
|
3389
|
-
successPaths.push(
|
|
3795
|
+
fs7.writeFileSync(snapPath, newContentForFile);
|
|
3796
|
+
successPaths.push(path6.relative(projectDir, snapPath));
|
|
3390
3797
|
didUpdate = true;
|
|
3391
3798
|
}
|
|
3392
3799
|
} else if (!equal) {
|
|
3393
3800
|
mismatches.push(diffPath ? `${snapPath} (diff: ${diffPath})` : snapPath);
|
|
3394
3801
|
} else {
|
|
3395
|
-
successPaths.push(
|
|
3802
|
+
successPaths.push(path6.relative(projectDir, snapPath));
|
|
3396
3803
|
}
|
|
3397
3804
|
}
|
|
3398
3805
|
return {
|
|
@@ -3405,8 +3812,8 @@ var processSnapshotFile = async ({
|
|
|
3405
3812
|
};
|
|
3406
3813
|
|
|
3407
3814
|
// lib/project-config/index.ts
|
|
3408
|
-
import * as
|
|
3409
|
-
import * as
|
|
3815
|
+
import * as fs8 from "node:fs";
|
|
3816
|
+
import * as path7 from "node:path";
|
|
3410
3817
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
3411
3818
|
|
|
3412
3819
|
// lib/project-config/project-config-schema.ts
|
|
@@ -3481,10 +3888,10 @@ var stripWrappingQuotes = (value) => {
|
|
|
3481
3888
|
var loadProjectEnv = (projectDir) => {
|
|
3482
3889
|
const initialEnvKeys = new Set(Object.keys(process.env));
|
|
3483
3890
|
for (const envFileName of ENV_FILENAMES) {
|
|
3484
|
-
const envPath =
|
|
3485
|
-
if (!
|
|
3891
|
+
const envPath = path7.join(projectDir, envFileName);
|
|
3892
|
+
if (!fs8.existsSync(envPath))
|
|
3486
3893
|
continue;
|
|
3487
|
-
const envContent =
|
|
3894
|
+
const envContent = fs8.readFileSync(envPath, "utf8");
|
|
3488
3895
|
for (const rawLine of envContent.split(/\r?\n/)) {
|
|
3489
3896
|
const line = rawLine.trim();
|
|
3490
3897
|
if (!line || line.startsWith("#"))
|
|
@@ -3502,12 +3909,12 @@ var loadProjectEnv = (projectDir) => {
|
|
|
3502
3909
|
}
|
|
3503
3910
|
};
|
|
3504
3911
|
var loadProjectConfigSync = (projectDir = process.cwd()) => {
|
|
3505
|
-
const configPath =
|
|
3506
|
-
if (!
|
|
3912
|
+
const configPath = path7.join(projectDir, CONFIG_FILENAME);
|
|
3913
|
+
if (!fs8.existsSync(configPath)) {
|
|
3507
3914
|
return null;
|
|
3508
3915
|
}
|
|
3509
3916
|
try {
|
|
3510
|
-
const configContent =
|
|
3917
|
+
const configContent = fs8.readFileSync(configPath, "utf8");
|
|
3511
3918
|
const parsedConfig = JSON.parse(configContent);
|
|
3512
3919
|
return projectConfigSchema.parse(parsedConfig);
|
|
3513
3920
|
} catch (error) {
|
|
@@ -3518,12 +3925,12 @@ var loadProjectConfigSync = (projectDir = process.cwd()) => {
|
|
|
3518
3925
|
var loadProjectConfigModule = async (projectDir) => {
|
|
3519
3926
|
loadProjectEnv(projectDir);
|
|
3520
3927
|
for (const configFileName of CONFIG_MODULE_FILENAMES) {
|
|
3521
|
-
const configPath =
|
|
3522
|
-
if (!
|
|
3928
|
+
const configPath = path7.join(projectDir, configFileName);
|
|
3929
|
+
if (!fs8.existsSync(configPath))
|
|
3523
3930
|
continue;
|
|
3524
3931
|
try {
|
|
3525
3932
|
const moduleUrl = pathToFileURL2(configPath);
|
|
3526
|
-
const stat =
|
|
3933
|
+
const stat = fs8.statSync(configPath);
|
|
3527
3934
|
moduleUrl.searchParams.set("tsci", String(stat.mtimeMs));
|
|
3528
3935
|
const importedModule = await import(moduleUrl.href);
|
|
3529
3936
|
const exportedConfig = importedModule.default ?? importedModule.config ?? importedModule;
|
|
@@ -3570,13 +3977,13 @@ var getSnapshotsDir = (projectDir = process.cwd()) => {
|
|
|
3570
3977
|
return config?.snapshotsDir;
|
|
3571
3978
|
};
|
|
3572
3979
|
var saveProjectConfig = (config, projectDir = process.cwd()) => {
|
|
3573
|
-
const configPath =
|
|
3980
|
+
const configPath = path7.join(projectDir, CONFIG_FILENAME);
|
|
3574
3981
|
try {
|
|
3575
3982
|
const configWithSchema = {
|
|
3576
3983
|
$schema: CONFIG_SCHEMA_URL,
|
|
3577
3984
|
...config ?? {}
|
|
3578
3985
|
};
|
|
3579
|
-
|
|
3986
|
+
fs8.writeFileSync(configPath, JSON.stringify(configWithSchema, null, 2));
|
|
3580
3987
|
return true;
|
|
3581
3988
|
} catch (error) {
|
|
3582
3989
|
console.error(`Error saving tscircuit config: ${error}`);
|