From e6486c1b3516c8ff48e6cba3393f4a9d715e432e Mon Sep 17 00:00:00 2001 From: slhx agent Date: Mon, 1 Jun 2026 20:20:26 +0200 Subject: [PATCH] fix(js): release superseded latest pending state When data-slhx-policy=latest aborts an in-flight request, release that request's pending UI bookkeeping before starting the replacement request so pending classes, indicators, and disabled controls do not leak. req: convention/006 req: convention/007 --- slhx-js/runtime/slhx.js | 5 ++++- slhx-js/tests/runtime.rs | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/slhx-js/runtime/slhx.js b/slhx-js/runtime/slhx.js index 94da095..b1a2de1 100644 --- a/slhx-js/runtime/slhx.js +++ b/slhx-js/runtime/slhx.js @@ -174,7 +174,10 @@ const policy = requestPolicy(target, eventName); const active = pending.get(target); if (active && policy === "drop") return; - if (active && policy === "latest") active.abort.abort(); + if (active && policy === "latest") { + active.abort.abort(); + showPending(target, false); + } if (active && policy === "queue") { const base = queues.get(target) || active.done; let queued; diff --git a/slhx-js/tests/runtime.rs b/slhx-js/tests/runtime.rs index 69e1ad5..e9da75e 100644 --- a/slhx-js/tests/runtime.rs +++ b/slhx-js/tests/runtime.rs @@ -143,6 +143,15 @@ fn runtime_supports_queued_request_policy() { assert!(source.contains("const base = queues.get(target) || active.done")); } +#[test] +fn runtime_latest_request_policy_releases_superseded_pending_state() { + // req: convention/006 req: convention/007 + let source = slhx_js::RUNTIME_JS; + + assert!(source.contains("if (active && policy === \"latest\") {\n active.abort.abort();\n showPending(target, false);\n }")); + assert!(source.contains("if (pending.get(target)?.abort === abort)")); +} + #[test] fn runtime_exposes_page_swap_hooks() { let source = slhx_js::RUNTIME_JS;