Solid Cache

hey @lxsmnsyc sorry to bother you. I´ve been trying your library, am I doing this correctly:
const [queryParams, setQueryParams] = useSearchParams()

const { data: bookings, isFetching } = createCachedResource({
source: () => queryParams,
key: ({ page, query }) => [page, query],
get: async () => {
const searchQuery =
queryParams.query === undefined ? '' : queryParams.query
const currentPage = queryParams.page ? Number(queryParams.page) : 1

return await supabaseClient
.from('bookings')
.select(
'booking_start, booking_end, reference, created_at, products!inner(product_name, product_id)',
{ count: 'exact' },
)
.eq('tenant_id', user?.user_metadata.tenant_id)
.ilike('reference', '%' + searchQuery + '%')
.range(
currentPage * pageSize() - pageSize(),
currentPage * pageSize() - 1,
)
.order('reference', { ascending: true })
},
})
const [queryParams, setQueryParams] = useSearchParams()

const { data: bookings, isFetching } = createCachedResource({
source: () => queryParams,
key: ({ page, query }) => [page, query],
get: async () => {
const searchQuery =
queryParams.query === undefined ? '' : queryParams.query
const currentPage = queryParams.page ? Number(queryParams.page) : 1

return await supabaseClient
.from('bookings')
.select(
'booking_start, booking_end, reference, created_at, products!inner(product_name, product_id)',
{ count: 'exact' },
)
.eq('tenant_id', user?.user_metadata.tenant_id)
.ilike('reference', '%' + searchQuery + '%')
.range(
currentPage * pageSize() - pageSize(),
currentPage * pageSize() - 1,
)
.order('reference', { ascending: true })
},
})
I'm not really sure how key works, I see it's string based, but was wondering how to effectively use this correctly
34 Replies
lxsmnsyc
lxsmnsyc2y ago
Key is for caching purposes. It allows solid cache where to save/load a resolved resource - source doesn't do anything here; you aren't tracking anything. - key must be string (as mentioned) You should invert your key as source then produce a string from the source
Casacobra
CasacobraOP2y ago
@lxsmnsyc something like this:
const { data: bookings, isFetching } = createCachedResource({
source: () => [queryParams.page, queryParams.query],
key: ([page, query]) => `/page=${page}&query=${query}`,
get: async ([page, query]) => {
const searchQuery = query === undefined ? '' : query
const currentPage = page ? Number(page) : 1

return await supabaseClient
.from('bookings')
.select(
'booking_start, booking_end, reference, created_at, products!inner(product_name, product_id)',
{ count: 'exact' },
)
.eq('tenant_id', user?.user_metadata.tenant_id)
.ilike('reference', '%' + searchQuery + '%')
.range(
currentPage * pageSize() - pageSize(),
currentPage * pageSize() - 1,
)
.order('reference', { ascending: true })
},
})
const { data: bookings, isFetching } = createCachedResource({
source: () => [queryParams.page, queryParams.query],
key: ([page, query]) => `/page=${page}&query=${query}`,
get: async ([page, query]) => {
const searchQuery = query === undefined ? '' : query
const currentPage = page ? Number(page) : 1

return await supabaseClient
.from('bookings')
.select(
'booking_start, booking_end, reference, created_at, products!inner(product_name, product_id)',
{ count: 'exact' },
)
.eq('tenant_id', user?.user_metadata.tenant_id)
.ilike('reference', '%' + searchQuery + '%')
.range(
currentPage * pageSize() - pageSize(),
currentPage * pageSize() - 1,
)
.order('reference', { ascending: true })
},
})
lxsmnsyc
lxsmnsyc2y ago
yes! I think this should work I would recommend though, adding a unique prefix to that string Because solid-cache uses the same single cache for every boundary, and so it may conflict if you have too similar key factories
Casacobra
CasacobraOP2y ago
So, the key is basically what gets stored in cache?
lxsmnsyc
lxsmnsyc2y ago
no, it's the "key" to the data stored in cache imagine a Map
Casacobra
CasacobraOP2y ago
i see!
source: () => [queryParams.page, queryParams.query],
key: ([page, query]) => `bookings:${page}${query}`,
source: () => [queryParams.page, queryParams.query],
key: ([page, query]) => `bookings:${page}${query}`,
lxsmnsyc
lxsmnsyc2y ago
yes that should work too
Casacobra
CasacobraOP2y ago
we need the source values in the key, right?
lxsmnsyc
lxsmnsyc2y ago
basically source is for tracking what you return in source is passed to the key and getter key produces the key, get produces the value
Casacobra
CasacobraOP2y ago
got it! Thanks my man
lxsmnsyc
lxsmnsyc2y ago
let me know if there are any issues
Casacobra
CasacobraOP2y ago
@lxsmnsyc thanks my man. Question, is there anyway I can see where this cached data is being stored, just for debugging reasons? I tried using solid devtools, but no luck
lxsmnsyc
lxsmnsyc2y ago
hmmm, yeah I don't think it can be inspected in solid-devtools there's not much right now
Casacobra
CasacobraOP2y ago
even if i can console.log the data
thetarnav
thetarnav2y ago
how do you store it though? is something missing in the devtools?
Casacobra
CasacobraOP2y ago
I think its stored in context, but maybe this is a question for @lxsmnsyc
Nin
Nin2y ago
Also how would one console.log by key? Currently getting an error that says "Missing CacheBoundary"
thetarnav
thetarnav2y ago
signals/stores in context should be inspectable in devtools but if it's just plain js variables then I can't do much
lxsmnsyc
lxsmnsyc2y ago
do you have a CacheBoundary mounted?
Casacobra
CasacobraOP2y ago
I do have CacheBoundry mounted
lxsmnsyc
lxsmnsyc2y ago
I was replying to @arvalaan. Unless of course you share the same account 😂
Casacobra
CasacobraOP2y ago
Hahaha my bad 😂
Nin
Nin2y ago
Yeah sorry we were pair programming so yes, we did have it mounted as it worked on the other one we just created a new CacheBoundary to log a to be defined key to see if we could get the values that way Whole other topic @lxsmnsyc - How would we invalidate a key? Since it's a string we can't really give it a time to live in an object and check based on this. Our situation right now is where we have cached a page of results on page 1, we add something new which would then be listed on page 1, however after returning to page 1 after creation, the key being the same we get a cached result
Casacobra
CasacobraOP2y ago
const navigate = useNavigate()
const refreshCache = useCacheBoundaryRefresh()

