Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mojang API Caching Changes #490

Merged
merged 5 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions src/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,12 +348,13 @@ class Client extends EventEmitter {
}
/**
* @typedef {object} ClientOptions
* @prop {boolean} [cache=false] Enable/Disable request caching.
* @prop {number} [cacheTime=60] Amount of time in seconds to cache the requests.
* @prop {boolean} [cache=true] Enable/Disable request caching.
* @prop {number} [hypixelCacheTime=60] Amount of time in seconds to cache the hypixel api requests.
* @prop {number} [mojangCacheTime=600] Amount of time in seconds to cache the mojang api requests.
* @prop {CacheHandler} [cacheHandler] Custom Cache Handler
* @prop {AUTO|HARD|NONE} [rateLimit='AUTO'] Rate limit mode.
* @prop {boolean} [syncWithHeaders=false] Sync with headers rate limit information. Usually not necessary nor recommended ( because of latency )
* @prop {number} [keyLimit=120] Key limit of your key.
* @prop {number} [keyLimit=60] Key limit of your key.
* @prop {number} [cacheSize=-1] The amount how many results will be cached. (`-1` for infinity)
* @prop {boolean} [silent=false] Don't automatically put warnings into console.
* @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request.
Expand Down
2 changes: 1 addition & 1 deletion src/Private/requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class Requests {
if (this.client.options.cacheSize < (await this.cached.size())) await this.cached.delete(Array.from(await this.cached.keys())[0]);
await this.cached.delete(endpoint);
await this.cached.set(endpoint, parsedRes);
if (this.client.options.cacheTime >= 0) setTimeout(() => this.cached.delete(endpoint), 1000 * this.client.options.cacheTime);
if (this.client.options.hypixelCacheTime >= 0) setTimeout(() => this.cached.delete(endpoint), 1000 * this.client.options.hypixelCacheTime);
}
return parsedRes;
}
Expand Down
49 changes: 28 additions & 21 deletions src/Private/uuidCache.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,39 @@ const cachedUuids = new Map();

// TODO - use this for all cache models

async function putCache(response) {
try {
response = await response.json();
cachedUuids.set(response.id, response.name);
setTimeout(deleteCache, 1000 * 60 * 10, response.id);
} catch (e) {
// F
class UUIDCache {
constructor(client) {
this.client = client;
}
async putCache(response) {
try {
response = await response.json();
cachedUuids.set(response.id, response.name);
setTimeout(deleteCache, this.client.options.mojangCacheTime * 1000, response.id);
} catch (e) {
// F
}
}
deleteCache(id) {
return cachedUuids.delete(id);
}
response(obj) {
return new fetch.Response(JSON.stringify(obj));
}
checkHit(query) {
if (cachedUuids.has(query)) return response({ id: query, name: cachedUuids.get(query) });
const reverseSearch = Array.from(cachedUuids.entries()).find((pair) => pair[1].toLowerCase() === query.toLowerCase());
if (reverseSearch) return response({ id: reverseSearch[0], name: query });
return null;
}
}
function deleteCache(id) {
return cachedUuids.delete(id);
}
function response(obj) {
return new fetch.Response(JSON.stringify(obj));
}
function checkHit(query) {
if (cachedUuids.has(query)) return response({ id: query, name: cachedUuids.get(query) });
const reverseSearch = Array.from(cachedUuids.entries()).find((pair) => pair[1].toLowerCase() === query.toLowerCase());
if (reverseSearch) return response({ id: reverseSearch[0], name: query });
return null;
}

module.exports = async (url, query) => {
if (checkHit(query || url)) return checkHit(query || url);
const cache = new UUIDCache();
if (cache.checkHit(query || url)) return cache.checkHit(query || url);
const res = await fetch(url);
const response = await res.clone().json();
// Don't cache 5xx
if (response.error !== 'Internal Server Error' && response.status < 500) setTimeout(putCache, 0, res.clone());
if (response.error !== 'Internal Server Error' && response.status < 500) setTimeout(cache.putCache, 0, res.clone());
return res;
};
10 changes: 6 additions & 4 deletions src/Private/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ class Validation {
* @private
*/
validateOptions(options) {
if (typeof options.cacheTime !== 'number') throw new Error(Errors.CACHE_TIME_MUST_BE_A_NUMBER);
if (typeof options.hypixelCacheTime !== 'number') throw new Error(Errors.CACHE_TIME_MUST_BE_A_NUMBER);
if (typeof options.mojangCacheTime !== 'number') throw new Error(Errors.CACHE_TIME_MUST_BE_A_NUMBER);
if (typeof options.cacheSize !== 'number') throw new Error(Errors.CACHE_LIMIT_MUST_BE_A_NUMBER);
if (typeof options.rateLimit !== 'string' || !['AUTO', 'HARD', 'NONE'].includes(options.rateLimit)) throw new Error(Errors.INVALID_RATE_LIMIT_OPTION);
if (typeof options.keyLimit !== 'number') throw new Error(Errors.INVALID_KEY_LIMIT_OPTION);
Expand All @@ -29,12 +30,13 @@ class Validation {
parseOptions(options) {
if (typeof options !== 'object' || options === null) throw new Error(Errors.OPTIONS_MUST_BE_AN_OBJECT);
return {
cache: options.cache || false,
cacheTime: options.cacheTime || 60,
cache: options.cache || true,
hypixelCacheTime: options.hypixelCacheTime || 60,
mojangCacheTime: options.mojangCacheTime || 600,
cacheSize: (options.cacheSize === -1 ? Infinity : options.cacheSize) || Infinity,
cacheFilter: typeof options.cacheFilter === 'function' ? options.cacheFilter : this._handleFilter(options.cacheFilter),
rateLimit: options.rateLimit || 'AUTO',
keyLimit: options.keyLimit || 120,
keyLimit: options.keyLimit || 60,
syncWithHeaders: !!options.syncWithHeaders,
headers: options.headers || {},
silent: !!options.silent,
Expand Down
2 changes: 1 addition & 1 deletion src/utils/toUuid.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const fetch = require('../Private/uuidCache');
const fetch = require('../Private/uuidCache.js');
const isUUID = require('./isUUID.js');
const Errors = require('../Errors');

Expand Down
3 changes: 2 additions & 1 deletion typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ export interface SKYBLOCK_SLAYER_DATA {
}
export interface clientOptions {
cache?: boolean;
cacheTime?: number;
hypixelCacheTime?: number;
mojangCacheTime?: number;
cacheSize?: number;
cacheFilter?: string | string[] | { whitelist: string | string[]; blacklist: string | string[] };
cacheHandler?: CacheHandler & unknown;
Expand Down
Loading