← All posts
Fix

v1.8.1 — a same-event bind + handler ordering fix

spark-html 1.8.1 is a small, focused patch: it fixes the order two kinds of listeners get wired onto the same element when they share an event.

The bug

Spark supports two ways to react to an event on the same element — a bind: (e.g. bind:checked) that writes a DOM value back into your state, and a plain onXXX handler for your own logic. Write both on the same event and you'd reasonably expect your handler to see the state after the bind has written back — that's the whole point of a two-way bind.

<input type="checkbox" bind:checked="agreed" onchange="{track}" />

<script>
  let agreed = false;
  function track() {
    // expected: agreed already reflects the new checkbox state
  }
</script>

Internally, wireElement() registered a component's declared onXXX handlers before its binds. The DOM fires same-type listeners in registration order, so track() could run before the bind's write-back had updated agreed — the handler observed the pre-write-back value on that first tick.

The fix

The fix is a three-line reorder in packages/spark/src/index.js: binds wire before handlers, unconditionally, so registration order always puts the write-back first.

// binds wire BEFORE handlers: a same-event onXXX (onchange={…} beside
// bind:checked=…) must observe the write-back's new value, not the stale
// one — DOM fires same-type listeners in registration order.
for (const b of a.binds) { /* … */ }
for (const h of a.handlers) { /* … */ }

No new concepts, no API surface change, no size cost — this is exactly the kind of fix the limits table and this changelog exist for: name the bug precisely, fix it, ship it, move on.

Verifying it

Every core change here runs the full suite before it ships — 500 fuzz scenarios, the scanner fuzzer, spark-html doctor, the snippet and ecosystem checks, and the gzip budget gate — plus a manual convergence check for the ordering itself. All green:

500 passed, 0 failed (500 scenarios, 29 corpus)
scanner-fuzz: 200 passed, 0 failed
spark-html runtime: 17.93 KB gzip · budget 18 KB
✅ within budget

Upgrading

1.8.1 is a pure bug fix with no breaking changes — bump your spark-html range and you're done:

npm install spark-html@^1.8.1

Full details: spark-html on npm · v1.8.1 on GitHub.