Files
Aislo/resources/tester/helper_511_a_browser.cjs
T

91 lines
3.8 KiB
JavaScript

/* PLAN 511-A 브라우저 길 헬퍼 — `design_calc_server.ts` 를 그 자리에서 트랜스파일 · 판(`design_calc_sites`)과
* fetch 를 가짜로 끼워 판 따라 길 고름 · 잠잠 · 끊음 · 대조 · 기록을 잼. 결과 = 표준출력 JSON 한 벌.
* 짝 = `test_511_a_calc_browser.py`. */
const path = require("path");
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const board = {};
const fetched = [];
let answer = (body) => ({ [body.run[0]]: body.inputs.args?.[body.run[0]]?.[0] ?? null });
globalThis.fetch = async (url, init) => {
const body = JSON.parse(init.body);
fetched.push({ url, run: body.run, at: Date.now() });
if (init.signal?.aborted) throw new DOMException("끊김", "AbortError");
return {
ok: true,
status: 200,
json: async () => ({ results: answer(body), ms: 1, wall_ms: 2 }),
};
};
const plain = (value) => JSON.parse(JSON.stringify(value));
const { loadTs } = makeLoader({
root: ROOT,
stubs: {
design_calc_sites: {
calcOnServerNow: (key) => board[key] === "server",
calcProjectId: () => "p1",
},
design_calc_node_trial: { plain },
},
});
const mod = loadTs(path.join(ROOT, "A00_Common", "design", "design_calc_server.ts"));
const tick = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const echo = (value) => value;
(async () => {
const out = {};
// 1 판 both — 브라우저 값 · 서버 부름 0 · 브라우저 ms 기록
out.both = mod.calcChecked("quantity", "cross.fit", echo, [5]);
await tick(500);
out.bothFetched = fetched.length;
out.local = globalThis.__aisloCalcServer.local["cross.fit"].length;
// 2 판 server — 브라우저 값 바로 · 잠잠 뒤 한 번(빠른 둘째 부름이 첫째를 끊음) · 같음
board.quantity = "server";
let applied = 0;
mod.calcChecked("quantity", "cross.fit", echo, [6], { apply: () => (applied += 1) });
out.server = mod.calcChecked("quantity", "cross.fit", echo, [7], { apply: () => (applied += 1) });
out.beforeQuiet = fetched.length;
await tick(500);
out.afterQuiet = fetched.length;
const calls = globalThis.__aisloCalcServer.calls;
out.same = calls[calls.length - 1].same;
out.applied = applied;
// 3 서버 값이 다름 — apply(서버 값)
answer = () => ({ "cross.fit": 99 });
let got = null;
mod.calcChecked("quantity", "cross.fit", echo, [8], { apply: (v) => (got = v) });
await tick(500);
out.diffApplied = got;
out.diffSame = calls[calls.length - 1].same;
// 4 그리기 자리 — 처음 undefined · 답 오면 redraw · 같은 입력 = fresh
answer = (body) => ({ "masshaul.series": ["s", body.inputs.args["masshaul.series"][0]] });
let redraws = 0;
const first = mod.calcFromServer("quantity", "masshaul.series", [1], () => (redraws += 1));
await tick(500);
const second = mod.calcFromServer("quantity", "masshaul.series", [1], () => (redraws += 1));
const third = mod.calcFromServer("quantity", "masshaul.series", [2], () => (redraws += 1));
out.draw = { first, second, third, redraws };
await tick(500);
// 5 비동기 자리 — outer 끊음 = undefined · 부름 0
const before = fetched.length;
const outer = new AbortController();
const pending = mod.calcOnServerOnly("quantity", "slot", mod.areasRequest([]), outer.signal);
outer.abort();
out.aborted = (await pending) === undefined && fetched.length === before;
// 6 왕복 흉내 — delayMs 만큼 늦음
globalThis.__aisloCalcServer.delayMs = 80;
answer = () => ({ "structure.layouts": { areas: [1] } });
const t0 = Date.now();
out.onlyValue = await mod.calcOnServerOnly("quantity", "slot2", mod.areasRequest([]));
out.delayed = Date.now() - t0 >= 400 + 80;
out.roundMs = calls[calls.length - 1].roundMs;
out.url = fetched[fetched.length - 1].url;
process.stdout.write(JSON.stringify(out));
})();