/** * Client-side async-concurrency primitives for keeping the UI responsive. * * These are about **UI scheduling**, not worker offloading: a declarative * async boundary (`suspense`), a non-urgent update marker (`startTransition`), * and a trailing value wrapper (`deferred`). They build directly on bQuery * signals, add no dependencies, and are independently tree-shakeable. * * @module bquery/concurrency */ import { type ReadonlySignalHandle } from '../reactive/readonly'; import type { DeferredOptions, DeferredSource, SuspenseBoundary, SuspenseOptions, SuspenseSource, StartTransitionOptions, Transition } from './types'; /** * Marks updates as non-urgent so urgent work (typing, clicks) stays responsive. * * `start(scope)` flips `isPending` to `true` immediately, then runs `scope` on a * low-priority schedule inside a reactive `batch`. The expensive reactive * fallout of the update is decoupled from the urgent event that triggered it. * * @example * ```ts * import { startTransition } from '@bquery/bquery/concurrency'; * * const [isPending, start] = startTransition(); * input.addEventListener('input', (event) => { * query.value = event.target.value; // urgent: keeps the field snappy * start(() => filter.value = event.target.value); // non-urgent: heavy list update * }); * ``` */ export declare function startTransition(options?: StartTransitionOptions): Transition; /** * Produces a readonly signal that lags behind its source, throttling expensive * derived UI. Rapid source changes coalesce into a single trailing update. * * The deferred signal exposes the previous value until the scheduler flushes, * so a heavy computed driven by it does not recompute on every keystroke. * * @example * ```ts * import { deferred } from '@bquery/bquery/concurrency'; * import { computed } from '@bquery/bquery/reactive'; * * const deferredQuery = deferred(query); // lags `query` * const results = computed(() => expensiveSearch(deferredQuery.value)); * ``` */ export declare function deferred(source: DeferredSource, options?: DeferredOptions): ReadonlySignalHandle; /** * Declarative async boundary: aggregates promises and reactive async states * (e.g. `useAsyncData()` / `useResource()`) into reactive `pending` / `settled` * / `error` signals so the view can swap fallback and content without bespoke * loading flags. Pairs with SSR suspense streaming so the same boundary streams * on the server and suspends on the client. * * @example * ```ts * import { suspense } from '@bquery/bquery/concurrency'; * import { useAsyncData } from '@bquery/bquery/reactive'; * * const user = useAsyncData(() => fetchUser(id)); * const boundary = suspense(user); * * //
Loading…
* //
…content…
* effect(() => { * if (boundary.error.value) reportError(boundary.error.value); * }); * ``` * * @param sources - One source or an array of promises / reactive states / pending getters * @param options - Boundary behavior (e.g. `retrigger`) */ export declare function suspense(sources: SuspenseSource | readonly SuspenseSource[], options?: SuspenseOptions): SuspenseBoundary; //# sourceMappingURL=scheduling.d.ts.map