useProjection<
T
>(
registry: ValueOrGetter<ChannelRegistry | null | undefined>,
specFactory: () =>| Name | Type | Description |
|---|---|---|
registry* | ValueOrGetter<ChannelRegistry | null | undefined> | |
specFactory* | () => ProjectionSpec<T> | |
key* | ValueOrGetter<string> | |
initialValue* | T |
Svelte binding over ChannelRegistry.acquire. Mirrors the
React and Vue useProjection primitives with an idiomatic Svelte
shape:
$effect run the composable acquires a ref-counted
projection from the registry, seeds the returned current with
the current snapshot, and subscribes to the store so templates
auto-update on subsequent snapshots.$effect cleanup returned from the effect body runs on both
scope teardown and before the next run, releasing the previous
acquisition (and letting the registry close the underlying
server subscription once the last consumer leaves).registry is null / undefined the
composable stays at initialValue. This is the happy path for
selector composables that short-circuit the root namespace by
reading stream.messages / stream.values directly — they
don't call useProjection at all at the root. Dynamic inputs
that flip from root to scoped can pass null for the root case
and fall back to initialValue.registry and key accept plain values or getters. Reading the
getter inside $effect auto-tracks any $state the getter
references, so the effect re-runs and re-acquires whenever the
resolved target changes.
Must be called from a reactive context (a .svelte component
script or inside $effect.root). Calls outside a reactive scope
will not receive store updates because $effect never fires.