Add explicit signal subscriptions to component() renders#60
Add explicit signal subscriptions to component() renders#60JosunLP merged 10 commits intodevelopmentfrom
component() renders#60Conversation
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
component() renders
There was a problem hiding this comment.
Pull request overview
Adds an explicit, typed subscription boundary between the component() Web Component system and the reactive module so components can declare external reactive sources (signals) that drive re-renders via effect(), including reconnect resubscription/sync behavior.
Changes:
- Extends
ComponentDefinition/ComponentRenderContextwithsignalsand introducesComponentSignalLike/ComponentSignalstypes. - Wires component instances to re-render on declared signal/computed changes using
effect()+untrack(), with cleanup on disconnect and resubscribe on reconnect. - Adds component tests covering signal-driven updates, computed-driven updates, explicit-only subscription behavior, and reconnect synchronization.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/component/component.ts |
Adds reactive effect subscription lifecycle to trigger component re-renders from declared signals and dispose/resubscribe across connect/disconnect. |
src/component/types.ts |
Introduces signal-related types and threads signals through the render context and component definition generics. |
src/component/index.ts |
Re-exports the new signal-related component types from the component module entrypoint. |
tests/component.test.ts |
Adds tests validating signal/computed re-rendering, explicit subscription boundaries, and reconnect resync behavior. |
…nent Signed-off-by: Jonas Pfalzgraf <info@josunlp.de>
|
@copilot apply changes based on the comments in this thread |
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Applied the requested review-thread fixes in c9d7ec8: |
There was a problem hiding this comment.
Pull request overview
This PR adds an explicit bridge between the component and reactive modules so Web Components defined via component() can declare external reactive sources and automatically re-render when those sources change.
Changes:
- Adds
signalstoComponentDefinitionand exposes typedsignalsonComponentRenderContext. - Wires component instances to declared reactive sources via
effect(), re-rendering on updates and cleaning up on disconnect/reconnect. - Adds component tests covering signal/computed-driven re-rendering, explicit-only subscriptions, and reconnect synchronization.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/component.test.ts | Adds new tests validating re-render behavior driven by declared signals/computeds and reconnect resubscription behavior. |
| src/component/types.ts | Introduces ComponentSignalLike, ComponentSignals, and extends render context/definition generics to include typed signals. |
| src/component/component.ts | Subscribes to declared signals via effect(), triggers re-renders under untrack(), and disposes/restores subscriptions on disconnect/reconnect. |
| src/component/index.ts | Re-exports newly added public component signal-related types. |
| src/full.ts | Adds the new component signal-related types to the full/CDN entrypoint exports. |
|
@copilot apply changes based on the comments in this thread |
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Applied the follow-up fixes in 6910e00: non-empty typed |
There was a problem hiding this comment.
Pull request overview
This PR adds an explicit integration point between the component and reactive modules so Web Components can declare which external reactive sources (signals/computeds) should drive re-renders, instead of relying on incidental reads during render().
Changes:
- Introduces
signalsonComponentDefinitionand threads typedsignalsthroughComponentRenderContext. - Wires component instances to declared reactive sources via
effect(), re-rendering on changes and cleaning up on disconnect/reconnect. - Adds tests covering signal/computed re-rendering, explicit-only subscriptions, and reconnect synchronization.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/component/types.ts |
Adds ComponentSignalLike, ComponentSignals, and extends component typing to include signals in the definition + render context. |
src/component/component.ts |
Subscribes to declared signals via effect() and triggers update renders under untrack(); cleans up subscriptions on disconnect and restores on reconnect. |
tests/component.test.ts |
Adds type-level and runtime tests for signal-driven rendering and reconnect behavior. |
src/component/index.ts |
Re-exports new public types from the component module entrypoint. |
src/full.ts |
Re-exports new component types from the full/CDN entrypoint. |
|
@copilot apply changes based on the comments in this thread |
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Erledigt in 7b29f98. Beim Reconnect ruft |
There was a problem hiding this comment.
Pull request overview
This PR adds an explicit, typed “signals” subscription bridge between the component system and the reactive module so components can re-render when declared external reactive sources change (without implicitly subscribing to incidental reads during render()).
Changes:
- Adds
signalstyping toComponentDefinitionand exposes typedsignalsonComponentRenderContext. - Wires component instances to declared signal/computed sources via
effect()and usesuntrack()for signal-driven renders. - Adds component tests covering signal/computed-driven re-rendering, explicit-only subscription behavior, reconnect sync, and error routing.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/component/types.ts |
Introduces ComponentSignalLike/ComponentSignals and extends component definition/render context generics to include typed signals. |
src/component/component.ts |
Implements runtime signal subscription setup/teardown using effect() + untrack(), including reconnect resubscription logic. |
tests/component.test.ts |
Adds runtime and type-level tests validating re-render behavior, explicit subscription boundaries, reconnect behavior, and error routing. |
src/component/index.ts |
Re-exports new public component signal-related types. |
src/full.ts |
Exposes the new component signal-related types in the full/CDN entrypoint. |
|
@copilot apply changes based on the comments in this thread |
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Erledigt in 3fe00bc. Die JSDoc für |
There was a problem hiding this comment.
Pull request overview
This PR adds an explicit integration point between the component system and the reactive module so components can declare external reactive sources (signals) and automatically re-render when those sources change, including resubscribing and resyncing on reconnect.
Changes:
- Extends component typings with
ComponentSignalLike,ComponentSignals, and asignalsfield onComponentRenderContext, plus a newTSignalsgeneric onComponentDefinition. - Wires component instances to reactive
effect()subscriptions for declared signals, with cleanup on disconnect and resubscribe/resync on reconnect (underuntrack()to prevent implicit subscriptions fromrender()). - Adds component tests covering signal/computed-driven re-rendering, explicit-only subscription behavior, reconnect behavior, and error routing via
onError.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/component/types.ts |
Introduces the public signals typing surface area (signal-like types, render context extension, generic enforcement). |
src/component/component.ts |
Implements runtime subscription lifecycle via effect()/cleanup and passes signals into render context. |
src/component/index.ts |
Re-exports the new public component signal types. |
src/full.ts |
Exposes the new component signal types from the full/CDN entrypoint. |
tests/component.test.ts |
Adds test coverage for signal/computed re-rendering, explicit-only subscription boundary, reconnect resync, and error handling. |
|
@copilot apply changes based on the comments in this thread |
Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com>
Erledigt in b783a30. Signal-getriebene Re-Renders und Reconnect-Resyncs umgehen |
There was a problem hiding this comment.
Pull request overview
This pull request adds an explicit, typed integration point between the component() module and the reactive module so Web Components can subscribe to declared external reactive sources and re-render when those sources change (without creating implicit subscriptions from incidental reads during render()).
Changes:
- Introduces
signalsonComponentDefinitionplusComponentSignalLike/ComponentSignalstypes, and addssignalstoComponentRenderContext. - Wires component instances to re-render on declared signal/computed changes via
effect(), with teardown on disconnect and resubscription + resync on reconnect (renders run underuntrack()). - Expands component tests to cover signal-driven re-renders, computed support, explicit-only subscription behavior, reconnect syncing, and error routing.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
src/component/types.ts |
Adds signal-related public types and threads typed signals into component definition/context generics. |
src/component/component.ts |
Implements runtime subscription lifecycle (effect/untrack), reconnect behavior, and passes signals into render context. |
src/component/index.ts |
Re-exports new public signal-related component types. |
src/full.ts |
Keeps the full/CDN entrypoint type exports in sync with the component module. |
tests/component.test.ts |
Adds coverage for signal/computed-driven renders, explicit subscription boundary, reconnect behavior, and error handling. |
* Add `bool()` support for boolean attributes in component templates (#55) Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Jonas Pfalzgraf <info@josunlp.de> * Add typed state generics to component definitions (#56) Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Jonas Pfalzgraf <info@josunlp.de> * Pass attribute change metadata to component `updated()` hooks (#58) Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Jonas Pfalzgraf <info@josunlp.de> * Add per-component sanitizer overrides for component render output (#57) * Initial plan * feat: add per-component sanitizer options Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * docs: clarify component sanitizer baseline Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * docs: warn about sensitive component sanitizer opts Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * test: cover sanitizer allowTags overrides Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * perf: precompute component sanitizer allowlists Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> --------- Signed-off-by: Jonas Pfalzgraf <info@josunlp.de> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> Co-authored-by: Jonas Pfalzgraf <info@josunlp.de> * Pass previous props into component `beforeUpdate` (#59) * Initial plan * Add previous props to beforeUpdate hook Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * Refine beforeUpdate old props implementation Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * Fix beforeUpdate typing regressions Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> --------- Signed-off-by: Jonas Pfalzgraf <info@josunlp.de> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> Co-authored-by: Jonas Pfalzgraf <info@josunlp.de> * Add explicit signal subscriptions to `component()` renders (#60) * Initial plan * feat: add component signal subscriptions Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * chore: document signal subscription tracking Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix: address signal integration review feedback Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix: tighten component signal typing Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix: resolve eslint failure in component signal test Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix: handle reconnect lifecycle and signal effect errors Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix: preserve reconnect signal wiring after hook errors Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix: skip beforeUpdate for signal rerenders Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> --------- Signed-off-by: Jonas Pfalzgraf <info@josunlp.de> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> Co-authored-by: Jonas Pfalzgraf <info@josunlp.de> * Add trusted sanitized fragments for `safeHtml` composition (#61) * Initial plan * feat: add trusted safeHtml fragment support Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * chore: finalize trusted safeHtml support Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * docs: address trusted safeHtml review feedback Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * docs: fix second trusted safeHtml review follow-up Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * refactor: split trusted html helpers from sanitizer Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * refactor: tighten trusted html branding Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * docs: tighten trusted html internals Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> --------- Signed-off-by: Jonas Pfalzgraf <info@josunlp.de> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> Co-authored-by: Jonas Pfalzgraf <info@josunlp.de> * Reuse component shadow-root style nodes across re-renders (#62) * Initial plan * fix: reuse component style element on rerender Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * chore: finalize component style reuse fix Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * test: tighten style reuse regression assertions Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * Add `@bquery/bquery/storybook` template helpers for Storybook stories (#63) * Initial plan * feat: add storybook template helper Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * docs: clarify storybook when fallback behavior Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix: keep storybook helpers out of full bundle Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix: sanitize storybook helper output Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * test: tighten storybook helper security coverage Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * feat: enhance storyHtml with improved boolean attribute handling and sanitization tests * fix: update storyHtml example to reflect correct boolean attribute output * fix: defensive tag delimiter and parser comments per code review Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * chore: release version 1.6.0 - Update CHANGELOG.md for version 1.6.0 release notes including added features, changes, fixes, and security improvements. - Enhance README.md to document new boolean attribute helpers and Storybook integration. - Update bun.lock to reflect dependency upgrades for Storybook and happy-dom. - Modify definition.md to include new Storybook helpers and component state management features. - Revise components.md to demonstrate new boolean attribute handling and typed state in components. - Update getting-started.md with Storybook authoring examples and improved module descriptions. - Enhance security.md to clarify sanitization practices and introduce trusted fragment handling. - Revise index.md to highlight new Storybook helpers in the feature list. - Update llms.txt to reflect the new version 1.6.0. - Bump version in package.json to 1.6.0 and update devDependencies for Storybook. * Address review feedback for test setup, test type coverage, and component state keys (#65) * Initial plan * Address review feedback for test typing and setup Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * Finalize review feedback fixes Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * Export component state key type Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * Default component state key generic Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * Tighten component/state update semantics and Storybook attribute sanitization (#66) * Initial plan * fix review follow-up for state updates and storybook sanitization Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix storybook attribute value scanning Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix storybook interpolation boundary parsing Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * docs align storybook attribute scan jsdoc Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> --------- Signed-off-by: Jonas Pfalzgraf <info@josunlp.de> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Initial plan * feat: add component signal subscriptions Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * chore: document signal subscription tracking Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix: address signal integration review feedback Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix: tighten component signal typing Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix: resolve eslint failure in component signal test Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix: handle reconnect lifecycle and signal effect errors Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix: preserve reconnect signal wiring after hook errors Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> * fix: skip beforeUpdate for signal rerenders Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> --------- Signed-off-by: Jonas Pfalzgraf <info@josunlp.de> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: JosunLP <20913954+JosunLP@users.noreply.github.com> Co-authored-by: Jonas Pfalzgraf <info@josunlp.de>
component()could read reactive values duringrender(), but those reads were one-shot and never drove future updates. This change adds an explicit bridge between the component and reactive modules so components can declare external reactive sources and re-render when those sources change.New component API
signalstoComponentDefinition.ComponentRenderContextwith typedsignalsso render functions can consume declared reactive sources directly.Reactive lifecycle wiring
effect()mechanism.Explicit subscription boundary
signalsdrive re-renders.untrack()so incidental signal reads insiderender()do not create implicit subscriptions.Coverage
💬 Send tasks to Copilot coding agent from Slack and Teams to turn conversations into code. Copilot posts an update in your thread when it's finished.