UNPKG

@febkosq8/local-save

Version:

Lightweight wrapper around IndexedDB for secure and structured client-side data storage.

154 lines (110 loc) • 6.43 kB
<div align="center"> <p> <a href="https://local-save.febkosq8.me/"><img src="https://github.com/febkosq8/local-save/blob/main/src/assets/local-save_transparent_trimmed.png?raw=true" width="400" alt="local-save" /></a> </p> <p> <a href="https://www.npmjs.com/package/@febkosq8/local-save"> <img alt="NPM Version" src="https://img.shields.io/npm/v/%40febkosq8%2Flocal-save"></a> <a href="https://www.npmjs.com/package/@febkosq8/local-save"> <img alt="NPM Downloads" src="https://img.shields.io/npm/dm/%40febkosq8%2Flocal-save"></a> </p> </div> `local-save` is a lightweight wrapper around IndexedDB for secure and structured client-side data storage. It provides encryption, expiration, and organized data storage across configurable categories. --- #### Looking to experience how `local-save` can securely store and retrieve data? šŸ‘‰ **[Try the Live Demo](https://local-save.febkosq8.me/)** šŸ‘ˆ ## Features - **Lightweight & Widespread Support:** No external dependencies and works in all modern browsers. - **TypeScript Support :** Written in TypeScript for maximum type-safety and a great developer experience. - **Encryption Support :** Uses [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto) for secure data encryption with [AES-GCM](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/encrypt#aes-gcm) algorithm. - **Category Management :** Organize data into predefined categories. - **Data Expiry :** Allows setting an expiration threshold for data and a method to clear expired data. - **IndexedDB Management :** Handles IndexedDB, object store creation and IndexedDB versioning management automatically. - **Logging :** Debug logs for detailed insights. --- ## Installation ```bash npm install @febkosq8/local-save # or pnpm add @febkosq8/local-save ``` --- ## Usage ### Configuration Options | Option Key | Type | Default | Description | | ----------------------------- | ---------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | **_dbName_** | `string` | `"LocalSave"` | Name of the IndexedDB database. | | **_encryptionKey_** | `string` | `undefined` | Encryption key that should be either [16, 24, or 32] characters to be used for AES-GCM encryption. If not provided, data will be stored in plain text. | | **_categories_** | `string[]` | `["userData"]` | Array of categories (Object store names). | | **_expiryThreshold_** | `number` | `2592000000` | Data expiration threshold in milliseconds. | | **_blockedTimeoutThreshold_** | `number` | `10000` | Timeout in milliseconds before blocked IndexedDB open/delete requests fail. | | **_clearOnDecryptError_** | `boolean` | `true` | Whether to clear a category if decryption fails. | | **_printLogs_** | `boolean` | `false` | Whether to print logs (Debug and errors). | ### Initialization Create a new instance of `LocalSave` with the available configuration options ```typescript import LocalSave from "@febkosq8/local-save"; ... const localSaveConfig = { encryptionKey: "MyRandEncryptKeyThatIs32CharLong", // Encryption key for data categories: ["userData", "settings"], // Define categories for data storage expiryThreshold: 14 * 24 * 60 * 60 * 1000, // Clear data older than 14 days (in ms) blockedTimeoutThreshold: 15000, // Wait up to 15s when IndexedDB requests are blocked }; const localSave = new LocalSave(localSaveConfig); ``` ### Storing data Store data in a category _Here `userData` is the category. The key is `user001` for the data `{ name: "John Doe", age: 30 }`._ ```typescript await localSave.set('userData', 'user001', { name: 'John Doe', age: 30 }); ``` ### List saved data keys in a category List all keys of the data stored in a category ```typescript const keys = await localSave.listKeys('userData'); console.log(keys); // ['user001'] ``` ### Fetching data Fetch data from a category using the `category` and `key` _The data will be returned along with the timestamp when it was stored. If the data is expired, it will return `null`._ ```typescript try { const localDataFetch = await localSave.get('userData', 'user001'); const { timestamp, data } = localDataFetch; console.log(data); // { name: "John Doe", age: 30 } console.log(timestamp); // UNIX timestamp of calling `set` method //handle data here } catch (error) { //Error will be thrown if the decryption fails //handle error here } ``` ### Removing data Remove data using the `category` and `key` ```typescript await localSave.remove('userData', 'user001'); ``` ### Clearing a category Clear all data from a `category` ```typescript await localSave.clear('userData'); ``` ### Clearing expired data Clear all expired data from all categories ```typescript // If a value is provided, it will override the default expiry threshold // This can be placed on top of the file to clear expired data on page load await localSave.expire(14 * 24 * 60 * 60 * 1000); // Clear data older than 14 days from all categories (in ms) ``` ### Destroying the entire database Clear all data from all categories and delete the database ```typescript await localSave.destroy(); ``` ### Decrypting data manually Decrypt data using the encryption key This is useful when you want to decrypt the `DBItemEncryptedBase64` string manually without using the `get` method ```typescript const decryptedData = await localSave.decryptData(DBItemEncryptedBase64); ```