Streaming & Batching Queries
Relevant source files
The following files were used as context for generating this wiki page:
- modules/svelte-effect-runtime/src/server/types.ts
- skills/svelte-effect-runtime/references/runtime-and-server.md
- modules/svelte-effect-runtime/src/script-transform/index.ts
- modules/svelte-effect-runtime/src/markup/transform/index.ts
- skills/svelte-effect-runtime/references/syntax.md
- modules/svelte-effect-runtime/src/compiler.ts
Streaming and Batching Queries are advanced data retrieval patterns within the Svelte Effect Runtime (SER) that leverage the Effect ecosystem to optimize server-client communication. These patterns allow developers to handle continuous data streams and consolidate multiple concurrent requests into single, efficient operations.
These features are exposed through the Query factory, which provides specialized builders like Query.live for streams and Query.batch for bulk operations. By integrating with the SER compiler and runtime, these queries maintain reactivity and SvelteKit's native resource management while providing full access to Effect's concurrency and error-handling primitives.
Sources: modules/svelte-effect-runtime/src/server/types.ts:258-305, skills/svelte-effect-runtime/references/runtime-and-server.md:38-46
Batching Queries
Batching allows the runtime to collect multiple requests of the same kind that are discovered during a single render pass and resolve them in a single server-side execution. This is particularly useful for avoiding "N+1" query problems in Svelte components.
Architecture and Data Flow
The Query.batch factory creates an EffectRemoteQueryFunction. When these functions are called within a component, the SER dispatcher identifies the batched context. On the server, the EffectRemoteBatchHandler receives a readonly Input[] containing all collected inputs and returns an Effect that yields a resolver function.
The diagram shows how individual requests discovered during rendering are queued by the dispatcher and sent as a group to the server batch handler.
Sources: modules/svelte-effect-runtime/src/server/types.ts:98-107, modules/svelte-effect-runtime/src/server/types.ts:285-305
Key Components for Batching
| Component | Type | Description |
|---|---|---|
QueryBatchFactory | Interface | The factory used to define batched queries. |
EffectRemoteBatchHandler | Type | A handler that receives an array of inputs and returns a resolver. |
inputs | readonly Input[] | The collection of validated inputs gathered from the client. |
resolver | (input: Input, index: number) => A | A function returned by the handler to map results back to individual requests. |
Sources: modules/svelte-effect-runtime/src/server/types.ts:98-107, modules/svelte-effect-runtime/src/server/types.ts:285-305
Streaming Queries (Live Queries)
Streaming queries, often referred to as "Live" queries, enable the server to push continuous updates to the client using Effect's Stream primitive. This is implemented via the Query.live builder.
Data Flow for Live Queries
A live query handler returns a Stream.Stream<A, E, R>. On the client side, this is received as an EffectRemoteLiveQuery, which allows the component to react to each new value emitted by the stream.
The sequence diagram illustrates the lifecycle of a live query, from the initial yield* call to the continuous updates pushed from the server.
Sources: modules/svelte-effect-runtime/src/server/types.ts:72-96, modules/svelte-effect-runtime/src/server/types.ts:318-333, skills/svelte-effect-runtime/references/runtime-and-server.md:43
Specialized Types for Streaming
RemoteLiveHandler: A function that takes an input and returns anEffectStream.EffectRemoteLiveQuery: The client-side representation of the stream, compatible with SER syntax.RemoteLiveSource: A no-argument version of a live query that acts as a direct stream source.
Sources: modules/svelte-effect-runtime/src/server/types.ts:72-96, modules/svelte-effect-runtime/src/server/types.ts:517-542
Implementation and Transformation
The SER compiler identifies these query types during the transformation of <script effect> and markup.
Compiler Logic
The compiler looks for yield* expressions targeting these remote functions. It replaces them with dispatcher calls that handle the specific protocol (streaming or batching).
/** Phase 2: lower every top-level statement that contains yield*. */
for (const stmt of source_file.statements) {
// ... validation logic
const has_top_level_yield_star = contains_top_level_yield_star(stmt);
if (!has_top_level_yield_star) continue;
const lowered = lower_statement(stmt, content, context);
// ... code rewriting
}
Sources: modules/svelte-effect-runtime/src/script-transform/index.ts:133-146, modules/svelte-effect-runtime/src/compiler.ts:134-152
Syntax Usage
In components, these queries are used via the yield* keyword, ensuring they are integrated into the Svelte lifecycle.
<script lang="ts" effect>
import { Clock } from "./time.remote";
// Live query usage
const time = yield* Clock();
</script>
{#each yield* BatchItems(ids) as item}
<li>{item.name}</li>
{/each}
Sources: skills/svelte-effect-runtime/references/syntax.md:43-58, README.md:10-25
Comparison of Query Types
| Feature | Query (Standard) | Query.batch | Query.live |
|---|---|---|---|
| Return Type | Effect<A, E> | Effect<A, E> | Stream<A, E> |
| Execution | Immediate/One-off | Consolidated | Continuous |
| Input Handling | Single Input | Array of Inputs | Single Input |
| Use Case | Fetching a single resource | List items, bulk data | Real-time updates, logs |
Sources: modules/svelte-effect-runtime/src/server/types.ts:258-333, skills/svelte-effect-runtime/references/runtime-and-server.md:38-46
Streaming and Batching Queries provide high-level abstractions for complex data patterns, allowing developers to optimize performance and real-time capabilities without leaving the declarative Effect and Svelte models.