npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@eredzik/foundry-react-query

v1.0.0

Published

tRPC-like TanStack Query wrapper for Foundry OSDK client in React apps

Downloads

122

Readme

@eredzik/foundry-react-query

A tRPC-style wrapper around TanStack Query for the Foundry OSDK client. Use your generated application SDK (e.g. @frontend-app-application/sdk) to get typed onto.actions.*.useMutation(), onto.queries.*.useQuery(), and custom hooks with full access to the client and object types.

Install

pnpm add @eredzik/foundry-react-query @osdk/client @tanstack/react-query

Peer dependencies: @osdk/client, @tanstack/react-query, react.

Setup

  1. Create your OSDK client (same instance you use with your generated SDK).
  2. Wrap your app in FoundryQueryProvider.
  3. Build the ontology once from your SDK ($Actions, $Objects, $Queries) and use onto in components.
import { createClient } from "@osdk/client";
import { createPublicOauthClient } from "@osdk/oauth";
import { createFoundryOntology, FoundryQueryProvider } from "@eredzik/foundry-react-query";
import * as sdk from "@frontend-app-application/sdk";

const auth = createPublicOauthClient(clientId, foundryUrl, redirectUrl, { scopes });
const client = createClient(foundryUrl, ontologyRid, auth);
const onto = createFoundryOntology(sdk);

function App() {
  return (
    <FoundryQueryProvider client={client}>
      <YourApp />
    </FoundryQueryProvider>
  );
}

Your SDK must expose $Actions, $Objects, and $Queries (e.g. export * as $Actions from './ontology/actions.js').


Usage

Create onto once (e.g. next to your client) with createFoundryOntology(sdk). In components, use the following.

Actions (mutations)

import { onto } from "./onto";

function DeleteButton() {
  const deleteTest = onto.actions.deleteTest.useMutation();

  return (
    <button
      onClick={() =>
        deleteTest.mutate({
          Test: { $primaryKey: 1, $apiName: "Test" },
        })
      }
      disabled={deleteTest.isPending}
    >
      {deleteTest.isPending ? "Deleting…" : "Delete"}
    </button>
  );
}

Object sets (queries)

Object types from $Objects are on onto.queries. Pass optional fetch-page options as the first argument:

import { onto } from "./onto";

function TestList() {
  const { data, isLoading, error } = onto.queries.Test.useQuery({ $pageSize: 20 });
  const items = data?.data ?? [];

  if (isLoading) return <div>Loading…</div>;
  if (error) return <div>Error: {error.message}</div>;
  return (
    <ul>
      {items.map((obj) => (
        <li key={obj.$primaryKey}>{String(obj.primaryKey_)}</li>
      ))}
    </ul>
  );
}

Ontology queries (queries)

If your SDK defines ontology queries in $Queries, they appear on onto.queries with the same name:

import { onto } from "./onto";

function MyQueryView() {
  const { data } = onto.queries.myQuery.useQuery({ param: "value" });
  // ...
}

Custom hooks (onto.custom)

For logic that needs the raw client and all SDK exports (objects, actions, queries), use the custom hooks. The callback receives a typed client and your objects, actions, and queries.

Custom query

import { onto } from "./onto";

function CustomList() {
  const { data } = onto.custom.useCustomQuery(
    ["customTests", 20],
    async ({ client, objects }) => {
      const page = await client(objects.Test).fetchPage({ $pageSize: 20 });
      return page.data;
    }
  );
  // ...
}

Custom mutation

import { onto } from "./onto";

function CreateButton() {
  const create = onto.custom.useCustomMutation(
    ({ client, actions }) => client(actions.createTest).applyAction({})
  );

  return (
    <button onClick={() => create.mutate(undefined)} disabled={create.isPending}>
      {create.isPending ? "Creating…" : "Create"}
    </button>
  );
}

You can pass TanStack Query options as the last argument to both useCustomQuery and useCustomMutation (e.g. staleTime, onSuccess).

Imperative client

For one-off calls without hooks:

import { useFoundryClient } from "@eredzik/foundry-react-query";

function SomeComponent() {
  const client = useFoundryClient();
  // client($Actions.deleteTest).applyAction(...)
}

API reference

| API | Description | |-----|-------------| | createFoundryOntology(sdk) | Builds onto from sdk.$Actions, sdk.$Objects, sdk.$Queries. Call once. | | FoundryQueryProvider | Wraps the tree; provides the OSDK client and optional QueryClient. | | useFoundryClient() | Returns the OSDK Client from context. | | onto.actions.<name>.useMutation(options?) | Typed mutation for that action. | | onto.queries.<objectType>.useQuery(fetchPageOptions?, queryOptions?) | Query for object set pages ($Objects). | | onto.queries.<queryName>.useQuery(params?, queryOptions?) | Query for ontology functions ($Queries). | | onto.custom.useCustomQuery(key, queryFn, options?) | Custom query with (ctx) => Promise<TData>; ctx has client, objects, actions, queries. | | onto.custom.useCustomMutation(mutationFn, options?) | Custom mutation with (ctx, variables) => Promise<TData>. |

Low-level hooks (used by onto internally): useAction, useObjectSet, useOntologyQuery.