npm package: @qkit/tanstack-query
Description: Reusable query definitions for TanStack Query
Latest version: 0.1.0

# @qkit/tanstack-query

Reusable query definitions for TanStack Query that work with any framework.

## Features

- 🎯 **Type-safe** - Full TypeScript support with automatic type inference
- 🔄 **Reusable** - Define queries once, use them anywhere
- 🎨 **Framework agnostic** - Works with React, Vue, Solid, and more
- ⚡ **Optimized** - Built on top of @tanstack/query-core
- 🔧 **Flexible** - Dynamic cache keys and query options

## Installation

```bash
npm install @qkit/tanstack-query @tanstack/query-core
# or
pnpm add @qkit/tanstack-query @tanstack/query-core
# or
yarn add @qkit/tanstack-query @tanstack/query-core
```

## Basic Usage

### 1. Define your query function

```typescript
import type { QKitQueryContext } from '@qkit/tanstack-query';

interface User {
  id: number;
  name: string;
  email: string;
}

interface LoadUsersParams {
  page: number;
  limit?: number;
}

const loadUsers = async (
  params: LoadUsersParams,
  context: QKitQueryContext
): Promise<User[]> => {
  const response = await fetch(
    `/api/users?page=${params.page}&limit=${params.limit || 10}`,
    { signal: context.signal }
  );
  return response.json();
};
```

### 2. Create a reusable query

```typescript
import { createQuery } from '@qkit/tanstack-query';

const usersQuery = createQuery(loadUsers, {
  cacheKey: (params) => ['users', params.page, params.limit],
  staleTime: 5 * 60 * 1000, // 5 minutes
  gcTime: 10 * 60 * 1000,   // 10 minutes
});
```

### 3. Use in your components

```typescript
// React example
import { useQuery } from '@tanstack/react-query';

function UsersPage() {
  const { data, isLoading, error } = useQuery(
    usersQuery.getQueryOptions({ page: 1, limit: 20 })
  );

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <ul>
      {data?.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}
```

## Advanced Features

### Dynamic Cache Keys

```typescript
const userQuery = createQuery(loadUserById, {
  cacheKey: (params) => ['user', params.userId],
});
```

### Dynamic Options

```typescript
const priorityQuery = createQuery(loadData, {
  staleTime: (params) => params.priority === 'high' ? 1000 : 10000,
  retry: (params) => params.priority === 'high' ? 5 : 2,
  enabled: (params) => params.priority !== 'disabled',
});
```

### With Context

```typescript
const query = createQuery(queryFn);

// Pass additional context
const options = query.getQueryOptions(params, {
  meta: { source: 'user-action' }
});
```

## API Reference

### `createQuery(queryFn, options?)`

Creates a reusable query wrapper.

**Parameters:**
- `queryFn`: Function that fetches data
- `options`: Optional configuration object

**Options:**
- `cacheKey`: Static array or dynamic function for cache keys
- `staleTime`: Time until data is considered stale
- `gcTime`: Time until inactive data is garbage collected
- `retry`: Retry configuration
- `retryDelay`: Delay between retries
- `refetchOnWindowFocus`: Refetch when window gains focus
- `refetchOnReconnect`: Refetch on network reconnect
- `refetchOnMount`: Refetch when component mounts
- `enabled`: Whether the query is enabled

### `QueryWrapper.getQueryOptions(params?, context?)`

Gets query options for use with TanStack Query hooks.

**Parameters:**
- `params`: Parameters for the query function
- `context`: Additional context to merge

**Returns:** QueryOptions object compatible with useQuery

## Type Safety

The library provides full type inference:

```typescript
// Types are automatically inferred
const query = createQuery(
  async (params: { id: string }) => ({ name: 'John' }),
  { cacheKey: (params) => ['user', params.id] }
);

// TypeScript knows the parameter and return types
const options = query.getQueryOptions({ id: '123' });
// options.queryFn returns Promise<{ name: string }>
```

## License

MIT