Pre-flight checklist
Problem or use case
bQuery has worker-based concurrency and SSR defer, and async data lives in reactive (useAsyncData/useFetch), but there is no UI-level concurrency model for keeping the interface responsive during async work: no Suspense-equivalent for declarative loading boundaries, no transition primitive to mark non-urgent updates, and no deferred-value primitive to debounce expensive derived UI. React 19 (<Suspense>, useTransition, useDeferredValue) and Svelte 5 (await + $effect.pending()) both ship these, and their absence is a visible capability gap for interactive apps.
Proposed solution
Add client concurrency primitives that build on existing signals: a declarative async boundary (Suspense-equivalent) that shows fallback UI while tracked async work is pending, a transition primitive that flags updates as non-urgent so input stays responsive, and a deferred signal wrapper that lags behind its source to throttle expensive recomputation. Keep them in or adjacent to concurrency/reactive, zero-dependency and tree-shakeable.
Possible API or UX shape
import { suspense, startTransition, deferred } from "@bquery/bquery/concurrency";
// declarative async boundary in the view layer
// <div bq-suspense="userResource" bq-fallback="Loading…">…</div>
const [isPending, start] = startTransition();
start(() => filter.value = nextQuery); // non-urgent, keeps input snappy
const deferredQuery = deferred(query); // lags source; drives expensive list
Alternatives considered
Telling users to debounce manually and roll their own loading flags — works but is boilerplate every app reinvents, and has no parity with the ergonomic primitives competitors ship. Folding this into the worker concurrency API — different concern; worker concurrency is about offloading CPU, this is about UI scheduling, so they should be distinct primitives even if co-located.
Relevant area
concurrency
Additional context
This closes one of the clearest React-parity gaps. Pairs with SSR suspense streaming (renderToStreamSuspense/defer) so the same async boundaries can stream on the server and suspend on the client.
Pre-flight checklist
Problem or use case
bQuery has worker-based concurrency and SSR
defer, and async data lives inreactive(useAsyncData/useFetch), but there is no UI-level concurrency model for keeping the interface responsive during async work: no Suspense-equivalent for declarative loading boundaries, no transition primitive to mark non-urgent updates, and no deferred-value primitive to debounce expensive derived UI. React 19 (<Suspense>,useTransition,useDeferredValue) and Svelte 5 (await+$effect.pending()) both ship these, and their absence is a visible capability gap for interactive apps.Proposed solution
Add client concurrency primitives that build on existing signals: a declarative async boundary (Suspense-equivalent) that shows fallback UI while tracked async work is pending, a
transitionprimitive that flags updates as non-urgent so input stays responsive, and adeferredsignal wrapper that lags behind its source to throttle expensive recomputation. Keep them in or adjacent toconcurrency/reactive, zero-dependency and tree-shakeable.Possible API or UX shape
Alternatives considered
Telling users to debounce manually and roll their own loading flags — works but is boilerplate every app reinvents, and has no parity with the ergonomic primitives competitors ship. Folding this into the worker
concurrencyAPI — different concern; worker concurrency is about offloading CPU, this is about UI scheduling, so they should be distinct primitives even if co-located.Relevant area
concurrencyAdditional context
This closes one of the clearest React-parity gaps. Pairs with SSR suspense streaming (
renderToStreamSuspense/defer) so the same async boundaries can stream on the server and suspend on the client.