diff options
-rw-r--r-- | package-lock.json | 8 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | source/background.ts | 1 | ||||
-rw-r--r-- | source/features/clean-issue-filters.tsx | 35 | ||||
-rw-r--r-- | source/features/releases-tab.tsx | 2 | ||||
-rw-r--r-- | source/libs/cache.ts | 69 | ||||
-rw-r--r-- | source/libs/get-default-branch.ts | 2 |
7 files changed, 40 insertions, 79 deletions
diff --git a/package-lock.json b/package-lock.json index b39362ad..904722c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12994,6 +12994,14 @@ "resolved": "https://registry.npmjs.org/webext-options-sync/-/webext-options-sync-0.15.5.tgz", "integrity": "sha512-Xrmp0Ri13/AY57YCqQA0qajCKpAE2cZ+sDI+d0maMlVz4M3k1i175nbDOHexKd+JdKYNIRW2Nx+XWJtuPyAF1w==" }, + "webext-storage-cache": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/webext-storage-cache/-/webext-storage-cache-0.0.0.tgz", + "integrity": "sha512-ZwBQLPHrETO5uf81Cw4iTr75KaQj5vGs8vW3LXfm1pl3FitflGMB2h/x1zEs8c5nkGJWseD6sF3dftx4XJ2ZgA==", + "requires": { + "webext-detect-page": "^0.9.1" + } + }, "webextension-polyfill": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/webextension-polyfill/-/webextension-polyfill-0.4.0.tgz", diff --git a/package.json b/package.json index 64de18bf..212ac2fe 100644 --- a/package.json +++ b/package.json @@ -38,10 +38,10 @@ "shorten-repo-url": "^1.5.1", "tiny-version-compare": "^1.0.0", "type-fest": "^0.4.1", - "webext-detect-page": "^0.9.1", "webext-domain-permission-toggle": "^0.1.0", "webext-dynamic-content-scripts": "^5.0.2-0", "webext-options-sync": "^0.15.5", + "webext-storage-cache": "0.0.0", "webextension-polyfill": "^0.4.0", "zip-text-nodes": "^1.0.0-0" }, diff --git a/source/background.ts b/source/background.ts index 5d3200c7..1d10de83 100644 --- a/source/background.ts +++ b/source/background.ts @@ -1,6 +1,5 @@ import {addContextMenu} from 'webext-domain-permission-toggle'; import {addToFutureTabs} from 'webext-dynamic-content-scripts'; -import './libs/cache'; import './options-storage'; browser.runtime.onMessage.addListener(async message => { diff --git a/source/features/clean-issue-filters.tsx b/source/features/clean-issue-filters.tsx index befed5e6..608bd6dd 100644 --- a/source/features/clean-issue-filters.tsx +++ b/source/features/clean-issue-filters.tsx @@ -1,10 +1,23 @@ import select from 'select-dom'; +import cache from 'webext-storage-cache'; import features from '../libs/features'; import * as api from '../libs/api'; import {getOwnerAndRepo} from '../libs/utils'; -async function init(): Promise<void> { +interface CacheEntry { + repoProjectCount: number; + orgProjectCount: number; + milestoneCount: number; +} + +async function getCount(): Promise<CacheEntry> { const {ownerName, repoName} = getOwnerAndRepo(); + const cacheKey = `clean-issue-filters:${ownerName}/${repoName}`; + const cachedData = await cache.get<CacheEntry>(cacheKey); + if (cachedData) { + return cachedData; + } + const result = await api.v4(` query { repository(owner: "${ownerName}", name: "${repoName}") { @@ -19,16 +32,26 @@ async function init(): Promise<void> { allowErrors: true }); + const cacheEntry = { + repoProjectCount: result.repository.projects.totalCount, + orgProjectCount: result.organization ? result.organization.projects.totalCount : 0, + milestoneCount: result.repository.milestones.totalCount + }; + + cache.set(cacheKey, cacheEntry, 1); + return cacheEntry; +} + +async function init(): Promise<void> { + const {repoProjectCount, orgProjectCount, milestoneCount} = await getCount(); + // If the repo and organization has no projects, its selector will be empty - if ( - result.repository.projects.totalCount === 0 && - (!result.organization || result.organization.projects.totalCount === 0) - ) { + if (repoProjectCount === 0 && orgProjectCount === 0 && select.exists('[data-hotkey="p"')) { select('[data-hotkey="p"')!.parentElement!.remove(); } // If the repo has no milestones, its selector will be empty - if (result.repository.milestones.totalCount === 0) { + if (milestoneCount === 0 && select.exists('[data-hotkey="m"')) { select('[data-hotkey="m"')!.parentElement!.remove(); } } diff --git a/source/features/releases-tab.tsx b/source/features/releases-tab.tsx index c97072a9..22211601 100644 --- a/source/features/releases-tab.tsx +++ b/source/features/releases-tab.tsx @@ -1,9 +1,9 @@ import React from 'dom-chef'; import select from 'select-dom'; import elementReady from 'element-ready'; +import cache from 'webext-storage-cache'; import features from '../libs/features'; import * as icons from '../libs/icons'; -import cache from '../libs/cache'; import {getRepoURL} from '../libs/utils'; import {isRepoRoot, isReleasesOrTags} from '../libs/page-detect'; diff --git a/source/libs/cache.ts b/source/libs/cache.ts deleted file mode 100644 index fe2acd8f..00000000 --- a/source/libs/cache.ts +++ /dev/null @@ -1,69 +0,0 @@ -import {isBackgroundPage} from 'webext-detect-page'; - -interface CacheItem<TValue extends unknown = unknown> { - data: TValue; - expiration: number; -} - -const storage: browser.storage.StorageArea = browser.storage.local; - -async function has(key: string): Promise<boolean> { - const cachedKey = `cache:${key}`; - const values = await storage.get(cachedKey); - return values[cachedKey] !== undefined; -} - -async function get<TValue extends unknown = unknown>(key: string): Promise<TValue | undefined> { - const cachedKey = `cache:${key}`; - const values = await storage.get(cachedKey); - const value = values[cachedKey] as CacheItem<TValue>; - // If it's not in the cache, it's best to return "undefined" - if (value === undefined) { - return undefined; - } - - if (Date.now() > value.expiration) { - await storage.remove(cachedKey); - return undefined; - } - - console.log('CACHE: found', key, value.data); - return value.data; -} - -function set<TValue extends unknown = unknown>(key: string, value: TValue, expiration: number /* in days */): Promise<void> { - console.log('CACHE: setting', key, value); - const cachedKey = `cache:${key}`; - return storage.set({ - [cachedKey]: { - data: value, - expiration: Date.now() + (1000 * 3600 * 24 * expiration) - } - }); -} - -async function purge(): Promise<void> { - const values = await storage.get(); - const removableItems = []; - for (const [key, value] of Object.entries(values)) { - if (key.startsWith('cache:') && Date.now() > (value as CacheItem).expiration) { - removableItems.push(key); - } - } - - if (removableItems.length > 0) { - await storage.remove(removableItems); - } -} - -// Automatically clear cache every day -if (isBackgroundPage()) { - setTimeout(purge, 60000); // Purge cache on launch, but wait a bit - setInterval(purge, 1000 * 3600 * 24); -} - -export default { - has, - get, - set -}; diff --git a/source/libs/get-default-branch.ts b/source/libs/get-default-branch.ts index 859be3e2..cf2722f9 100644 --- a/source/libs/get-default-branch.ts +++ b/source/libs/get-default-branch.ts @@ -1,5 +1,5 @@ import select from 'select-dom'; -import cache from './cache'; +import cache from 'webext-storage-cache'; import * as api from './api'; import {getOwnerAndRepo} from './utils'; |