@uecsio/query-cache
v1.0.0
Published
Cache management utilities for TanStack Query (Vue Query)
Downloads
24
Maintainers
Readme
@uecsio/query-cache
A lightweight utility library for managing TanStack Query (Vue Query) cache in Vue 3 applications.
Features
- 🎯 Simple API - Intuitive functions for common cache operations
- 🔧 Type-safe - Full TypeScript support
- 🪶 Lightweight - Minimal bundle size, only wraps TanStack Query
- 🚀 Zero config - Works out of the box with Vue Query
- 📦 Tree-shakeable - Import only what you need
Installation
npm install @uecsio/query-cachePeer Dependencies:
npm install vue @tanstack/vue-querySetup
Make sure you have TanStack Query configured in your Vue app:
// main.js
import { createApp } from 'vue'
import { VueQueryPlugin } from '@tanstack/vue-query'
import App from './App.vue'
const app = createApp(App)
app.use(VueQueryPlugin)
app.mount('#app')Usage
Basic Cache Operations
import {
clearCache,
invalidateCache,
clearAllCache
} from '@uecsio/query-cache'
// Clear specific query cache
clearCache(['users', 1])
// Clear all queries matching pattern
clearCache(['users']) // Clears all queries starting with 'users'
// Invalidate cache (mark as stale and refetch)
invalidateCache(['users', 1])
// Clear all application cache
clearAllCache()After Data Mutations
<script setup>
import { invalidateCache } from '@uecsio/query-cache'
async function createUser(userData) {
await api.post('/users', userData)
// Invalidate users list to show new user
invalidateCache(['users'])
}
async function updateUser(id, userData) {
await api.put(`/users/${id}`, userData)
// Invalidate specific user and list
invalidateCache(['users', id])
invalidateCache(['users'])
}
async function deleteUser(id) {
await api.delete(`/users/${id}`)
// Clear deleted user from cache
clearCache(['users', id])
invalidateCache(['users'])
}
</script>Advanced Operations
import {
getCachedData,
setCachedData,
hasCache,
refetchQueries,
cancelQueries,
prefetchQuery
} from '@uecsio/query-cache'
// Get cached data
const userData = getCachedData(['users', 1])
// Check if data exists in cache
if (hasCache(['users', 1])) {
console.log('User data is cached')
}
// Set/update cached data (optimistic updates)
setCachedData(['users', 1], (oldData) => ({
...oldData,
name: 'New Name'
}))
// Force refetch
await refetchQueries(['users'])
// Cancel ongoing requests (prevent race conditions)
await cancelQueries(['users'])
// Prefetch data
await prefetchQuery(['users', 2], () => fetchUser(2))Optimistic Updates Example
<script setup>
import { getCachedData, setCachedData, invalidateCache } from '@uecsio/query-cache'
async function toggleUserStatus(userId) {
const queryKey = ['users']
// Save previous state
const previousData = getCachedData(queryKey)
// Optimistically update UI
setCachedData(queryKey, (old) => ({
...old,
data: old.data.map(user =>
user.id === userId
? { ...user, active: !user.active }
: user
)
}))
try {
// Make API call
await api.patch(`/users/${userId}/toggle-status`)
} catch (error) {
// Rollback on error
setCachedData(queryKey, previousData)
throw error
} finally {
// Refetch to ensure consistency
invalidateCache(queryKey)
}
}
</script>Refresh Button
<template>
<div>
<button @click="handleRefresh" :disabled="isRefreshing">
{{ isRefreshing ? 'Refreshing...' : 'Refresh Data' }}
</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { invalidateCache } from '@uecsio/query-cache'
const isRefreshing = ref(false)
async function handleRefresh() {
isRefreshing.value = true
try {
await invalidateCache(['users'])
} finally {
isRefreshing.value = false
}
}
</script>On User Logout
import { clearAllCache } from '@uecsio/query-cache'
import { router } from './router'
function logout() {
// Clear authentication
localStorage.removeItem('token')
// Clear all cached data
clearAllCache()
// Redirect to login
router.push('/login')
}API Reference
Core Functions
clearCache(queryKey)
Removes queries from cache completely. Next access will show loading state.
clearCache(['users', 1]) // Clear specific query
clearCache(['users']) // Clear all matching queriesinvalidateCache(queryKey)
Marks cache as stale and refetches if active. Shows old data while loading (better UX).
invalidateCache(['users', 1]) // Invalidate specific query
invalidateCache(['users']) // Invalidate all matching queriesclearAllCache()
Clears ALL TanStack Query cache. Use with caution.
clearAllCache()Data Access
getCachedData<T>(queryKey): T | undefined
Retrieves cached data without triggering a fetch.
const user = getCachedData<User>(['users', 1])setCachedData<T>(queryKey, data | updater)
Manually update cached data.
// Set directly
setCachedData(['users', 1], newUser)
// Update function
setCachedData(['users', 1], (old) => ({ ...old, name: 'New Name' }))hasCache(queryKey): boolean
Check if data exists in cache.
if (hasCache(['users', 1])) {
// Data is cached
}Advanced Functions
refetchQueries(queryKey, options?): Promise<void>
Force immediate refetch of queries.
await refetchQueries(['users'])
await refetchQueries(['users'], { active: true }) // Only active queriesresetQueries(queryKey, options?)
Reset queries to initial state.
resetQueries(['users'])cancelQueries(queryKey): Promise<void>
Cancel ongoing requests to prevent race conditions.
await cancelQueries(['users'])prefetchQuery(queryKey, queryFn, options?): Promise<void>
Preload data before it's needed.
await prefetchQuery(['users', 2], () => fetchUser(2))getQueryState(queryKey)
Get query state information (loading, error, etc.).
const state = getQueryState(['users', 1])
console.log(state.status) // 'loading', 'success', 'error'getQueryClient(): QueryClient
Get direct access to TanStack Query client for advanced operations.
const queryClient = getQueryClient()
queryClient.setDefaultOptions({ queries: { staleTime: 60000 } })Query Key Patterns
Query keys can be strings or arrays. Arrays allow hierarchical patterns:
// Specific user
['users', 1]
// All users
['users']
// User with filters
['users', { role: 'admin' }]
// Paginated data
['users', { page: 1, limit: 10 }]When clearing/invalidating with partial keys, all matching queries are affected:
clearCache(['users']) // Clears ALL user-related queries
clearCache(['users', 1]) // Clears only user with ID 1Clear vs Invalidate
| Method | Behavior | Loading State | Best For |
|--------|----------|---------------|----------|
| clearCache() | Removes data completely | Shows loading spinner | Deleted records, major changes |
| invalidateCache() | Marks stale, refetches | Shows old data while loading | Updates, creates, refreshes |
Recommendation: Use invalidateCache() for most cases as it provides smoother UX.
TypeScript Support
Full TypeScript support with proper types:
import { getCachedData, setCachedData } from '@uecsio/query-cache'
interface User {
id: number
name: string
email: string
}
// Typed cache access
const user = getCachedData<User>(['users', 1])
// Typed cache updates
setCachedData<User>(['users', 1], (oldUser) => ({
...oldUser,
name: 'New Name'
}))Best Practices
- Use specific query keys - More granular control over cache
- Prefer invalidate over clear - Better UX with background refetching
- Handle errors in optimistic updates - Always have a rollback strategy
- Cancel queries on cleanup - Prevent memory leaks and race conditions
- Prefetch predictable navigation - Improve perceived performance
Integration Examples
With Pinia Store
// stores/users.js
import { defineStore } from 'pinia'
import { invalidateCache } from '@uecsio/query-cache'
export const useUsersStore = defineStore('users', () => {
async function createUser(data) {
await api.post('/users', data)
invalidateCache(['users'])
}
return { createUser }
})With Vue Router
// router/index.js
import { clearAllCache } from '@uecsio/query-cache'
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isAuthenticated()) {
clearAllCache()
next('/login')
} else {
next()
}
})License
MIT
Credits
Built on top of TanStack Query (formerly React Query).
