From b1c86f21427af5766a544a4255dbc73c589f6efb Mon Sep 17 00:00:00 2001 From: Lei Nelissen Date: Mon, 27 Jan 2025 17:21:44 +0100 Subject: [PATCH] fix: save store file to filesystem AsyncStorage can only save 2MB on Android. This might not be enough for large libraries. Hence, we'll save the file to disk, where space is (virtually) unlimited --- package-lock.json | 4 +-- package.json | 2 +- src/store/index.ts | 6 ++-- src/utility/MigratedStorage.ts | 51 ++++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 src/utility/MigratedStorage.ts diff --git a/package-lock.json b/package-lock.json index 9862386..5d1d31d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "fintunes", - "version": "2.4.0", + "version": "2.4.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "fintunes", - "version": "2.4.0", + "version": "2.4.1", "hasInstallScript": true, "dependencies": { "@react-native-async-storage/async-storage": "^1.21.0", diff --git a/package.json b/package.json index 5197c9b..7390b1f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fintunes", - "version": "2.4.0", + "version": "2.4.1", "main": "src/index.js", "private": true, "scripts": { diff --git a/src/store/index.ts b/src/store/index.ts index 67ffbe8..ec87c46 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,6 +1,5 @@ import { configureStore, combineReducers } from '@reduxjs/toolkit'; import { useSelector, TypedUseSelectorHook, useDispatch } from 'react-redux'; -import AsyncStorage from '@react-native-async-storage/async-storage'; import { persistStore, persistReducer, PersistConfig, createMigrate, PersistState } from 'redux-persist'; import autoMergeLevel2 from 'redux-persist/es/stateReconciler/autoMergeLevel2'; @@ -9,10 +8,11 @@ import music, { initialState as musicInitialState } from './music'; import downloads, { initialState as downloadsInitialState } from './downloads'; import sleepTimer from './sleep-timer'; import { ColorScheme } from './settings/types'; +import MigratedStorage from '@/utility/MigratedStorage'; const persistConfig: PersistConfig> = { key: 'root', - storage: AsyncStorage, + storage: MigratedStorage, version: 2, stateReconciler: autoMergeLevel2, migrate: createMigrate({ @@ -80,7 +80,7 @@ const persistConfig: PersistConfig> = { credentials, }, }; - } + }, }) }; diff --git a/src/utility/MigratedStorage.ts b/src/utility/MigratedStorage.ts new file mode 100644 index 0000000..38ea13f --- /dev/null +++ b/src/utility/MigratedStorage.ts @@ -0,0 +1,51 @@ +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { DocumentDirectoryPath, exists, readFile, writeFile, unlink, mkdir } from 'react-native-fs'; +import { Storage } from 'redux-persist'; + +const STORAGE_BASE_PATH = DocumentDirectoryPath + '/store/'; + +/** Retrieve the path of a store file for a given key */ +function getFileByKey(key: string) { + return STORAGE_BASE_PATH + encodeURIComponent(key) + '.json'; +} + +/** Ensure that the store directory exists on the local filesystem */ +async function ensureDirectoryExists() { + if (!(await exists(STORAGE_BASE_PATH))) { + await mkdir(STORAGE_BASE_PATH); + } +} + +/** + * Migrates the Redux store from AsyncStorage to react-native-fs. + */ +const MigratedStorage: Storage = { + async getItem(key) { + const path = getFileByKey(key); + + // GUARD: Check whether a store already exists on the filesystem + if (await exists(path)) { + // In which case, we'll read it from disk + return readFile(path); + } else { + // If not, attempt to read the previous store from AsyncStorage + const oldStore = await AsyncStorage.getItem(key); + + // GUARD: If it exists, migrate it to a file on the filesystem + if (oldStore) { + await ensureDirectoryExists(); + await writeFile(path, oldStore); + return oldStore; + } + } + }, + removeItem(key) { + return unlink(getFileByKey(key)); + }, + async setItem(key, value) { + await ensureDirectoryExists(); + return writeFile(getFileByKey(key), value); + }, +}; + +export default MigratedStorage; \ No newline at end of file