Skip to content

feat(core): async useComputed$ - #8807

Merged
wmertens merged 8 commits into
build/v2from
drop-useAsync
Jul 12, 2026
Merged

wmertens merged 8 commits into
build/v2from
drop-useAsync

Conversation

@wmertens

@wmertens wmertens commented Jul 7, 2026

Copy link
Copy Markdown
Member

This PR deprecates useAsync$ and instead moves all async the machinery to ComputedSignal.

This means that the synchronous part of the compute function gets reactive-tracked automatically, and after the first await, track() needs to be used.

@wmertens
wmertens requested a review from a team as a code owner July 7, 2026 20:57
Copilot AI review requested due to automatic review settings July 7, 2026 20:57
@wmertens
wmertens requested review from a team as code owners July 7, 2026 20:57
@changeset-bot

changeset-bot Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3672ae5

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

This PR includes changesets to release 5 packages
Name Type
@qwik.dev/core Major
@qwik.dev/router Major
eslint-plugin-qwik Major
@qwik.dev/react Major
create-qwik 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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR extends Qwik core’s computed signals to support async compute functions, deprecating useAsync$/createAsync$ and moving the async-signal machinery (pending/error state, jobs, polling, cleanup, serialization behavior) into ComputedSignalImpl. It also updates Qwik Router loader signals to use ComputedSignal, refreshes docs and API outputs to reflect the new async useComputed$ behavior, and updates e2e snapshots/budgets accordingly.

Changes:

  • Add async support to useComputed$/createComputed$ and unify async-signal behavior into ComputedSignalImpl (with .pending, .error, .promise(), polling, etc.).
  • Deprecate useAsync$/createAsync$ and migrate router loaders and docs examples from AsyncSignal/.loading to ComputedSignal/.pending.
  • Update serialization/resume paths and SSG snapshot/budget expectations for the new signal engine behavior.

Reviewed changes

