Query Reference
@svelte-lean/query/live
live() and rule(): socket events that invalidate cached entries or patch them with patch(). Nothing subscribes until an entry a rule targets is observed.
Markdown version of this page, for assistants (Markdown for AI)
Note ./live is experimental: the API can still change in a minor release.
Stability per entry point: Entry points.
On this page
Import
import { live, rule } from '@svelte-lean/query/live';Usage
// src/lib/api/live.ts
import { patch, tag, type } from '@svelte-lean/query';
import { live, rule, type LiveSource } from '@svelte-lean/query/live';
import { getMember } from '$api/members';
import type { Member } from '$api/types';
// An adapter: one EventSource per channel.
const source: LiveSource = {
subscribe({ channel, event }, deliver, ready) {
const events = new EventSource(`/events/${channel}`);
events.addEventListener('open', ready, { once: true });
events.addEventListener(event, (e) => deliver(JSON.parse((e as MessageEvent).data)));
return () => events.close();
}
};
export const realtime = live(source, [
// Poke, then pull: the observed member lists refetch, coalesced.
rule('Members', { channel: 'members', event: 'MemberCreated' }),
// The event carries the row: every cached copy of it is patched, nothing is refetched.
rule('Members', {
channel: 'members',
event: 'MemberUpdated',
message: type<{ member: Member }>(),
patch: (m) => patch(tag('Member', m.member.id), () => m.member)
}),
// Patch the one detail entry the message names.
rule(getMember, {
channel: 'members',
event: 'MemberPinned',
message: type<{ id: number; pinned: boolean }>(),
patch: (m) => patch([getMember, { id: m.id }], (member) => ({ ...member, pinned: m.pinned }))
})
]);Size
Production Vite builds of a small consumer entry, Svelte external. A marginal row is the bytes the entry adds over the row it names.
| Build | Over | gzip | brotli | Budget (gzip) |
|---|---|---|---|---|
live (marginal) | query | 2777 B | 2565 B | 3100 B |
Read from packages/query/artifacts/size.json. Every entry and its method: Performance.
Functions
The module and its rules.
Exports
Runtime exports of the entry.
| Name | Type | Default | Description |
|---|---|---|---|
# live | (source: LiveSource, rules: LiveRule[], options?: LiveOptions) => Module | – | The realtime module; channels are reference-counted and reseeded on reconnect. Inert on the server. |
# rule | (target: TagTarget, init: LiveRuleInit) => LiveRule | – | A rule on a tag: every event invalidates it (poke, then pull), or patches the entity it carries. |
# rule (endpoint) | (target: QueryEndpoint | [QueryEndpoint, Partial<P>], init: LiveRuleInit & { match? }) => LiveRule | – | A rule on an endpoint: match narrows its default invalidation to the entries a message concerns. |
Options
The module options and the rule options.
LiveOptions
The third argument of live().
| Name | Type | Default | Description |
|---|---|---|---|
# window | Duration | '100ms' | Coalescing window per burst. |
# maxWindow | Duration | '2s' | Adaptive ceiling of the window under sustained bursts. |
# linger | Duration | '1.5s' | Keep a channel after its last observer left. |
LiveRuleInit
The second argument of rule(). match applies to endpoint targets only.
| Name | Type | Default | Description |
|---|---|---|---|
# channel required | string | ((params) => string) | – | A channel name, or one per entry from its params. |
# event required | string | – | The event name. |
# message | StandardSchemaV1<unknown, M> | – | Validates each payload; type<M>() for no validation. A failure drops the event. |
# access | Access<P> | – | The rule's own access; endpoint targets also need the endpoint's verdict. |
# when | boolean | (() => boolean) | – | Reactive gate (session, settings). |
# invalidate | InvalidateTarget[] | ((message) => InvalidateTarget[]) | – | What an event invalidates; default the rule's target (narrowed by match) without patch, nothing with it. |
# patch | (message: M, at: { channel, event }) => void | – | Applies the event to cached values: call patch() here (the entity it carries, or the entry it concerns). Local writes, also applied when another tab forwards the event. |
# reseed | boolean | true | Invalidate on a confirmed subscription and on reconnect. |
# reason | Reason | – | Reason carried by the refetches this rule starts. |
# name | string | 'channel:event' | Source label of those refetches. |
# match | (message: M) => Partial<P> | undefined | – | The params of the entries a message concerns; the default invalidation reaches only those. |
Source
Where events come from: a Pusher or Reverb client, an EventSource, a test double (fakeSource() in ./testing).
LiveSource
The contract an adapter implements.
| Name | Type | Default | Description |
|---|---|---|---|
# subscribe required | (at: { channel, event }, deliver, ready) => () => void | – | Start delivering an event; call ready once the server confirmed; return the stop function. |
# watch | (listener: (connected: boolean) => void) => () => void | – | Optional connection state; true after false after true is a reconnect. |
Guide
How to use it, with examples: Realtime. All entry points: Svelte Lean Query.