Skip to content

Instantly share code, notes, and snippets.

@Chooks22
Last active August 26, 2022 14:25
Show Gist options
  • Save Chooks22/714d98e8125990a41f17ea58055e60d2 to your computer and use it in GitHub Desktop.
Save Chooks22/714d98e8125990a41f17ea58055e60d2 to your computer and use it in GitHub Desktop.
Cache Creators for Kemono.Party
// ==UserScript==
// @name Cache Creators for Kemono.Party
// @namespace https://kemono.party/
// @version 1.0.4
// @description Intercept API call to cache creator data and speed up search index load times.
// @updateURL https://gist.githubusercontent.com/Choooks22/714d98e8125990a41f17ea58055e60d2/raw
// @downloadURL https://gist.githubusercontent.com/Choooks22/714d98e8125990a41f17ea58055e60d2/raw
// @author Chooks22 <chooksdev@gmail.com> (https://github.com/Choooks22)
// @match https://kemono.party/artists
// @icon https://kemono.party/favicon.ico
// @grant none
// @run-at document-start
// ==/UserScript==
(function() {
'use strict'
const _fetch = window.fetch
const ONE_MINUTE = 60 * 1000
// TTL: Time To Live
// determines how long cached data should be stored until it is marked stale and should be refreshed before using.
// value is in minutes, so this default means 24 (hours) * 60 (mins) = 1 day.
const TTL = 24 * 60
/** @param {Response} res */
const saveData = async res => {
localStorage.setItem('last_fetched', String(Date.now()))
const content = await res.text()
localStorage.setItem('creators', content)
}
/** @type {typeof window.fetch} */
const getFreshData = async (input, init) => {
const res = await _fetch(input, init)
void saveData(res.clone())
return res
}
const getCached = () => {
const cached = localStorage.getItem('creators')
return new Response(cached)
}
window.fetch = async (input, init) => {
if (input === '/api/creators') {
console.debug('intercepted request.')
const now = Date.now()
if ('creators' in localStorage) {
const lastFetch = Number(localStorage.getItem('last_fetched'))
// if timestamp is past ttl, don't use cache and fetch fresh data
if (lastFetch + TTL * ONE_MINUTE < now) {
console.debug('cache miss. fetching creators...')
return getFreshData(input, init)
}
// else refresh in background if 30 mins have past
if (lastFetch + 30 * ONE_MINUTE < now) {
console.debug('cache hit. refreshing in background...')
void getFreshData(input, init)
} else {
console.debug('cache hit.')
}
return getCached()
}
// no creators in cache yet, initialize data
console.debug('no cache found. fetching creators...')
return getFreshData(input, init)
}
return _fetch(input, init)
}
}())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment