A library using the Vue Composition API for remote data fetching with stale-while-revalidate caching strategy
—
Global mutation function and cross-component data synchronization for coordinating cache updates across all swrv instances.
Updates cache globally and triggers revalidation across all components using the same key.
/**
* Global function to mutate cache data and trigger revalidation across all swrv instances
* @param key - Cache key to update
* @param res - New data or Promise resolving to new data
* @param cache - Cache instance to update (defaults to global cache)
* @param ttl - Time to live for the cached data (defaults to config ttl)
* @returns Promise resolving to the new cache data object
*/
function mutate<Data>(
key: string,
res: Promise<Data> | Data,
cache?: SWRVCache<any>,
ttl?: number
): Promise<{data: Data, error: any, isValidating: boolean}>;Usage Examples:
import { mutate } from "swrv";
// Update cache with new data
await mutate('/api/users', newUsersList);
// Update cache with promise
await mutate('/api/users', fetch('/api/users').then(res => res.json()));
// Optimistic update
await mutate('/api/users', [...existingUsers, newUser]);
// Update specific cache instance
const customCache = new SWRVCache();
await mutate('/api/data', newData, customCache);
// Update with custom TTL
await mutate('/api/temp-data', tempData, undefined, 5000); // 5 second TTLLoad data into cache before components request it, improving perceived performance.
Prefetching Examples:
import { mutate } from "swrv";
// Prefetch on hover
function prefetchUser(userId) {
mutate(
`/api/users/${userId}`,
fetch(`/api/users/${userId}`).then(res => res.json())
);
}
// Prefetch in route guards
router.beforeEach(async (to) => {
if (to.name === 'user-profile') {
await mutate(
`/api/users/${to.params.id}`,
userApi.getUser(to.params.id)
);
}
});
// Batch prefetch related data
async function prefetchDashboardData() {
await Promise.all([
mutate('/api/stats', statsApi.getStats()),
mutate('/api/notifications', notificationApi.getRecent()),
mutate('/api/user/profile', userApi.getCurrentUser())
]);
}Automatically synchronize data across multiple components using the same cache key.
Synchronization Examples:
// Component A - Updates user data
export default {
setup() {
const { data: user, mutate: updateUser } = useSWRV('/api/user/profile', fetcher);
const saveProfile = async (updates) => {
// Optimistic update - immediately visible in all components
await updateUser(async () => {
const updated = { ...user.value, ...updates };
await userApi.updateProfile(updates);
return updated;
});
};
return { user, saveProfile };
}
};
// Component B - Automatically receives updates
export default {
setup() {
// Automatically syncs with Component A's updates
const { data: user } = useSWRV('/api/user/profile', fetcher);
return { user };
}
};
// Component C - Also automatically synced
export default {
setup() {
// All three components share the same cache entry
const { data: user } = useSWRV('/api/user/profile', fetcher);
return { user };
}
};Serve data exclusively from cache without triggering network requests.
/**
* Cache-only fetching by passing null as fetcher
* Useful when you know data is already cached by another component
*/
useSWRV(key, null); // null fetcher = cache-only modeCache-Only Examples:
// Main component fetches data
const MainComponent = {
setup() {
const { data } = useSWRV('/api/config', fetcher);
return { data };
}
};
// Child components use cache-only mode
const ChildComponent = {
setup() {
// Only retrieve from cache, no network request
const { data } = useSWRV('/api/config', null);
return { data };
}
};
// Conditional cache-only mode
const ConditionalComponent = {
setup() {
const isOnline = ref(navigator.onLine);
// Use cache-only when offline
const { data } = useSWRV('/api/data', isOnline.value ? fetcher : null);
return { data };
}
};Errors from global mutations are propagated to all components using the same key.
Error Handling Examples:
import { mutate } from "swrv";
// Error handling in global mutation
try {
await mutate('/api/users', fetch('/api/users').then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}));
} catch (error) {
console.error('Global mutation failed:', error);
// Error will appear in all components using '/api/users'
}
// Component error handling
export default {
setup() {
const { data, error } = useSWRV('/api/users', fetcher);
// Watch for errors (including from global mutations)
watch(error, (newError) => {
if (newError) {
showErrorNotification(newError.message);
}
});
return { data, error };
}
};Integrate swrv with Vuex or other state management solutions.
Vuex Integration Examples:
// Vuex store actions
const store = createStore({
actions: {
async updateUser({ commit }, userData) {
// Update both Vuex and swrv cache
commit('SET_USER', userData);
await mutate('/api/user', userData);
},
async syncUserFromServer({ commit }) {
// Fetch fresh data and update both stores
const user = await fetch('/api/user').then(res => res.json());
commit('SET_USER', user);
await mutate('/api/user', user);
}
}
});
// Component using both Vuex and swrv
export default {
setup() {
const store = useStore();
const { data: swrvUser } = useSWRV('/api/user', fetcher);
// Sync Vuex when swrv data changes
watch(swrvUser, (newUser) => {
if (newUser) {
store.commit('SET_USER', newUser);
}
});
return {
user: computed(() => store.state.user),
swrvUser
};
}
};Automatic cleanup of cached references when components unmount.
Cleanup Examples:
// Automatic cleanup - no manual intervention needed
export default {
setup() {
const { data } = useSWRV('/api/data', fetcher);
// swrv automatically cleans up internal references
// when this component unmounts
return { data };
}
};
// Manual cache cleanup if needed
import { mutate } from "swrv";
export default {
setup() {
const { data } = useSWRV('/api/temp-data', fetcher);
onUnmounted(() => {
// Manually clear cache entry if needed
mutate('/api/temp-data', undefined);
});
return { data };
}
};Install with Tessl CLI
npx tessl i tessl/npm-swrv