- 새 산근(로직 연결 · 입력값) = 연결 즉시 뒤에서 POST …/estimation/calc(화면 캐시로 셈 · 저장 안 함) · 차례 번호 · 옛 요청 끊기 · 오는 동안 그 줄 금액 칸만 「셈 중」 · 잠금 없음 (새 `B09_Estimation_UI_Live.ts`) · 기준 = payload.user(서버가 그 셈에 쓴 값) - 조작 중 셈 = 마지막 GET · [저장] 의 B08 원천 다시 씀(120 s · 0.6 → 0.15 s) · [저장] · GET 은 늘 새로 읽음 - [저장] 단추 = 왼쪽 아래 [초기화] 옆(B08 과 같은 부품 · 꼴) · 고침 없으면 알림만 - 단계 이동 · [>] = 저장 안 한 고침 있으면 공용 떠남 물음(취소 · 폐기 · 저장) — 옛 자동 저장 없앰 - 서고 사본 payload 의 user 받음(서버 기준) — 화면 캐시와 다른 로직 줄은 뒤에서 다시 셈 - 낡은 시험 고침: 481-2 · 298-2(자동 저장 → 물음 · [저장] 단추) · 184-3 · 304(단추 줄) · 204-2(user 받음) · 200-2(701-3 띠 · 702-1 펼침 뒤 셸 꼴) - 확인 = test_702_3 3 · B09 관련 312 통과 · typecheck 0 · 검증_sub5 T6 11 누름 · 연결 뒤 0.32~0.49 s 금액 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
103 lines
3.8 KiB
JavaScript
103 lines
3.8 KiB
JavaScript
/* 702-3 B09 조작 중 서버 셈 — 진짜 `B09_Estimation_UI_Live.ts` 를 트랜스파일해 가짜 fetch 위에서 돌림 ·
|
|
* 차례 번호 · 옛 요청 끊기 · 같은 지문 다시 안 보냄 · 기다리는 줄(옛 산근 안 씀 · 「셈 중」) · 못 받음 = 한 번만.
|
|
*/
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
|
|
const ROOT = path.join(__dirname, "..", "..");
|
|
|
|
const toasts = [];
|
|
function load(rel, stubs) {
|
|
const src = fs.readFileSync(path.join(ROOT, rel), "utf8");
|
|
const js = ts.transpileModule(src, {
|
|
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
|
|
}).outputText;
|
|
const mod = { exports: {} };
|
|
new Function("exports", "module", "require", js)(mod.exports, mod, (id) => stubs[id] ?? {});
|
|
return mod.exports;
|
|
}
|
|
const live = load("B09_Estimation/B09_Estimation_UI_Live.ts", {
|
|
"@config/config_frontend": { API_BASE_URL: "/api" },
|
|
"@ui/ui_template_elements": { showToast: (text, kind) => toasts.push(kind) },
|
|
});
|
|
|
|
// 가짜 fetch — 보낸 차례대로 쥐고 있다가 손으로 답함 · 끊김 = AbortError
|
|
const pending = [];
|
|
global.fetch = (url, init) =>
|
|
new Promise((resolve, reject) => {
|
|
const one = { url, body: JSON.parse(init.body), resolve, reject, aborted: false };
|
|
init.signal.addEventListener("abort", () => {
|
|
one.aborted = true;
|
|
reject(Object.assign(new Error("aborted"), { name: "AbortError" }));
|
|
});
|
|
pending.push(one);
|
|
});
|
|
const answer = (one, ok = true) =>
|
|
one.resolve({
|
|
ok,
|
|
status: ok ? 200 : 500,
|
|
json: async () => (ok ? { tag: one.body.user.tag } : {}),
|
|
});
|
|
const flush = async () => {
|
|
for (let k = 0; k < 8; k++) await new Promise((r) => setTimeout(r, 0));
|
|
};
|
|
|
|
const logic = (given) => ({
|
|
bill: { rows: [{ key: "hand:a", ref: { tab: "logic", code: "GF1", given } }, { key: "b" }] },
|
|
});
|
|
|
|
(async () => {
|
|
const out = {};
|
|
const settled = [];
|
|
const calc = live.createLiveCalc("P1", (next, sent) =>
|
|
settled.push([next && next.tag, sent.tag]),
|
|
);
|
|
const base = { user: logic({ 높이: 3 }), sheets: { sg_hand: { "hand:a": "SG:old" } } };
|
|
// 기다리는 줄 = 서버 기준과 다른 로직 연결만
|
|
const u1 = { ...logic({ 높이: 4 }), tag: 1 };
|
|
const wait = live.waitingKeys(base, u1);
|
|
out.wait = [...wait];
|
|
out.same = [...live.waitingKeys(base, base.user)];
|
|
out.strip = live.withoutWaiting(base, wait).sheets.sg_hand;
|
|
const sheets = {
|
|
bill: {
|
|
rows: [
|
|
{ key: "hand:a", sum: null },
|
|
{ key: "b", sum: null },
|
|
],
|
|
},
|
|
};
|
|
live.markWaiting(sheets, wait);
|
|
out.mark = sheets.bill.rows.map((r) => r.sum);
|
|
// 차례 — 첫 요청 가는 중 같은 지문 = 안 보냄 · 바뀐 지문 = 옛 것 끊고 새로
|
|
calc.kick(wait, u1);
|
|
calc.kick(wait, u1);
|
|
out.sentAfterSame = pending.length;
|
|
const u2 = { ...logic({ 높이: 5 }), tag: 2 };
|
|
calc.kick(live.waitingKeys(base, u2), u2);
|
|
await flush();
|
|
out.firstAborted = pending[0].aborted;
|
|
out.url = pending[1].url;
|
|
answer(pending[1]);
|
|
await flush();
|
|
out.settled = settled.slice();
|
|
out.busyAfter = calc.busy();
|
|
// 기다릴 줄 없음 = 가던 것 끊음
|
|
const u3 = { ...logic({ 높이: 6 }), tag: 3 };
|
|
calc.kick(live.waitingKeys(base, u3), u3);
|
|
calc.kick(new Set(), base.user);
|
|
await flush();
|
|
out.cancelled = [pending[2].aborted, calc.busy()];
|
|
// 못 받음 = 알림 한 번 · 같은 지문 다시 안 보냄
|
|
const u4 = { ...logic({ 높이: 7 }), tag: 4 };
|
|
calc.kick(live.waitingKeys(base, u4), u4);
|
|
answer(pending[3], false);
|
|
await flush();
|
|
calc.kick(live.waitingKeys(base, u4), u4);
|
|
out.failed = [toasts, settled[settled.length - 1], pending.length];
|
|
console.log(JSON.stringify(out));
|
|
})().catch((e) => {
|
|
console.error(e && e.stack ? e.stack : e);
|
|
process.exit(1);
|
|
});
|