A library using the Vue Composition API for remote data fetching with stale-while-revalidate caching strategy
—
Core composable for reactive data fetching with automatic caching, revalidation, and error handling using the stale-while-revalidate strategy.
Main composable that provides reactive data fetching with caching.
/**
* Vue composable for data fetching with stale-while-revalidate caching
* @param key - Unique identifier for the request (string, array, function, or reactive)
* @returns IResponse object with reactive data, error, loading states, and mutate function
*/
function useSWRV<Data = any, Error = any>(
key: IKey
): IResponse<Data, Error>;
/**
* Vue composable for data fetching with stale-while-revalidate caching
* @param key - Unique identifier for the request
* @param fn - Fetcher function that returns data or promise (null for cache-only, undefined for default fetcher)
* @param config - Configuration options
* @returns IResponse object with reactive data, error, loading states, and mutate function
*/
function useSWRV<Data = any, Error = any>(
key: IKey,
fn: fetcherFn<Data> | undefined | null,
config?: IConfig
): IResponse<Data, Error>;Usage Examples:
import useSWRV from "swrv";
// Basic usage with default fetch
const { data, error, isValidating } = useSWRV('/api/users');
// Custom fetcher function
const fetcher = (url) => axios.get(url).then(res => res.data);
const { data } = useSWRV('/api/users', fetcher);
// With configuration
const { data, error } = useSWRV('/api/users', fetcher, {
refreshInterval: 1000,
revalidateOnFocus: false
});
// Reactive key (dependent fetching)
const userId = ref(null);
const { data: user } = useSWRV(() => userId.value && `/api/users/${userId.value}`, fetcher);
// Array key for complex parameters
const { data } = useSWRV(['/api/search', { query: 'vue', page: 1 }],
([url, params]) => api.get(url, { params })
);The IResponse object returned by useSWRV contains reactive properties and methods.
interface IResponse<Data = any, Error = any> {
/** Reactive reference to fetched data (undefined until first successful fetch) */
data: Ref<Data | undefined>;
/** Reactive reference to error object (undefined when no error) */
error: Ref<Error | undefined>;
/** Reactive reference indicating if currently revalidating data */
isValidating: Ref<boolean>;
/** Reactive reference indicating if initially loading (no cached data available) */
isLoading: Ref<boolean>;
/** Function to manually trigger revalidation with optional new data */
mutate: (data?: fetcherFn<Data>, opts?: revalidateOptions) => Promise<void>;
}Flexible key system supporting various identifier patterns.
/** Union type for cache key identifiers */
type IKey = keyType | WatchSource<keyType>;
/** Basic key types supported */
type keyType = string | any[] | null | undefined;Key Examples:
// String key
useSWRV('/api/users');
// Array key (serialized to stable string)
useSWRV(['/api/users', { active: true, limit: 10 }]);
// Function key (reactive, watched for changes)
useSWRV(() => user.value ? `/api/users/${user.value.id}/posts` : null);
// Ref key (reactive)
const endpoint = ref('/api/users');
useSWRV(endpoint);
// Conditional key (null disables fetching)
useSWRV(isAuthenticated.value ? '/api/profile' : null);Function responsible for data fetching logic.
/**
* Function that fetches data for a given key
* @param args - Arguments passed from the key (single value for string keys, spread array for array keys)
* @returns Data directly or Promise resolving to data
*/
type fetcherFn<Data> = (...args: any) => Data | Promise<Data>;Fetcher Examples:
// Default fetch API
const defaultFetcher = (url) => fetch(url).then(res => res.json());
// Axios fetcher
const axiosFetcher = (url) => axios.get(url).then(res => res.data);
// Custom fetcher with error handling
const customFetcher = async (url, options = {}) => {
const response = await fetch(url, {
headers: { 'Authorization': `Bearer ${getToken()}` },
...options
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
};
// Fetcher for array keys
const searchFetcher = ([endpoint, params]) =>
fetch(`${endpoint}?${new URLSearchParams(params)}`).then(res => res.json());Comprehensive configuration for customizing swrv behavior.
interface IConfig<Data = any, Fn extends fetcherFn<Data> = fetcherFn<Data>> {
/** Polling interval in milliseconds (0 disables polling) */
refreshInterval?: number;
/** Cache implementation to use */
cache?: LocalStorageCache | SWRVCache<any>;
/** Time window in ms to deduplicate identical requests */
dedupingInterval?: number;
/** Time to live for cache entries in milliseconds (0 = no expiration) */
ttl?: number;
/** Server-side time to live in milliseconds */
serverTTL?: number;
/** Automatically revalidate when window regains focus */
revalidateOnFocus?: boolean;
/** Debounce revalidation by this many milliseconds */
revalidateDebounce?: number;
/** Retry requests when they fail */
shouldRetryOnError?: boolean;
/** Interval between error retries in milliseconds */
errorRetryInterval?: number;
/** Maximum number of error retries */
errorRetryCount?: number;
/** Default fetcher function to use when none provided */
fetcher?: Fn;
/** Function to check online status */
isOnline?: () => boolean;
/** Function to check if document is visible */
isDocumentVisible?: () => boolean;
}Configuration Examples:
// Polling configuration
const { data } = useSWRV('/api/stats', fetcher, {
refreshInterval: 5000, // Poll every 5 seconds
revalidateOnFocus: false // Don't revalidate on focus during polling
});
// Error handling configuration
const { data, error } = useSWRV('/api/flaky-endpoint', fetcher, {
shouldRetryOnError: true,
errorRetryCount: 3,
errorRetryInterval: 1000 // 1 second between retries
});
// Performance optimization
const { data } = useSWRV('/api/heavy-data', fetcher, {
dedupingInterval: 10000, // Dedupe for 10 seconds
revalidateDebounce: 500, // Debounce rapid revalidations
ttl: 300000 // Cache for 5 minutes
});Options for controlling manual revalidation behavior.
interface revalidateOptions {
/** Whether to retry on error for this revalidation */
shouldRetryOnError?: boolean;
/** Current error retry count (internal use) */
errorRetryCount?: number;
/** Force revalidation even if within deduping interval */
forceRevalidate?: boolean;
}Manual Revalidation Examples:
const { data, mutate } = useSWRV('/api/users', fetcher);
// Revalidate with current fetcher
await mutate();
// Optimistic update then revalidate
await mutate(async () => {
const newUser = await createUser(userData);
return [...data.value, newUser];
});
// Force revalidation (ignore deduping)
await mutate(undefined, { forceRevalidate: true });
// Revalidate without error retry
await mutate(undefined, { shouldRetryOnError: false });Install with Tessl CLI
npx tessl i tessl/npm-swrv