/* 510-1 [자동 제안] 후보 목록 — 진짜 `B05_Profile_UI_Drainage_Propose.ts` · 관 속성 보관소를 가짜 DOM · fetch 로. * node helper_510_propose.cjs (짝 = `test_510_auto_pipe_propose.py`) */ const path = require("path"); const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); /* ---- 가짜 DOM(쓰는 것만) ---- */ function el(tag) { const listeners = {}; const node = { tag, children: [], hidden: false, disabled: false, checked: false, textContent: "", append(...items) { items.forEach((item) => node.children.push(typeof item === "string" ? { text: item } : item), ); }, replaceChildren(...items) { node.children = []; node.append(...items); }, addEventListener(type, fn) { (listeners[type] ??= []).push(fn); }, fire(type) { (listeners[type] ?? []).forEach((fn) => fn()); }, }; return node; } globalThis.document = { createElement: el }; const sent = []; globalThis.fetch = async (url, init) => { sent.push({ url, body: JSON.parse(init.body) }); return { ok: true, json: async () => ({ spacing: true, proposals: [ { chainage_m: 50, kind: "stream", state: "dismissed", stream_label: { stream: "S1", order: 1 } }, { chainage_m: 150, kind: "stream", state: "held", stream_label: { stream: "S2", order: 1 } }, { chainage_m: 320, kind: "stream", state: "new", stream_label: { stream: "S4", order: 1 }, stream_name: "작은골", }, { chainage_m: 420, kind: "spacing", state: "new" }, ], }), }; }; const { load } = makeLoader({ root: ROOT }); const { createDrainagePropose } = load("B05_Profile", "B05_Profile_UI_Drainage_Propose.ts"); const { createFacilityStore } = load("B05_Profile", "B05_Profile_UI_Drainage_Facility.ts"); (async () => { const added = []; const propose = createDrainagePropose({ projectId: () => "p1", pipeRequest: () => [{ chainage_m: 150, source: "user" }], addPipes: (picks) => picks.forEach((item) => added.push([item.chainage_m, item.stream_label?.stream ?? null])), redraw: () => undefined, }); await propose.open(); const [head, list] = propose.root.children; const [title, add] = head.children; const boxes = list.children.map((row) => row.children[0].children[0]); const out = { sent: { url: sent[0].url, points: sent[0].body.points.length }, rows: list.children.map((row) => row.children[0].children[1].text.trim()), title: title.textContent, addOff: add.disabled, candidates: propose.candidates(), }; boxes[1].checked = true; boxes[1].fire("change"); boxes[2].checked = true; boxes[2].fire("change"); add.fire("click"); out.added = added; out.afterClose = { hidden: propose.root.hidden, candidates: propose.candidates() }; // 관 속성 보관소 — 응답 라벨이 다음 요청에 실림(라벨만 있는 맨 배관도 보관) const store = createFacilityStore(); store.replaceFromResponse([{ chainage_m: 320, stream_label: { stream: "S4", order: 1 } }]); out.carried = store.attach([{ chainage_m: 320, source: "user" }])[0].stream_label ?? null; console.log(JSON.stringify(out)); })();