async function handleSubmit(event: { preventDefault: () => void }) {
event.preventDefault()
setPending(true)
const { data: product, error } = await saveProduct(data())
refreshCache()
navigate('/products')
})
const navigate = useNavigate()
const refreshCache = useCacheBoundaryRefresh()

async function handleSubmit(event: { preventDefault: () => void }) {
event.preventDefault()
setPending(true)
const { data: product, error } = await saveProduct(data())
refreshCache()
navigate('/products')
})
lxsmnsyc
lxsmnsyc2y ago
there's no "invalidation by key". Solid Cache only has cache invalidation (as shared by @casacobra)
Casacobra
CasacobraOP2y ago
@lxsmnsyc would it only invalidate on the current route you’re in or would it affect the invalidation of cache globally?
lxsmnsyc
lxsmnsyc2y ago
solid cache has no idea about routing
Casacobra
CasacobraOP2y ago
Thought so Any idea on how someone might handle that situation?
lxsmnsyc
lxsmnsyc2y ago
caching happens in CacheBoundary. You can isolate caching if you have multiple different instances of it
Casacobra
CasacobraOP2y ago
Ah interesting, yes, you're absolutely right. So, whenever I use a useCacheBoundaryRefresh, does this refresh the entire cache within that boundary
lxsmnsyc
lxsmnsyc2y ago
yes it refers to the closest boundary
Casacobra
CasacobraOP2y ago
Hey @lxsmnsyc not too sure how the cache stuff works. I have a /products route and then a /products/new route. When creating a new product and successful I am navigating back to /products then want to invalidate and refresh/invalidate all cache. Is there a way to handle this solution?
lxsmnsyc
lxsmnsyc2y ago
I'd recommend the solution in the other thread you've made
Casacobra
CasacobraOP2y ago
Creating separate cache boundaries for each route or refresh the cache on route change? I tried doing something along these lines, but doesn't seem to work: /products/new.tsx
const refresh = useRefreshCacheBoundary()
return (
<button
onClick={async () => {
await saveProduct(data())
refresh(false)
navigate('/products')
}}
>
Save
</button>
)
const refresh = useRefreshCacheBoundary()
return (
<button
onClick={async () => {
await saveProduct(data())
refresh(false)
navigate('/products')
}}
>
Save
</button>
)
@lxsmnsyc is this the right approach, by any chance? Sorry to bother you...
Want results from more Discord servers?
Add your server