Svelte (store)
Svelte store adapter — Readable stacks, $stack, standalone callFor.
@stainless-code/svelte-layers/store binds stacks to Svelte readable stores. Most core symbols are re-exported. Core’s headless createLayer is createLayerHandle; the wired handle is createLayer. Use this entry for Svelte 3+ projects that prefer the store contract over runes.
Install
npm install @stainless-code/svelte-layerspnpm add @stainless-code/svelte-layersyarn add @stainless-code/svelte-layersbun add @stainless-code/svelte-layersnub add @stainless-code/svelte-layersaube add @stainless-code/svelte-layersImport from the /store subpath:
import { useStack, callFor } from "@stainless-code/svelte-layers/store";
Peer: svelte >=3.0.0
For Svelte 5.7+ runes, see Svelte (runes).
Client
setLayerClient() in a parent; useLayerClient() in descendants — same as the runes entry.
Render a stack
useStack({ stack }) returns a Readable<T>. Subscribe with $stack in components. Pair each state with the standalone callFor(client, stackId, state):
<script>
import {
callFor,
setLayerClient,
useLayerClient,
useStack,
} from "@stainless-code/svelte-layers/store";
setLayerClient();
const client = useLayerClient();
const stack = useStack({ stack: "confirm" });
</script>
{#each $stack as state (state.id)}
{@const call = callFor(client, "confirm", state)}
{#if call}
<Confirm {call} payload={state.payload} />
{/if}
{/each}
Confirm dialog
<script lang="ts">
import {
callFor,
createLayer,
layerOptions,
setLayerClient,
useLayerClient,
useStack,
} from "@stainless-code/svelte-layers/store";
type ConfirmPayload = { title: string };
type ConfirmResponse = boolean;
setLayerClient();
const client = useLayerClient();
const confirmStack = useStack({ stack: "confirm" });
const confirm = layerOptions<ConfirmPayload, ConfirmResponse>({
stack: "confirm",
key: ["confirm", "remove"],
});
const c = createLayer(confirm);
async function remove() {
await c.open({ title: "Remove item?" });
}
</script>
{#each $confirmStack as state (state.id)}
{@const call = callFor(client, "confirm", state)}
{#if call}
<div role="dialog">
<h2>{state.payload.title}</h2>
<button onclick={() => void call.end(true)}>Yes</button>
<button onclick={() => void call.end(false)}>No</button>
</div>
{/if}
{/each}
<button onclick={remove}>Remove</button>
Primitives
Options bag plus optional trailing LayerClient. Drive with createLayer(options); observe with createLayerState({ key, … }). Queued counterparts: createQueuedStack, createLayerQueuedState.
| Export | Role |
|---|---|
setLayerClient(client?) |
Provide a LayerClient via Svelte context |
useLayerClient() |
Read the nearest context client |
useStack({ stack?, select?, compare? }, client?) |
Readable<T> of the selected stack slice |
createLayer(options, client?) |
Drive — wired handle stores + open() / dismiss() + reactive state / queued / top |
createLayerState({ key, stack?, select?, compare? }, client?) |
Observe — Readable<LayerState[]> for mounted same-key layers |
createLayerQueuedState({ key, stack?, select?, compare? }, client?) |
Observe — queued same-key layers |
callFor(client, stackId, state, rootProps?) |
Standalone call-context builder |
Ergonomic APIs
| Export | Role |
|---|---|
useMutationFlow(call) |
pending is a Readable<boolean> — subscribe with $pending |
useLayerGroup(call, options?) |
Child stack as Readable<LayerState[]> — render {#each $group.stack} + callFor |
No shipped outlet or subscribe components — render with $stack + callFor in your markup.
Learn more
- Svelte (runes) — Svelte 5.7+ with
.current - Lifecycle · Adapter parity