2
0
mirror of https://github.com/iconify/iconify.git synced 2025-01-06 07:20:40 +00:00

In SVG framework expose internal API and fix issues preventing it from running in Node environment

This commit is contained in:
Vjacheslav Trushkin 2020-06-03 22:01:45 +03:00
parent b87edf3f20
commit 4fc2a3727b
2 changed files with 136 additions and 94 deletions

View File

@ -61,11 +61,38 @@ const loaderFlags: Record<string, Record<string, boolean>> = Object.create(
const queueFlags: Record<string, Record<string, boolean>> = Object.create(null);
// Redundancy instances cache, sorted by provider
interface LocalCache {
export interface IconifyAPIInternalStorage {
config: IconifyAPIConfig;
redundancy: Redundancy;
}
const redundancyCache: Record<string, LocalCache> = Object.create(null);
const redundancyCache: Record<
string,
IconifyAPIInternalStorage
> = Object.create(null);
/**
* Get Redundancy instance for provider
*/
export function getRedundancyCache(
provider: string
): IconifyAPIInternalStorage | undefined {
if (redundancyCache[provider] === void 0) {
const config = getAPIConfig(provider);
if (!config) {
// No way to load icons because configuration is not set!
return;
}
const redundancy = initRedundancy(config);
const cachedReundancy = {
config,
redundancy,
};
redundancyCache[provider] = cachedReundancy;
}
return redundancyCache[provider];
}
/**
* Function called when new icons have been loaded
@ -124,7 +151,7 @@ function loadNewIcons(provider: string, prefix: string, icons: string[]): void {
}
// Redundancy item
let cachedReundancy: LocalCache;
let cachedReundancy: IconifyAPIInternalStorage;
// Trigger update on next tick, mering multiple synchronous requests into one asynchronous request
if (!providerQueueFlags[prefix]) {
@ -146,23 +173,13 @@ function loadNewIcons(provider: string, prefix: string, icons: string[]): void {
// Get API config and Redundancy instance
if (cachedReundancy === void 0) {
if (redundancyCache[provider] === void 0) {
const config = getAPIConfig(provider);
if (!config) {
// No way to load icons because configuration is not set!
err();
return;
}
const redundancy = initRedundancy(config);
cachedReundancy = {
config,
redundancy,
};
redundancyCache[provider] = cachedReundancy;
} else {
cachedReundancy = redundancyCache[provider];
const redundancy = getRedundancyCache(provider);
if (redundancy === void 0) {
// No way to load icons because configuration is not set!
err();
return;
}
cachedReundancy = redundancy;
}
// Prepare parameters and run queries

View File

@ -39,7 +39,11 @@ import { finder as iconifyFinder } from './finders/iconify';
import { storeCache, loadCache, config } from '@iconify/core/lib/cache/storage';
// API
import { API } from '@iconify/core/lib/api/';
import {
API,
getRedundancyCache,
IconifyAPIInternalStorage,
} from '@iconify/core/lib/api/';
import { setAPIModule } from '@iconify/core/lib/api/modules';
import {
setAPIConfig,
@ -60,6 +64,7 @@ import { renderIcon } from './render';
// Scan
import { scanDOM } from './scan';
import { Redundancy } from '@iconify/core/node_modules/@cyberalien/redundancy';
/**
* Export required types
@ -79,7 +84,12 @@ export {
export { IconifyIconBuildResult };
// API
export { IconifyAPIConfig, IconifyIconLoaderCallback, IconifyIconLoaderAbort };
export {
IconifyAPIConfig,
IconifyIconLoaderCallback,
IconifyIconLoaderAbort,
IconifyAPIInternalStorage,
};
/**
* Cache types
@ -183,6 +193,13 @@ export interface IconifyGlobal {
customConfig: Partial<IconifyAPIConfig>
) => void;
/**
* Get internal API data, used by Icon Finder
*/
_getInternalAPI: (
provider: string
) => IconifyAPIInternalStorage | undefined;
/* Scan DOM */
/**
* Scan DOM
@ -390,9 +407,12 @@ const Iconify: IconifyGlobal = {
// Resume observer
resumeObserver: observer.resume,
// Add API provider
// API providers
addAPIProvider: setAPIConfig,
// Get API data
_getInternalAPI: getRedundancyCache,
// Scan DOM
scanDOM: scanDOM,
@ -427,14 +447,6 @@ const Iconify: IconifyGlobal = {
/**
* Initialise stuff
*/
// Add finder modules
// addFinder(iconifyIconFinder);
addFinder(iconifyFinder);
// Set cache and load existing cache
coreModules.cache = storeCache;
loadCache();
// Set API
coreModules.api = API;
setAPIModule('', {
@ -442,76 +454,89 @@ setAPIModule('', {
prepare: prepareQuery,
});
// Load icons from global "IconifyPreload"
interface WindowWithIconifyPreload {
IconifyPreload: IconifyJSON[] | IconifyJSON;
}
if (
((window as unknown) as WindowWithIconifyPreload).IconifyPreload !== void 0
) {
const preload = ((window as unknown) as WindowWithIconifyPreload)
.IconifyPreload;
const err = 'Invalid IconifyPreload syntax.';
if (typeof preload === 'object' && preload !== null) {
(preload instanceof Array ? preload : [preload]).forEach((item) => {
try {
if (
// Check if item is an object and not null/array
typeof item !== 'object' ||
item === null ||
item instanceof Array ||
// Check for 'icons' and 'prefix'
typeof item.icons !== 'object' ||
typeof item.prefix !== 'string' ||
// Add icon set
!addCollection(item)
) {
console.error(err);
}
} catch (e) {
console.error(err);
}
});
}
}
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
// Add finder modules
// addFinder(iconifyIconFinder);
addFinder(iconifyFinder);
// Set API from global "IconifyProviders"
interface WindowWithIconifyProviders {
IconifyProviders: Record<string, PartialIconifyAPIConfig>;
}
if (
((window as unknown) as WindowWithIconifyProviders).IconifyProviders !==
void 0
) {
const providers = ((window as unknown) as WindowWithIconifyProviders)
.IconifyProviders;
if (typeof providers === 'object' && providers !== null) {
for (let key in providers) {
const err = 'IconifyProviders[' + key + '] is invalid.';
try {
const value = providers[key];
if (
typeof value !== 'object' ||
!value ||
value.resources === void 0
) {
continue;
}
if (!setAPIConfig(key, value)) {
// Set cache and load existing cache
coreModules.cache = storeCache;
loadCache();
const _window = window;
// Load icons from global "IconifyPreload"
interface WindowWithIconifyPreload {
IconifyPreload: IconifyJSON[] | IconifyJSON;
}
if (
((_window as unknown) as WindowWithIconifyPreload).IconifyPreload !==
void 0
) {
const preload = ((_window as unknown) as WindowWithIconifyPreload)
.IconifyPreload;
const err = 'Invalid IconifyPreload syntax.';
if (typeof preload === 'object' && preload !== null) {
(preload instanceof Array ? preload : [preload]).forEach((item) => {
try {
if (
// Check if item is an object and not null/array
typeof item !== 'object' ||
item === null ||
item instanceof Array ||
// Check for 'icons' and 'prefix'
typeof item.icons !== 'object' ||
typeof item.prefix !== 'string' ||
// Add icon set
!addCollection(item)
) {
console.error(err);
}
} catch (e) {
console.error(err);
}
});
}
}
// Set API from global "IconifyProviders"
interface WindowWithIconifyProviders {
IconifyProviders: Record<string, PartialIconifyAPIConfig>;
}
if (
((_window as unknown) as WindowWithIconifyProviders)
.IconifyProviders !== void 0
) {
const providers = ((_window as unknown) as WindowWithIconifyProviders)
.IconifyProviders;
if (typeof providers === 'object' && providers !== null) {
for (let key in providers) {
const err = 'IconifyProviders[' + key + '] is invalid.';
try {
const value = providers[key];
if (
typeof value !== 'object' ||
!value ||
value.resources === void 0
) {
continue;
}
if (!setAPIConfig(key, value)) {
console.error(err);
}
} catch (e) {
console.error(err);
}
} catch (e) {
console.error(err);
}
}
}
// Load observer
browserModules.observer = observer;
setTimeout(() => {
// Init on next tick when entire document has been parsed
observer.init(scanDOM);
});
}
// Load observer
browserModules.observer = observer;
setTimeout(() => {
// Init on next tick when entire document has been parsed
observer.init(scanDOM);
});
export default Iconify;