From 09d7ec3161b6db411d076d495ad86eb4231bccca Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Thu, 15 Jul 2021 12:28:18 -0500 Subject: [PATCH] Remove unused IndexedDB reads https://github.com/mastodon/mastodon/pull/14730 --- app/soapbox/actions/accounts.js | 39 +---- app/soapbox/actions/statuses.js | 69 +-------- app/soapbox/reducers/accounts.js | 2 - app/soapbox/service_worker/entry.js | 31 +--- app/soapbox/storage/db.js | 27 ---- app/soapbox/storage/modifier.js | 211 ---------------------------- 6 files changed, 12 insertions(+), 367 deletions(-) delete mode 100644 app/soapbox/storage/db.js delete mode 100644 app/soapbox/storage/modifier.js diff --git a/app/soapbox/actions/accounts.js b/app/soapbox/actions/accounts.js index 5908f01f1..307d98a39 100644 --- a/app/soapbox/actions/accounts.js +++ b/app/soapbox/actions/accounts.js @@ -1,7 +1,5 @@ import api, { getLinks } from '../api'; -import openDB from '../storage/db'; import { - importAccount, importFetchedAccount, importFetchedAccounts, importErrorWhileFetchingAccountByUsername, @@ -96,24 +94,6 @@ export const NOTIFICATION_SETTINGS_REQUEST = 'NOTIFICATION_SETTINGS_REQUEST'; export const NOTIFICATION_SETTINGS_SUCCESS = 'NOTIFICATION_SETTINGS_SUCCESS'; export const NOTIFICATION_SETTINGS_FAIL = 'NOTIFICATION_SETTINGS_FAIL'; -function getFromDB(dispatch, getState, index, id) { - return new Promise((resolve, reject) => { - const request = index.get(id); - - request.onerror = reject; - - request.onsuccess = () => { - if (!request.result) { - reject(); - return; - } - - dispatch(importAccount(request.result)); - resolve(request.result.moved && getFromDB(dispatch, getState, index, request.result.moved)); - }; - }); -} - export function createAccount(params) { return (dispatch, getState) => { dispatch({ type: ACCOUNT_CREATE_REQUEST, params }); @@ -138,18 +118,9 @@ export function fetchAccount(id) { dispatch(fetchAccountRequest(id)); - openDB().then(db => getFromDB( - dispatch, - getState, - db.transaction('accounts', 'read').objectStore('accounts').index('id'), - id, - ).then(() => db.close(), error => { - db.close(); - throw error; - })).catch(() => api(getState).get(`/api/v1/accounts/${id}`).then(response => { + api(getState).get(`/api/v1/accounts/${id}`).then(response => { dispatch(importFetchedAccount(response.data)); - })).then(() => { - dispatch(fetchAccountSuccess()); + dispatch(fetchAccountSuccess(response.data)); }).catch(error => { dispatch(fetchAccountFail(id, error)); }); @@ -168,8 +139,7 @@ export function fetchAccountByUsername(username) { api(getState).get(`/api/v1/accounts/${username}`).then(response => { dispatch(fetchRelationships([response.data.id])); dispatch(importFetchedAccount(response.data)); - }).then(() => { - dispatch(fetchAccountSuccess()); + dispatch(fetchAccountSuccess(response.data)); }).catch(error => { dispatch(fetchAccountFail(null, error)); dispatch(importErrorWhileFetchingAccountByUsername(username)); @@ -184,9 +154,10 @@ export function fetchAccountRequest(id) { }; }; -export function fetchAccountSuccess() { +export function fetchAccountSuccess(account) { return { type: ACCOUNT_FETCH_SUCCESS, + account, }; }; diff --git a/app/soapbox/actions/statuses.js b/app/soapbox/actions/statuses.js index a9123cd64..0c6dd73ab 100644 --- a/app/soapbox/actions/statuses.js +++ b/app/soapbox/actions/statuses.js @@ -1,8 +1,6 @@ import api from '../api'; -import openDB from '../storage/db'; -import { evictStatus } from '../storage/modifier'; import { deleteFromTimelines } from './timelines'; -import { importFetchedStatus, importFetchedStatuses, importAccount, importStatus } from './importer'; +import { importFetchedStatus, importFetchedStatuses } from './importer'; import { openModal } from './modal'; import { isLoggedIn } from 'soapbox/utils/auth'; @@ -59,48 +57,6 @@ export function createStatus(params, idempotencyKey) { }; }; -function getFromDB(dispatch, getState, accountIndex, index, id) { - return new Promise((resolve, reject) => { - const request = index.get(id); - - request.onerror = reject; - - request.onsuccess = () => { - const promises = []; - - if (!request.result) { - reject(); - return; - } - - dispatch(importStatus(request.result)); - - if (getState().getIn(['accounts', request.result.account], null) === null) { - promises.push(new Promise((accountResolve, accountReject) => { - const accountRequest = accountIndex.get(request.result.account); - - accountRequest.onerror = accountReject; - accountRequest.onsuccess = () => { - if (!request.result) { - accountReject(); - return; - } - - dispatch(importAccount(accountRequest.result)); - accountResolve(); - }; - })); - } - - if (request.result.reblog && getState().getIn(['statuses', request.result.reblog], null) === null) { - promises.push(getFromDB(dispatch, getState, accountIndex, index, request.result.reblog)); - } - - resolve(Promise.all(promises)); - }; - }); -} - export function fetchStatus(id) { return (dispatch, getState) => { const skipLoading = getState().getIn(['statuses', id], null) !== null; @@ -113,31 +69,19 @@ export function fetchStatus(id) { dispatch(fetchStatusRequest(id, skipLoading)); - openDB().then(db => { - const transaction = db.transaction(['accounts', 'statuses'], 'read'); - const accountIndex = transaction.objectStore('accounts').index('id'); - const index = transaction.objectStore('statuses').index('id'); - - return getFromDB(dispatch, getState, accountIndex, index, id).then(() => { - db.close(); - }, error => { - db.close(); - throw error; - }); - }).then(() => { - dispatch(fetchStatusSuccess(skipLoading)); - }, () => api(getState).get(`/api/v1/statuses/${id}`).then(response => { + api(getState).get(`/api/v1/statuses/${id}`).then(response => { dispatch(importFetchedStatus(response.data)); - dispatch(fetchStatusSuccess(skipLoading)); - })).catch(error => { + dispatch(fetchStatusSuccess(response.data, skipLoading)); + }).catch(error => { dispatch(fetchStatusFail(id, error, skipLoading)); }); }; }; -export function fetchStatusSuccess(skipLoading) { +export function fetchStatusSuccess(status, skipLoading) { return { type: STATUS_FETCH_SUCCESS, + status, skipLoading, }; }; @@ -173,7 +117,6 @@ export function deleteStatus(id, routerHistory, withRedraft = false) { dispatch(deleteStatusRequest(id)); api(getState).delete(`/api/v1/statuses/${id}`).then(response => { - evictStatus(id); dispatch(deleteStatusSuccess(id)); dispatch(deleteFromTimelines(id)); diff --git a/app/soapbox/reducers/accounts.js b/app/soapbox/reducers/accounts.js index b366702d2..943f0002c 100644 --- a/app/soapbox/reducers/accounts.js +++ b/app/soapbox/reducers/accounts.js @@ -26,8 +26,6 @@ import { ADMIN_REMOVE_PERMISSION_GROUP_REQUEST, ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS, ADMIN_REMOVE_PERMISSION_GROUP_FAIL, -} from 'soapbox/actions/admin'; -import { ADMIN_USERS_DELETE_REQUEST, ADMIN_USERS_DELETE_FAIL, ADMIN_USERS_DEACTIVATE_REQUEST, diff --git a/app/soapbox/service_worker/entry.js b/app/soapbox/service_worker/entry.js index db15c8b2f..1147f003f 100644 --- a/app/soapbox/service_worker/entry.js +++ b/app/soapbox/service_worker/entry.js @@ -1,10 +1,5 @@ -// import { freeStorage, storageFreeable } from '../storage/modifier'; import './web_push_notifications'; -// function openSystemCache() { -// return caches.open('soapbox-system'); -// } - function openWebCache() { return caches.open('soapbox-web'); } @@ -13,9 +8,6 @@ function fetchRoot() { return fetch('/', { credentials: 'include', redirect: 'manual' }); } -// const firefox = navigator.userAgent.match(/Firefox\/(\d+)/); -// const invalidOnlyIfCached = firefox && firefox[1] < 60; - // Cause a new version of a registered Service Worker to replace an existing one // that is already installed, and replace the currently active worker on open pages. self.addEventListener('install', function(event) { @@ -81,26 +73,5 @@ self.addEventListener('fetch', function(event) { return response; }, () => asyncCache.then(cache => cache.match('/')))); - } /* else if (storageFreeable && (ATTACHMENT_HOST ? url.host === ATTACHMENT_HOST : url.pathname.startsWith('/system/'))) { - event.respondWith(openSystemCache().then(cache => { - return cache.match(event.request.url).then(cached => { - if (cached === undefined) { - const asyncResponse = invalidOnlyIfCached && event.request.cache === 'only-if-cached' ? - fetch(event.request, { cache: 'no-cache' }) : fetch(event.request); - - return asyncResponse.then(response => { - if (response.ok) { - cache - .put(event.request.url, response.clone()) - .catch(()=>{}).then(freeStorage()).catch(); - } - - return response; - }); - } - - return cached; - }); - })); - } */ + } }); diff --git a/app/soapbox/storage/db.js b/app/soapbox/storage/db.js deleted file mode 100644 index 0620a0b3a..000000000 --- a/app/soapbox/storage/db.js +++ /dev/null @@ -1,27 +0,0 @@ -export default () => new Promise((resolve, reject) => { - // ServiceWorker is required to synchronize the login state. - // Microsoft Edge 17 does not support getAll according to: - // Catalog of standard and vendor APIs across browsers - Microsoft Edge Development - // https://developer.microsoft.com/en-us/microsoft-edge/platform/catalog/?q=specName%3Aindexeddb - if (!('caches' in self && 'getAll' in IDBObjectStore.prototype)) { - reject(); - return; - } - - const request = indexedDB.open('soapbox'); - - request.onerror = reject; - request.onsuccess = ({ target }) => resolve(target.result); - - request.onupgradeneeded = ({ target }) => { - const accounts = target.result.createObjectStore('accounts', { autoIncrement: true }); - const statuses = target.result.createObjectStore('statuses', { autoIncrement: true }); - - accounts.createIndex('id', 'id', { unique: true }); - accounts.createIndex('moved', 'moved'); - - statuses.createIndex('id', 'id', { unique: true }); - statuses.createIndex('account', 'account'); - statuses.createIndex('reblog', 'reblog'); - }; -}); diff --git a/app/soapbox/storage/modifier.js b/app/soapbox/storage/modifier.js deleted file mode 100644 index 74bf3cb5b..000000000 --- a/app/soapbox/storage/modifier.js +++ /dev/null @@ -1,211 +0,0 @@ -import openDB from './db'; - -const accountAssetKeys = ['avatar', 'avatar_static', 'header', 'header_static']; -const storageMargin = 8388608; -const storeLimit = 1024; - -// navigator.storage is not present on: -// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.100 Safari/537.36 Edge/16.16299 -// estimate method is not present on Chrome 57.0.2987.98 on Linux. -export const storageFreeable = 'storage' in navigator && 'estimate' in navigator.storage; - -function openCache() { - // ServiceWorker and Cache API is not available on iOS 11 - // https://webkit.org/status/#specification-service-workers - return self.caches ? caches.open('soapbox-system') : Promise.reject(); -} - -function printErrorIfAvailable(error) { - if (error) { - console.warn(error); - } -} - -function put(name, objects, onupdate, oncreate) { - return openDB().then(db => (new Promise((resolve, reject) => { - const putTransaction = db.transaction(name, 'readwrite'); - const putStore = putTransaction.objectStore(name); - const putIndex = putStore.index('id'); - - objects.forEach(object => { - putIndex.getKey(object.id).onsuccess = retrieval => { - function addObject() { - putStore.add(object); - } - - function deleteObject() { - putStore.delete(retrieval.target.result).onsuccess = addObject; - } - - if (retrieval.target.result) { - if (onupdate) { - onupdate(object, retrieval.target.result, putStore, deleteObject); - } else { - deleteObject(); - } - } else { - if (oncreate) { - oncreate(object, addObject); - } else { - addObject(); - } - } - }; - }); - - putTransaction.oncomplete = () => { - const readTransaction = db.transaction(name, 'readonly'); - const readStore = readTransaction.objectStore(name); - const count = readStore.count(); - - count.onsuccess = () => { - const excess = count.result - storeLimit; - - if (excess > 0) { - const retrieval = readStore.getAll(null, excess); - - retrieval.onsuccess = () => resolve(retrieval.result); - retrieval.onerror = reject; - } else { - resolve([]); - } - }; - - count.onerror = reject; - }; - - putTransaction.onerror = reject; - })).then(resolved => { - db.close(); - return resolved; - }, error => { - db.close(); - throw error; - })); -} - -function evictAccountsByRecords(records) { - return openDB().then(db => { - const transaction = db.transaction(['accounts', 'statuses'], 'readwrite'); - const accounts = transaction.objectStore('accounts'); - const accountsIdIndex = accounts.index('id'); - const accountsMovedIndex = accounts.index('moved'); - const statuses = transaction.objectStore('statuses'); - const statusesIndex = statuses.index('account'); - - function evict(toEvict) { - toEvict.forEach(record => { - openCache() - .then(cache => accountAssetKeys.forEach(key => cache.delete(records[key]))) - .catch(printErrorIfAvailable); - - accountsMovedIndex.getAll(record.id).onsuccess = ({ target }) => evict(target.result); - - statusesIndex.getAll(record.id).onsuccess = - ({ target }) => evictStatusesByRecords(target.result); - - accountsIdIndex.getKey(record.id).onsuccess = - ({ target }) => target.result && accounts.delete(target.result); - }); - } - - evict(records); - - db.close(); - }).catch(printErrorIfAvailable); -} - -export function evictStatus(id) { - evictStatuses([id]); -} - -export function evictStatuses(ids) { - return openDB().then(db => { - const transaction = db.transaction('statuses', 'readwrite'); - const store = transaction.objectStore('statuses'); - const idIndex = store.index('id'); - const reblogIndex = store.index('reblog'); - - ids.forEach(id => { - reblogIndex.getAllKeys(id).onsuccess = - ({ target }) => target.result.forEach(reblogKey => store.delete(reblogKey)); - - idIndex.getKey(id).onsuccess = - ({ target }) => target.result && store.delete(target.result); - }); - - db.close(); - }).catch(printErrorIfAvailable); -} - -function evictStatusesByRecords(records) { - return evictStatuses(records.map(({ id }) => id)); -} - -export function putAccounts(records, avatarStatic) { - const avatarKey = avatarStatic ? 'avatar_static' : 'avatar'; - const newURLs = []; - - put('accounts', records, (newRecord, oldKey, store, oncomplete) => { - store.get(oldKey).onsuccess = ({ target }) => { - accountAssetKeys.forEach(key => { - const newURL = newRecord[key]; - const oldURL = target.result[key]; - - if (newURL !== oldURL) { - openCache() - .then(cache => cache.delete(oldURL)) - .catch(printErrorIfAvailable); - } - }); - - const newURL = newRecord[avatarKey]; - const oldURL = target.result[avatarKey]; - - if (newURL !== oldURL) { - newURLs.push(newURL); - } - - oncomplete(); - }; - }, (newRecord, oncomplete) => { - newURLs.push(newRecord[avatarKey]); - oncomplete(); - }).then(records => Promise.all([ - evictAccountsByRecords(records), - openCache().then(cache => cache.addAll(newURLs)), - ])).then(freeStorage, error => { - freeStorage(); - throw error; - }).catch(printErrorIfAvailable); -} - -export function putStatuses(records) { - put('statuses', records) - .then(evictStatusesByRecords) - .catch(printErrorIfAvailable); -} - -export function freeStorage() { - return storageFreeable && navigator.storage.estimate().then(({ quota, usage }) => { - if (usage + storageMargin < quota) { - return null; - } - - return openDB().then(db => new Promise((resolve, reject) => { - const retrieval = db.transaction('accounts', 'readonly').objectStore('accounts').getAll(null, 1); - - retrieval.onsuccess = () => { - if (retrieval.result.length > 0) { - resolve(evictAccountsByRecords(retrieval.result).then(freeStorage)); - } else { - resolve(caches.delete('soapbox-system')); - } - }; - - retrieval.onerror = reject; - - db.close(); - })); - }); -}