import { register } from "../engine/registry"; import { BreakSignal, ContinueSignal, RuntimeError, StopSignal } from "../engine/types"; import { interpolate, toNumber } from "../engine/expression"; function sleep(ms: number, signal: AbortSignal): Promise { if (ms <= 0) return Promise.resolve(); return new Promise((resolve, reject) => { const timer = setTimeout(() => { signal.removeEventListener("abort", onAbort); resolve(); }, ms); const onAbort = () => { clearTimeout(timer); reject(new RuntimeError("cancelled", "运行已取消")); }; if (signal.aborted) return onAbort(); signal.addEventListener("abort", onAbort, { once: true }); }); } register(["Trigger.Manual", "Trigger.Schedule", "Trigger.FileArrival"], () => null); register("Basic_Delay_V2", async (ctx, node, args) => { const random = String(args.is_random ?? "0") === "1" || String(args.is_random) === "true"; const seconds = random ? toNumber(args.min_second, 1) + Math.random() * Math.max(0, toNumber(args.max_second, 5) - toNumber(args.min_second, 1)) : toNumber(args.second, 1); ctx.log(`等待 ${seconds.toFixed(2)} 秒`, "info", node.id); await sleep(Math.max(0, seconds) * 1000, ctx.signal); return seconds; }); register("Basic_Delay_V1", async (ctx, node, args) => { const seconds = toNumber(args.second ?? args.time ?? 1, 1); await sleep(Math.max(0, seconds) * 1000, ctx.signal); return seconds; }); register("Basic_Delay", async (ctx, node, args) => { const milliseconds = Number(args.mileSecond ?? 1000); if (!Number.isFinite(milliseconds) || milliseconds < 0 || milliseconds > 2_147_483_647) { throw new RuntimeError("validation_error", "延时时间必须是 0~2147483647 范围内的毫秒数", { nodeId: node.id, componentId: node.componentId }); } await sleep(milliseconds, ctx.signal); return milliseconds / 1000; }); register("Basic_DebugOutput", (ctx, node, args) => { const message = String(args.msg ?? args.message ?? ""); ctx.log(message || "(空)", "info", node.id); return message; }); register("Basic_SetVariable", (ctx, node, args) => { const name = String(node.options?.outputVar || "").trim(); const value = args.value; if (!name) { throw new RuntimeError("validation_error", "「设置变量」未配置输出变量", { nodeId: node.id, componentId: node.componentId, recommendation: "在属性面板的输出变量里填写变量名" }); } ctx.vars[name] = value; ctx.log(`${name} = ${typeof value === "object" ? JSON.stringify(value) : String(value)}`, "info", node.id); return value; }); register("logic_control_var", (ctx, node, args) => { const name = String(interpolate(args.var_name ?? node.options?.outputVar ?? "", ctx.vars) || "").trim(); if (!name) { throw new RuntimeError("validation_error", "「设置变量」未填写变量名称", { nodeId: node.id, componentId: node.componentId }); } const value = interpolate(args.var_value ?? args.value, ctx.vars); ctx.vars[name] = value; ctx.log(`${name} = ${typeof value === "object" ? JSON.stringify(value) : String(value)}`, "info", node.id); return value; }); register("logic_control_break_for", () => { throw new BreakSignal(); }); register("logic_control_next_for", () => { throw new ContinueSignal(); }); register(["logic_control_stop", "logic_control_stop_return"], () => { throw new StopSignal(); });