Storage Utility
This `storage-utility` package, currently at version 3.1.3, provides a unified and persistent key-value storage solution for both web environments (using `localStorage` by default) and React Native applications (integrating with `AsyncStorage`). It aims to simplify cross-platform storage management. Since its 2.0.0 release, it supports time-based data expiration, allowing developers to store values with a defined lifespan, similar to HTTP cookies. A key feature introduced in version 3.0.0 is the transition to promise-based getter functions, primarily addressed through `GetItemAsync`, to robustly handle the asynchronous nature of storage engines like `AsyncStorage` and prevent race conditions encountered in earlier synchronous approaches. Additionally, the library offers a unique categorization of data into 'volatile' and 'nonVolatile' sets, enabling targeted data cleanup operations, such as clearing all user-specific 'volatile' data upon logout. It has an active release cycle, with significant updates in major versions focusing on stability, performance, and expanded functionality. Its core differentiator lies in its dual-platform support and advanced storage policies like time-based invalidation and data categorization.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'getItem')
cause The `InitializeStorageUtils` function was not called or was called with an invalid `engine` object, especially common in React Native where `AsyncStorage` needs to be provided.fixEnsure `InitializeStorageUtils` is called at application startup with a valid storage engine. For React Native, this means `InitializeStorageUtils({ engine: AsyncStorage, engineName: 'AsyncStorage' });` after importing `AsyncStorage`. -
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'then') OR GetItem returns Promise {<pending>}cause Attempting to use `GetItem` or `GetItemAsync` (post v3.0.0) in an asynchronous context (like React Native's AsyncStorage) without `await`.fixAlways `await` the result of `GetItemAsync('key')`. If using `GetItem` and encountering this, switch to `GetItemAsync` or ensure `await` is applied if `GetItem` is configured with an async engine. -
ReferenceError: AsyncStorage is not defined
cause You are attempting to use `AsyncStorage` in React Native but have not imported it or installed the necessary package (`@react-native-async-storage/async-storage`).fixInstall `@react-native-async-storage/async-storage` (`npm install @react-native-async-storage/async-storage`) and `import AsyncStorage from '@react-native-async-storage/async-storage';` in your React Native files.
Warnings
- breaking With v3.0.0, getter functions became promise-based, primarily manifesting through the introduction of `GetItemAsync`. The `GetItem` function itself might now return a Promise if configured with an asynchronous engine like AsyncStorage, which is a breaking change from its previous synchronous behavior.
- gotcha The `InitializeStorageUtils` function is critical for setting up the environment in React Native with `AsyncStorage`. Failing to call it with the correct `engine` and `engineName` will lead to runtime errors when attempting to use storage functions.
- breaking Version 2.0.0 introduced time-based storage policy via the `span` option in `SetItem`. While a feature, it changed the `SetItem` API signature by adding an options object, meaning older direct calls without the options object might behave differently or need adjustment if `span` functionality is desired.
- gotcha Data stored using `SetItem` without `isNonVolatile: true` is considered 'volatile' and can be mass-deleted by specific utility functions not detailed in the provided API. If data must persist across specific actions (like user logout), ensure it's marked as non-volatile.
Install
-
npm install storage-utility -
yarn add storage-utility -
pnpm add storage-utility
Imports
- InitializeStorageUtils
const InitializeStorageUtils = require('storage-utility').InitializeStorageUtils;import { InitializeStorageUtils } from 'storage-utility'; - SetItem
import SetItem from 'storage-utility';
import { SetItem } from 'storage-utility'; - GetItemAsync
const GetItemAsync = require('storage-utility').GetItemAsync;import { GetItemAsync } from 'storage-utility'; - GetItem
await GetItem('key'); // If used for AsyncStorage without await in v3+import { GetItem } from 'storage-utility';
Quickstart
import React, { useEffect, useState } from 'react';
import { GetItemAsync, SetItem, InitializeStorageUtils } from 'storage-utility';
import AsyncStorage from '@react-native-async-storage/async-storage'; // Ensure this is installed for RN
// This setup would typically be in your app's entry point or root component constructor
// For a browser environment, InitializeStorageUtils can often be skipped.
InitializeStorageUtils({
storeName: 'MyTestStore',
engine: AsyncStorage, // Use localStorage for web: window.localStorage
engineName: 'AsyncStorage' // Use 'localStorage' for web
});
const StorageExample = () => {
const [value, setValue] = useState(null);
const key = 'myPersistentData';
useEffect(() => {
const storeAndRetrieve = async () => {
console.log('Attempting to set item...');
// Store data that expires in 1 minute and is volatile
SetItem(key, { message: 'Hello from storage!', timestamp: Date.now() }, { span: 1, isNonVolatile: false });
console.log('Item set. Waiting for retrieval...');
// Retrieve the data using the async getter
const stored = await GetItemAsync(key);
setValue(stored);
console.log('Retrieved:', stored);
};
storeAndRetrieve();
}, []);
return (
<div>
<h1>Storage Utility Example</h1>
<p>Stored Value: {value ? JSON.stringify(value) : 'No value found or expired'}</p>
<p>Check console for logs.</p>
</div>
);
};
export default StorageExample;