Some checks failed
Deploy / build-and-deploy (push) Has been cancelled
- 调试逻辑下沉到 composables/debug.ts,桌面和移动端共用;模态框抽成 DebugModal.vue(桌面 80vw / 移动 96vw),用 update:show 收口, 关闭按钮、Esc、遮罩三条路径都会清理状态 - 移动端在"操作"菜单里补上调试入口(仅 Python) - 变量面板改为分组展示:栈顶帧的局部变量在前、全局变量在后, 顺序用 pg_encoder 的 ordered_globals / ordered_varnames, __return__ 显示成"返回值"。原来两者是 merge 成一份的, 在函数里分不清哪个是局部、哪个是外面的全局 - 面板关闭时还原全局 output / status,否则主页输出区会停在某一调试步 - 输入切分不再过滤空行,只丢掉末尾换行产生的空串:程序可能正需要读一个 空行,过滤掉会让输入提前耗尽、误报"需要更多输入" - 后端超时/超限的 detail 透传到提示里,调试按钮加 loading 态 - 清掉 computed 和高亮更新里遗留的 console.log(自动播放时 500ms 刷一次) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019QGZaLUWzGPEMTk6A5RShC
75 lines
2.0 KiB
TypeScript
75 lines
2.0 KiB
TypeScript
import { ref } from "vue"
|
||
import { debug as fetchDebugTrace } from "../api"
|
||
import { code, input } from "./code"
|
||
|
||
export const showDebugModal = ref(false)
|
||
export const debugData = ref<any>(null)
|
||
export const debugLoading = ref(false)
|
||
|
||
/**
|
||
* 把输入框内容切成 stdin 行。
|
||
* 只丢掉末尾换行产生的那个空串,中间的空行必须保留 ——
|
||
* 程序可能正需要读一个空行(input() 返回 ""),过滤掉会导致输入提前耗尽。
|
||
*/
|
||
function splitInputLines(text: string): string[] {
|
||
if (!text) return []
|
||
const lines = text.split("\n")
|
||
if (lines[lines.length - 1] === "") lines.pop()
|
||
return lines
|
||
}
|
||
|
||
/**
|
||
* trace 末尾停在 raw_input 即说明输入不足
|
||
* (pg_logger 在缺输入时会立刻 done=True,trace 中至多只有 1 个 raw_input 事件,
|
||
* 所以不能用计数对比,只能看末尾)
|
||
*/
|
||
function endsAtRawInput(data: any): boolean {
|
||
const trace = data?.trace
|
||
if (!trace?.length) return false
|
||
return trace[trace.length - 1].event === "raw_input"
|
||
}
|
||
|
||
export type DebugResult =
|
||
| { ok: true }
|
||
| { ok: false; level: "error" | "warning"; message: string }
|
||
|
||
/**
|
||
* 请求调试数据并打开面板。
|
||
* 提示文案交给调用方展示:useMessage() 只能在组件的 setup 里取。
|
||
*/
|
||
export async function startDebug(): Promise<DebugResult> {
|
||
if (debugLoading.value) return { ok: true }
|
||
|
||
debugLoading.value = true
|
||
let res
|
||
try {
|
||
res = await fetchDebugTrace(code.value, splitInputLines(input.value))
|
||
} catch (err: any) {
|
||
return {
|
||
ok: false,
|
||
level: "error",
|
||
message: `调试失败: ${err?.response?.data?.detail ?? err?.message ?? "未知错误"}`,
|
||
}
|
||
} finally {
|
||
debugLoading.value = false
|
||
}
|
||
|
||
debugData.value = res.data
|
||
|
||
if (endsAtRawInput(res.data)) {
|
||
return {
|
||
ok: false,
|
||
level: "warning",
|
||
message: "程序需要更多输入,请在输入框补全后重新点击调试",
|
||
}
|
||
}
|
||
|
||
showDebugModal.value = true
|
||
return { ok: true }
|
||
}
|
||
|
||
export function closeDebug() {
|
||
showDebugModal.value = false
|
||
debugData.value = null
|
||
}
|