Copilot reviewed 69 out of 69 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/qwik/src/core/use/use-resource.ts Switch ResourceCtx to extend ComputeCtx.
packages/qwik/src/core/use/use-computed.ts Update computed hook types/docs for async compute functions and ComputeCtx.
packages/qwik/src/core/use/use-async.ts Deprecate useAsync$ and switch ctx type to ComputeCtx.
packages/qwik/src/core/tests/use-resource.spec.tsx Adjust resource test timing to accommodate new scheduling behavior.
packages/qwik/src/core/tests/use-computed.spec.tsx Replace “promise disallowed” test with async-computed behavior tests.
packages/qwik/src/core/tests/use-async.spec.tsx Update tests for .pending/internal field renames and new typing shape.
packages/qwik/src/core/ssr/ssr-render-jsx.ts Treat computed signals as the relevant async/polling signal type for eager resume.
packages/qwik/src/core/shared/serdes/serialize.ts Serialize async-mode computeds based on flags (not instanceof), and handle errored async mode.
packages/qwik/src/core/shared/serdes/serdes.unit.ts Update serialization unit snapshots/expectations for new async-mode computed serialization.
packages/qwik/src/core/shared/serdes/inflate.ts Update inflate logic to use $untrackedPending$ instead of $untrackedLoading$.
packages/qwik/src/core/shared/error/error.ts Clear Q29 text since async computed is now supported.
packages/qwik/src/core/reactive-primitives/types.ts Introduce ComputeCtx, expand ComputedOptions<T> to include async-signal options, add new async flags.
packages/qwik/src/core/reactive-primitives/signal.public.ts Unify async API onto ComputedSignal (pending, error, promise, etc.), deprecate AsyncSignal as an alias.
packages/qwik/src/core/reactive-primitives/signal-api.ts Update createComputedSignal signature to accept ComputedFn<T> and typed ComputedOptions<T>.
packages/qwik/src/core/reactive-primitives/internal-api.ts Update signal-impl checks from AsyncSignalImpl to ComputedSignalImpl.
packages/qwik/src/core/reactive-primitives/impl/computed-signal-impl.ts Core change: embed async engine state/behavior in ComputedSignalImpl and add async-computed execution semantics.
packages/qwik/src/core/reactive-primitives/impl/async-signal.unit.tsx Update unit tests to stop depending on AsyncCtx typing and reflect new ctx shape.
packages/qwik/src/core/reactive-primitives/impl/async-signal-impl.ts Reduce AsyncSignalImpl to a thin wrapper configuring flags/options; move engine logic to ComputedSignalImpl.
packages/qwik/src/core/reactive-primitives/impl/async-computed.unit.tsx New unit coverage for async computed behavior: pending/error, tracking rules, previous/info, cleanup, options.
packages/qwik/src/core/reactive-primitives/cleanup.ts Ensure cleanup removes pending/error subscriptions for computeds carrying async state.
packages/qwik/src/core/qwik.core.api.md Update extracted core API docs for async useComputed$, deprecated async APIs, and new signal surface.
packages/qwik/src/core/client/vnode-diff.ts Update cleanup logic to treat async-mode computeds as destroyable (similar to previous async-signal cleanup).
packages/qwik-router/src/runtime/src/types.ts Refine action option typing (introduce ActionOptions and expand constructor overloads).
packages/qwik-router/src/runtime/src/server-functions.unit.ts Add a type-level regression for routeAction$ invalidate typing without validators.
packages/qwik-router/src/runtime/src/route-loaders.ts Switch loader signals from createAsync$ to async createComputed$ and update injected-value tracking notes.
packages/qwik-router/src/runtime/src/qwik-router.runtime.api.md Update router API docs to reference ComputedSignal and new ActionOptions.
packages/qwik-router/src/runtime/src/qwik-router-component.tsx Switch runtime loader state to ComputedSignal and update pending-trigger reads.
packages/qwik-router/src/runtime/src/index.ts Export ActionOptions.
packages/qwik-router/src/runtime/src/head.ts Update head resolution types to use ComputedSignal.
packages/qwik-router/ARCHITECTURE.md Update documentation to refer to .untrackedPending for loader signal triggering.
packages/docs/src/routes/tutorial/reactivity/resource/solution/app.tsx Migrate tutorial solution from useAsync$ to async useComputed$ and .pending.
packages/docs/src/routes/tutorial/reactivity/resource/problem/app.tsx Migrate tutorial problem from useAsync$ to async useComputed$ and .pending.
packages/docs/src/routes/tutorial/reactivity/resource/index.mdx Update tutorial copy/snippets from useAsync$ to async useComputed$.
packages/docs/src/routes/tutorial/introduction/resource/solution/app.tsx Migrate intro tutorial solution to async useComputed$ and .pending.
packages/docs/src/routes/tutorial/introduction/resource/problem/app.tsx Migrate intro tutorial problem to async useComputed$ and .pending.
packages/docs/src/routes/tutorial/introduction/resource/index.mdx Update intro tutorial narrative/examples to async useComputed$ and .pending.
packages/docs/src/routes/examples/apps/reactivity/auto-complete/app.tsx Update example from useAsync$ to async useComputed$.
packages/docs/src/routes/examples/apps/partial/hackernews-index/app.tsx Update example from useAsync$ to async useComputed$ and .pending.
packages/docs/src/routes/docs/upgrade/index.mdx Update upgrade guide to explain async useComputed$ and migration away from useAsync$.
packages/docs/src/routes/docs/labs/suspense/index.mdx Update Suspense docs to use async useComputed$ and .pending.
packages/docs/src/routes/docs/errors/index.mdx Mark Q29 as no longer used; update clientOnly SSR guidance to .pending.
packages/docs/src/routes/docs/(qwikrouter)/route-loader/index.mdx Update route loader docs to ComputedSignal + .pending terminology.
packages/docs/src/routes/docs/(qwikrouter)/guides/best-practices/index.mdx Update best-practices guidance to use async useComputed$ instead of useAsync$.
packages/docs/src/routes/docs/(qwik)/getting-started/index.mdx Add/describe invalidate option in action examples.
packages/docs/src/routes/docs/(qwik)/core/tasks/index.mdx Update guidance from useAsync$ to async useComputed$.
packages/docs/src/routes/docs/(qwik)/core/state/index.mdx Replace useAsync$ section with “async computed values” guidance and migration note.
packages/docs/src/routes/docs/(qwik)/core/overview/index.mdx Update overview bullets to reflect async useComputed$ and remove useAsync$.
packages/docs/src/routes/demo/state/async-joke/index.tsx Migrate demo from useAsync$ to async useComputed$.
packages/docs/src/routes/demo/getting-started/06-styling/index.tsx Update demo action example to include invalidate.
packages/docs/src/routes/demo/getting-started/05-tasks/index.tsx Update demo action example to include invalidate.
packages/docs/src/routes/demo/getting-started/04-state/index.tsx Update demo action example to include invalidate.
packages/docs/src/routes/demo/getting-started/03-posting-data/index.tsx Update demo action example to include invalidate.
packages/docs/src/routes/demo/component/suspense-async/index.tsx Update suspense demo from useAsync$ to async useComputed$.
packages/docs/src/routes/api/qwik/api.json Update generated API JSON for deprecated async APIs and expanded computed signal API surface.
packages/docs/src/routes/api/qwik-router/index.mdx Update generated router API docs to ActionOptions and ComputedSignal loader signal shape.
packages/docs/src/routes/api/qwik-router/api.json Update generated router API JSON to include ActionOptions and new loader-signal pick set.
e2e/qwik-e2e/tests/qwikrouter/ssg-snapshot.e2e.ts Bump core brotli budget to account for computed async engine move.
e2e/qwik-e2e/tests/qwikrouter/nav.e2e.ts Strengthen nav assertions to ensure loader-driven content is visible after navigation.
e2e/qwik-e2e/apps/qwikrouter-ssg-snapshot/expected.state.txt Update SSG serialized state golden to match new signal engine serialization layout.
e2e/qwik-e2e/apps/qwikrouter-ssg-snapshot/expected.ssg.html Update SSG HTML golden to match new preload list/output.
.ruler/skills/qwik-e2e-verification/SKILL.md Document SSG snapshot suite traps and regeneration behavior.
.ruler/skills/qwik-core-development/references/core-notes.md Update core notes to reflect async engine move and new invariants (flags vs class identity).
.codex/skills/qwik-e2e-verification/SKILL.md Regenerated skill output mirroring the updated .ruler source.
.codex/skills/qwik-core-development/references/core-notes.md Regenerated skill output mirroring the updated .ruler source.
.claude/skills/qwik-e2e-verification/SKILL.md Regenerated skill output mirroring the updated .ruler source.
.claude/skills/qwik-core-development/references/core-notes.md Regenerated skill output mirroring the updated .ruler source.
.changeset/route-action-invalidate-types.md Changeset for router type-level fix around action invalidation typing.
.changeset/async-computed.md Changeset for core feature: async useComputed$ and async API deprecations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@pkg-pr-new

pkg-pr-new Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@qwik.dev/core

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/core@8807

@qwik.dev/router

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/router@8807

eslint-plugin-qwik

npm i https://pkg.pr.new/QwikDev/qwik/eslint-plugin-qwik@8807

create-qwik

npm i https://pkg.pr.new/QwikDev/qwik/create-qwik@8807

@qwik.dev/optimizer

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/optimizer@8807

@qwik.dev/devtools

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/devtools@8807

commit: d724737

@github-actions

github-actions Bot commented Jul 7, 2026 •

Copy link
Copy Markdown
Contributor
built with Refined Cloudflare Pages Action

⚡ Cloudflare Pages Deployment

Name Status Preview Last Commit
qwik-docs ✅ Ready (View Log) Visit Preview 3672ae5

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I dont quite like that. The implementation is really loooong, even if someone is not using features, they need to download all the code, can we do it more tree shakeable? 🤔

@wmertens wmertens Jul 10, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It's 200 brotli bytes more for the router e2e build hmmm.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Well, we can't determine if the result is a Promise at build time, and making the async machinery lazy loaded dependent on that requires overhauling the core build and that's definitely a different PR.

wmertens added 4 commits July 10, 2026 19:47
useComputed$ now accepts async functions again.
Reactive reads before the first `await` are
auto-tracked, and later reads need the ComputeCtx track().

The AsyncSignal engine moves into ComputedSignalImpl.
Add a qwik-e2e-verification note on the two independent SSG snapshot
assertion types (serialized goldens vs bundle-size budgets) and the
update-does-not-fix-budgets / exit-1 traps. Regenerate committed skill
outputs.
- reading .error triggers the compute if needed
- synchronous throws also populate .error
@wmertens

Copy link
Copy Markdown
Member Author

@copilot resolve the merge conflicts in this pull request

Copilot AI commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Resolved the merge conflict in e2e/qwik-e2e/tests/qwikrouter/nav.e2e.ts (commit d72473743). The single conflict combined:

  • Our branch's price text assertions (Price: $21.96 / Price: $48.96)
  • Base branch's navigation status checks (idle/navigating) and the async click-intercept mechanism

Both sets of checks are preserved in the merged result.

@wmertens
wmertens merged commit 5c6a303 into build/v2 Jul 12, 2026
46 of 47 checks passed
@wmertens
wmertens deleted the drop-useAsync branch July 12, 2026 20:40
@github-project-automation github-project-automation Bot moved this from Waiting For Review to Done in Qwik Development Jul 12, 2026
AmariahAK pushed a commit to AmariahAK/qwik that referenced this pull request Jul 13, 2026
AmariahAK pushed a commit to AmariahAK/qwik that referenced this pull request Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

4 participants