fix(operations): bound handler lifetimes

req: operations/003
This commit is contained in:
slhx agent
2026-07-13 22:06:12 +02:00
parent 2bc68c5777
commit d2ae025e13
7 changed files with 240 additions and 16 deletions
+16
View File
@@ -21,6 +21,14 @@
let currentOperationId = null;
const clientHandlers = new Map();
const clientRuns = new WeakMap();
const activeRequests = new Set();
const REQUEST_TIMEOUT_MS = 10_000;
window.addEventListener("pagehide", () => {
for (const controller of activeRequests) {
controller.abort(new DOMException("hemx request cancelled because page is hidden", "AbortError"));
}
});
function roots() {
const found = [];
@@ -315,6 +323,11 @@
}
const abort = new AbortController();
const timeout = setTimeout(
() => abort.abort(new DOMException(`hemx request timed out after ${REQUEST_TIMEOUT_MS} ms`, "TimeoutError")),
REQUEST_TIMEOUT_MS,
);
activeRequests.add(abort);
let finish;
const done = new Promise((resolve) => { finish = resolve; });
const method = String((form && form.getAttribute("method")) || "POST").toUpperCase();
@@ -346,6 +359,8 @@
emit(rootOf(target), "hemx:error", { message: String(error), status: error.status || null });
}
} finally {
clearTimeout(timeout);
activeRequests.delete(abort);
if (pending.get(target)?.abort === abort) {
pending.delete(target);
showPending(target, false);
@@ -1080,6 +1095,7 @@
function start() {
roots().forEach((root) => {
root.setAttribute("data-hemx-request-timeout-ms", String(REQUEST_TIMEOUT_MS));
try {
bootstrapState(root);
} catch (error) {