Skip to content

Migrate web core to signals#795

Merged
jacobsimionato merged 5 commits intogoogle:mainfrom
jacobsimionato:signals
Mar 11, 2026
Merged

Migrate web core to signals#795
jacobsimionato merged 5 commits intogoogle:mainfrom
jacobsimionato:signals

Conversation

@jacobsimionato
Copy link
Collaborator

@jacobsimionato jacobsimionato commented Mar 8, 2026

This PR migrates the core reactive reactivity system in web_core from RxJS to Preact Signals.

Motivation

The migration to Preact Signals significantly simplifies the data-binding layer and aligns with a more modern, synchronous state management paradigm. RxJS Observable streams, while powerful, introduce overhead when handling simple state properties and make synchronous resolution complex (e.g., needing to emit an initial value synchronously upon subscription). Signals inherently hold a current value and provide granular reactivity with less boilerplate.

Key Architectural Changes

  1. DataContext Reactivity Model

    • Removed all RxJS dependencies (Observable, combineLatest, switchMap, etc.).
    • Introduced resolveSignal<V>(), which converts A2UI DynamicValue objects (literals, paths, and function calls) into a reactive Preact Signal<V>.
    • subscribeDynamicValue now creates a Preact effect that watches the underlying Signal and emits changes to the subscriber.
  2. DataModel Updates

    • The DataModel was refactored to manage a map of paths to Signal instances rather than relying on custom RxJS subjects.
    • Introduced a shallow-cloning mechanism during updates to ensure object/array reference changes correctly trigger Signal updates (as Signals use strict equality).
  3. Function Execution & Resource Management (AbortSignal)

    • Crucial Fix: Addressed a fundamental impedance mismatch between Observables and Signals. Observables couple data emission with lifecycle teardown (via subscription disposal). Signals do not.
    • To prevent resource leaks (like dangling setInterval timers in the metronome function), introduced the Cancellation Token Pattern using standard web AbortSignal APIs.
    • Functions that manage long-running resources now receive an abortSignal?: AbortSignal parameter.
    • DataContext now creates an AbortController for each reactive function execution. It aborts the controller when the function arguments change (triggering a re-evaluation) or when the component utilizing the function is disposed.
  4. Basic Functions & Catalog

    • Refactored BASIC_FUNCTIONS (like formatString) to consume and return Signals instead of Observables. formatString now uses computed() to combine dynamic parts.
  5. Test Migration

    • Migrated all unit tests across the framework to assert against Signals and synchronous value resolution, replacing RxJS subscription testing patterns.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request migrates the reactive programming paradigm from RxJS Observables to Preact Signals across the web_core renderer. Key changes include updating package.json dependencies, refactoring DataContext and DataModel classes to use Signals for reactive value resolution and subscriptions, and adapting function implementations and tests accordingly. Specifically, rxjs imports are replaced with @preact/signals-core, FunctionImplementation types are updated, and the internal subscription and notification mechanisms in DataModel are re-engineered to leverage Signals, including shallow cloning for object/array updates. Review comments highlight a resource leak in a test metronome function due to the lack of a cleanup mechanism for setInterval after the migration from Observables, the removal of essential JSDoc comments from the DataContext class that need to be restored, and a request to replace verbose internal comments in DataModel's updateSignal with a concise explanation for shallow copying. An outdated test description also needs to be updated to reflect the change from observables to signals.

@jacobsimionato jacobsimionato merged commit 31d57cb into google:main Mar 11, 2026
9 checks passed
@github-project-automation github-project-automation bot moved this from Todo to Done in A2UI Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants