QwikDev / QwikDev/qwik

[v2] Suspense-deferral-through-component: non-EB test + extract to build/v2 + deeper cursor-boundary propagation fix

Open
#8,801 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement reactivity runtime V2
Dominant language
TypeScript
Stars
22.1k
Forks
1.4k
Avg merge
1d 10h
Merged PRs (30d)
52

Description

Context

The addCursorBoundary walk-up in packages/qwik/src/core/use/use-cursor-boundary.ts:38-52 (fix 50c9666e2, landed on the ErrorBoundary PR #8745 branch) makes a suspending child register against the nearest cursor boundary by walking slotParent || parent. It fixes a real bug — a <Suspense> whose deferred child sits behind an intervening stateful component (e.g. an <ErrorBoundary>, which adds dirty component frames) did not show the Suspense fallback on client nav and instead blocked. The fix is Suspense-generic, but it currently only has ErrorBoundary-shaped coverage.

Three related follow-ups:

1. Add a non-EB walk-up test

suspense.e2e.ts / suspense.spec.tsx have no intervening-component client-deferral case (verified untouched vs base). Add a plain-wrapper test: a non-EB stateful component (e.g. useStore + useContextProvider) projecting a suspending child, asserting the Suspense fallback shows during client navigation. The user-facing behavior is already proven by the EB suites; this covers the generic path.

2. Extract the fix to build/v2

It's EB-independent and self-contained (one file + .changeset/suspense-deferral-through-component.md), so it fits the copy-not-move extraction pattern used for #8790 / #8791 / #8772. Blocked on (1) — a standalone PR needs the non-EB test.

3. Deeper follow-up: repair downward cursor-boundary propagation

The registration-site walk is a bounded mitigation on the rare blocking-promise path (sole caller: cursor-walker.ts:206, inside the isPromise(result) branch — not the hot dirty-mark path). The cleaner fix is to repair the downward NEAREST_CURSOR_BOUNDARY inheritance itself, so projected children of a dirty intervening component inherit the boundary — likely expectSlot (vnode-diff.ts ~735, which overwrites the slot boundary to null instead of inheriting the parent's) and/or setNearestCursorBoundary propagation (vnode-dirty.ts). That path runs on every dirty-mark, so it needs benchmarking + the full suspense suite before it can replace the registration-site walk.

None of this blocks #8745 (the shipped behavior is proven by the EB suites).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with packages/qwik/src/core/use/use-cursor-boundary.ts:38-52 and the existing suspense.e2e.ts and suspense.spec.tsx suites; run the relevant Suspense tests to understand the ErrorBoundary coverage. Add the non-ErrorBoundary client-deferral case, then follow the copy pattern for #8790, #8791, and #8772 to extract the fix to build/v2 with .changeset/suspense-deferral-through-component.md. If pursuing the deeper follow-up, inspect cursor-walker.ts:206, vnode-diff.ts around expectSlot, and vnode-dirty.ts, then benchmark and run the full Suspense suite.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
build-system, frontend, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.