We keep an honest known-issues table in the docs. This release sweeps it: three core bugs fixed, two spark-ssr fixes (one found while verifying the sweep), and two reports we could not reproduce — now marked that way in the table, with the correct behavior pinned by permanent tests.
spark-html 1.8.2 — three fixes
1. A boolean attribute bound to a falsy non-boolean stayed
on. :disabled="col" with a SQLite
0 rendered disabled="0" — which is still disabled;
presence is what counts for boolean attributes. The :attr
patcher now knows the genuine HTML boolean attributes
(disabled checked selected readonly required multiple hidden
open): a falsy non-boolean removes them. Truthy strings keep their
value (hidden="until-found" still works), and non-boolean
attributes are untouched — :value="0" still renders
value="0". No more :disabled="!!col"
coercion.
2. An interpolated src/poster fetched
the literal . On an imported component, the raw
markup briefly held <img src="{url}"> before
the first patch — and the browser fired a real request for
/%7Burl%7D (a cosmetic but noisy 404 on any component whose
data arrives async). The import path now parks those templates in the
element's patch plan and blanks the attribute until the first patch writes
the real value. Verified in a real browser: zero literal-brace requests,
image loads once, with the final URL.
3. A loop variable passed as a prop to an imported component
crashed hydration. An each nested inside a
<template if> resolved its rows' import placeholders
twice — once with the loop scope (correct) and once more by the
if-block's own import sweep, whose scope doesn't have the loop variable:
"h is not defined", plus a wasted duplicate fetch and boot.
Placeholders are now claimed by the first resolver; nested blocks keep
their own scope. Inlining child markup as a workaround is no longer
needed.
spark-ssr 1.3.4 — two fixes
1. Boolean attributes, mirrored server-side. The same falsy-non-boolean rule now applies in the server renderer, with the same attribute list — otherwise SSR and the hydrated client would disagree about the attribute.
2. An interactive page with zero data sources was served
dead. A page with handlers and binds but no
<spark-ssr> source didn't hydrate at all: handlers
stripped server-side, no client component, no warning. It's a client page
that happens to live in pages/ — it now hydrates like any
other interactive page. (Found while verifying this sweep; it never bit
real apps because real pages have sources.)
While in there, we re-reviewed 1.3.1's live-on-raw-writes
feature end to end. The design held up — per-request coalescing, flush in
finally, opt-in broadcast gating — but the SQL classifier had
two gaps, now fixed: a CTE-led write
(WITH … INSERT/UPDATE/DELETE) was classified as a
read and silently skipped the live ping, cache invalidation, and job hooks;
and a leading SQL comment made an insert fire hooks under the
generic write event, so on="insert:table" jobs
missed it.
Update — spark-ssr 1.3.5 (same day): porting the fixes
back into the San-App example surfaced one more live gap: background
jobs ran with the unwrapped db, so a job's writes (an
hourly payout notifier, an on-insert hook) never pinged live tabs or
invalidated caches. Jobs now get the same coalesced live automation as
custom endpoints — hookless, so a job writing its own trigger table can
never loop.
The two we could not reproduce
Two reports from the San-App port — bind:value losing its
value inside a display:none-toggled container, and interpolated
width/height on a raw <svg>
coming back empty after hydration — did not reproduce on 1.7.0, 1.8.0, or
1.8.1, across client-only, prerender-style hydration, spark-ssr hydration,
a hydrating layout, and template if-nested shapes, in a real
Chromium. Rather than claim a fix we can't verify, the table now marks both
(unconfirmed), the correct behavior is pinned by permanent suite
tests, and we'd love a minimized repro if you can trigger either.
Verifying it
Every fix ships with a regression test (the import double-resolve and eager-src ones poll mid-mount, so a revert fails loudly), and the whole chain ran green: the 500-scenario fuzzer, scanner fuzzer, all package suites, the SSR security and bench suites (render floor intact), the relocation e2e (client / ssr / prerender converge), and the budget gate:
112 passed, 0 failed (spark-ssr)
500 passed, 0 failed (fuzz)
spark-html runtime: 18.00 KB gzip · budget 18 KB
✅ within budget
That last line is exact — the three fixes cost bytes, so two verbose dev warnings got shorter to pay for them. The 18 KB ceiling doesn't move.
Upgrading
Both are pure bug-fix releases, no breaking changes:
npm install spark-html@^1.8.2
bun add spark-ssr@^1.3.5
Details: spark-html on npm · spark-ssr on npm · v1.8.2 · ssr-v1.3.4.