npm package: @spoosh/plugin-prefetch
Description: Prefetch plugin for Spoosh - preload data before it's needed
Latest version: 0.6.0

# @spoosh/plugin-prefetch

Prefetch plugin for Spoosh - preload data before it's needed.

**[Documentation](https://spoosh.dev/docs/react/plugins/prefetch)** · **Requirements:** TypeScript >= 5.0 · **Peer Dependencies:** `@spoosh/core`

## Installation

```bash
npm install @spoosh/plugin-prefetch
```

## Usage

```typescript
import { Spoosh } from "@spoosh/core";
import { create } from "@spoosh/react";
import { prefetchPlugin } from "@spoosh/plugin-prefetch";
import { cachePlugin } from "@spoosh/plugin-cache";
import { retryPlugin } from "@spoosh/plugin-retry";

// Setup - prefetch is returned from create
const spoosh = new Spoosh<ApiSchema, Error>("/api").use([
  prefetchPlugin(),
  cachePlugin(),
  retryPlugin(),
]);
const { useRead, useWrite, prefetch } = create(spoosh);

// Basic prefetch
await prefetch((api) => api("posts").GET());

// Prefetch with query options
await prefetch((api) => api("posts").GET({ query: { page: 1, limit: 10 } }));

// Prefetch with plugin options (staleTime, retries, etc.)
await prefetch(
  (api) => api("users/:id").GET({ params: { id: userId } }),
  {
    staleTime: 60000,
    retries: 3,
  }
);

// Prefetch on hover
<Link
  href="/posts/1"
  onMouseEnter={() => prefetch((api) => api("posts/:id").GET({ params: { id: 1 } }))}
>
  View Post
</Link>
```

## Options

### Plugin Config

| Option      | Type     | Default | Description                                                       |
| ----------- | -------- | ------- | ----------------------------------------------------------------- |
| `staleTime` | `number` | -       | Default stale time for prefetched data (ms)                       |
| `timeout`   | `number` | `30000` | Timeout to auto-clear stale promises (ms). Prevents memory leaks. |

### Prefetch Options

The second argument to `prefetch()` accepts any plugin options (staleTime, retries, dedupe, etc.) plus:

| Option | Type                                    | Description                                         |
| ------ | --------------------------------------- | --------------------------------------------------- |
| `tags` | `'all' \| 'self' \| 'none' \| string[]` | Tag mode or custom tags (replaces `additionalTags`) |

**Examples:**

```typescript
// Mode only - 'all' generates full hierarchy
await prefetch((api) => api("users/:id/posts").GET({ params: { id: "123" } }), {
  tags: "all", // ['users', 'users/123', 'users/123/posts']
});

// Mode only - 'self' generates only exact path
await prefetch((api) => api("users/:id/posts").GET({ params: { id: "123" } }), {
  tags: "self", // ['users/123/posts']
});

// Mode only - 'none' generates no tags
await prefetch((api) => api("posts").GET(), { tags: "none" }); // []

// Custom tags only - replaces auto-generated tags
await prefetch((api) => api("posts").GET(), {
  tags: ["custom", "dashboard"], // ['custom', 'dashboard']
});

// Mode + custom tags - 'all' mode combined with custom tags
await prefetch((api) => api("users/:id/posts").GET({ params: { id: "123" } }), {
  tags: ["all", "dashboard"], // ['users', 'users/123', 'users/123/posts', 'dashboard']
});

// Mode + custom tags - 'self' mode combined with custom tags
await prefetch((api) => api("users/:id/posts").GET({ params: { id: "123" } }), {
  tags: ["self", "dashboard"], // ['users/123/posts', 'dashboard']
});
```

## Features

### In-Flight Deduplication (Built-in)

Multiple calls to prefetch the same data will return the same promise, avoiding duplicate requests. This is built into the prefetch plugin - no deduplication plugin required.

```typescript
// These will only make ONE network request
prefetch((api) => api("posts").GET());
prefetch((api) => api("posts").GET());
prefetch((api) => api("posts").GET());
```

### Memory Leak Prevention

Prefetch automatically clears promise references after completion or after `promiseTimeout` (default 30s). This prevents memory leaks from requests that never settle.