}
}
- // Function to make a request to the runescape wiki api
+ // --- Request Queue System ---
+ const requestQueue = [];
+ let isProcessing = false;
+ const QUEUE_WAIT_TIME = 1000, MAX_QUEUE_SIZE = 10;
+
+ function enqueueRequest(fn) {
+ return new Promise((resolve, reject) => {
+ if (requestQueue.length >= MAX_QUEUE_SIZE) {
+ console.warn("Request queue full, dropping request.");
+ return;
+ }
+
+ requestQueue.push({ fn, resolve, reject });
+ processQueue();
+ });
+ }
+
+ async function processQueue() {
+ if (isProcessing || requestQueue.length === 0) return;
+
+ isProcessing = true;
+ const { fn, resolve, reject } = requestQueue.shift();
+
+ try {
+ const result = await fn();
+ resolve(result);
+ } catch (err) {
+ reject(err);
+ }
+
+ // Wait 1 second before processing the next request
+ setTimeout(() => {
+ isProcessing = false;
+ processQueue();
+ }, QUEUE_WAIT_TIME);
+ }
+
+ // Function to make a request to the RuneScape wiki API with caching and throttling
async function requestBucket(query) {
const url = new URL('https://oldschool.runescape.wiki/api.php');
const params = {
action: 'bucket',
format: 'json',
query: query,
- origin: '*' // This parameter is key for CORS
+ origin: '*' // Required for CORS
};
url.search = new URLSearchParams(params).toString();
- try {
- const response = await fetch(url);
+ const cacheKey = `bucketCache_${query}`;
+ const cacheTTL = 24 * 60 * 60 * 1000; // 24 hours in ms
+
+ // --- Cache check first ---
+ const cached = localStorage.getItem(cacheKey);
+ if (cached) {
+ const { timestamp, data } = JSON.parse(cached);
+ if (Date.now() - timestamp < cacheTTL) {
+ console.log(`Cache hit for query: ${query}`);
+ return data; // 🚀 Return immediately (no throttling)
+ } else {
+ console.log(`Cache expired for query: ${query}`);
+ localStorage.removeItem(cacheKey);
+ }
+ }
+ // --- Only network requests go into the queue ---
+ return enqueueRequest(async () => {
+ console.log(`Fetching fresh data: ${url}`);
+
+ const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
- // The Bucket API sometimes returns an error object on failure
if (data.error) {
- alert(`Query Error: ${query}`)
+ console.warn(`Query Error: ${query}`);
throw new Error(`API Error: ${data.error.info}`);
}
+ // Save to cache
+ localStorage.setItem(cacheKey, JSON.stringify({
+ timestamp: Date.now(),
+ data
+ }));
+
return data;
- } catch (error) {
- console.error('Error fetching data:', error);
- return null;
- }
+ });
}
</script>
</body>
}
}
- // Function to make a request to the runescape wiki api
+ // --- Request Queue System ---
+ const requestQueue = [];
+ let isProcessing = false;
+ const QUEUE_WAIT_TIME = 1000, MAX_QUEUE_SIZE = 10;
+
+ function enqueueRequest(fn) {
+ return new Promise((resolve, reject) => {
+ if (requestQueue.length >= MAX_QUEUE_SIZE) {
+ console.warn("Request queue full, dropping request.");
+ return;
+ }
+
+ requestQueue.push({ fn, resolve, reject });
+ processQueue();
+ });
+ }
+
+ async function processQueue() {
+ if (isProcessing || requestQueue.length === 0) return;
+
+ isProcessing = true;
+ const { fn, resolve, reject } = requestQueue.shift();
+
+ try {
+ const result = await fn();
+ resolve(result);
+ } catch (err) {
+ reject(err);
+ }
+
+ // Wait 1 second before processing the next request
+ setTimeout(() => {
+ isProcessing = false;
+ processQueue();
+ }, QUEUE_WAIT_TIME);
+ }
+
+ // Function to make a request to the RuneScape wiki API with caching and throttling
async function requestBucket(query) {
const url = new URL('https://oldschool.runescape.wiki/api.php');
const params = {
action: 'bucket',
format: 'json',
query: query,
- origin: '*' // This parameter is key for CORS
+ origin: '*' // Required for CORS
};
url.search = new URLSearchParams(params).toString();
- try {
- const response = await fetch(url);
+ const cacheKey = `bucketCache_${query}`;
+ const cacheTTL = 24 * 60 * 60 * 1000; // 24 hours in ms
+
+ // --- Cache check first ---
+ const cached = localStorage.getItem(cacheKey);
+ if (cached) {
+ const { timestamp, data } = JSON.parse(cached);
+ if (Date.now() - timestamp < cacheTTL) {
+ console.log(`Cache hit for query: ${query}`);
+ return data; // 🚀 Return immediately (no throttling)
+ } else {
+ console.log(`Cache expired for query: ${query}`);
+ localStorage.removeItem(cacheKey);
+ }
+ }
+ // --- Only network requests go into the queue ---
+ return enqueueRequest(async () => {
+ console.log(`Fetching fresh data: ${url}`);
+
+ const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
- // The Bucket API sometimes returns an error object on failure
if (data.error) {
- alert(`Query Error: ${query}`)
+ console.warn(`Query Error: ${query}`);
throw new Error(`API Error: ${data.error.info}`);
}
+ // Save to cache
+ localStorage.setItem(cacheKey, JSON.stringify({
+ timestamp: Date.now(),
+ data
+ }));
+
return data;
- } catch (error) {
- console.error('Error fetching data:', error);
- return null;
- }
+ });
}
</script>
</body>