swr
Version:
React Hooks library for remote data fetching
873 lines (870 loc) • 34.7 kB
text/typescript
import { SWRGlobalConfig } from '../index/index.mjs';
import * as revalidateEvents from './events.mjs';
/**
* Global state tuple containing SWR's internal state management structures.
*
* This is the core state structure that manages all SWR operations internally.
* Each element serves a specific purpose in the SWR ecosystem.
*
* @internal
*/
type GlobalState = [
/** Event revalidators: Maps cache keys to arrays of revalidation callbacks */
Record<string, RevalidateCallback[]>,
/** Mutation timestamps: Maps cache keys to [start_timestamp, end_timestamp] tuples */
Record<string, [number, number]>,
/** Fetch cache: Maps cache keys to [data, timestamp] tuples */
Record<string, [any, number]>,
/** Preload cache: Maps cache keys to fetcher responses */
Record<string, FetcherResponse<any>>,
/** Scoped mutator function for cache updates */
ScopedMutator,
/** Cache setter function with prev/current value comparison */
(key: string, value: any, prev: any) => void,
/** Cache subscriber function that returns an unsubscribe function */
(key: string, callback: (current: any, prev: any) => void) => () => void
];
/**
* Response type that can be returned by fetcher functions.
*
* @template Data - The type of data returned by the fetcher
* @public
*/
type FetcherResponse<Data = unknown> = Data | Promise<Data>;
/**
* Basic fetcher function that accepts any arguments and returns data or a promise.
*
* This is the most permissive fetcher type, allowing any number of arguments
* of any type. Used when type safety is not required or when dealing with
* dynamic fetcher signatures.
*
* @template Data - The type of data returned by the fetcher
* @param args - Variable arguments passed to the fetcher
* @returns Data or a Promise that resolves to data
* @public
*/
type BareFetcher<Data = unknown> = (...args: any[]) => FetcherResponse<Data>;
/**
* Typed fetcher function that is constrained by the SWR key type.
*
* Provides type safety by ensuring the fetcher argument matches the key type.
* The conditional type logic ensures that:
* - If the key is a function returning a value, the fetcher receives that value
* - If the key is falsy (null, undefined, false), the fetcher is never called
* - Otherwise, the fetcher receives the key directly as its argument
*
* @template Data - The type of data returned by the fetcher
* @template SWRKey - The type of the SWR key, used to infer fetcher arguments
* @public
*/
type Fetcher<Data = unknown, SWRKey extends Key = Key> = SWRKey extends () => infer Arg | null | undefined | false ? (arg: Arg) => FetcherResponse<Data> : SWRKey extends null | undefined | false ? never : SWRKey extends infer Arg ? (arg: Arg) => FetcherResponse<Data> : never;
/**
* Determines if data should block rendering based on suspense configuration.
*
* This conditional type is used internally to determine the return type of `data`
* in SWRResponse. When suspense is enabled or fallbackData is provided, data
* will never be undefined, allowing for non-nullable return types.
*
* The type resolution follows this logic:
* 1. If global suspense is enabled → `true` (data never undefined)
* 2. If no options provided → `false` (data can be undefined)
* 3. If suspense is enabled in options → `true` (data never undefined)
* 4. If fallbackData is provided → `true` (data never undefined)
* 5. Otherwise → `false` (data can be undefined)
*
* @template Data - The data type
* @template Options - The SWR configuration options
* @returns `true` if data is guaranteed to be defined, `false` if it can be undefined
* @internal
*/
type BlockingData<Data = any, Options = SWRDefaultOptions<Data>> = SWRGlobalConfig extends {
suspense: true;
} ? true : Options extends undefined ? false : Options extends {
suspense: true;
} ? true : Options extends {
fallbackData: Data | Promise<Data>;
} ? true : false;
/**
* Configuration types that are only used internally, not exposed to the user.
*
* These options are managed internally by SWR and passed between internal
* functions. They are not part of the public API and should not be used
* directly by consumers.
*
* @internal
*/
interface InternalConfiguration {
/** The cache instance used to store SWR data and state */
cache: Cache;
/** Scoped mutator function for updating cache entries */
mutate: ScopedMutator;
}
/**
* Public configuration options for SWR.
*
* This interface defines all the configuration options that users can pass
* to customize SWR's behavior. These options can be provided globally via
* SWRConfig or per-hook via the config parameter.
*
* @template Data - The type of data returned by the fetcher
* @template Error - The type of error that can be thrown
* @template Fn - The fetcher function type
*
* @public
* @see {@link https://swr.vercel.app/docs/options | SWR Options Documentation}
*/
interface PublicConfiguration<Data = any, Error = any, Fn extends Fetcher = BareFetcher> {
/**
* error retry interval in milliseconds
* @defaultValue 5000
*/
errorRetryInterval: number;
/** max error retry count */
errorRetryCount?: number;
/**
* timeout to trigger the onLoadingSlow event in milliseconds
* @defaultValue 3000
*/
loadingTimeout: number;
/**
* only revalidate once during a time span in milliseconds
* @defaultValue 5000
*/
focusThrottleInterval: number;
/**
* dedupe requests with the same key in this time span in milliseconds
* @defaultValue 2000
*/
dedupingInterval: number;
/**
* * Disabled by default: `refreshInterval = 0`
* * If set to a number, polling interval in milliseconds
* * If set to a function, the function will receive the latest data and should return the interval in milliseconds
* @see {@link https://swr.vercel.app/docs/revalidation}
*/
refreshInterval?: number | ((latestData: Data | undefined) => number);
/**
* polling when the window is invisible (if `refreshInterval` is enabled)
* @defaultValue false
*/
refreshWhenHidden?: boolean;
/**
* polling when the browser is offline (determined by `navigator.onLine`)
*
* When enabled, SWR will continue polling even when the browser is offline.
* This can be useful for applications that need to check for connectivity
* or cache updates while offline.
*
* @defaultValue false
*/
refreshWhenOffline?: boolean;
/**
* automatically revalidate when window gets focused
*
* When enabled, SWR will automatically revalidate data when the user
* returns focus to the window/tab. This ensures data freshness when
* users switch between applications.
*
* @defaultValue true
* @see {@link https://swr.vercel.app/docs/revalidation | Revalidation Documentation}
*/
revalidateOnFocus: boolean;
/**
* automatically revalidate when the browser regains a network connection (via `navigator.onLine`)
*
* When enabled, SWR will automatically revalidate data when the browser
* goes from offline to online state, ensuring data is up-to-date when
* connectivity is restored.
*
* @defaultValue true
* @see {@link https://swr.vercel.app/docs/revalidation | Revalidation Documentation}
*/
revalidateOnReconnect: boolean;
/**
* enable or disable automatic revalidation when component is mounted
*
* Controls whether SWR should automatically fetch data when the component
* mounts. When `undefined`, the behavior depends on `revalidateIfStale`.
*
* @defaultValue undefined (inherits from revalidateIfStale)
*/
revalidateOnMount?: boolean;
/**
* automatically revalidate even if there is stale data
* @defaultValue true
* @see {@link https://swr.vercel.app/docs/revalidation#disable-automatic-revalidations}
*/
revalidateIfStale: boolean;
/**
* retry when fetcher has an error
* @defaultValue true
*/
shouldRetryOnError: boolean | ((err: Error) => boolean);
/**
* keep the previous result when key is changed but data is not ready
* @defaultValue false
*/
keepPreviousData?: boolean;
/**
* @experimental enable React Suspense mode
* @defaultValue false
* @see {@link https://swr.vercel.app/docs/suspense}
*/
suspense?: boolean;
/**
* initial data to be returned (note: ***This is per-hook***)
* @see {@link https://swr.vercel.app/docs/with-nextjs}
*/
fallbackData?: Data | Promise<Data>;
/**
* warns when preload data is missing for a given key, this includes fallback
* data, preload calls, or initial data from the cache provider
* @defaultValue false
*/
strictServerPrefetchWarning?: boolean;
/**
* the fetcher function
*/
fetcher?: Fn;
/**
* array of middleware functions
* @see {@link https://swr.vercel.app/docs/middleware}
*/
use?: Middleware[];
/**
* a key-value object of multiple fallback data
* @see {@link https://swr.vercel.app/docs/with-nextjs#pre-rendering-with-default-data}
*/
fallback: {
[key: string]: any;
};
/**
* Function to detect whether pause revalidations, will ignore fetched data and errors when it returns true. Returns false by default.
*/
isPaused: () => boolean;
/**
* callback function when a request takes too long to load (see `loadingTimeout`)
*/
onLoadingSlow: (key: string, config: Readonly<PublicConfiguration<Data, Error, Fn>>) => void;
/**
* callback function when a request finishes successfully
*/
onSuccess: (data: Data, key: string, config: Readonly<PublicConfiguration<Data, Error, Fn>>) => void;
/**
* callback function when a request returns an error
*/
onError: (err: Error, key: string, config: Readonly<PublicConfiguration<Data, Error, Fn>>) => void;
/**
* handler for error retry
*/
onErrorRetry: (err: Error, key: string, config: Readonly<PublicConfiguration<Data, Error, Fn>>, revalidate: Revalidator, revalidateOpts: Required<RevalidatorOptions>) => void;
/**
* callback function when a request is ignored due to race conditions
*/
onDiscarded: (key: string) => void;
/**
* Comparison function used to detect when returned data has changed, to avoid spurious rerenders. By default, [dequal](https://github.com/lukeed/dequal) is used.
*/
compare: (a: Data | undefined, b: Data | undefined) => boolean;
/**
* IsOnline and isVisible are functions that return a boolean, to determine if the application is "active". By default, SWR will bail out a revalidation if these conditions are not met.
* @see {@link https://swr.vercel.app/docs/advanced/react-native#customize-focus-and-reconnect-events}
*/
isOnline: () => boolean;
/**
* IsOnline and isVisible are functions that return a boolean, to determine if the application is "active". By default, SWR will bail out a revalidation if these conditions are not met.
* @see {@link https://swr.vercel.app/docs/advanced/react-native#customize-focus-and-reconnect-events}
*/
isVisible: () => boolean;
}
type FullConfiguration<Data = any, Error = any, Fn extends Fetcher = BareFetcher> = InternalConfiguration & PublicConfiguration<Data, Error, Fn>;
/**
* Provider configuration for custom focus and reconnect event handling.
*
* This configuration allows custom implementations for detecting window focus
* and network reconnection events. Useful for React Native or other environments
* where the default browser APIs are not available.
*
* @public
* @see {@link https://swr.vercel.app/docs/advanced/react-native | React Native Documentation}
*/
type ProviderConfiguration = {
/**
* Initialize focus event listener.
*
* @param callback - Function to call when window gains focus
* @returns Optional cleanup function to remove the listener
*/
initFocus: (callback: () => void) => (() => void) | void;
/**
* Initialize reconnect event listener.
*
* @param callback - Function to call when network reconnects
* @returns Optional cleanup function to remove the listener
*/
initReconnect: (callback: () => void) => (() => void) | void;
};
/**
* The main useSWR hook interface with multiple overloads for different usage patterns.
*
* This interface provides type-safe overloads for various ways to call useSWR,
* from simple key-only calls to complex configurations with custom fetchers.
* The overloads ensure proper type inference for data, error, and configuration.
*
* @public
*
* @example Basic usage
* ```ts
* const { data, error } = useSWR('/api/data', fetcher)
* ```
*
* @example With configuration
* ```ts
* const { data, error } = useSWR('/api/data', fetcher, {
* refreshInterval: 1000,
* revalidateOnFocus: false
* })
* ```
*
* @example Conditional fetching
* ```ts
* const { data, error } = useSWR(
* user.id ? `/api/user/${user.id}` : null,
* fetcher
* )
* ```
*
* @example Dynamic key with function
* ```ts
* const { data, error } = useSWR(
* () => user.id ? [`/api/user/${user.id}`, user.token] : null,
* ([url, token]) => fetcher(url, { headers: { Authorization: token } })
* )
* ```
*/
interface SWRHook {
/**
* Basic usage with just a key. Requires a global fetcher to be configured,
* or can be used for client-side state management without fetching.
*
* @example
* ```ts
* // With global fetcher
* const { data } = useSWR('/api/user')
*
* // Client state management
* const { data, mutate } = useSWR('user-settings')
* mutate({ theme: 'dark' })
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey>(key: SWRKey): SWRResponse<Data, Error>;
/**
* Most common usage pattern with key and explicit fetcher function.
* The fetcher receives the key as its argument and returns the data.
*
* @example
* ```ts
* const { data, error } = useSWR('/api/user/123',
* (url) => fetch(url).then(res => res.json())
* )
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey>(key: SWRKey, fetcher: Fetcher<Data, SWRKey> | null): SWRResponse<Data, Error>;
/**
* Key with fetcher using relaxed key constraints for dynamic or complex keys.
* Allows more flexible key types including functions and objects.
*
* @example
* ```ts
* const { data } = useSWR(
* () => user ? ['/api/posts', user.id] : null,
* ([url, userId]) => fetchUserPosts(url, userId)
* )
* ```
*/
<Data = any, Error = any, SWRKey extends Key = Key>(key: SWRKey, fetcher: Fetcher<Data, SWRKey> | null): SWRResponse<Data, Error>;
/**
* Key-only with advanced configuration options and strict typing.
* Useful when you need specific SWR options but rely on a global fetcher.
*
* @example
* ```ts
* const { data } = useSWR<User>('/api/user', {
* refreshInterval: 5000,
* revalidateOnFocus: false
* })
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey, SWROptions extends SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined = SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined>(key: SWRKey): SWRResponse<Data, Error, SWROptions>;
/**
* Key with fetcher and advanced configuration options with strict typing.
* Provides full control over fetching behavior and SWR options.
*
* @example
* ```ts
* const { data } = useSWR('/api/data', fetcher, {
* suspense: true,
* fallbackData: initialData
* })
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey, SWROptions extends SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined = SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined>(key: SWRKey, fetcher: Fetcher<Data, SWRKey> | null): SWRResponse<Data, Error, SWROptions>;
/**
* Key with configuration object but no explicit fetcher. Uses global fetcher
* or can be used for pure client state management with configuration.
*
* @example
* ```ts
* // With global fetcher and config
* const { data } = useSWR('/api/user', {
* refreshInterval: 1000
* })
*
* // Client state with config
* const { data } = useSWR('local-state', {
* fallbackData: defaultValue
* })
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey, SWROptions extends SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined = SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined>(key: SWRKey, config: SWRConfigurationWithOptionalFallback<SWROptions>): SWRResponse<Data, Error, SWROptions>;
/**
* Complete signature with key, fetcher, and configuration options.
* Provides maximum flexibility and control over all SWR behavior.
*
* @example
* ```ts
* const { data, error, isLoading } = useSWR(
* '/api/user',
* async (url) => {
* const res = await fetch(url)
* if (!res.ok) throw new Error('Failed to fetch')
* return res.json()
* },
* {
* refreshInterval: 5000,
* onError: (error) => console.error('SWR Error:', error),
* fallbackData: { name: 'Loading...' }
* }
* )
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey, SWROptions extends SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined = SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined>(key: SWRKey, fetcher: Fetcher<Data, SWRKey> | null, config: SWRConfigurationWithOptionalFallback<SWROptions>): SWRResponse<Data, Error, SWROptions>;
/**
* Simple key-only usage with flexible key types. Most permissive overload
* that accepts any valid key format.
*
* @example
* ```ts
* const { data } = useSWR('/api/data')
* const { data: userData } = useSWR(['user', userId])
* const { data: settings } = useSWR({ endpoint: '/settings', version: 'v1' })
* ```
*/
<Data = any, Error = any>(key: Key): SWRResponse<Data, Error>;
/**
* Key-only with configuration options using bare fetcher constraints.
* Suitable for cases where fetcher type safety is less important.
*
* @example
* ```ts
* const { data } = useSWR('/api/data', {
* dedupingInterval: 5000
* })
* ```
*/
<Data = any, Error = any, SWROptions extends SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined = SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined>(key: Key): SWRResponse<Data, Error, SWROptions>;
/**
* Key with bare fetcher function that accepts any arguments.
* Provides less type safety but maximum flexibility for fetcher signatures.
*
* @example
* ```ts
* const { data } = useSWR('/api/user',
* (...args) => customFetcher(...args)
* )
* ```
*/
<Data = any, Error = any, SWROptions extends SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined = SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined>(key: Key, fetcher: BareFetcher<Data> | null): SWRResponse<Data, Error, SWROptions>;
/**
* Key with configuration using relaxed fetcher typing constraints.
* Useful when working with dynamic or loosely-typed fetcher functions.
*
* @example
* ```ts
* const { data } = useSWR(dynamicKey, {
* fetcher: customFetcher,
* refreshInterval: 2000
* })
* ```
*/
<Data = any, Error = any, SWROptions extends SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined = SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined>(key: Key, config: SWRConfigurationWithOptionalFallback<SWROptions>): SWRResponse<Data, Error, SWROptions>;
/**
* Complete signature with key, bare fetcher, and configuration.
* Most flexible overload with minimal type constraints, suitable for
* complex scenarios where strict typing isn't feasible.
*
* @example
* ```ts
* const { data } = useSWR(
* complexKey,
* (...args) => legacyFetcher(...args),
* {
* refreshInterval: 10000,
* errorRetryCount: 3
* }
* )
* ```
*/
<Data = any, Error = any, SWROptions extends SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined = SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined>(key: Key, fetcher: BareFetcher<Data> | null, config: SWRConfigurationWithOptionalFallback<SWROptions>): SWRResponse<Data, Error, SWROptions>;
}
/**
* Middleware function type for extending SWR functionality.
*
* Middleware functions receive the next SWR hook in the chain and return
* a modified hook function. This allows for composition of multiple
* middleware functions to add features like logging, caching, or
* request/response transformation.
*
* The middleware guarantees that a SWRHook receives a key, fetcher,
* and config as arguments, providing a consistent interface for
* middleware authors.
*
* @param useSWRNext - The next SWR hook function in the middleware chain
* @returns A new SWR hook function with middleware functionality applied
*
* @template Data - The type of data returned by the fetcher
* @template Error - The type of error that can be thrown
*
* @public
* @see {@link https://swr.vercel.app/docs/middleware | Middleware Documentation}
*
* @example
* ```ts
* const logger: Middleware = (useSWRNext) => (key, fetcher, config) => {
* console.log('SWR Request:', key)
* return useSWRNext(key, fetcher, config)
* }
* ```
*/
type Middleware = (useSWRNext: SWRHook) => <Data = any, Error = any>(key: Key, fetcher: BareFetcher<Data> | null, config: SWRConfiguration<Data, Error, BareFetcher<Data>>) => SWRResponse<Data, Error>;
/**
* Represents a tuple of arguments that can be passed to a fetcher.
*
* The first element is typically the primary key (like a URL), followed
* by additional parameters that affect the request (like query parameters,
* headers, or request options).
*
*/
type ArgumentsTuple = readonly [any, ...unknown[]];
/**
* Valid types for SWR keys.
*
* SWR keys identify unique requests and can be:
* - `string`: Simple URL or identifier
* - `ArgumentsTuple`: Array with URL and additional parameters
* - `Record<any, any>`: Object that will be serialized
* - `null | undefined | false`: Falsy values disable the request
*
* When a key is falsy, SWR will not make the request, allowing for
* conditional fetching based on application state.
*
* @public
*
* @example
* ```ts
* // String key
* useSWR('/api/users', fetcher)
*
* // Array key with parameters
* useSWR(['/api/user', userId], ([url, id]) => fetcher(`${url}/${id}`))
*
* // Object key
* useSWR({ url: '/api/data', params: { page: 1 } }, fetcher)
*
* // Conditional key
* useSWR(userId ? `/api/user/${userId}` : null, fetcher)
* ```
*/
type Arguments = string | ArgumentsTuple | Record<any, any> | null | undefined | false;
/**
* SWR key that can be static or a function that returns arguments.
*
* When a function is provided, it's called on each render to determine
* the current key. This allows for dynamic keys based on component state
* or props.
*
* @public
*
* @example
* ```ts
* // Static key
* useSWR('/api/data', fetcher)
*
* // Dynamic key function
* useSWR(() => user ? `/api/user/${user.id}` : null, fetcher)
* ```
*/
type Key = Arguments | (() => Arguments);
/**
* Strict tuple key type that only allows tuples or falsy values.
*
* @internal
*/
type StrictTupleKey = ArgumentsTuple | null | undefined | false;
/**
* Strict key type for internal use.
*
* @internal
*/
type StrictKey = StrictTupleKey | (() => StrictTupleKey);
/**
* Callback function type for mutator operations.
*
* This function receives the current cached data and can return new data
* to update the cache. It can be synchronous or asynchronous, and can
* return undefined to indicate no change should be made.
*
* @template Data - The type of the cached data
* @param currentData - The current data in the cache (may be undefined)
* @returns New data to set, undefined for no change, or a Promise resolving to either
*
* @public
*
* @example
* ```ts
* // Increment a counter
* mutate(key, (current: number = 0) => current + 1)
*
* // Async update
* mutate(key, async (current) => {
* const updated = await updateData(current)
* return updated
* })
* ```
*/
type MutatorCallback<Data = any> = (currentData?: Data) => Promise<undefined | Data> | undefined | Data;
/**
* Options for configuring mutator behavior.
*
* These options control how the mutation affects the cache, revalidation,
* and error handling behavior.
*
* @template Data - The type of the data related to the key
* @template MutationData - The type of the data returned by the mutator
*
* @public
*/
type MutatorOptions<Data = any, MutationData = Data> = {
/**
* Whether to revalidate the cache after mutation.
*
* Can be a boolean or a function that receives the new data and key
* to determine whether revalidation should occur.
*
* @defaultValue true
*/
revalidate?: boolean | ((data: Data, key: Arguments) => boolean);
/**
* Whether and how to populate the cache with mutation results.
*
* - `false`: Don't update the cache
* - `true`: Update cache with mutation result directly
* - Function: Transform mutation result before caching
*
* @defaultValue true
*/
populateCache?: boolean | ((result: MutationData, currentData: Data | undefined) => Data);
/**
* Optimistic data to show immediately while mutation is pending.
*
* Can be the data directly or a function that computes it based on
* current and displayed data. Useful for immediate UI feedback.
*
* @defaultValue undefined
*/
optimisticData?: Data | ((currentData: Data | undefined, displayedData: Data | undefined) => Data);
/**
* Whether to rollback optimistic updates on error.
*
* Can be a boolean or a function that receives the error to determine
* whether rollback should occur.
*
* @defaultValue true
*/
rollbackOnError?: boolean | ((error: unknown) => boolean);
/**
* Whether to throw errors instead of returning them in the error field.
*
* When true, errors will be thrown and can be caught with try/catch.
* When false, errors are returned in the response object.
*
* @defaultValue false
*/
throwOnError?: boolean;
};
type MutatorConfig = {
revalidate?: boolean;
populateCache?: boolean;
};
type Broadcaster<Data = any, Error = any> = (cache: Cache<Data>, key: string, data: Data, error?: Error, isValidating?: boolean, revalidate?: boolean, populateCache?: boolean) => Promise<Data>;
/**
* Internal state structure stored in the cache.
*
* This represents the complete state for a cache entry, including
* data, error, and loading states. All fields are optional as they
* may not be present depending on the request lifecycle.
*
* @template Data - The type of data stored
* @template Error - The type of error that can occur
*
* @internal
*/
type State<Data = any, Error = any> = {
/** The cached data, if available */
data?: Data;
/** The error object, if an error occurred */
error?: Error;
/** Whether a revalidation is currently in progress */
isValidating?: boolean;
/** Whether this is the initial load with no cached data */
isLoading?: boolean;
};
type MutatorFn<Data = any> = (cache: Cache, key: Key, data?: Data | Promise<Data> | MutatorCallback<Data>, opts?: boolean | MutatorOptions<Data>) => Promise<Data | undefined>;
type MutatorWrapper<Fn> = Fn extends (...args: [...infer Parameters]) => infer Result ? Parameters[3] extends boolean ? Result : Parameters[3] extends Required<Pick<MutatorOptions, 'populateCache'>> ? Parameters[3]['populateCache'] extends false ? never : Result : Result : never;
type Mutator<Data = any> = MutatorWrapper<MutatorFn<Data>>;
interface ScopedMutator {
/**
* @typeParam Data - The type of the data related to the key
* @typeParam MutationData - The type of the data returned by the mutator
*/
<Data = any, MutationData = Data>(matcher: (key?: Arguments) => boolean, data?: MutationData | Promise<MutationData> | MutatorCallback<MutationData>, opts?: boolean | MutatorOptions<Data, MutationData>): Promise<Array<MutationData | undefined>>;
/**
* @typeParam Data - The type of the data related to the key
* @typeParam MutationData - The type of the data returned by the mutator
*/
<Data = any, T = Data>(key: Arguments, data?: T | Promise<T> | MutatorCallback<T>, opts?: boolean | MutatorOptions<Data, T>): Promise<T | undefined>;
}
/**
* @typeParam Data - The type of the data related to the key
* @typeParam MutationData - The type of the data returned by the mutator
*/
type KeyedMutator<Data> = <MutationData = Data>(data?: Data | Promise<Data | undefined> | MutatorCallback<Data>, opts?: boolean | MutatorOptions<Data, MutationData>) => Promise<Data | MutationData | undefined>;
type SWRConfiguration<Data = any, Error = any, Fn extends BareFetcher<any> = BareFetcher<any>> = Partial<PublicConfiguration<Data, Error, Fn>> & Partial<ProviderConfiguration> & {
provider?: (cache: Readonly<Cache>) => Cache;
};
type IsLoadingResponse<Data = any, Options = SWRDefaultOptions<Data>> = SWRGlobalConfig extends {
suspense: true;
} ? Options extends {
suspense: true;
} ? false : false : boolean;
type SWRDefaultOptions<Data> = SWRConfiguration<Data, Error, Fetcher<Data, Key>>;
type SWRConfigurationWithOptionalFallback<Options> = Options extends SWRConfiguration & Required<Pick<SWRConfiguration, 'fallbackData'>> ? Omit<Options, 'fallbackData'> & Pick<Partial<Options>, 'fallbackData'> : Options;
/**
* The response object returned by SWR hooks.
*
* This interface represents the return value of useSWR and related hooks,
* providing access to data, error state, and control functions.
*
* @template Data - The type of data returned by the fetcher
* @template Error - The type of error that can be thrown
* @template Config - The configuration type used to determine blocking behavior
*
* @public
*/
interface SWRResponse<Data = any, Error = any, Config = any> {
/**
* The data returned by the fetcher function.
*
* - When suspense is enabled or fallbackData is provided: always defined
* - Otherwise: `undefined` during initial load or when key is falsy
*/
data: BlockingData<Data, Config> extends true ? Data : Data | undefined;
/**
* The error object thrown by the fetcher function.
*
* `undefined` when there's no error or when a request is in progress.
*/
error: Error | undefined;
/**
* Function to mutate the cached data for this specific key.
*
* This is a bound version of the global mutate function that automatically
* uses the current key, providing type safety and convenience.
*/
mutate: KeyedMutator<Data>;
/**
* Whether the request is currently being validated (loading fresh data).
*
* `true` during initial load, revalidation, or when mutate is called
* with a promise or async function.
*/
isValidating: boolean;
/**
* Whether the request is in initial loading state.
*
* `true` only during the initial load when there's no cached data.
* Unlike `isValidating`, this becomes `false` once data is available.
*/
isLoading: IsLoadingResponse<Data, Config>;
}
type KeyLoader<Args extends Arguments = Arguments> = ((index: number, previousPageData: any | null) => Args) | null;
interface RevalidatorOptions {
retryCount?: number;
dedupe?: boolean;
}
type Revalidator = (revalidateOpts?: RevalidatorOptions) => Promise<boolean> | void;
type RevalidateEvent = typeof revalidateEvents.FOCUS_EVENT | typeof revalidateEvents.RECONNECT_EVENT | typeof revalidateEvents.MUTATE_EVENT | typeof revalidateEvents.ERROR_REVALIDATE_EVENT;
type RevalidateCallbackReturnType = {
[revalidateEvents.FOCUS_EVENT]: void;
[revalidateEvents.RECONNECT_EVENT]: void;
[revalidateEvents.MUTATE_EVENT]: Promise<boolean>;
[revalidateEvents.ERROR_REVALIDATE_EVENT]: void;
};
type RevalidateCallback = <K extends RevalidateEvent>(type: K, opts?: any) => RevalidateCallbackReturnType[K];
/**
* Cache interface for storing SWR state.
*
* This interface defines the contract for cache providers used by SWR.
* The default implementation uses a Map, but custom cache providers
* can implement this interface to provide different storage mechanisms.
*
* @template Data - The type of data stored in the cache
*
* @public
* @see {@link https://swr.vercel.app/docs/advanced/cache | Cache Documentation}
*/
interface Cache<Data = any> {
/**
* Get an iterator of all cache keys.
*
* @returns Iterator that yields all cache keys as strings
*/
keys(): IterableIterator<string>;
/**
* Get the cached state for a key.
*
* @param key - The cache key to look up
* @returns The cached state or undefined if not found
*/
get(key: string): State<Data> | undefined;
/**
* Set the cached state for a key.
*
* @param key - The cache key to set
* @param value - The state to cache
*/
set(key: string, value: State<Data>): void;
/**
* Delete a cached entry.
*
* @param key - The cache key to delete
*/
delete(key: string): void;
}
interface StateDependencies {
data?: boolean;
error?: boolean;
isValidating?: boolean;
isLoading?: boolean;
}
export type { Arguments, BareFetcher, BlockingData, Broadcaster, Cache, Fetcher, FetcherResponse, FullConfiguration, GlobalState, InternalConfiguration, IsLoadingResponse, Key, KeyLoader, KeyedMutator, Middleware, Mutator, MutatorCallback, MutatorConfig, MutatorFn, MutatorOptions, MutatorWrapper, ProviderConfiguration, PublicConfiguration, RevalidateCallback, RevalidateEvent, Revalidator, RevalidatorOptions, SWRConfiguration, SWRHook, SWRResponse, ScopedMutator, State, StateDependencies, StrictTupleKey };