@georapbox/web-storage
Version:
WebStorage is a lightweight wrapper for namespaced localStorage/sessionStorage with support for serializable values and safe, tuple-based error handling.
284 lines (180 loc) • 9.35 kB
Markdown
[](https://www.npmjs.com/package/@georapbox/web-storage)
[](https://www.npmjs.com/package/@georapbox/web-storage)
[demo]: https://georapbox.github.io/alert-element/
[license]: https://github.com/georapbox/web-storage/blob/master/LICENSE
[changelog]: https://github.com/georapbox/web-storage/blob/master/CHANGELOG.md
# WebStorage
`WebStorage` is a lightweight JavaScript library that improves how you work with `localStorage` or `sessionStorage` by providing a clean, consistent API. It supports storing and retrieving any serializable value (not just strings) by automatically handling JSON encoding and decoding internally.
A key feature of `WebStorage` is its use of namespacing via a configurable key prefix (default: `'web-storage/'`). This ensures that all stored items are scoped to your application, preventing collisions with other data in storage. For example, using a prefix like `'my-app/'` means calling clear() will only remove items with that prefix—leaving unrelated data untouched.
`WebStorage` is also designed with error handling in mind. Instead of throwing exceptions, all methods return a `[result, error]` tuple-style value allowing you to handle errors gracefully—or ignore them entirely—without needing `try...catch`.
## Install
```sh
$ npm install --save @georapbox/web-storage
```
## Import
The library is exported in ESM format.
```js
import { WebStorage } from '@georapbox/web-storage';
```
## API
## Constructor
### new WebStorage(options = {})
Creates a new instance of the `WebStorage` with the specified options. The following options can be set:
| Option | Type | Default | Description |
| ------ | ---- | ------- | ----------- |
| **driver** | `String` | "localStorage" | Specifies the storage driver to use. Accepts either "localStorage" or "sessionStorage". This determines where data will be persisted. |
| **keyPrefix** | `String` | "web-storage/" | A prefix applied to all keys stored in offline storage. It is automatically trimmed on both sides to prevent user errors. You only need to set `keyPrefix` when creating a `WebStorage` instance. After that, API methods should be used with plain keys—`keyPrefix` is applied internally. |
**Example**
```js
const myStore = new WebStorage({
driver: 'sessionStorage',
keyPrefix: 'my-storage/'
});
```
## Static methods
### WebStorage.createInstance(options = {})
Creates and returns a new `WebStorage` instance, just like the constructor. This convenience method allows you to instantiate without using the `new` keyword.
**Example**
```js
const myStore = WebStorage.createInstance({
driver: 'sessionStorage',
keyPrefix: 'my-storage/'
});
```
### WebStorage.isAvailable(storageType)
Checks if `storageType` is supported and is available.
Storage might be unavailable due to no browser support or due to being full or due to browser privacy settings.
**Returns**: `boolean` - Returns `true` if Storage available; otherwise `false`.
| Param | Type | Description |
| ----- | ---- | ----------- |
| storageType | `string` | The storage type; available values "localStorage" or "sessionStorage" |
**Usage**
```js
WebStorage.isAvailable('localStorage');
```
## Instance methods
### setItem(key, value)
Saves an item to storage with the specified key. Any value that can be serialized to JSON can be stored, including objects, arrays, strings, numbers, and booleans.
**Throws:** `TypeError` - Throws if `key` is not a string.
**Returns:** `[boolean, Error | null]` - Returns an array with two elements: the first is `true` if the item was saved successfully, or `false` if it was not, and the second is `null` if no error occurred, or an `Error` object if an error occurred.
| Param | Type | Default | Description |
| ----- | ---- | ------- | ----------- |
| key | `string` | - | The key under which to store the item. |
| value | `unknown` | - | The item to save to the selected storage. |
**Usage**
```js
const [saved, error] = myStore.setItem('somekey', { foo: 'bar' });
```
#### Note on value serialization
`WebStorage` uses `JSON.stringify()` internally to serialize values before saving them. While this supports most common JavaScript types, some special values are silently converted:
- `NaN`, `Infinity`, `-Infinity`, and `undefined` → become null
- Functions and symbols → are omitted or stored as `null/undefined`
- Circular references → will throw a `TypeError`
For example:
```js
storage.setItem('foo', NaN);
// Will be stored as: "null"
storage.getItem('foo');
// => [null, null]
```
**Why this matters:**
If you store special or non-JSON-safe values, they may not round-trip exactly as expected. This is a deliberate design decision to keep the API simple and compatible with `Storage` constraints. If needed, consider manually encoding such values before storing them.
### getItem(key)
Gets the saved item for the specified key from the storage for a specific datastore.
**Throws:** `TypeError` - Throws if `key` is not a string.
**Returns:** `[unknown, Error | null]` - Returns an array with two elements: the first is the value of the saved item, and the second is `null` if no error occurred, or an `Error` object if an error occurred.
| Param | Type | Default | Description |
| ----- | ---- | ------- | ----------- |
| key | `string` | - | The key of the item to retrieve. |
**Usage**
```js
const [value, error] = myStore.getItem('somekey');
```
### removeItem(key)
Removes the saved item for the specified key from storage.
**Throws:** `TypeError` - Throws if `key` is not a string.
**Returns:** `[boolean, Error | null]` - Returns an array with two elements: the first is `true` if the item was removed successfully, or `false` if it was not, and the second is `null` if no error occurred, or an `Error` object if an error occurred.
| Param | Type | Default | Description |
| ----- | ---- | ------- | ----------- |
| key | `string` | - | The key of the item to remove. |
**Usage**
```js
const [removed, error] = myStore.removeItem('somekey');
```
### clear()
Removes all saved items from storage for a specific datastore.
**Returns:** `[boolean, Error | null]` - Returns an array with two elements: the first is `true` if all items were removed successfully, or `false` if they were not, and the second is `null` if no error occurred, or an `Error` object if an error occurred.
**Usage**
```js
const [cleared, error] = myStore.clear();
```
### keys()
Gets all keys (unprefixed) of saved items in a specific datastore.
**Returns:** `[string[], Error | null]` - Returns an array with two elements: the first is an array of keys (without the prefix) for the saved items, and the second is `null` if no error occurred, or an `Error` object if an error occurred.
**Usage**
```js
const [keys, error] = myStore.keys();
```
### length()
Gets the number of saved items in a specific datastore.
**Returns:** `[number, Error | null]` - Returns an array with two elements: the first is the number of items saved in the datastore, and the second is `null` if no error occurred, or an `Error` object if an error occurred.
**Usage**
```js
const [len, error] = myStore.length();
```
### iterate(iteratorCallback)
Iterates over all saved items in storage for a specific datastore and execute a callback function for each key-value pair.
> [ ]
> `iterate` does not guarantee the order of iteration. The order may vary depending on the browser implementation and storage driver used.
**Throws:** `TypeError` - Throws if `callback` is not a function.
**Returns:** `[boolean, Error | null]` - Returns an array with two elements: the first is `true` if the iteration was successful, or `false` if it was not, and the second is `null` if no error occurred, or an `Error` object if an error occurred.
| Param | Type | Default | Description |
| ----- | ---- | ------- | ----------- |
| iteratorCallback | `(value: unknown, key: string) => void` | - | A callabck function to be executed for each iteration |
**Usage**
```js
const [iterated, error] = myStore.iterate((value, key) => {
console.log(value, key);
});
```
## Development
Below are the instructions for setting up the development environment.
### Prerequisites
- Node.js (v22.x.x)
- npm (v10.x.x)
### Installation
Clone the repository and install the dependencies:
```sh
$ git clone git@github.com:georapbox/web-storage.git
$ cd web-storage
$ npm install
```
### Build for development
Build the library for development and watch for any changes to the source files:
```sh
$ npm run dev
```
### Build for production
Build the library for production. This will create a minified version of the library in the `dist` directory.
```sh
$ npm run build
```
### Test
Run the tests to ensure everything is working correctly:
```sh
$ npm test
```
### Test with coverage
Generate a test coverage report. This will run the tests and generate a coverage report in the `coverage` directory.
```sh
$ npm run test:coverage
```
### Linting
Run the linter to check for any code style issues:
```sh
$ npm run lint
```
## Changelog
For API updates and breaking changes, check the [CHANGELOG][changelog].
## License
[The MIT License (MIT)][license]