query icon indicating copy to clipboard operation
query copied to clipboard

refactor(angular-query): Remove effects from base query

Open ThiloAschebrock opened this issue 3 months ago โ€ข 2 comments

๐ŸŽฏ Changes

This PR is a follow-up to #9098 and aligns queries with the proposed change for mutations. With this change queries should have a more consistent state as they no longer depend on Angular to sync the state via effects.

Additionally, this change would allow to (optionally?) lazily execute queries in future, i.e., queries would only run if the data is read by some consumer.

โœ… Checklist

  • [x] I have followed the steps in the Contributing guide.
  • [x] I have tested this code locally with pnpm run test:pr.

๐Ÿš€ Release Impact

  • [x] This change affects published code, and I have generated a changeset.
  • [ ] This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Refactor
    • Improved query internals for more consistent reactive restoration, persistent observer behavior, proactive result updates, and more reliable pending-fetch tracking and cleanup.
  • Tests
    • Updated test suite to use async timer APIs and direct stability awaits for more reliable, consistent tests.
  • Chores
    • Added a changeset marking a minor version bump.

ThiloAschebrock avatar Oct 26 '25 05:10 ThiloAschebrock

๐Ÿฆ‹ Changeset detected

Latest commit: d4f6b87872db28c937fa749479b13b4f8e3c0f2c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@tanstack/angular-query-experimental Minor
@tanstack/angular-query-persist-client Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

changeset-bot[bot] avatar Oct 26 '25 05:10 changeset-bot[bot]

Walkthrough

Refactors the base query in @tanstack/angular-query-experimental to stop relying on effect execution, introducing signal-based persistent observer handling, a linkedResultSignal, PendingTaskRef-based fetch tracking, DestroyRef cleanup, and test updates replacing TestBed.tick with Vitest async timer APIs.

Changes

Cohort / File(s) Summary
Changeset
.changeset/little-parks-arrive.md
Adds a changeset documenting a minor version bump and the refactor removing effect-execution dependency.
Tests
packages/angular-query-experimental/src/__tests__/inject-query.test.ts
Replaces synchronous TestBed.tick usage and manual Promise.resolve waits with Vitest async timer APIs (vi.runAllTimersAsync, vi.runOnlyPendingTimersAsync, vi.advanceTimersByTimeAsync) and direct awaits of app.whenStable().
Core Query Logic
packages/angular-query-experimental/src/create-base-query.ts
Reworks base query: uses DestroyRef, replaces isRestoring() with isRestoringSignal(), keeps a persistent observer updated via untracked(), replaces optimistic-outcome signal with a writable linkedResultSignal, integrates PendingTaskRef for fetch tracking, batches notifications, adds cleanup on destroy, and adds a proactive effect to drive execution.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Component
    participant createBaseQuery
    participant Observer
    participant linkedResultSignal
    participant PendingTaskRef
    participant DestroyRef

    Component->>createBaseQuery: instantiate query
    createBaseQuery->>Observer: create persistent observer (untracked updates)
    createBaseQuery->>linkedResultSignal: register proactive effect
    linkedResultSignal->>Observer: trigger evaluation / execution

    Observer->>PendingTaskRef: add pending task (fetching)
    Observer->>linkedResultSignal: update result signal
    PendingTaskRef->>linkedResultSignal: clear when idle

    Component->>DestroyRef: component destroyed
    DestroyRef->>createBaseQuery: invoke cleanup
    createBaseQuery->>Observer: unsubscribe
    createBaseQuery->>PendingTaskRef: clear pending tasks

Estimated code review effort

๐ŸŽฏ 3 (Moderate) | โฑ๏ธ ~20 minutes

  • Pay special attention to the linkedResultSignal implementation and its writable semantics for Angular <19 compatibility.
  • Verify PendingTaskRef integration and the correctness of adding/clearing pending tasks around observer state transitions.
  • Review the proactive effect and DestroyRef cleanup to ensure no timing or memory-leak regressions.
  • Confirm test changes correctly flush timers and app.whenStable() in all edge cases.

Possibly related PRs

  • TanStack/query#9666: Overlapping changes to angular-query-experimental base query handling and pending-task/cleanup behavior; likely closely related.

Suggested reviewers

  • arnoud-dv
  • TkDodo

Poem

๐Ÿฐ
I hopped through signals, soft and spry,
LinkedResult hummed without a sigh,
Pending tasks I gently keep,
Cleanup neat before I sleep,
Timers async โ€” hop, leap, reply!

Pre-merge checks and finishing touches

โœ… Passed checks (3 passed)
Check name Status Explanation
Title Check โœ… Passed The pull request title "refactor(angular-query): Remove effects from base query" is directly aligned with the main changes in the changeset. The raw summary confirms that the primary change is a refactor of the base query to "no longer rely on the execution of effects," and the create-base-query.ts changes show removal of effect-based state synchronization in favor of a signal-based approach. The title is concise, uses a clear conventional commit format, and specifically identifies what is being removed (effects) and from where (base query), making it easily understandable for someone scanning the pull request history.
Description Check โœ… Passed The pull request description fully adheres to the repository template structure. All three required sections are present: the ๐ŸŽฏ Changes section provides clear context about the refactor being a follow-up to PR #9098 and explains the motivation around state consistency and future lazy execution; the โœ… Checklist section has both items properly checked, confirming the contributing guide was followed and tests were run locally; and the ๐Ÿš€ Release Impact section correctly indicates that a changeset was generated for this published code change. The description is complete and not vague, providing meaningful information about the PR's purpose and ensuring all compliance items are addressed.
Docstring Coverage โœ… Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
โœจ Finishing touches
๐Ÿงช Generate unit tests (beta)
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment

๐Ÿ“œ Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between 274cd5d13d2d39ea9ad47c6498e0d6de4dbdbfc7 and d4f6b87872db28c937fa749479b13b4f8e3c0f2c.

๐Ÿ“’ Files selected for processing (1)
  • .changeset/little-parks-arrive.md (1 hunks)
๐Ÿ”‡ Additional comments (1)
.changeset/little-parks-arrive.md (1)

1-5: Changeset looks good.

The format is correct, the version bump (minor) is appropriate for a refactor, and the description accurately captures the nature of the change. The previously flagged typo ("executation" โ†’ "execution") appears to have been resolved.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

โค๏ธ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Oct 26 '25 05:10 coderabbitai[bot]