Svelte

Install the adapter alongside Svelte 5:

pnpm add @omni-async/svelte

Query stores

<script lang="ts">
  import { useQuery } from "@omni-async/svelte";

  const { data, error, loading, trigger } = useQuery(
    async (team: string) => {
      const response = await fetch(`/api/teams/${team}/users`);
      if (!response.ok) throw new Error("Unable to load users");
      return response.json() as Promise<string[]>;
    },
    { initial: () => [] },
  );
</script>

<button disabled={$loading} onclick={() => trigger("platform")}>
  Load users
</button>

{#if $error}
  <p>Unable to load users</p>
{/if}

{#each $data as user}
  <p>{user}</p>
{/each}

data, error, and loading are readable stores. Active work is invalidated when the component is destroyed.

Fetch on mount

const users = useFetch(
  (signal) => fetch("/api/users", { signal }).then((response) => response.json()),
  { initial: () => [] },
);

useFetch starts when the component mounts and exposes fetch() and abort() for later control.