Picadabra Docs

React

TanStack Query integration for React applications.

Installation

npm install @picadabra/client @tanstack/react-query

Setup

Create a React client with TanStack Query utilities:

// lib/picadabra.ts
import { createPicadabraClient } from "@picadabra/client";
import { createPicadabraReactClient } from "@picadabra/client/react";

const client = createPicadabraClient({
  baseUrl: "https://api.picadabra.ai",
  credentials: () => getAuthToken(), // your auth token getter
});

export const picadabra = createPicadabraReactClient(client);

Streaming with TanStack Query

Use streamedOptions to consume SSE streams with automatic state management:

import {  } from "@tanstack/react-query";

import {  } from "../lib/picadabra";

function ({  }: { : string }) {
  const { ,  } = (
    .stream.streamedOptions({
      : { : "generate", : {  } },
      : true, // Auto-reconnect on disconnect
    }),
  );

  // data is StreamEvent[], new events appended to end
  const  = ?.at(-1);

  if ( === "pending") return <>Connecting...</>;
  if (?.type === "error") return <>Error: {.error}</>;
  if (?.type === "done") return <>Complete!</>;

  return <>Progress: {.(?.data)}</>;
}

Multiple Concurrent Streams

TanStack Query automatically manages multiple streams with distinct query keys:

import {  } from "@tanstack/react-query";

import {  } from "../lib/picadabra";

function ({  }: { : string }) {
  const {  } = (
    .stream.streamedOptions({
      : { : "process", : {  } },
      : true,
    }),
  );

  const  = ?.at(-1);
  const  = (?.data as { ?: number })?. ?? 0;

  return (
    <>
      <>Task {}</>
      < ={} ={100} />
    </>
  );
}

// Render 5 concurrent task progress bars
function ({  }: { : string[] }) {
  return (
    <>
      {.(() => (
        < ={} ={} />
      ))}
    </>
  );
}

Each TaskProgress component:

  • Has its own SSE connection
  • Shares data if the same taskId is used elsewhere
  • Automatically cleans up when unmounted

Query Options

streamedOptions

For accumulating events (chat messages, logs):

picadabra.stream.streamedOptions({
  input: { endpoint: "chat", input: { message: "Hello" } },
  queryFnOptions: {
    refetchMode: "reset", // 'reset' | 'append'
    maxChunks: 100, // Limit stored events
  },
  retry: true,
});

liveOptions

For latest-value only (progress, status):

picadabra.stream.liveOptions({
  input: { endpoint: "status", input: { taskId } },
  retry: true,
});
// data is always the latest StreamEvent (not an array)

Cancellation

Streams are automatically cancelled when the component unmounts. For manual control:

import { ,  } from "@tanstack/react-query";

import {  } from "../lib/picadabra";

function ({  }: { : string }) {
  const  = ();

  const {  } = (
    .stream.streamedOptions({
      : { : "process", : {  } },
    }),
  );

  const  = () => {
    .({
      : .stream.key({
        : { : "process", : {  } },
      }),
    });
  };

  return (
    <>
      <>{.(?.at(-1))}</>
      < ={}>Cancel</>
    </>
  );
}

Error Handling

import {  } from "@orpc/client";
import {  } from "@tanstack/react-query";

import {  } from "../lib/picadabra";

function ({  }: { : string }) {
  const { , ,  } = (
    .stream.streamedOptions({
      : { : "process", : {  } },
    }),
  );

  // Connection-level error
  if ( && ()) {
    return <>Connection error: {.message}</>;
  }

  // Stream-level error (from event)
  const  = ?.at(-1);
  if (?.type === "error") {
    return <>Task error: {.error}</>;
  }

  return <>{.(?.data)}</>;
}

How is this guide?