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

Complete restructure of browser storage

This commit is contained in:
Vjacheslav Trushkin 2022-06-28 22:37:23 +03:00
parent 7980cce929
commit 0e0b6b66ef
13 changed files with 117 additions and 130 deletions

View File

@ -54,9 +54,7 @@ import { loadIcons, loadIcon } from '@iconify/core/lib/api/icons';
import { sendAPIQuery } from '@iconify/core/lib/api/query';
// Cache
import { cache } from '@iconify/core/lib/cache';
import { storeCache } from '@iconify/core/lib/browser-storage';
import { loadBrowserStorageCache } from '@iconify/core/lib/browser-storage/load';
import { initBrowserStorage } from '@iconify/core/lib/browser-storage';
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
import type {
IconifyBrowserCacheType,
@ -144,8 +142,7 @@ setAPIModule('', fetchAPIModule);
*/
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
// Set cache and load existing cache
cache.store = storeCache;
loadBrowserStorageCache();
initBrowserStorage();
interface WindowWithIconifyStuff {
IconifyPreload?: IconifyJSON[] | IconifyJSON;

View File

@ -58,9 +58,7 @@ import { loadIcons, loadIcon } from '@iconify/core/lib/api/icons';
import { sendAPIQuery } from '@iconify/core/lib/api/query';
// Cache
import { cache } from '@iconify/core/lib/cache';
import { storeCache } from '@iconify/core/lib/browser-storage';
import { loadBrowserStorageCache } from '@iconify/core/lib/browser-storage/load';
import { initBrowserStorage } from '@iconify/core/lib/browser-storage';
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
import type {
IconifyBrowserCacheType,
@ -153,8 +151,7 @@ setAPIModule('', fetchAPIModule);
*/
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
// Set cache and load existing cache
cache.store = storeCache;
loadBrowserStorageCache();
initBrowserStorage();
interface WindowWithIconifyStuff {
IconifyPreload?: IconifyJSON[] | IconifyJSON;

View File

@ -57,9 +57,7 @@ import { loadIcons, loadIcon } from '@iconify/core/lib/api/icons';
import { sendAPIQuery } from '@iconify/core/lib/api/query';
// Cache
import { cache } from '@iconify/core/lib/cache';
import { storeCache } from '@iconify/core/lib/browser-storage';
import { loadBrowserStorageCache } from '@iconify/core/lib/browser-storage/load';
import { initBrowserStorage } from '@iconify/core/lib/browser-storage';
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
import type {
IconifyBrowserCacheType,
@ -150,8 +148,7 @@ setAPIModule('', fetchAPIModule);
*/
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
// Set cache and load existing cache
cache.store = storeCache;
loadBrowserStorageCache();
initBrowserStorage();
interface WindowWithIconifyStuff {
IconifyPreload?: IconifyJSON[] | IconifyJSON;

View File

@ -17,9 +17,7 @@ import { replaceIDs } from '@iconify/utils/lib/svg/id';
import { calculateSize } from '@iconify/utils/lib/svg/size';
// Cache
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 { initBrowserStorage } from '@iconify/core/lib/browser-storage';
import type {
IconifyBrowserCacheFunctions,
IconifyBrowserCacheType,
@ -150,8 +148,7 @@ setAPIModule('', fetchAPIModule);
*/
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
// Set cache and load existing cache
cache.store = storeCache;
loadBrowserStorageCache();
initBrowserStorage();
interface WindowWithIconifyStuff {
IconifyProviders?: Record<string, PartialIconifyAPIConfig>;

View File

@ -67,9 +67,7 @@ import { loadIcons, loadIcon } from '@iconify/core/lib/api/icons';
import { sendAPIQuery } from '@iconify/core/lib/api/query';
// Cache
import { cache } from '@iconify/core/lib/cache';
import { storeCache } from '@iconify/core/lib/browser-storage';
import { loadBrowserStorageCache } from '@iconify/core/lib/browser-storage/load';
import { initBrowserStorage } from '@iconify/core/lib/browser-storage';
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
import type {
IconifyBrowserCacheType,
@ -161,8 +159,7 @@ setAPIModule('', fetchAPIModule);
*/
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
// Set cache and load existing cache
cache.store = storeCache;
loadBrowserStorageCache();
initBrowserStorage();
interface WindowWithIconifyStuff {
IconifyPreload?: IconifyJSON[] | IconifyJSON;

View File

@ -60,9 +60,7 @@ import { loadIcons, loadIcon } from '@iconify/core/lib/api/icons';
import { sendAPIQuery } from '@iconify/core/lib/api/query';
// Cache
import { cache } from '@iconify/core/lib/cache';
import { storeCache } from '@iconify/core/lib/browser-storage';
import { loadBrowserStorageCache } from '@iconify/core/lib/browser-storage/load';
import { initBrowserStorage } from '@iconify/core/lib/browser-storage';
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
import type {
IconifyBrowserCacheType,
@ -152,8 +150,7 @@ setAPIModule('', fetchAPIModule);
*/
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
// Set cache and load existing cache
cache.store = storeCache;
loadBrowserStorageCache();
initBrowserStorage();
interface WindowWithIconifyStuff {
IconifyPreload?: IconifyJSON[] | IconifyJSON;

View File

@ -37,9 +37,7 @@ import { loadIcons, loadIcon } from '@iconify/core/lib/api/icons';
import { sendAPIQuery } from '@iconify/core/lib/api/query';
// Cache
import { cache } from '@iconify/core/lib/cache';
import { storeCache } from '@iconify/core/lib/browser-storage';
import { loadBrowserStorageCache } from '@iconify/core/lib/browser-storage/load';
import { initBrowserStorage } from '@iconify/core/lib/browser-storage';
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
import type {
IconifyBrowserCacheType,
@ -85,8 +83,7 @@ export function exportFunctions(): IconifyExportedFunctions {
}
if (_window) {
// Set cache and load existing cache
cache.store = storeCache;
loadBrowserStorageCache();
initBrowserStorage();
// Load icons from global "IconifyPreload"
if (_window.IconifyPreload !== void 0) {

View File

@ -93,6 +93,10 @@
"require": "./lib/browser-storage/mock.cjs",
"import": "./lib/browser-storage/mock.mjs"
},
"./lib/browser-storage/store": {
"require": "./lib/browser-storage/store.cjs",
"import": "./lib/browser-storage/store.mjs"
},
"./lib/browser-storage/types": {
"require": "./lib/browser-storage/types.cjs",
"import": "./lib/browser-storage/types.mjs"

View File

@ -1,78 +1,11 @@
import type { IconifyJSON } from '@iconify/types';
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 { cache } from '../cache';
import { loadBrowserStorageCache } from './load';
import type { BrowserStorageConfig, BrowserStorageItem } from './types';
import { storeInBrowserStorage } from './store';
/**
* Function to cache icons
* Init browser storage
*/
export const storeCache: CacheIcons = (
provider: string,
data: IconifyJSON
): void => {
if (!browserStorageLoaded) {
loadBrowserStorageCache();
}
function store(key: keyof BrowserStorageConfig): boolean {
if (!browserStorageConfig[key]) {
return false;
}
const func = getBrowserStorage(key);
if (!func) {
return false;
}
// Get item index
let index = browserStorageEmptyItems[key].shift();
if (index === void 0) {
// Create new index
index = browserStorageItemsCount[key];
if (!setBrowserStorageItemsCount(func, key, index + 1)) {
return false;
}
}
// Create and save item
try {
const item: BrowserStorageItem = {
cached: Math.floor(Date.now() / browserStorageHour),
provider,
data,
};
func.setItem(
browserCachePrefix + index.toString(),
JSON.stringify(item)
);
} catch (err) {
return false;
}
return true;
}
// Do not store empty sets
if (!Object.keys(data.icons).length) {
return;
}
// Remove not_found (clone object to keep old object intact)
if (data.not_found) {
data = Object.assign({}, data);
delete data.not_found;
}
// Attempt to store at localStorage first, then at sessionStorage
if (!store('local')) {
store('session');
}
};
export function initBrowserStorage() {
cache.store = storeInBrowserStorage;
loadBrowserStorageCache();
}

View File

@ -1,4 +1,3 @@
import type { LoadIconsCache } from '../cache';
import { addIconSet, getStorage } from '../storage/storage';
import {
browserCachePrefix,
@ -52,7 +51,7 @@ function initBrowserStorage(
/**
* Load icons from cache
*/
export const loadBrowserStorageCache: LoadIconsCache = (): void => {
export function loadBrowserStorageCache() {
if (browserStorageLoaded) {
return;
}
@ -149,4 +148,4 @@ export const loadBrowserStorageCache: LoadIconsCache = (): void => {
for (const key in browserStorageConfig) {
load(key as keyof BrowserStorageConfig);
}
};
}

View File

@ -0,0 +1,78 @@
import type { IconifyJSON } from '@iconify/types';
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';
/**
* Function to cache icons
*/
export const storeInBrowserStorage: CacheIcons = (
provider: string,
data: IconifyJSON
): void => {
if (!browserStorageLoaded) {
loadBrowserStorageCache();
}
function store(key: keyof BrowserStorageConfig): boolean {
if (!browserStorageConfig[key]) {
return false;
}
const func = getBrowserStorage(key);
if (!func) {
return false;
}
// Get item index
let index = browserStorageEmptyItems[key].shift();
if (index === void 0) {
// Create new index
index = browserStorageItemsCount[key];
if (!setBrowserStorageItemsCount(func, key, index + 1)) {
return false;
}
}
// Create and save item
try {
const item: BrowserStorageItem = {
cached: Math.floor(Date.now() / browserStorageHour),
provider,
data,
};
func.setItem(
browserCachePrefix + index.toString(),
JSON.stringify(item)
);
} catch (err) {
return false;
}
return true;
}
// Do not store empty sets
if (!Object.keys(data.icons).length) {
return;
}
// Remove not_found (clone object to keep old object intact)
if (data.not_found) {
data = Object.assign({}, data);
delete data.not_found;
}
// Attempt to store at localStorage first, then at sessionStorage
if (!store('local')) {
store('session');
}
};

View File

@ -5,17 +5,11 @@ import type { IconifyJSON } from '@iconify/types';
*/
export type CacheIcons = (provider: string, data: IconifyJSON) => void;
/**
* Function to load icons from cache
*/
export type LoadIconsCache = () => void;
/**
* Module
*/
interface CacheModule {
store?: CacheIcons;
load?: LoadIconsCache;
}
export const cache: CacheModule = {};

View File

@ -1,6 +1,6 @@
import type { IconifyJSON } from '@iconify/types';
import type { BrowserStorageItem } from '../../lib/browser-storage/types';
import { storeCache } from '../../lib/browser-storage';
import { storeInBrowserStorage } from '../../lib/browser-storage/store';
import { loadBrowserStorageCache } from '../../lib/browser-storage/load';
import {
browserStorageItemsCount,
@ -50,7 +50,7 @@ describe('Testing saving to localStorage', () => {
expect(iconExists(icons, 'foo')).toBe(false);
// Save item
storeCache(provider, icon);
storeInBrowserStorage(provider, icon);
// Storing in cache should not add item to storage
expect(iconExists(icons, 'foo')).toBe(false);
@ -116,8 +116,8 @@ describe('Testing saving to localStorage', () => {
});
// Save items
storeCache(provider, icon0);
storeCache(provider, icon1);
storeInBrowserStorage(provider, icon0);
storeInBrowserStorage(provider, icon1);
// Check data that should have been updated because storeCache()
// should call load function before first execution
@ -205,7 +205,7 @@ describe('Testing saving to localStorage', () => {
});
// Save items
storeCache(provider, icon0);
storeInBrowserStorage(provider, icon0);
// Check data
expect(browserStorageItemsCount).toEqual({
@ -316,7 +316,7 @@ describe('Testing saving to localStorage', () => {
});
// Add item 5
storeCache(provider, icons[5]);
storeInBrowserStorage(provider, icons[5]);
expect(browserStorageItemsCount).toEqual({
local: 0,
session: 9,
@ -331,7 +331,7 @@ describe('Testing saving to localStorage', () => {
const list = [4, 2, 1];
list.slice(0).forEach((index) => {
expect(list.shift()).toBe(index);
storeCache(provider, icons[index]);
storeInBrowserStorage(provider, icons[index]);
expect(browserStorageItemsCount).toEqual({
local: 0,
session: 9,
@ -344,7 +344,7 @@ describe('Testing saving to localStorage', () => {
});
// Add item 10
storeCache(provider, icons[10]);
storeInBrowserStorage(provider, icons[10]);
expect(browserStorageItemsCount).toEqual({
local: 0,
session: 10,
@ -356,7 +356,7 @@ describe('Testing saving to localStorage', () => {
expect(cache.getItem(browserCacheCountKey)).toBe('10');
// Add item 11
storeCache(provider, icons[11]);
storeInBrowserStorage(provider, icons[11]);
expect(browserStorageItemsCount).toEqual({
local: 0,
session: 11,
@ -430,7 +430,7 @@ describe('Testing saving to localStorage', () => {
};
// Save item
storeCache(provider, icon);
storeInBrowserStorage(provider, icon);
// Storing in cache should not add item to storage
expect(iconExists(icons, 'foo')).toBe(false);
@ -555,7 +555,7 @@ describe('Testing saving to localStorage', () => {
provider,
data: icon,
};
storeCache(provider, icon);
storeInBrowserStorage(provider, icon);
// Check data
expect(browserStorageItemsCount).toEqual({
@ -673,7 +673,7 @@ describe('Testing saving to localStorage', () => {
provider,
data: icon,
};
storeCache(provider, icon);
storeInBrowserStorage(provider, icon);
// Check data
expect(browserStorageItemsCount).toEqual({