mirror of
https://github.com/iconify/iconify.git
synced 2024-11-17 01:55:09 +00:00
Reuse storage for API data, clean up build scripts
This commit is contained in:
parent
9f71691fd2
commit
c1c849a61c
@ -1,16 +1,12 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
|
||||||
const child_process = require('child_process');
|
const child_process = require('child_process');
|
||||||
|
|
||||||
const coreDir = path.dirname(require.resolve('@iconify/core/package.json'));
|
|
||||||
|
|
||||||
// List of commands to run
|
// List of commands to run
|
||||||
const commands = [];
|
const commands = [];
|
||||||
|
|
||||||
// Parse command line
|
// Parse command line
|
||||||
const compile = {
|
const compile = {
|
||||||
core: false,
|
|
||||||
lib: true,
|
lib: true,
|
||||||
rollup: true,
|
rollup: true,
|
||||||
api: true,
|
api: true,
|
||||||
@ -58,22 +54,9 @@ const fileExists = (file) => {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (compile.lib && !fileExists(coreDir + '/lib/cache.mjs')) {
|
// Compile packages
|
||||||
compile.core = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile core before compiling this package
|
|
||||||
if (compile.core) {
|
|
||||||
commands.push({
|
|
||||||
cmd: 'npm',
|
|
||||||
args: ['run', 'build'],
|
|
||||||
cwd: coreDir,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile other packages
|
|
||||||
Object.keys(compile).forEach((key) => {
|
Object.keys(compile).forEach((key) => {
|
||||||
if (key !== 'core' && compile[key]) {
|
if (compile[key]) {
|
||||||
commands.push({
|
commands.push({
|
||||||
cmd: 'npm',
|
cmd: 'npm',
|
||||||
args: ['run', 'build:' + key],
|
args: ['run', 'build:' + key],
|
||||||
|
@ -1,17 +1,12 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
|
||||||
const child_process = require('child_process');
|
const child_process = require('child_process');
|
||||||
|
|
||||||
const coreDir = path.dirname(require.resolve('@iconify/core/package.json'));
|
|
||||||
|
|
||||||
// List of commands to run
|
// List of commands to run
|
||||||
const commands = [];
|
const commands = [];
|
||||||
|
|
||||||
// Build process
|
// Build process
|
||||||
const compile = {
|
const compile = {
|
||||||
// Compile @iconify/core
|
|
||||||
core: false,
|
|
||||||
// Compile TypeScript src -> lib
|
// Compile TypeScript src -> lib
|
||||||
lib: true,
|
lib: true,
|
||||||
// Fix types for icon components
|
// Fix types for icon components
|
||||||
@ -72,22 +67,9 @@ if (compile.api && !fileExists('./lib/icon.d.ts')) {
|
|||||||
compile.lib = true;
|
compile.lib = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compile.lib && !fileExists(coreDir + '/lib/cache.mjs')) {
|
// Compile packages
|
||||||
compile.core = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile core before compiling this package
|
|
||||||
if (compile.core) {
|
|
||||||
commands.push({
|
|
||||||
cmd: 'npm',
|
|
||||||
args: ['run', 'build'],
|
|
||||||
cwd: coreDir,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile other packages
|
|
||||||
Object.keys(compile).forEach((key) => {
|
Object.keys(compile).forEach((key) => {
|
||||||
if (key !== 'core' && compile[key]) {
|
if (compile[key]) {
|
||||||
commands.push({
|
commands.push({
|
||||||
cmd: 'npm',
|
cmd: 'npm',
|
||||||
args: ['run', 'build:' + key],
|
args: ['run', 'build:' + key],
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
|
||||||
const child_process = require('child_process');
|
const child_process = require('child_process');
|
||||||
|
|
||||||
const coreDir = path.dirname(require.resolve('@iconify/core/package.json'));
|
|
||||||
|
|
||||||
// List of commands to run
|
// List of commands to run
|
||||||
const commands = [];
|
const commands = [];
|
||||||
|
|
||||||
@ -13,7 +10,6 @@ const extractor = (name) =>
|
|||||||
|
|
||||||
// Parse command line
|
// Parse command line
|
||||||
const compile = {
|
const compile = {
|
||||||
core: false,
|
|
||||||
tsc: true,
|
tsc: true,
|
||||||
bundles: true,
|
bundles: true,
|
||||||
api: true,
|
api: true,
|
||||||
@ -61,28 +57,12 @@ const fileExists = (file) => {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (compile.dist && !fileExists(coreDir + '/lib/modules.mjs')) {
|
// Compile packages
|
||||||
compile.core = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile core before compiling this package
|
|
||||||
if (compile.core) {
|
|
||||||
commands.push({
|
|
||||||
cmd: 'npm',
|
|
||||||
args: ['run', 'build'],
|
|
||||||
cwd: coreDir,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile other packages
|
|
||||||
Object.keys(compile).forEach((key) => {
|
Object.keys(compile).forEach((key) => {
|
||||||
if (!compile[key]) {
|
if (!compile[key]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'core':
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'api':
|
case 'api':
|
||||||
apiFiles().forEach((name) => {
|
apiFiles().forEach((name) => {
|
||||||
const cmd = extractor(name).split(' ');
|
const cmd = extractor(name).split(' ');
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
|
||||||
const child_process = require('child_process');
|
const child_process = require('child_process');
|
||||||
|
|
||||||
const coreDir = path.dirname(require.resolve('@iconify/core/package.json'));
|
|
||||||
|
|
||||||
// List of commands to run
|
// List of commands to run
|
||||||
const commands = [];
|
const commands = [];
|
||||||
|
|
||||||
// Parse command line
|
// Parse command line
|
||||||
const compile = {
|
const compile = {
|
||||||
core: false,
|
|
||||||
lib: true,
|
lib: true,
|
||||||
dist: true,
|
dist: true,
|
||||||
api: true,
|
api: true,
|
||||||
@ -65,27 +61,14 @@ if (compile.api && !fileExists('./lib/iconify.d.ts')) {
|
|||||||
compile.lib = true;
|
compile.lib = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compile.lib && !fileExists(coreDir + '/lib/cache.mjs')) {
|
|
||||||
compile.core = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile core before compiling this package
|
|
||||||
if (compile.core) {
|
|
||||||
commands.push({
|
|
||||||
cmd: 'npm',
|
|
||||||
args: ['run', 'build'],
|
|
||||||
cwd: coreDir,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add api2
|
// Add api2
|
||||||
if (compile.api) {
|
if (compile.api) {
|
||||||
compile.api2 = true;
|
compile.api2 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile other packages
|
// Compile packages
|
||||||
Object.keys(compile).forEach((key) => {
|
Object.keys(compile).forEach((key) => {
|
||||||
if (key !== 'core' && compile[key]) {
|
if (compile[key]) {
|
||||||
commands.push({
|
commands.push({
|
||||||
cmd: 'npm',
|
cmd: 'npm',
|
||||||
args: ['run', 'build:' + key],
|
args: ['run', 'build:' + key],
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
|
||||||
const child_process = require('child_process');
|
const child_process = require('child_process');
|
||||||
|
|
||||||
const coreDir = path.dirname(require.resolve('@iconify/core/package.json'));
|
|
||||||
|
|
||||||
// List of commands to run
|
// List of commands to run
|
||||||
const commands = [];
|
const commands = [];
|
||||||
|
|
||||||
// Parse command line
|
// Parse command line
|
||||||
const compile = {
|
const compile = {
|
||||||
core: false,
|
|
||||||
lib: true,
|
lib: true,
|
||||||
dist: true,
|
dist: true,
|
||||||
api: true,
|
api: true,
|
||||||
@ -65,22 +61,9 @@ if (compile.api && !fileExists('./lib/IconifyIcon.d.ts')) {
|
|||||||
compile.lib = true;
|
compile.lib = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compile.lib && !fileExists(coreDir + '/lib/cache.mjs')) {
|
// Compile packages
|
||||||
compile.core = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile core before compiling this package
|
|
||||||
if (compile.core) {
|
|
||||||
commands.push({
|
|
||||||
cmd: 'npm',
|
|
||||||
args: ['run', 'build'],
|
|
||||||
cwd: coreDir,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile other packages
|
|
||||||
Object.keys(compile).forEach((key) => {
|
Object.keys(compile).forEach((key) => {
|
||||||
if (key !== 'core' && compile[key]) {
|
if (compile[key]) {
|
||||||
commands.push({
|
commands.push({
|
||||||
cmd: 'npm',
|
cmd: 'npm',
|
||||||
args: ['run', 'build:' + key],
|
args: ['run', 'build:' + key],
|
||||||
|
@ -1,21 +1,17 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
|
||||||
const child_process = require('child_process');
|
const child_process = require('child_process');
|
||||||
|
|
||||||
const coreDir = path.dirname(require.resolve('@iconify/core/package.json'));
|
|
||||||
|
|
||||||
// List of commands to run
|
// List of commands to run
|
||||||
const commands = [];
|
const commands = [];
|
||||||
|
|
||||||
// Parse command line
|
// Parse command line
|
||||||
const compile = {
|
const compile = {
|
||||||
core: false,
|
|
||||||
lib: true,
|
lib: true,
|
||||||
dist: true,
|
dist: true,
|
||||||
api: true,
|
api: true,
|
||||||
};
|
};
|
||||||
process.argv.slice(2).forEach(cmd => {
|
process.argv.slice(2).forEach((cmd) => {
|
||||||
if (cmd.slice(0, 2) !== '--') {
|
if (cmd.slice(0, 2) !== '--') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -39,7 +35,7 @@ process.argv.slice(2).forEach(cmd => {
|
|||||||
|
|
||||||
case 'only':
|
case 'only':
|
||||||
// disable other modules
|
// disable other modules
|
||||||
Object.keys(compile).forEach(key2 => {
|
Object.keys(compile).forEach((key2) => {
|
||||||
compile[key2] = key2 === key;
|
compile[key2] = key2 === key;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@ -48,7 +44,7 @@ process.argv.slice(2).forEach(cmd => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Check if required modules in same monorepo are available
|
// Check if required modules in same monorepo are available
|
||||||
const fileExists = file => {
|
const fileExists = (file) => {
|
||||||
try {
|
try {
|
||||||
fs.statSync(file);
|
fs.statSync(file);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -65,22 +61,9 @@ if (compile.api && !fileExists('./lib/IconifyIcon.d.ts')) {
|
|||||||
compile.lib = true;
|
compile.lib = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compile.lib && !fileExists(coreDir + '/lib/cache.mjs')) {
|
// Compile packages
|
||||||
compile.core = true;
|
Object.keys(compile).forEach((key) => {
|
||||||
}
|
if (compile[key]) {
|
||||||
|
|
||||||
// Compile core before compiling this package
|
|
||||||
if (compile.core) {
|
|
||||||
commands.push({
|
|
||||||
cmd: 'npm',
|
|
||||||
args: ['run', 'build'],
|
|
||||||
cwd: coreDir,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile other packages
|
|
||||||
Object.keys(compile).forEach(key => {
|
|
||||||
if (key !== 'core' && compile[key]) {
|
|
||||||
commands.push({
|
commands.push({
|
||||||
cmd: 'npm',
|
cmd: 'npm',
|
||||||
args: ['run', 'build:' + key],
|
args: ['run', 'build:' + key],
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
|
||||||
const child_process = require('child_process');
|
const child_process = require('child_process');
|
||||||
|
|
||||||
const coreDir = path.dirname(require.resolve('@iconify/core/package.json'));
|
|
||||||
|
|
||||||
// List of commands to run
|
// List of commands to run
|
||||||
const commands = [];
|
const commands = [];
|
||||||
|
|
||||||
// Parse command line
|
// Parse command line
|
||||||
const compile = {
|
const compile = {
|
||||||
core: false,
|
|
||||||
lib: true,
|
lib: true,
|
||||||
dist: true,
|
dist: true,
|
||||||
api: true,
|
api: true,
|
||||||
@ -65,22 +61,9 @@ if (compile.api && !fileExists('./lib/index.d.ts')) {
|
|||||||
compile.lib = true;
|
compile.lib = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compile.lib && !fileExists(coreDir + '/lib/cache.mjs')) {
|
// Compile packages
|
||||||
compile.core = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile core before compiling this package
|
|
||||||
if (compile.core) {
|
|
||||||
commands.push({
|
|
||||||
cmd: 'npm',
|
|
||||||
args: ['run', 'build'],
|
|
||||||
cwd: coreDir,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile other packages
|
|
||||||
Object.keys(compile).forEach((key) => {
|
Object.keys(compile).forEach((key) => {
|
||||||
if (key !== 'core' && compile[key]) {
|
if (compile[key]) {
|
||||||
commands.push({
|
commands.push({
|
||||||
cmd: 'npm',
|
cmd: 'npm',
|
||||||
args: ['run', 'build:' + key],
|
args: ['run', 'build:' + key],
|
||||||
|
@ -57,6 +57,10 @@
|
|||||||
"require": "./lib/api/query.cjs",
|
"require": "./lib/api/query.cjs",
|
||||||
"import": "./lib/api/query.mjs"
|
"import": "./lib/api/query.mjs"
|
||||||
},
|
},
|
||||||
|
"./lib/api/types": {
|
||||||
|
"require": "./lib/api/types.cjs",
|
||||||
|
"import": "./lib/api/types.mjs"
|
||||||
|
},
|
||||||
"./lib/browser-storage/config": {
|
"./lib/browser-storage/config": {
|
||||||
"require": "./lib/browser-storage/config.cjs",
|
"require": "./lib/browser-storage/config.cjs",
|
||||||
"import": "./lib/browser-storage/config.mjs"
|
"import": "./lib/browser-storage/config.mjs"
|
||||||
|
@ -2,59 +2,17 @@ import type {
|
|||||||
IconifyIconLoaderCallback,
|
IconifyIconLoaderCallback,
|
||||||
IconifyIconLoaderAbort,
|
IconifyIconLoaderAbort,
|
||||||
} from './icons';
|
} from './icons';
|
||||||
import { getStorage } from '../storage/storage';
|
|
||||||
import type { SortedIcons } from '../icon/sort';
|
import type { SortedIcons } from '../icon/sort';
|
||||||
import type { IconifyIconSource } from '@iconify/utils/lib/icon/name';
|
import type { APICallbackItem, IconStorageWithIcons } from './types';
|
||||||
|
|
||||||
/**
|
|
||||||
* Storage for callbacks
|
|
||||||
*/
|
|
||||||
interface CallbackItem {
|
|
||||||
// id
|
|
||||||
id: number;
|
|
||||||
|
|
||||||
// Icons
|
|
||||||
icons: SortedIcons;
|
|
||||||
|
|
||||||
// Callback to call on any update
|
|
||||||
callback: IconifyIconLoaderCallback;
|
|
||||||
|
|
||||||
// Callback to call to remove item from queue
|
|
||||||
abort: IconifyIconLoaderAbort;
|
|
||||||
}
|
|
||||||
|
|
||||||
type PrefixCallbackItems = CallbackItem[];
|
|
||||||
type ProviderCallbackItems = Record<string, PrefixCallbackItems>;
|
|
||||||
|
|
||||||
// Records sorted by provider and prefix
|
|
||||||
// This export is only for unit testing, should not be used
|
|
||||||
export const callbacks = Object.create(null) as Record<
|
|
||||||
string,
|
|
||||||
ProviderCallbackItems
|
|
||||||
>;
|
|
||||||
|
|
||||||
// List of provider/prefix combinations that need to be updated
|
|
||||||
type ProviderPendingUpdates = Record<string, boolean>;
|
|
||||||
const pendingUpdates = Object.create(null) as Record<
|
|
||||||
string,
|
|
||||||
ProviderPendingUpdates
|
|
||||||
>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove callback
|
* Remove callback
|
||||||
*/
|
*/
|
||||||
function removeCallback(sources: IconifyIconSource[], id: number): void {
|
function removeCallback(storages: IconStorageWithIcons[], id: number): void {
|
||||||
sources.forEach((source) => {
|
storages.forEach((storage) => {
|
||||||
const provider = source.provider;
|
const items = storage.loaderCallbacks;
|
||||||
if (callbacks[provider] === void 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const providerCallbacks = callbacks[provider];
|
|
||||||
|
|
||||||
const prefix = source.prefix;
|
|
||||||
const items = providerCallbacks[prefix];
|
|
||||||
if (items) {
|
if (items) {
|
||||||
providerCallbacks[prefix] = items.filter((row) => row.id !== id);
|
storage.loaderCallbacks = items.filter((row) => row.id !== id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -62,37 +20,26 @@ function removeCallback(sources: IconifyIconSource[], id: number): void {
|
|||||||
/**
|
/**
|
||||||
* Update all callbacks for provider and prefix
|
* Update all callbacks for provider and prefix
|
||||||
*/
|
*/
|
||||||
export function updateCallbacks(provider: string, prefix: string): void {
|
export function updateCallbacks(storage: IconStorageWithIcons): void {
|
||||||
if (pendingUpdates[provider] === void 0) {
|
if (!storage.pendingCallbacksFlag) {
|
||||||
pendingUpdates[provider] = Object.create(
|
storage.pendingCallbacksFlag = true;
|
||||||
null
|
|
||||||
) as ProviderPendingUpdates;
|
|
||||||
}
|
|
||||||
const providerPendingUpdates = pendingUpdates[provider];
|
|
||||||
|
|
||||||
if (!providerPendingUpdates[prefix]) {
|
|
||||||
providerPendingUpdates[prefix] = true;
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
providerPendingUpdates[prefix] = false;
|
storage.pendingCallbacksFlag = false;
|
||||||
|
|
||||||
if (
|
|
||||||
callbacks[provider] === void 0 ||
|
|
||||||
callbacks[provider][prefix] === void 0
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get all items
|
// Get all items
|
||||||
const items = callbacks[provider][prefix].slice(0);
|
const items = storage.loaderCallbacks
|
||||||
|
? storage.loaderCallbacks.slice(0)
|
||||||
|
: [];
|
||||||
if (!items.length) {
|
if (!items.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const storage = getStorage(provider, prefix);
|
|
||||||
|
|
||||||
// Check each item for changes
|
// Check each item for changes
|
||||||
let hasPending = false;
|
let hasPending = false;
|
||||||
items.forEach((item: CallbackItem) => {
|
const provider = storage.provider;
|
||||||
|
const prefix = storage.prefix;
|
||||||
|
|
||||||
|
items.forEach((item) => {
|
||||||
const icons = item.icons;
|
const icons = item.icons;
|
||||||
const oldLength = icons.pending.length;
|
const oldLength = icons.pending.length;
|
||||||
icons.pending = icons.pending.filter((icon) => {
|
icons.pending = icons.pending.filter((icon) => {
|
||||||
@ -129,15 +76,7 @@ export function updateCallbacks(provider: string, prefix: string): void {
|
|||||||
if (icons.pending.length !== oldLength) {
|
if (icons.pending.length !== oldLength) {
|
||||||
if (!hasPending) {
|
if (!hasPending) {
|
||||||
// All icons have been loaded - remove callback from prefix
|
// All icons have been loaded - remove callback from prefix
|
||||||
removeCallback(
|
removeCallback([storage], item.id);
|
||||||
[
|
|
||||||
{
|
|
||||||
provider,
|
|
||||||
prefix,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
item.id
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
item.callback(
|
item.callback(
|
||||||
icons.loaded.slice(0),
|
icons.loaded.slice(0),
|
||||||
@ -162,7 +101,7 @@ let idCounter = 0;
|
|||||||
export function storeCallback(
|
export function storeCallback(
|
||||||
callback: IconifyIconLoaderCallback,
|
callback: IconifyIconLoaderCallback,
|
||||||
icons: SortedIcons,
|
icons: SortedIcons,
|
||||||
pendingSources: IconifyIconSource[]
|
pendingSources: IconStorageWithIcons[]
|
||||||
): IconifyIconLoaderAbort {
|
): IconifyIconLoaderAbort {
|
||||||
// Create unique id and abort function
|
// Create unique id and abort function
|
||||||
const id = idCounter++;
|
const id = idCounter++;
|
||||||
@ -174,24 +113,15 @@ export function storeCallback(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create item and store it for all pending prefixes
|
// Create item and store it for all pending prefixes
|
||||||
const item: CallbackItem = {
|
const item: APICallbackItem = {
|
||||||
id,
|
id,
|
||||||
icons,
|
icons,
|
||||||
callback,
|
callback,
|
||||||
abort: abort,
|
abort: abort,
|
||||||
};
|
};
|
||||||
|
|
||||||
pendingSources.forEach((source) => {
|
pendingSources.forEach((storage) => {
|
||||||
const provider = source.provider;
|
(storage.loaderCallbacks || (storage.loaderCallbacks = [])).push(item);
|
||||||
const prefix = source.prefix;
|
|
||||||
if (callbacks[provider] === void 0) {
|
|
||||||
callbacks[provider] = Object.create(null) as ProviderCallbackItems;
|
|
||||||
}
|
|
||||||
const providerCallbacks = callbacks[provider];
|
|
||||||
if (providerCallbacks[prefix] === void 0) {
|
|
||||||
providerCallbacks[prefix] = [];
|
|
||||||
}
|
|
||||||
providerCallbacks[prefix].push(item);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return abort;
|
return abort;
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
import type { IconifyIcon, IconifyJSON } from '@iconify/types';
|
import type { IconifyIcon, IconifyJSON } from '@iconify/types';
|
||||||
import {
|
import { IconifyIconName, stringToIcon } from '@iconify/utils/lib/icon/name';
|
||||||
IconifyIconName,
|
|
||||||
IconifyIconSource,
|
|
||||||
stringToIcon,
|
|
||||||
} from '@iconify/utils/lib/icon/name';
|
|
||||||
import type { SortedIcons } from '../icon/sort';
|
import type { SortedIcons } from '../icon/sort';
|
||||||
import { sortIcons } from '../icon/sort';
|
import { sortIcons } from '../icon/sort';
|
||||||
import { storeCallback, updateCallbacks } from './callbacks';
|
import { storeCallback, updateCallbacks } from './callbacks';
|
||||||
@ -13,6 +9,7 @@ import { listToIcons } from '../icon/list';
|
|||||||
import { allowSimpleNames, getIconData } from '../storage/functions';
|
import { allowSimpleNames, getIconData } from '../storage/functions';
|
||||||
import { sendAPIQuery } from './query';
|
import { sendAPIQuery } from './query';
|
||||||
import { storeInBrowserStorage } from '../browser-storage/store';
|
import { storeInBrowserStorage } from '../browser-storage/store';
|
||||||
|
import type { IconStorageWithIcons } from './types';
|
||||||
|
|
||||||
// Empty abort callback for loadIcons()
|
// Empty abort callback for loadIcons()
|
||||||
function emptyCallback(): void {
|
function emptyCallback(): void {
|
||||||
@ -49,126 +46,46 @@ export type IconifyLoadIcons = (
|
|||||||
*/
|
*/
|
||||||
export type IsPending = (icon: IconifyIconName) => boolean;
|
export type IsPending = (icon: IconifyIconName) => boolean;
|
||||||
|
|
||||||
/**
|
|
||||||
* List of icons that are being loaded.
|
|
||||||
*
|
|
||||||
* Icons are added to this list when they are being checked and
|
|
||||||
* removed from this list when they are added to storage as
|
|
||||||
* either an icon or a missing icon. This way same icon should
|
|
||||||
* never be requested twice.
|
|
||||||
*
|
|
||||||
* [provider][prefix][icon] = time when icon was added to queue
|
|
||||||
*/
|
|
||||||
type PrefixPendingIcons = Record<string, number>;
|
|
||||||
type ProviderPendingIcons = Record<string, PrefixPendingIcons>;
|
|
||||||
|
|
||||||
const pendingIcons = Object.create(null) as Record<
|
|
||||||
string,
|
|
||||||
ProviderPendingIcons
|
|
||||||
>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of icons that are waiting to be loaded.
|
|
||||||
*
|
|
||||||
* List is passed to API module, then cleared.
|
|
||||||
*
|
|
||||||
* This list should not be used for any checks, use pendingIcons to check
|
|
||||||
* if icons is being loaded.
|
|
||||||
*
|
|
||||||
* [provider][prefix] = array of icon names
|
|
||||||
*/
|
|
||||||
type IconsToLoadPrefixItem = string[];
|
|
||||||
type IconsToLoadProviderItem = Record<string, IconsToLoadPrefixItem>;
|
|
||||||
|
|
||||||
const iconsToLoad = Object.create(null) as Record<
|
|
||||||
string,
|
|
||||||
IconsToLoadProviderItem
|
|
||||||
>;
|
|
||||||
|
|
||||||
// Flags to merge multiple synchronous icon requests in one asynchronous request
|
|
||||||
type FlagsItem = Record<string, boolean>;
|
|
||||||
|
|
||||||
const loaderFlags = Object.create(null) as Record<string, FlagsItem>;
|
|
||||||
const queueFlags = Object.create(null) as Record<string, FlagsItem>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called when new icons have been loaded
|
* Function called when new icons have been loaded
|
||||||
*/
|
*/
|
||||||
function loadedNewIcons(provider: string, prefix: string): void {
|
function loadedNewIcons(storage: IconStorageWithIcons): void {
|
||||||
// Run only once per tick, possibly joining multiple API responses in one call
|
// Run only once per tick, possibly joining multiple API responses in one call
|
||||||
if (loaderFlags[provider] === void 0) {
|
if (!storage.iconsLoaderFlag) {
|
||||||
loaderFlags[provider] = Object.create(null) as FlagsItem;
|
storage.iconsLoaderFlag = true;
|
||||||
}
|
|
||||||
const providerLoaderFlags = loaderFlags[provider];
|
|
||||||
if (!providerLoaderFlags[prefix]) {
|
|
||||||
providerLoaderFlags[prefix] = true;
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
providerLoaderFlags[prefix] = false;
|
storage.iconsLoaderFlag = false;
|
||||||
updateCallbacks(provider, prefix);
|
updateCallbacks(storage);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Storage for errors for loadNewIcons(). Used to avoid spamming log with identical errors.
|
|
||||||
const errorsCache = Object.create(null) as Record<string, number>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load icons
|
* Load icons
|
||||||
*/
|
*/
|
||||||
function loadNewIcons(provider: string, prefix: string, icons: string[]): void {
|
function loadNewIcons(storage: IconStorageWithIcons, icons: string[]): void {
|
||||||
function err(): void {
|
|
||||||
const key = (provider === '' ? '' : '@' + provider + ':') + prefix;
|
|
||||||
const time = Math.floor(Date.now() / 60000); // log once in a minute
|
|
||||||
if (errorsCache[key] < time) {
|
|
||||||
errorsCache[key] = time;
|
|
||||||
console.error(
|
|
||||||
'Unable to retrieve icons for "' +
|
|
||||||
key +
|
|
||||||
'" because API is not configured properly.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create nested objects if needed
|
|
||||||
if (iconsToLoad[provider] === void 0) {
|
|
||||||
iconsToLoad[provider] = Object.create(null) as IconsToLoadProviderItem;
|
|
||||||
}
|
|
||||||
const providerIconsToLoad = iconsToLoad[provider];
|
|
||||||
|
|
||||||
if (queueFlags[provider] === void 0) {
|
|
||||||
queueFlags[provider] = Object.create(null) as FlagsItem;
|
|
||||||
}
|
|
||||||
const providerQueueFlags = queueFlags[provider];
|
|
||||||
|
|
||||||
if (pendingIcons[provider] === void 0) {
|
|
||||||
pendingIcons[provider] = Object.create(null) as ProviderPendingIcons;
|
|
||||||
}
|
|
||||||
const providerPendingIcons = pendingIcons[provider];
|
|
||||||
|
|
||||||
// Add icons to queue
|
// Add icons to queue
|
||||||
if (providerIconsToLoad[prefix] === void 0) {
|
if (!storage.iconsToLoad) {
|
||||||
providerIconsToLoad[prefix] = icons;
|
storage.iconsToLoad = icons;
|
||||||
} else {
|
} else {
|
||||||
providerIconsToLoad[prefix] = providerIconsToLoad[prefix]
|
storage.iconsToLoad = storage.iconsToLoad.concat(icons).sort();
|
||||||
.concat(icons)
|
|
||||||
.sort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger update on next tick, mering multiple synchronous requests into one asynchronous request
|
// Trigger update on next tick, mering multiple synchronous requests into one asynchronous request
|
||||||
if (!providerQueueFlags[prefix]) {
|
if (!storage.iconsQueueFlag) {
|
||||||
providerQueueFlags[prefix] = true;
|
storage.iconsQueueFlag = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
providerQueueFlags[prefix] = false;
|
storage.iconsQueueFlag = false;
|
||||||
|
const { provider, prefix } = storage;
|
||||||
|
|
||||||
// Get icons and delete queue
|
// Get icons and delete queue
|
||||||
const icons = providerIconsToLoad[prefix];
|
const icons = storage.iconsToLoad;
|
||||||
delete providerIconsToLoad[prefix];
|
delete storage.iconsToLoad;
|
||||||
|
|
||||||
// Get API module
|
// Get API module
|
||||||
const api = getAPIModule(provider);
|
let api: ReturnType<typeof getAPIModule>;
|
||||||
if (!api) {
|
if (!icons || !(api = getAPIModule(provider))) {
|
||||||
// No way to load icons!
|
// No icons or no way to load icons!
|
||||||
err();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,8 +93,6 @@ function loadNewIcons(provider: string, prefix: string, icons: string[]): void {
|
|||||||
const params = api.prepare(provider, prefix, icons);
|
const params = api.prepare(provider, prefix, icons);
|
||||||
params.forEach((item) => {
|
params.forEach((item) => {
|
||||||
sendAPIQuery(provider, item, (data, error) => {
|
sendAPIQuery(provider, item, (data, error) => {
|
||||||
const storage = getStorage(provider, prefix);
|
|
||||||
|
|
||||||
// Check for error
|
// Check for error
|
||||||
if (typeof data !== 'object') {
|
if (typeof data !== 'object') {
|
||||||
if (error !== 404) {
|
if (error !== 404) {
|
||||||
@ -201,10 +116,12 @@ function loadNewIcons(provider: string, prefix: string, icons: string[]): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove added icons from pending list
|
// Remove added icons from pending list
|
||||||
const pending = providerPendingIcons[prefix];
|
const pending = storage.pendingIcons;
|
||||||
parsed.forEach((name) => {
|
if (pending) {
|
||||||
delete pending[name];
|
parsed.forEach((name) => {
|
||||||
});
|
pending.delete(name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Cache API response
|
// Cache API response
|
||||||
storeInBrowserStorage(
|
storeInBrowserStorage(
|
||||||
@ -217,7 +134,7 @@ function loadNewIcons(provider: string, prefix: string, icons: string[]): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Trigger update on next tick
|
// Trigger update on next tick
|
||||||
loadedNewIcons(provider, prefix);
|
loadedNewIcons(storage);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -228,13 +145,12 @@ function loadNewIcons(provider: string, prefix: string, icons: string[]): void {
|
|||||||
* Check if icon is being loaded
|
* Check if icon is being loaded
|
||||||
*/
|
*/
|
||||||
export const isPending: IsPending = (icon: IconifyIconName): boolean => {
|
export const isPending: IsPending = (icon: IconifyIconName): boolean => {
|
||||||
const provider = icon.provider;
|
const storage = getStorage(
|
||||||
const prefix = icon.prefix;
|
icon.provider,
|
||||||
return (
|
icon.prefix
|
||||||
pendingIcons[provider] &&
|
) as IconStorageWithIcons;
|
||||||
pendingIcons[provider][prefix] &&
|
const pending = storage.pendingIcons;
|
||||||
pendingIcons[provider][prefix][icon.name] !== void 0
|
return !!(pending && pending.has(icon.name));
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -280,59 +196,41 @@ export const loadIcons: IconifyLoadIcons = (
|
|||||||
string,
|
string,
|
||||||
ProviderNewIconsList
|
ProviderNewIconsList
|
||||||
>;
|
>;
|
||||||
const sources: IconifyIconSource[] = [];
|
const sources: IconStorageWithIcons[] = [];
|
||||||
let lastProvider: string, lastPrefix: string;
|
let lastProvider: string, lastPrefix: string;
|
||||||
|
|
||||||
sortedIcons.pending.forEach((icon) => {
|
sortedIcons.pending.forEach((icon) => {
|
||||||
const provider = icon.provider;
|
const { provider, prefix } = icon;
|
||||||
const prefix = icon.prefix;
|
|
||||||
if (prefix === lastPrefix && provider === lastProvider) {
|
if (prefix === lastPrefix && provider === lastProvider) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastProvider = provider;
|
lastProvider = provider;
|
||||||
lastPrefix = prefix;
|
lastPrefix = prefix;
|
||||||
sources.push({
|
sources.push(getStorage(provider, prefix));
|
||||||
provider,
|
|
||||||
prefix,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (pendingIcons[provider] === void 0) {
|
const providerNewIcons =
|
||||||
pendingIcons[provider] = Object.create(
|
newIcons[provider] ||
|
||||||
null
|
(newIcons[provider] = Object.create(null) as ProviderNewIconsList);
|
||||||
) as ProviderPendingIcons;
|
if (!providerNewIcons[prefix]) {
|
||||||
}
|
|
||||||
const providerPendingIcons = pendingIcons[provider];
|
|
||||||
if (providerPendingIcons[prefix] === void 0) {
|
|
||||||
providerPendingIcons[prefix] = Object.create(
|
|
||||||
null
|
|
||||||
) as PrefixPendingIcons;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newIcons[provider] === void 0) {
|
|
||||||
newIcons[provider] = Object.create(null) as ProviderNewIconsList;
|
|
||||||
}
|
|
||||||
const providerNewIcons = newIcons[provider];
|
|
||||||
if (providerNewIcons[prefix] === void 0) {
|
|
||||||
providerNewIcons[prefix] = [];
|
providerNewIcons[prefix] = [];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// List of new icons
|
// List of new icons
|
||||||
const time = Date.now();
|
|
||||||
|
|
||||||
// Filter pending icons list: find icons that are not being loaded yet
|
// Filter pending icons list: find icons that are not being loaded yet
|
||||||
// If icon was called before, it must exist in pendingIcons or storage, but because this
|
// If icon was called before, it must exist in pendingIcons or storage, but because this
|
||||||
// function is called right after sortIcons() that checks storage, icon is definitely not in storage.
|
// function is called right after sortIcons() that checks storage, icon is definitely not in storage.
|
||||||
sortedIcons.pending.forEach((icon) => {
|
sortedIcons.pending.forEach((icon) => {
|
||||||
const provider = icon.provider;
|
const { provider, prefix, name } = icon;
|
||||||
const prefix = icon.prefix;
|
|
||||||
const name = icon.name;
|
|
||||||
|
|
||||||
const pendingQueue = pendingIcons[provider][prefix];
|
const storage = getStorage(provider, prefix) as IconStorageWithIcons;
|
||||||
if (pendingQueue[name] === void 0) {
|
const pendingQueue =
|
||||||
|
storage.pendingIcons || (storage.pendingIcons = new Set());
|
||||||
|
|
||||||
|
if (!pendingQueue.has(name)) {
|
||||||
// New icon - add to pending queue to mark it as being loaded
|
// New icon - add to pending queue to mark it as being loaded
|
||||||
pendingQueue[name] = time;
|
pendingQueue.add(name);
|
||||||
// Add it to new icons list to pass it to API module for loading
|
// Add it to new icons list to pass it to API module for loading
|
||||||
newIcons[provider][prefix].push(name);
|
newIcons[provider][prefix].push(name);
|
||||||
}
|
}
|
||||||
@ -340,11 +238,10 @@ export const loadIcons: IconifyLoadIcons = (
|
|||||||
|
|
||||||
// Load icons on next tick to make sure result is not returned before callback is stored and
|
// Load icons on next tick to make sure result is not returned before callback is stored and
|
||||||
// to consolidate multiple synchronous loadIcons() calls into one asynchronous API call
|
// to consolidate multiple synchronous loadIcons() calls into one asynchronous API call
|
||||||
sources.forEach((source) => {
|
sources.forEach((storage) => {
|
||||||
const provider = source.provider;
|
const { provider, prefix } = storage;
|
||||||
const prefix = source.prefix;
|
|
||||||
if (newIcons[provider][prefix].length) {
|
if (newIcons[provider][prefix].length) {
|
||||||
loadNewIcons(provider, prefix, newIcons[provider][prefix]);
|
loadNewIcons(storage, newIcons[provider][prefix]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
60
packages/core/src/api/types.ts
Normal file
60
packages/core/src/api/types.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import type {
|
||||||
|
IconifyIconLoaderCallback,
|
||||||
|
IconifyIconLoaderAbort,
|
||||||
|
} from './icons';
|
||||||
|
import type { SortedIcons } from '../icon/sort';
|
||||||
|
import type { IconStorage } from '../storage/storage';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage for callbacks
|
||||||
|
*/
|
||||||
|
export interface APICallbackItem {
|
||||||
|
// id
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
// Icons
|
||||||
|
icons: SortedIcons;
|
||||||
|
|
||||||
|
// Callback to call on any update
|
||||||
|
callback: IconifyIconLoaderCallback;
|
||||||
|
|
||||||
|
// Callback to call to remove item from queue
|
||||||
|
abort: IconifyIconLoaderAbort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add custom stuff to storage
|
||||||
|
*/
|
||||||
|
export interface IconStorageWithIcons extends IconStorage {
|
||||||
|
/**
|
||||||
|
* List of icons that are being loaded, added to storage
|
||||||
|
*
|
||||||
|
* Icons are added to this list when they are being checked and
|
||||||
|
* removed from this list when they are added to storage as
|
||||||
|
* either an icon or a missing icon. This way same icon should
|
||||||
|
* never be requested twice.
|
||||||
|
*/
|
||||||
|
pendingIcons?: Set<string>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of icons that are waiting to be loaded.
|
||||||
|
*
|
||||||
|
* List is passed to API module, then cleared.
|
||||||
|
*
|
||||||
|
* This list should not be used for any checks, use pendingIcons to check
|
||||||
|
* if icons is being loaded.
|
||||||
|
*
|
||||||
|
* [provider][prefix] = array of icon names
|
||||||
|
*/
|
||||||
|
iconsToLoad?: string[];
|
||||||
|
|
||||||
|
// Flags to merge multiple synchronous icon requests in one asynchronous request
|
||||||
|
iconsLoaderFlag?: boolean;
|
||||||
|
iconsQueueFlag?: boolean;
|
||||||
|
|
||||||
|
// Loader callbacks
|
||||||
|
loaderCallbacks?: APICallbackItem[];
|
||||||
|
|
||||||
|
// Pending callbacks update
|
||||||
|
pendingCallbacksFlag?: boolean;
|
||||||
|
}
|
@ -2,7 +2,6 @@ import type {
|
|||||||
BrowserStorageConfig,
|
BrowserStorageConfig,
|
||||||
BrowserStorageCount,
|
BrowserStorageCount,
|
||||||
BrowserStorageEmptyList,
|
BrowserStorageEmptyList,
|
||||||
BrowserStorageStatus,
|
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,8 +31,8 @@ export const browserStorageEmptyItems: BrowserStorageEmptyList = {
|
|||||||
/**
|
/**
|
||||||
* Flag to check if storage has been loaded
|
* Flag to check if storage has been loaded
|
||||||
*/
|
*/
|
||||||
export let browserStorageStatus: BrowserStorageStatus = false;
|
export let browserStorageStatus = false;
|
||||||
|
|
||||||
export function setBrowserStorageStatus(status: BrowserStorageStatus) {
|
export function setBrowserStorageStatus(status: boolean) {
|
||||||
browserStorageStatus = status;
|
browserStorageStatus = status;
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,10 @@ import type { BrowserStorageConfig, BrowserStorageItem } from './types';
|
|||||||
* Load icons from cache
|
* Load icons from cache
|
||||||
*/
|
*/
|
||||||
export function initBrowserStorage() {
|
export function initBrowserStorage() {
|
||||||
if (browserStorageStatus === true) {
|
if (browserStorageStatus) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setBrowserStorageStatus('loading');
|
setBrowserStorageStatus(true);
|
||||||
|
|
||||||
// Minimum time
|
// Minimum time
|
||||||
const minTime =
|
const minTime =
|
||||||
@ -66,10 +66,12 @@ export function initBrowserStorage() {
|
|||||||
valid = false;
|
valid = false;
|
||||||
} else {
|
} else {
|
||||||
// Add icon set
|
// Add icon set
|
||||||
|
const iconSet = data.data;
|
||||||
|
|
||||||
const provider = data.provider;
|
const provider = data.provider;
|
||||||
const prefix = data.data.prefix;
|
const prefix = iconSet.prefix;
|
||||||
const storage = getStorage(provider, prefix);
|
const storage = getStorage(provider, prefix);
|
||||||
valid = addIconSet(storage, data.data).length > 0;
|
valid = addIconSet(storage, iconSet).length > 0;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
valid = false;
|
valid = false;
|
||||||
@ -129,9 +131,10 @@ export function initBrowserStorage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load each storage
|
||||||
for (const key in browserStorageConfig) {
|
for (const key in browserStorageConfig) {
|
||||||
load(key as keyof BrowserStorageConfig);
|
load(key as keyof BrowserStorageConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
setBrowserStorageStatus(true);
|
// Check for update
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,6 @@ export function storeInBrowserStorage(provider: string, data: IconifyJSON) {
|
|||||||
if (!browserStorageStatus) {
|
if (!browserStorageStatus) {
|
||||||
initBrowserStorage();
|
initBrowserStorage();
|
||||||
}
|
}
|
||||||
if (browserStorageStatus === 'loading') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
function store(key: BrowserStorageType): true | undefined {
|
function store(key: BrowserStorageType): true | undefined {
|
||||||
if (!browserStorageConfig[key]) {
|
if (!browserStorageConfig[key]) {
|
||||||
|
@ -18,6 +18,3 @@ export interface BrowserStorageItem {
|
|||||||
provider: string;
|
provider: string;
|
||||||
data: IconifyJSON;
|
data: IconifyJSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status: not loaded, loading, loaded
|
|
||||||
export type BrowserStorageStatus = false | 'loading' | true;
|
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import {
|
import { updateCallbacks, storeCallback } from '../../lib/api/callbacks';
|
||||||
callbacks,
|
import type { IconStorageWithIcons } from '../../lib/api/types';
|
||||||
updateCallbacks,
|
|
||||||
storeCallback,
|
|
||||||
} from '../../lib/api/callbacks';
|
|
||||||
import { sortIcons } from '../../lib/icon/sort';
|
import { sortIcons } from '../../lib/icon/sort';
|
||||||
import { getStorage, addIconSet } from '../../lib/storage/storage';
|
import { getStorage, addIconSet } from '../../lib/storage/storage';
|
||||||
|
|
||||||
@ -22,7 +19,7 @@ describe('Testing API callbacks', () => {
|
|||||||
const prefix = nextPrefix();
|
const prefix = nextPrefix();
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
|
|
||||||
const storage = getStorage(provider, prefix);
|
const storage = getStorage(provider, prefix) as IconStorageWithIcons;
|
||||||
const abort = storeCallback(
|
const abort = storeCallback(
|
||||||
(loaded, missing, pending, unsubscribe) => {
|
(loaded, missing, pending, unsubscribe) => {
|
||||||
expect(unsubscribe).toBe(abort);
|
expect(unsubscribe).toBe(abort);
|
||||||
@ -52,7 +49,7 @@ describe('Testing API callbacks', () => {
|
|||||||
name: 'icon2',
|
name: 'icon2',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
expect(callbacks[provider][prefix].length).toBe(1);
|
expect(storage.loaderCallbacks?.length).toBe(1);
|
||||||
|
|
||||||
// Add icon2 and trigger update
|
// Add icon2 and trigger update
|
||||||
addIconSet(storage, {
|
addIconSet(storage, {
|
||||||
@ -64,7 +61,7 @@ describe('Testing API callbacks', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
updateCallbacks(provider, prefix);
|
updateCallbacks(storage);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
@ -89,7 +86,7 @@ describe('Testing API callbacks', () => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
expect(pending).toEqual([]);
|
expect(pending).toEqual([]);
|
||||||
expect(callbacks[provider][prefix].length).toBe(0);
|
expect(storage.loaderCallbacks?.length).toBe(0);
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -110,19 +107,14 @@ describe('Testing API callbacks', () => {
|
|||||||
name: 'icon3',
|
name: 'icon3',
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
[
|
[storage]
|
||||||
{
|
|
||||||
provider,
|
|
||||||
prefix,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Test callbacks
|
// Test callbacks
|
||||||
expect(callbacks[provider][prefix].length).toBe(1);
|
expect(storage.loaderCallbacks?.length).toBe(1);
|
||||||
|
|
||||||
// Test update - should do nothing
|
// Test update - should do nothing
|
||||||
updateCallbacks(provider, prefix);
|
updateCallbacks(storage);
|
||||||
|
|
||||||
// Wait for tick because updateCallbacks will use one
|
// Wait for tick because updateCallbacks will use one
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -139,7 +131,7 @@ describe('Testing API callbacks', () => {
|
|||||||
},
|
},
|
||||||
not_found: ['icon3'],
|
not_found: ['icon3'],
|
||||||
});
|
});
|
||||||
updateCallbacks(provider, prefix);
|
updateCallbacks(storage);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -147,7 +139,7 @@ describe('Testing API callbacks', () => {
|
|||||||
const provider = '';
|
const provider = '';
|
||||||
const prefix = nextPrefix();
|
const prefix = nextPrefix();
|
||||||
|
|
||||||
const storage = getStorage(provider, prefix);
|
const storage = getStorage(provider, prefix) as IconStorageWithIcons;
|
||||||
addIconSet(storage, {
|
addIconSet(storage, {
|
||||||
prefix,
|
prefix,
|
||||||
icons: {
|
icons: {
|
||||||
@ -182,16 +174,11 @@ describe('Testing API callbacks', () => {
|
|||||||
name: 'icon3',
|
name: 'icon3',
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
[
|
[storage]
|
||||||
{
|
|
||||||
provider,
|
|
||||||
prefix,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// callbacks should not have been initialised
|
// callbacks should not have been initialised
|
||||||
expect(callbacks[prefix]).toBeUndefined();
|
expect(storage.loaderCallbacks).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Cancel callback', (done) => {
|
it('Cancel callback', (done) => {
|
||||||
@ -199,7 +186,7 @@ describe('Testing API callbacks', () => {
|
|||||||
const prefix = nextPrefix();
|
const prefix = nextPrefix();
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
|
|
||||||
const storage = getStorage(provider, prefix);
|
const storage = getStorage(provider, prefix) as IconStorageWithIcons;
|
||||||
const abort = storeCallback(
|
const abort = storeCallback(
|
||||||
(loaded, missing, pending, unsubscribe) => {
|
(loaded, missing, pending, unsubscribe) => {
|
||||||
expect(unsubscribe).toBe(abort);
|
expect(unsubscribe).toBe(abort);
|
||||||
@ -229,7 +216,7 @@ describe('Testing API callbacks', () => {
|
|||||||
name: 'icon2',
|
name: 'icon2',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
expect(callbacks[provider][prefix].length).toBe(1);
|
expect(storage.loaderCallbacks?.length).toBe(1);
|
||||||
|
|
||||||
// Add icon2 and trigger update
|
// Add icon2 and trigger update
|
||||||
addIconSet(storage, {
|
addIconSet(storage, {
|
||||||
@ -241,11 +228,11 @@ describe('Testing API callbacks', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
updateCallbacks(provider, prefix);
|
updateCallbacks(storage);
|
||||||
|
|
||||||
// Unsubscribe and set timer to call done()
|
// Unsubscribe and set timer to call done()
|
||||||
unsubscribe();
|
unsubscribe();
|
||||||
expect(callbacks[provider][prefix].length).toBe(0);
|
expect(storage.loaderCallbacks?.length).toBe(0);
|
||||||
setTimeout(done);
|
setTimeout(done);
|
||||||
},
|
},
|
||||||
sortIcons([
|
sortIcons([
|
||||||
@ -265,19 +252,14 @@ describe('Testing API callbacks', () => {
|
|||||||
name: 'icon3',
|
name: 'icon3',
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
[
|
[storage]
|
||||||
{
|
|
||||||
provider,
|
|
||||||
prefix,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Test callbacks
|
// Test callbacks
|
||||||
expect(callbacks[provider][prefix].length).toBe(1);
|
expect(storage.loaderCallbacks?.length).toBe(1);
|
||||||
|
|
||||||
// Test update - should do nothing
|
// Test update - should do nothing
|
||||||
updateCallbacks(provider, prefix);
|
updateCallbacks(storage);
|
||||||
|
|
||||||
// Wait for tick because updateCallbacks will use one
|
// Wait for tick because updateCallbacks will use one
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -294,7 +276,7 @@ describe('Testing API callbacks', () => {
|
|||||||
},
|
},
|
||||||
not_found: ['icon3'],
|
not_found: ['icon3'],
|
||||||
});
|
});
|
||||||
updateCallbacks(provider, prefix);
|
updateCallbacks(storage);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -304,8 +286,8 @@ describe('Testing API callbacks', () => {
|
|||||||
const prefix2 = nextPrefix();
|
const prefix2 = nextPrefix();
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
|
|
||||||
const storage1 = getStorage(provider, prefix1);
|
const storage1 = getStorage(provider, prefix1) as IconStorageWithIcons;
|
||||||
const storage2 = getStorage(provider, prefix2);
|
const storage2 = getStorage(provider, prefix2) as IconStorageWithIcons;
|
||||||
|
|
||||||
const abort = storeCallback(
|
const abort = storeCallback(
|
||||||
(loaded, missing, pending, unsubscribe) => {
|
(loaded, missing, pending, unsubscribe) => {
|
||||||
@ -336,8 +318,8 @@ describe('Testing API callbacks', () => {
|
|||||||
name: 'icon2',
|
name: 'icon2',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
expect(callbacks[provider][prefix1].length).toBe(0);
|
expect(storage1.loaderCallbacks?.length).toBe(0);
|
||||||
expect(callbacks[provider][prefix2].length).toBe(1);
|
expect(storage2.loaderCallbacks?.length).toBe(1);
|
||||||
|
|
||||||
// Add icon2 and trigger update
|
// Add icon2 and trigger update
|
||||||
addIconSet(storage2, {
|
addIconSet(storage2, {
|
||||||
@ -349,13 +331,13 @@ describe('Testing API callbacks', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
updateCallbacks(provider, prefix2);
|
updateCallbacks(storage2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
// Second run - icon2 should be loaded
|
// Second run - icon2 should be loaded
|
||||||
expect(callbacks[provider][prefix1].length).toBe(0);
|
expect(storage1.loaderCallbacks?.length).toBe(0);
|
||||||
expect(callbacks[provider][prefix2].length).toBe(0);
|
expect(storage2.loaderCallbacks?.length).toBe(0);
|
||||||
done();
|
done();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -380,18 +362,15 @@ describe('Testing API callbacks', () => {
|
|||||||
name: 'icon3',
|
name: 'icon3',
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
[
|
[storage1, storage2]
|
||||||
{ provider, prefix: prefix1 },
|
|
||||||
{ provider, prefix: prefix2 },
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Test callbacks
|
// Test callbacks
|
||||||
expect(callbacks[provider][prefix1].length).toBe(1);
|
expect(storage1.loaderCallbacks?.length).toBe(1);
|
||||||
expect(callbacks[provider][prefix2].length).toBe(1);
|
expect(storage2.loaderCallbacks?.length).toBe(1);
|
||||||
|
|
||||||
// Test update - should do nothing
|
// Test update - should do nothing
|
||||||
updateCallbacks(provider, prefix1);
|
updateCallbacks(storage1);
|
||||||
|
|
||||||
// Wait for tick because updateCallbacks will use one
|
// Wait for tick because updateCallbacks will use one
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -408,7 +387,7 @@ describe('Testing API callbacks', () => {
|
|||||||
},
|
},
|
||||||
not_found: ['icon3'],
|
not_found: ['icon3'],
|
||||||
});
|
});
|
||||||
updateCallbacks(provider, prefix1);
|
updateCallbacks(storage1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -419,8 +398,8 @@ describe('Testing API callbacks', () => {
|
|||||||
const prefix2 = nextPrefix();
|
const prefix2 = nextPrefix();
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
|
|
||||||
const storage1 = getStorage(provider1, prefix1);
|
const storage1 = getStorage(provider1, prefix1) as IconStorageWithIcons;
|
||||||
const storage2 = getStorage(provider2, prefix2);
|
const storage2 = getStorage(provider2, prefix2) as IconStorageWithIcons;
|
||||||
|
|
||||||
const abort = storeCallback(
|
const abort = storeCallback(
|
||||||
(loaded, missing, pending, unsubscribe) => {
|
(loaded, missing, pending, unsubscribe) => {
|
||||||
@ -451,12 +430,8 @@ describe('Testing API callbacks', () => {
|
|||||||
name: 'icon2',
|
name: 'icon2',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
expect(callbacks[provider1][prefix1].length).toBe(0);
|
expect(storage1.loaderCallbacks?.length).toBe(0);
|
||||||
expect(callbacks[provider2][prefix2].length).toBe(1);
|
expect(storage2.loaderCallbacks?.length).toBe(1);
|
||||||
|
|
||||||
// Make sure providers/prefixes aren't mixed
|
|
||||||
expect(callbacks[provider1][prefix2]).toBeUndefined();
|
|
||||||
expect(callbacks[provider2][prefix1]).toBeUndefined();
|
|
||||||
|
|
||||||
// Add icon2 and trigger update
|
// Add icon2 and trigger update
|
||||||
addIconSet(storage2, {
|
addIconSet(storage2, {
|
||||||
@ -468,17 +443,13 @@ describe('Testing API callbacks', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
updateCallbacks(provider2, prefix2);
|
updateCallbacks(storage2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
// Second run - icon2 should be loaded
|
// Second run - icon2 should be loaded
|
||||||
expect(callbacks[provider1][prefix1].length).toBe(0);
|
expect(storage1.loaderCallbacks?.length).toBe(0);
|
||||||
expect(callbacks[provider2][prefix2].length).toBe(0);
|
expect(storage2.loaderCallbacks?.length).toBe(0);
|
||||||
|
|
||||||
// Make sure providers/prefixes aren't mixed
|
|
||||||
expect(callbacks[provider1][prefix2]).toBeUndefined();
|
|
||||||
expect(callbacks[provider2][prefix1]).toBeUndefined();
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
break;
|
break;
|
||||||
@ -504,21 +475,15 @@ describe('Testing API callbacks', () => {
|
|||||||
name: 'icon3',
|
name: 'icon3',
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
[
|
[storage1, storage2]
|
||||||
{ provider: provider1, prefix: prefix1 },
|
|
||||||
{ provider: provider2, prefix: prefix2 },
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Test callbacks
|
// Test callbacks
|
||||||
expect(callbacks[provider1][prefix1].length).toBe(1);
|
expect(storage1.loaderCallbacks?.length).toBe(1);
|
||||||
expect(callbacks[provider2][prefix2].length).toBe(1);
|
expect(storage2.loaderCallbacks?.length).toBe(1);
|
||||||
|
|
||||||
expect(callbacks[provider1][prefix2]).toBeUndefined();
|
|
||||||
expect(callbacks[provider2][prefix1]).toBeUndefined();
|
|
||||||
|
|
||||||
// Test update - should do nothing
|
// Test update - should do nothing
|
||||||
updateCallbacks(provider1, prefix1);
|
updateCallbacks(storage1);
|
||||||
|
|
||||||
// Wait for tick because updateCallbacks will use one
|
// Wait for tick because updateCallbacks will use one
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -535,7 +500,7 @@ describe('Testing API callbacks', () => {
|
|||||||
},
|
},
|
||||||
not_found: ['icon3'],
|
not_found: ['icon3'],
|
||||||
});
|
});
|
||||||
updateCallbacks(provider1, prefix1);
|
updateCallbacks(storage1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user