mirror of
https://github.com/iconify/iconify.git
synced 2024-11-09 14:50:56 +00:00
More browser storage restructuring
This commit is contained in:
parent
a4240f122a
commit
7980cce929
@ -55,7 +55,8 @@ import { sendAPIQuery } from '@iconify/core/lib/api/query';
|
||||
|
||||
// Cache
|
||||
import { cache } from '@iconify/core/lib/cache';
|
||||
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage';
|
||||
import { storeCache } from '@iconify/core/lib/browser-storage';
|
||||
import { loadBrowserStorageCache } from '@iconify/core/lib/browser-storage/load';
|
||||
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
|
||||
import type {
|
||||
IconifyBrowserCacheType,
|
||||
@ -144,7 +145,7 @@ setAPIModule('', fetchAPIModule);
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// Set cache and load existing cache
|
||||
cache.store = storeCache;
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
interface WindowWithIconifyStuff {
|
||||
IconifyPreload?: IconifyJSON[] | IconifyJSON;
|
||||
|
@ -59,7 +59,8 @@ import { sendAPIQuery } from '@iconify/core/lib/api/query';
|
||||
|
||||
// Cache
|
||||
import { cache } from '@iconify/core/lib/cache';
|
||||
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage';
|
||||
import { storeCache } from '@iconify/core/lib/browser-storage';
|
||||
import { loadBrowserStorageCache } from '@iconify/core/lib/browser-storage/load';
|
||||
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
|
||||
import type {
|
||||
IconifyBrowserCacheType,
|
||||
@ -153,7 +154,7 @@ setAPIModule('', fetchAPIModule);
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// Set cache and load existing cache
|
||||
cache.store = storeCache;
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
interface WindowWithIconifyStuff {
|
||||
IconifyPreload?: IconifyJSON[] | IconifyJSON;
|
||||
|
@ -58,7 +58,8 @@ import { sendAPIQuery } from '@iconify/core/lib/api/query';
|
||||
|
||||
// Cache
|
||||
import { cache } from '@iconify/core/lib/cache';
|
||||
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage';
|
||||
import { storeCache } from '@iconify/core/lib/browser-storage';
|
||||
import { loadBrowserStorageCache } from '@iconify/core/lib/browser-storage/load';
|
||||
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
|
||||
import type {
|
||||
IconifyBrowserCacheType,
|
||||
@ -150,7 +151,7 @@ setAPIModule('', fetchAPIModule);
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// Set cache and load existing cache
|
||||
cache.store = storeCache;
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
interface WindowWithIconifyStuff {
|
||||
IconifyPreload?: IconifyJSON[] | IconifyJSON;
|
||||
|
@ -17,7 +17,8 @@ import { replaceIDs } from '@iconify/utils/lib/svg/id';
|
||||
import { calculateSize } from '@iconify/utils/lib/svg/size';
|
||||
|
||||
// Cache
|
||||
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage';
|
||||
import { storeCache } from '@iconify/core/lib/browser-storage';
|
||||
import { loadBrowserStorageCache } from '@iconify/core/lib/browser-storage/load';
|
||||
import { cache } from '@iconify/core/lib/cache';
|
||||
import type {
|
||||
IconifyBrowserCacheFunctions,
|
||||
@ -150,7 +151,7 @@ setAPIModule('', fetchAPIModule);
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// Set cache and load existing cache
|
||||
cache.store = storeCache;
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
interface WindowWithIconifyStuff {
|
||||
IconifyProviders?: Record<string, PartialIconifyAPIConfig>;
|
||||
|
@ -68,7 +68,8 @@ import { sendAPIQuery } from '@iconify/core/lib/api/query';
|
||||
|
||||
// Cache
|
||||
import { cache } from '@iconify/core/lib/cache';
|
||||
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage';
|
||||
import { storeCache } from '@iconify/core/lib/browser-storage';
|
||||
import { loadBrowserStorageCache } from '@iconify/core/lib/browser-storage/load';
|
||||
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
|
||||
import type {
|
||||
IconifyBrowserCacheType,
|
||||
@ -161,7 +162,7 @@ setAPIModule('', fetchAPIModule);
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// Set cache and load existing cache
|
||||
cache.store = storeCache;
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
interface WindowWithIconifyStuff {
|
||||
IconifyPreload?: IconifyJSON[] | IconifyJSON;
|
||||
|
@ -47,7 +47,11 @@ import {
|
||||
getAPIConfig,
|
||||
listAPIProviders,
|
||||
} from '@iconify/core/lib/api/config';
|
||||
import { fetchAPIModule, setFetch, getFetch } from '@iconify/core/lib/api/modules/fetch';
|
||||
import {
|
||||
fetchAPIModule,
|
||||
setFetch,
|
||||
getFetch,
|
||||
} from '@iconify/core/lib/api/modules/fetch';
|
||||
import type {
|
||||
IconifyIconLoaderCallback,
|
||||
IconifyIconLoaderAbort,
|
||||
@ -57,7 +61,8 @@ import { sendAPIQuery } from '@iconify/core/lib/api/query';
|
||||
|
||||
// Cache
|
||||
import { cache } from '@iconify/core/lib/cache';
|
||||
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage';
|
||||
import { storeCache } from '@iconify/core/lib/browser-storage';
|
||||
import { loadBrowserStorageCache } from '@iconify/core/lib/browser-storage/load';
|
||||
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
|
||||
import type {
|
||||
IconifyBrowserCacheType,
|
||||
@ -148,7 +153,7 @@ setAPIModule('', fetchAPIModule);
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// Set cache and load existing cache
|
||||
cache.store = storeCache;
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
interface WindowWithIconifyStuff {
|
||||
IconifyPreload?: IconifyJSON[] | IconifyJSON;
|
||||
@ -275,7 +280,7 @@ export const Icon = Vue.extend({
|
||||
this._name = '';
|
||||
this.abortLoading();
|
||||
return {
|
||||
data: {...defaultIconProps, ...icon},
|
||||
data: { ...defaultIconProps, ...icon },
|
||||
};
|
||||
}
|
||||
|
||||
@ -338,10 +343,9 @@ export const Icon = Vue.extend({
|
||||
let context = this.$data;
|
||||
|
||||
// Get icon data
|
||||
const icon: IconComponentData | null = this.iconMounted ? this.getIcon(
|
||||
props.icon,
|
||||
props.onLoad
|
||||
) : null;
|
||||
const icon: IconComponentData | null = this.iconMounted
|
||||
? this.getIcon(props.icon, props.onLoad)
|
||||
: null;
|
||||
|
||||
// Validate icon object
|
||||
if (!icon) {
|
||||
|
@ -38,7 +38,8 @@ import { sendAPIQuery } from '@iconify/core/lib/api/query';
|
||||
|
||||
// Cache
|
||||
import { cache } from '@iconify/core/lib/cache';
|
||||
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage';
|
||||
import { storeCache } from '@iconify/core/lib/browser-storage';
|
||||
import { loadBrowserStorageCache } from '@iconify/core/lib/browser-storage/load';
|
||||
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
|
||||
import type {
|
||||
IconifyBrowserCacheType,
|
||||
@ -85,7 +86,7 @@ export function exportFunctions(): IconifyExportedFunctions {
|
||||
if (_window) {
|
||||
// Set cache and load existing cache
|
||||
cache.store = storeCache;
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Load icons from global "IconifyPreload"
|
||||
if (_window.IconifyPreload !== void 0) {
|
||||
|
@ -61,6 +61,10 @@
|
||||
"require": "./lib/browser-storage/config.cjs",
|
||||
"import": "./lib/browser-storage/config.mjs"
|
||||
},
|
||||
"./lib/browser-storage/count": {
|
||||
"require": "./lib/browser-storage/count.cjs",
|
||||
"import": "./lib/browser-storage/count.mjs"
|
||||
},
|
||||
"./lib/browser-storage/data": {
|
||||
"require": "./lib/browser-storage/data.cjs",
|
||||
"import": "./lib/browser-storage/data.mjs"
|
||||
@ -69,6 +73,10 @@
|
||||
"require": "./lib/browser-storage/functions.cjs",
|
||||
"import": "./lib/browser-storage/functions.mjs"
|
||||
},
|
||||
"./lib/browser-storage/global": {
|
||||
"require": "./lib/browser-storage/global.cjs",
|
||||
"import": "./lib/browser-storage/global.mjs"
|
||||
},
|
||||
"./lib/browser-storage": {
|
||||
"require": "./lib/browser-storage/index.cjs",
|
||||
"import": "./lib/browser-storage/index.mjs"
|
||||
@ -77,6 +85,10 @@
|
||||
"require": "./lib/browser-storage/index.cjs",
|
||||
"import": "./lib/browser-storage/index.mjs"
|
||||
},
|
||||
"./lib/browser-storage/load": {
|
||||
"require": "./lib/browser-storage/load.cjs",
|
||||
"import": "./lib/browser-storage/load.mjs"
|
||||
},
|
||||
"./lib/browser-storage/mock": {
|
||||
"require": "./lib/browser-storage/mock.cjs",
|
||||
"import": "./lib/browser-storage/mock.mjs"
|
||||
|
35
packages/core/src/browser-storage/count.ts
Normal file
35
packages/core/src/browser-storage/count.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { browserCacheCountKey } from './config';
|
||||
import { browserStorageItemsCount } from './data';
|
||||
import type { BrowserStorageConfig } from './types';
|
||||
|
||||
/**
|
||||
* Change current count for storage
|
||||
*/
|
||||
export function setBrowserStorageItemsCount(
|
||||
storage: typeof localStorage,
|
||||
key: keyof BrowserStorageConfig,
|
||||
value: number
|
||||
): boolean {
|
||||
try {
|
||||
storage.setItem(browserCacheCountKey, value.toString());
|
||||
browserStorageItemsCount[key] = value;
|
||||
return true;
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current count from storage
|
||||
*/
|
||||
export function getBrowserStorageItemsCount(
|
||||
storage: typeof localStorage
|
||||
): number {
|
||||
const count = storage.getItem(browserCacheCountKey);
|
||||
if (count) {
|
||||
const total = parseInt(count);
|
||||
return total ? total : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -27,3 +27,12 @@ export const browserStorageEmptyItems: BrowserStorageEmptyList = {
|
||||
local: [],
|
||||
session: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Flag to check if storage has been loaded
|
||||
*/
|
||||
export let browserStorageLoaded = false;
|
||||
|
||||
export function setBrowserStorageStatus(loaded: boolean) {
|
||||
browserStorageLoaded = loaded;
|
||||
}
|
||||
|
16
packages/core/src/browser-storage/destroy.ts
Normal file
16
packages/core/src/browser-storage/destroy.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { browserCachePrefix } from './config';
|
||||
import { getBrowserStorageItemsCount } from './count';
|
||||
|
||||
/**
|
||||
* Destroy old cache
|
||||
*/
|
||||
export function destroyBrowserStorage(storage: typeof localStorage): void {
|
||||
try {
|
||||
const total = getBrowserStorageItemsCount(storage);
|
||||
for (let i = 0; i < total; i++) {
|
||||
storage.removeItem(browserCachePrefix + i.toString());
|
||||
}
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
}
|
40
packages/core/src/browser-storage/global.ts
Normal file
40
packages/core/src/browser-storage/global.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { browserStorageConfig } from './data';
|
||||
import type { BrowserStorageConfig } from './types';
|
||||
|
||||
/**
|
||||
* Fake window for unit testing
|
||||
*/
|
||||
type FakeWindow = Record<string, typeof localStorage>;
|
||||
|
||||
let _window: FakeWindow =
|
||||
typeof window === 'undefined' ? {} : (window as unknown as FakeWindow);
|
||||
|
||||
/**
|
||||
* Get browser storage
|
||||
*/
|
||||
export function getBrowserStorage(
|
||||
key: keyof BrowserStorageConfig
|
||||
): typeof localStorage | undefined {
|
||||
const attr = key + 'Storage';
|
||||
try {
|
||||
if (
|
||||
_window &&
|
||||
_window[attr] &&
|
||||
typeof _window[attr].length === 'number'
|
||||
) {
|
||||
return _window[attr];
|
||||
}
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
|
||||
// Failed - mark as disabled
|
||||
browserStorageConfig[key] = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock window for unit testing
|
||||
*/
|
||||
export function mockWindow(fakeWindow: FakeWindow): void {
|
||||
_window = fakeWindow;
|
||||
}
|
@ -1,232 +1,17 @@
|
||||
import type { IconifyJSON } from '@iconify/types';
|
||||
import type { CacheIcons, LoadIconsCache } from '../cache';
|
||||
import { getStorage, addIconSet } from '../storage/storage';
|
||||
import {
|
||||
browserCacheCountKey,
|
||||
browserCachePrefix,
|
||||
browserCacheVersion,
|
||||
browserCacheVersionKey,
|
||||
browserStorageCacheExpiration,
|
||||
browserStorageHour,
|
||||
} from './config';
|
||||
import type { CacheIcons } from '../cache';
|
||||
import { browserCachePrefix, browserStorageHour } from './config';
|
||||
import { setBrowserStorageItemsCount } from './count';
|
||||
import {
|
||||
browserStorageConfig,
|
||||
browserStorageEmptyItems,
|
||||
browserStorageItemsCount,
|
||||
browserStorageLoaded,
|
||||
} from './data';
|
||||
import { getBrowserStorage } from './global';
|
||||
import { loadBrowserStorageCache } from './load';
|
||||
import type { BrowserStorageConfig, BrowserStorageItem } from './types';
|
||||
|
||||
/**
|
||||
* Flag to check if storage has been loaded
|
||||
*/
|
||||
let loaded = false;
|
||||
|
||||
/**
|
||||
* Fake window for unit testing
|
||||
*/
|
||||
type FakeWindow = Record<string, typeof localStorage>;
|
||||
|
||||
let _window: FakeWindow =
|
||||
typeof window === 'undefined' ? {} : (window as unknown as FakeWindow);
|
||||
export function mock(fakeWindow: FakeWindow): void {
|
||||
loaded = false;
|
||||
_window = fakeWindow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get global
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
function getGlobal(
|
||||
key: keyof BrowserStorageConfig
|
||||
): typeof localStorage | null {
|
||||
const attr = key + 'Storage';
|
||||
try {
|
||||
if (
|
||||
_window &&
|
||||
_window[attr] &&
|
||||
typeof _window[attr].length === 'number'
|
||||
) {
|
||||
return _window[attr];
|
||||
}
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
|
||||
// Failed - mark as disabled
|
||||
browserStorageConfig[key] = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change current count for storage
|
||||
*/
|
||||
function setCount(
|
||||
storage: typeof localStorage,
|
||||
key: keyof BrowserStorageConfig,
|
||||
value: number
|
||||
): boolean {
|
||||
try {
|
||||
storage.setItem(browserCacheCountKey, value.toString());
|
||||
browserStorageItemsCount[key] = value;
|
||||
return true;
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current count from storage
|
||||
*
|
||||
* @param storage
|
||||
*/
|
||||
function getCount(storage: typeof localStorage): number {
|
||||
const count = storage.getItem(browserCacheCountKey);
|
||||
if (count) {
|
||||
const total = parseInt(count);
|
||||
return total ? total : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize storage
|
||||
*
|
||||
* @param storage
|
||||
* @param key
|
||||
*/
|
||||
function initCache(
|
||||
storage: typeof localStorage,
|
||||
key: keyof BrowserStorageConfig
|
||||
): void {
|
||||
try {
|
||||
storage.setItem(browserCacheVersionKey, browserCacheVersion);
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
setCount(storage, key, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy old cache
|
||||
*
|
||||
* @param storage
|
||||
*/
|
||||
function destroyCache(storage: typeof localStorage): void {
|
||||
try {
|
||||
const total = getCount(storage);
|
||||
for (let i = 0; i < total; i++) {
|
||||
storage.removeItem(browserCachePrefix + i.toString());
|
||||
}
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load icons from cache
|
||||
*/
|
||||
export const loadCache: LoadIconsCache = (): void => {
|
||||
if (loaded) {
|
||||
return;
|
||||
}
|
||||
loaded = true;
|
||||
|
||||
// Minimum time
|
||||
const minTime =
|
||||
Math.floor(Date.now() / browserStorageHour) -
|
||||
browserStorageCacheExpiration;
|
||||
|
||||
// Load data from storage
|
||||
function load(key: keyof BrowserStorageConfig): void {
|
||||
const func = getGlobal(key);
|
||||
if (!func) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get one item from storage
|
||||
const getItem = (index: number): boolean => {
|
||||
const name = browserCachePrefix + index.toString();
|
||||
const item = func.getItem(name);
|
||||
|
||||
if (typeof item !== 'string') {
|
||||
// Does not exist
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get item, validate it
|
||||
let valid = true;
|
||||
try {
|
||||
// Parse, check time stamp
|
||||
const data = JSON.parse(item) as BrowserStorageItem;
|
||||
if (
|
||||
typeof data !== 'object' ||
|
||||
typeof data.cached !== 'number' ||
|
||||
data.cached < minTime ||
|
||||
typeof data.provider !== 'string' ||
|
||||
typeof data.data !== 'object' ||
|
||||
typeof data.data.prefix !== 'string'
|
||||
) {
|
||||
valid = false;
|
||||
} else {
|
||||
// Add icon set
|
||||
const provider = data.provider;
|
||||
const prefix = data.data.prefix;
|
||||
const storage = getStorage(provider, prefix);
|
||||
valid = addIconSet(storage, data.data).length > 0;
|
||||
}
|
||||
} catch (err) {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
func.removeItem(name);
|
||||
}
|
||||
return valid;
|
||||
};
|
||||
|
||||
try {
|
||||
// Get version
|
||||
const version = func.getItem(browserCacheVersionKey);
|
||||
if (version !== browserCacheVersion) {
|
||||
if (version) {
|
||||
// Version is set, but invalid - remove old entries
|
||||
destroyCache(func);
|
||||
}
|
||||
// Empty data
|
||||
initCache(func, key);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get number of stored items
|
||||
let total = getCount(func);
|
||||
for (let i = total - 1; i >= 0; i--) {
|
||||
if (!getItem(i)) {
|
||||
// Remove item
|
||||
if (i === total - 1) {
|
||||
// Last item - reduce country
|
||||
total--;
|
||||
} else {
|
||||
// Mark as empty
|
||||
browserStorageEmptyItems[key].push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update total
|
||||
setCount(func, key, total);
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in browserStorageConfig) {
|
||||
load(key as keyof BrowserStorageConfig);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to cache icons
|
||||
*/
|
||||
@ -234,8 +19,8 @@ export const storeCache: CacheIcons = (
|
||||
provider: string,
|
||||
data: IconifyJSON
|
||||
): void => {
|
||||
if (!loaded) {
|
||||
loadCache();
|
||||
if (!browserStorageLoaded) {
|
||||
loadBrowserStorageCache();
|
||||
}
|
||||
|
||||
function store(key: keyof BrowserStorageConfig): boolean {
|
||||
@ -243,7 +28,7 @@ export const storeCache: CacheIcons = (
|
||||
return false;
|
||||
}
|
||||
|
||||
const func = getGlobal(key);
|
||||
const func = getBrowserStorage(key);
|
||||
if (!func) {
|
||||
return false;
|
||||
}
|
||||
@ -253,7 +38,7 @@ export const storeCache: CacheIcons = (
|
||||
if (index === void 0) {
|
||||
// Create new index
|
||||
index = browserStorageItemsCount[key];
|
||||
if (!setCount(func, key, index + 1)) {
|
||||
if (!setBrowserStorageItemsCount(func, key, index + 1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
152
packages/core/src/browser-storage/load.ts
Normal file
152
packages/core/src/browser-storage/load.ts
Normal file
@ -0,0 +1,152 @@
|
||||
import type { LoadIconsCache } from '../cache';
|
||||
import { addIconSet, getStorage } from '../storage/storage';
|
||||
import {
|
||||
browserCachePrefix,
|
||||
browserCacheVersion,
|
||||
browserCacheVersionKey,
|
||||
browserStorageCacheExpiration,
|
||||
browserStorageHour,
|
||||
} from './config';
|
||||
import {
|
||||
getBrowserStorageItemsCount,
|
||||
setBrowserStorageItemsCount,
|
||||
} from './count';
|
||||
import {
|
||||
browserStorageConfig,
|
||||
browserStorageEmptyItems,
|
||||
browserStorageLoaded,
|
||||
setBrowserStorageStatus,
|
||||
} from './data';
|
||||
import { getBrowserStorage } from './global';
|
||||
import type { BrowserStorageConfig, BrowserStorageItem } from './types';
|
||||
|
||||
/**
|
||||
* Destroy old cache
|
||||
*/
|
||||
function destroyBrowserStorage(storage: typeof localStorage): void {
|
||||
try {
|
||||
const total = getBrowserStorageItemsCount(storage);
|
||||
for (let i = 0; i < total; i++) {
|
||||
storage.removeItem(browserCachePrefix + i.toString());
|
||||
}
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize storage
|
||||
*/
|
||||
function initBrowserStorage(
|
||||
storage: typeof localStorage,
|
||||
key: keyof BrowserStorageConfig
|
||||
): void {
|
||||
try {
|
||||
storage.setItem(browserCacheVersionKey, browserCacheVersion);
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
setBrowserStorageItemsCount(storage, key, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load icons from cache
|
||||
*/
|
||||
export const loadBrowserStorageCache: LoadIconsCache = (): void => {
|
||||
if (browserStorageLoaded) {
|
||||
return;
|
||||
}
|
||||
setBrowserStorageStatus(true);
|
||||
|
||||
// Minimum time
|
||||
const minTime =
|
||||
Math.floor(Date.now() / browserStorageHour) -
|
||||
browserStorageCacheExpiration;
|
||||
|
||||
// Load data from storage
|
||||
function load(key: keyof BrowserStorageConfig): void {
|
||||
const func = getBrowserStorage(key);
|
||||
if (!func) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get one item from storage
|
||||
const getItem = (index: number): boolean => {
|
||||
const name = browserCachePrefix + index.toString();
|
||||
const item = func.getItem(name);
|
||||
|
||||
if (typeof item !== 'string') {
|
||||
// Does not exist
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get item, validate it
|
||||
let valid = true;
|
||||
try {
|
||||
// Parse, check time stamp
|
||||
const data = JSON.parse(item) as BrowserStorageItem;
|
||||
if (
|
||||
typeof data !== 'object' ||
|
||||
typeof data.cached !== 'number' ||
|
||||
data.cached < minTime ||
|
||||
typeof data.provider !== 'string' ||
|
||||
typeof data.data !== 'object' ||
|
||||
typeof data.data.prefix !== 'string'
|
||||
) {
|
||||
valid = false;
|
||||
} else {
|
||||
// Add icon set
|
||||
const provider = data.provider;
|
||||
const prefix = data.data.prefix;
|
||||
const storage = getStorage(provider, prefix);
|
||||
valid = addIconSet(storage, data.data).length > 0;
|
||||
}
|
||||
} catch (err) {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
func.removeItem(name);
|
||||
}
|
||||
return valid;
|
||||
};
|
||||
|
||||
try {
|
||||
// Get version
|
||||
const version = func.getItem(browserCacheVersionKey);
|
||||
if (version !== browserCacheVersion) {
|
||||
if (version) {
|
||||
// Version is set, but invalid - remove old entries
|
||||
destroyBrowserStorage(func);
|
||||
}
|
||||
// Empty data
|
||||
initBrowserStorage(func, key);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get number of stored items
|
||||
let total = getBrowserStorageItemsCount(func);
|
||||
for (let i = total - 1; i >= 0; i--) {
|
||||
if (!getItem(i)) {
|
||||
// Remove item
|
||||
if (i === total - 1) {
|
||||
// Last item - reduce country
|
||||
total--;
|
||||
} else {
|
||||
// Mark as empty
|
||||
browserStorageEmptyItems[key].push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update total
|
||||
setBrowserStorageItemsCount(func, key, total);
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in browserStorageConfig) {
|
||||
load(key as keyof BrowserStorageConfig);
|
||||
}
|
||||
};
|
@ -1,8 +1,9 @@
|
||||
import { mock } from './index';
|
||||
import { mockWindow } from './global';
|
||||
import {
|
||||
browserStorageItemsCount,
|
||||
browserStorageConfig,
|
||||
browserStorageEmptyItems,
|
||||
setBrowserStorageStatus,
|
||||
} from './data';
|
||||
|
||||
/**
|
||||
@ -93,9 +94,10 @@ export function createCache(): typeof localStorage {
|
||||
*/
|
||||
export function reset(fakeWindow: Record<string, typeof localStorage>): void {
|
||||
// Replace window
|
||||
mock(fakeWindow);
|
||||
mockWindow(fakeWindow);
|
||||
|
||||
// Reset all data
|
||||
setBrowserStorageStatus(false);
|
||||
for (const key in browserStorageConfig) {
|
||||
const attr = key as unknown as keyof typeof browserStorageConfig;
|
||||
browserStorageConfig[attr] = true;
|
||||
|
12
packages/core/tests/cache/basic-test.ts
vendored
12
packages/core/tests/cache/basic-test.ts
vendored
@ -1,4 +1,4 @@
|
||||
import { loadCache } from '../../lib/browser-storage';
|
||||
import { loadBrowserStorageCache } from '../../lib/browser-storage/load';
|
||||
import {
|
||||
browserStorageItemsCount,
|
||||
browserStorageConfig,
|
||||
@ -28,7 +28,7 @@ describe('Testing mocked localStorage', () => {
|
||||
});
|
||||
|
||||
// Attempt to load
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Everything should be disabled
|
||||
expect(browserStorageConfig).toEqual({
|
||||
@ -59,7 +59,7 @@ describe('Testing mocked localStorage', () => {
|
||||
});
|
||||
|
||||
// Attempt to load
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// sessionStorage should be disabled
|
||||
expect(browserStorageConfig).toEqual({
|
||||
@ -118,7 +118,7 @@ describe('Testing mocked localStorage', () => {
|
||||
});
|
||||
|
||||
// Attempt to load
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Everything should be disabled because read-only mock throws errors
|
||||
expect(browserStorageConfig).toEqual({
|
||||
@ -172,7 +172,7 @@ describe('Testing mocked localStorage', () => {
|
||||
});
|
||||
|
||||
// Attempt to load
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// sessionStorage should be disabled
|
||||
expect(browserStorageConfig).toEqual({
|
||||
@ -204,7 +204,7 @@ describe('Testing mocked localStorage', () => {
|
||||
});
|
||||
|
||||
// Attempt to load
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Everything should be working
|
||||
expect(browserStorageConfig).toEqual({
|
||||
|
18
packages/core/tests/cache/loading-test.ts
vendored
18
packages/core/tests/cache/loading-test.ts
vendored
@ -1,6 +1,6 @@
|
||||
import type { IconifyJSON } from '@iconify/types';
|
||||
import type { BrowserStorageItem } from '../../lib/browser-storage/types';
|
||||
import { loadCache } from '../../lib/browser-storage';
|
||||
import { loadBrowserStorageCache } from '../../lib/browser-storage/load';
|
||||
import {
|
||||
browserStorageItemsCount,
|
||||
browserStorageConfig,
|
||||
@ -52,7 +52,7 @@ describe('Testing loading from localStorage', () => {
|
||||
expect(iconExists(icons, 'foo')).toBe(false);
|
||||
|
||||
// Load localStorage
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Icon should exist now
|
||||
expect(iconExists(icons, 'foo')).toBe(true);
|
||||
@ -109,7 +109,7 @@ describe('Testing loading from localStorage', () => {
|
||||
expect(iconExists(icons2, 'foo')).toBe(false);
|
||||
|
||||
// Load localStorage
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Icon should exist now
|
||||
expect(iconExists(icons, 'foo')).toBe(true);
|
||||
@ -166,7 +166,7 @@ describe('Testing loading from localStorage', () => {
|
||||
expect(iconExists(icons, 'foo')).toBe(false);
|
||||
|
||||
// Load localStorage
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Icon should not have loaded
|
||||
expect(iconExists(icons, 'foo')).toBe(false);
|
||||
@ -220,7 +220,7 @@ describe('Testing loading from localStorage', () => {
|
||||
expect(iconExists(icons, 'foo')).toBe(false);
|
||||
|
||||
// Load localStorage
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Icon should not have loaded
|
||||
expect(iconExists(icons, 'foo')).toBe(false);
|
||||
@ -272,7 +272,7 @@ describe('Testing loading from localStorage', () => {
|
||||
expect(iconExists(icons, 'foo')).toBe(false);
|
||||
|
||||
// Load localStorage
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Icon should not have loaded
|
||||
expect(iconExists(icons, 'foo')).toBe(false);
|
||||
@ -324,7 +324,7 @@ describe('Testing loading from localStorage', () => {
|
||||
expect(iconExists(icons, 'foo')).toBe(false);
|
||||
|
||||
// Load localStorage
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Icon should exist now
|
||||
expect(iconExists(icons, 'foo')).toBe(true);
|
||||
@ -392,7 +392,7 @@ describe('Testing loading from localStorage', () => {
|
||||
expect(iconExists(icons, 'foo4')).toBe(false);
|
||||
|
||||
// Load localStorage
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Icons should exist now
|
||||
expect(iconExists(icons, 'foo1')).toBe(true);
|
||||
@ -476,7 +476,7 @@ describe('Testing loading from localStorage', () => {
|
||||
}
|
||||
|
||||
// Load localStorage
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Icons should exist now, except for number 4
|
||||
for (let i = 0; i < 6; i++) {
|
||||
|
13
packages/core/tests/cache/saving-test.ts
vendored
13
packages/core/tests/cache/saving-test.ts
vendored
@ -1,6 +1,7 @@
|
||||
import type { IconifyJSON } from '@iconify/types';
|
||||
import type { BrowserStorageItem } from '../../lib/browser-storage/types';
|
||||
import { loadCache, storeCache } from '../../lib/browser-storage';
|
||||
import { storeCache } from '../../lib/browser-storage';
|
||||
import { loadBrowserStorageCache } from '../../lib/browser-storage/load';
|
||||
import {
|
||||
browserStorageItemsCount,
|
||||
browserStorageConfig,
|
||||
@ -187,7 +188,7 @@ describe('Testing saving to localStorage', () => {
|
||||
});
|
||||
|
||||
// Load data
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Check data
|
||||
expect(browserStorageConfig).toEqual({
|
||||
@ -280,7 +281,7 @@ describe('Testing saving to localStorage', () => {
|
||||
});
|
||||
|
||||
// Load data
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Check data
|
||||
expect(browserStorageConfig).toEqual({
|
||||
@ -398,7 +399,7 @@ describe('Testing saving to localStorage', () => {
|
||||
expect(iconExists(icons, 'foo1')).toBe(false);
|
||||
|
||||
// Load cache
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
expect(browserStorageConfig).toEqual({
|
||||
local: true,
|
||||
@ -515,7 +516,7 @@ describe('Testing saving to localStorage', () => {
|
||||
});
|
||||
|
||||
// Load data
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Check data
|
||||
expect(browserStorageConfig).toEqual({
|
||||
@ -630,7 +631,7 @@ describe('Testing saving to localStorage', () => {
|
||||
});
|
||||
|
||||
// Load data
|
||||
loadCache();
|
||||
loadBrowserStorageCache();
|
||||
|
||||
// Check data
|
||||
expect(browserStorageConfig).toEqual({
|
||||
|
Loading…
Reference in New Issue
Block a user