2
0
mirror of https://github.com/iconify/iconify.git synced 2024-11-14 00:34:04 +00:00

Fix cache in JSONP module, add optional axios module (disabled by default because it is much bigger than jsonp)

This commit is contained in:
Vjacheslav Trushkin 2020-06-06 12:50:17 +03:00
parent 375863d9bb
commit de037e43e0
5 changed files with 164 additions and 11 deletions

View File

@ -273,7 +273,6 @@
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"follow-redirects": "1.5.10" "follow-redirects": "1.5.10"
} }
@ -385,7 +384,6 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"ms": "2.0.0" "ms": "2.0.0"
} }
@ -422,7 +420,6 @@
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"debug": "=3.1.0" "debug": "=3.1.0"
} }
@ -617,8 +614,7 @@
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true, "dev": true
"optional": true
}, },
"once": { "once": {
"version": "1.4.0", "version": "1.4.0",

View File

@ -29,6 +29,7 @@
"@rollup/plugin-commonjs": "^11.1.0", "@rollup/plugin-commonjs": "^11.1.0",
"@rollup/plugin-node-resolve": "^7.1.3", "@rollup/plugin-node-resolve": "^7.1.3",
"@rollup/plugin-replace": "^2.3.2", "@rollup/plugin-replace": "^2.3.2",
"axios": "^0.19.2",
"rollup": "^1.32.0", "rollup": "^1.32.0",
"rollup-plugin-terser": "^5.2.0", "rollup-plugin-terser": "^5.2.0",
"typescript": "^3.9.3" "typescript": "^3.9.3"

View File

@ -83,7 +83,14 @@ const config = [];
footer, footer,
}, },
], ],
plugins: [resolve(), commonjs(), replace(replacements), buble()], plugins: [
resolve({
browser: true,
}),
commonjs(),
replace(replacements),
buble(),
],
}; };
if (compress) { if (compress) {
item.plugins.push(terser()); item.plugins.push(terser());

View File

@ -0,0 +1,146 @@
import axios from 'axios';
import { RedundancyPendingItem } from '@cyberalien/redundancy';
import {
APIQueryParams,
IconifyAPIPrepareQuery,
IconifyAPISendQuery,
} from '@iconify/core/lib/api/modules';
import { getAPIConfig } from '@iconify/core/lib/api/config';
/**
* Endpoint
*/
let endPoint = '{prefix}.json?icons={icons}';
/**
* Cache
*/
const maxLengthCache: Record<string, number> = Object.create(null);
const pathCache: Record<string, string> = Object.create(null);
/**
* Calculate maximum icons list length for prefix
*/
function calculateMaxLength(provider: string, prefix: string): number {
// Get config and store path
const config = getAPIConfig(provider);
if (!config) {
return 0;
}
// Calculate
let result;
if (!config.maxURL) {
result = 0;
} else {
let maxHostLength = 0;
config.resources.forEach((host) => {
maxHostLength = Math.max(maxHostLength, host.length);
});
// Get available length
result =
config.maxURL -
maxHostLength -
config.path.length -
endPoint
.replace('{provider}', provider)
.replace('{prefix}', prefix)
.replace('{icons}', '').length;
}
// Cache stuff and return result
const cacheKey = provider + ':' + prefix;
pathCache[cacheKey] = config.path;
maxLengthCache[cacheKey] = result;
return result;
}
/**
* Prepare params
*/
export const prepareQuery: IconifyAPIPrepareQuery = (
provider: string,
prefix: string,
icons: string[]
): APIQueryParams[] => {
const results: APIQueryParams[] = [];
// Get maximum icons list length
let maxLength = maxLengthCache[prefix];
if (maxLength === void 0) {
maxLength = calculateMaxLength(provider, prefix);
}
// Split icons
let item: APIQueryParams = {
provider,
prefix,
icons: [],
};
let length = 0;
icons.forEach((name, index) => {
length += name.length + 1;
if (length >= maxLength && index > 0) {
// Next set
results.push(item);
item = {
provider,
prefix,
icons: [],
};
length = name.length;
}
item.icons.push(name);
});
results.push(item);
return results;
};
/**
* Load icons
*/
export const sendQuery: IconifyAPISendQuery = (
host: string,
params: APIQueryParams,
status: RedundancyPendingItem
): void => {
const provider = params.provider;
const prefix = params.prefix;
const icons = params.icons;
const iconsList = icons.join(',');
const cacheKey = provider + ':' + prefix;
let path =
pathCache[cacheKey] +
endPoint
.replace('{provider}', provider)
.replace('{prefix}', prefix)
.replace('{icons}', iconsList);
// console.log('API query:', host + path);
const instance = axios.create({
baseURL: host,
});
instance
.get(path)
.then((response) => {
if (response.status !== 200) {
return;
}
// Copy data. No need to parse it, axios parses JSON data
const data = response.data;
if (typeof data !== 'object' || data === null) {
return;
}
// Store cache and complete
status.done(data);
})
.catch((err) => {
// Do nothing
});
};

View File

@ -19,7 +19,7 @@ let global: JSONPRoot | null = null;
let endPoint = '{prefix}.js?icons={icons}&callback={callback}'; let endPoint = '{prefix}.js?icons={icons}&callback={callback}';
/** /**
* Cache * Cache: provider:prefix = value
*/ */
const maxLengthCache: Record<string, number> = Object.create(null); const maxLengthCache: Record<string, number> = Object.create(null);
const pathCache: Record<string, string> = Object.create(null); const pathCache: Record<string, string> = Object.create(null);
@ -120,8 +120,9 @@ function calculateMaxLength(provider: string, prefix: string): number {
} }
// Cache stuff and return result // Cache stuff and return result
pathCache[prefix] = config.path; const cacheKey = provider + ':' + prefix;
maxLengthCache[prefix] = result; pathCache[cacheKey] = config.path;
maxLengthCache[cacheKey] = result;
return result; return result;
} }
@ -136,7 +137,8 @@ export const prepareQuery: IconifyAPIPrepareQuery = (
const results: APIQueryParams[] = []; const results: APIQueryParams[] = [];
// Get maximum icons list length // Get maximum icons list length
let maxLength = maxLengthCache[prefix]; const cacheKey = provider + ':' + prefix;
let maxLength = maxLengthCache[cacheKey];
if (maxLength === void 0) { if (maxLength === void 0) {
maxLength = calculateMaxLength(provider, prefix); maxLength = calculateMaxLength(provider, prefix);
} }
@ -180,6 +182,7 @@ export const sendQuery: IconifyAPISendQuery = (
const prefix = params.prefix; const prefix = params.prefix;
const icons = params.icons; const icons = params.icons;
const iconsList = icons.join(','); const iconsList = icons.join(',');
const cacheKey = provider + ':' + prefix;
// Create callback prefix // Create callback prefix
const cbPrefix = prefix.split('-').shift().slice(0, 3); const cbPrefix = prefix.split('-').shift().slice(0, 3);
@ -196,7 +199,7 @@ export const sendQuery: IconifyAPISendQuery = (
const callbackName = cbPrefix + cbCounter; const callbackName = cbPrefix + cbCounter;
let path = let path =
pathCache[prefix] + pathCache[cacheKey] +
endPoint endPoint
.replace('{provider}', provider) .replace('{provider}', provider)
.replace('{prefix}', prefix) .replace('{prefix}', prefix)