Skip to content

Fix webcam input: Ensure state used in the template is @state()#7493

Merged
kevinpschaaf merged 1 commit intomainfrom
fix-webcam
Jan 15, 2026
Merged

Fix webcam input: Ensure state used in the template is @state()#7493
kevinpschaaf merged 1 commit intomainfrom
fix-webcam

Conversation

@kevinpschaaf
Copy link
Collaborator

@kevinpschaaf kevinpschaaf commented Jan 15, 2026

Fixes b/475312122

When the record button is clicked, the private #recorder field is set, which is what changes the template from the "record" button to the "stop" button. Since #recorder wasn't marked as state(), the template wasn't re-rendered based on this assignment, and since clicking the button immediately disables it, there was no way to stop recording.

Appears to have been a latent bug, exposed by #7458 (found via bisect). That PR resulted in lit being bumped from 3.3.1 to 3.3.2, which included a bugfix in the lit core library: lit/lit#4999 "Fix a bug in change detection with decorated standard private accessors".

The reason the fix in Lit broke Opal was because that in the same microtask that #recorder was being set, the #clearValues() method was being called which sets the @state() #value field to null. Since null is the initial value, this should not have triggered a re-render but did, because of the Lit bug above: Lit reading newValue in requestUpdate incorrectly returned undefined for a private field, hence setting to null always failed equality check and incorrectly triggered an update (compensating for #recorder not being marked as state). The fix to Lit means that nothing was triggering a re-render after the record button was clicked. Thus ensuring that the #recorder field was properly marked as @state is all that's needed.

@kevinpschaaf kevinpschaaf merged commit 0f925bf into main Jan 15, 2026
3 checks passed
@kevinpschaaf kevinpschaaf deleted the fix-webcam branch January 15, 2026 07:07
kevinpschaaf added a commit that referenced this pull request Jan 16, 2026
)

Fixes b/475312122

When the record button is clicked, the private `#recorder` field is set,
which is what changes the template from the "record" button to the
"stop" button. Since `#recorder` wasn't marked as `state()`, the
template wasn't re-rendered based on this assignment, and since clicking
the button immediately disables it, there was no way to stop recording.

Appears to have been a latent bug, exposed by
#7458 (found via
bisect). That PR resulted in `lit` being bumped from `3.3.1` to `3.3.2`,
which included a bugfix in the lit core library:
lit/lit#4999 "Fix a bug in change detection with
decorated standard private accessors".

The reason the fix in Lit broke Opal was because that in the same
microtask that `#recorder` was being set, the `#clearValues()` method
was being called which did set the `@state() #value` field to `null`.
Since `null` is the initial value, this should not have triggered a
re-render but did, because of the Lit bug above: Lit reading `newValue`
in `requestUpdate` incorrectly returned `undefined` for a private field,
hence setting to `null` always failed equality check and incorrectly
triggered an update (compensating for `#recorder` not being marked as
state). The fix to Lit means that nothing was triggering a re-render
after the record button was clicked. Thus ensuring that the `#recorder`
field was properly marked as `@state` is all that's needed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant