Tell the host when the version notice goes away with the element

The controller dropped its banner on disconnect without asking the host
to repaint. Lit renders neither on disconnect nor on reconnect, so the
markup produced before the detach outlived it: the notice stayed on
screen while the controller no longer owned one, and it left only when
some unrelated update happened to run. Correctness rested on a
coincidence.

Measured on the built module with a counter: the sequence mismatch ->
disconnect -> versions agree -> connect asked for exactly one repaint,
the one that showed the notice. It now asks for two, and the second is
the one that takes the notice away.

Nothing else about the teardown changes. The field is still cleared
because a detached element cannot deliver animationend, reconnect still
rebuilds the notice from the retained input, and a disconnect with no
notice still asks for nothing.

Issue: #536
User-Visible: no
This commit is contained in:
Claude
2026-09-12 03:49:46 +00:00
committed by claude[bot]
parent 4906f0a97f
commit 1e1880f010
50 changed files with 491 additions and 425 deletions
+12 -1
View File
@@ -202,7 +202,18 @@ export class VersionRecoveryController {
this._cancelTimer();
// A detached element cannot be trusted to deliver animationend. Reconnect
// reconstructs the right notice from the retained semantic input.
if (this._banner) this._banner = null;
//
// #536: dropping the field is not enough — the host has to be told. Lit
// renders neither on disconnect nor on reconnect, so markup produced before
// the detach survives it, and the controller would then own no notice while
// one is still on screen. Until some unrelated update happened to run, the
// banner stayed: correctness rested on a coincidence rather than on this
// class. Nothing else about the teardown changes; `changed()` is asked for
// only when a notice actually went away.
if (this._banner) {
this._banner = null;
this.hooks.changed();
}
}
public update(next: VersionRecoveryInput): void {