Skip to content

Commit 1b90dab

Browse files
committed
Update documentation, adding note for value serialization
1 parent 3815405 commit 1b90dab

File tree

4 files changed

+69
-44
lines changed

4 files changed

+69
-44
lines changed

CHANGELOG.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@
55
### BREAKING CHANGES
66

77
- The `WebStorage` module is now exclusively available as an ES module (ESM), aligning with the modern JavaScript module standard. Additionally, it is no longer the default export — you must import it using a named import.
8-
**v2.x.x**
9-
```js
10-
import WebStorage from '@georapbox/web-storage';
11-
```
12-
13-
**v3.x.x**
14-
```js
15-
import { WebStorage } from '@georapbox/web-storage';
16-
```
8+
**v2.x.x**
9+
```js
10+
import WebStorage from '@georapbox/web-storage';
11+
```
12+
13+
**v3.x.x**
14+
```js
15+
import { WebStorage } from '@georapbox/web-storage';
16+
```
1717
- All API methods now return `[value, error]` tuple-like values instead of accepting error callbacks.
18-
This allows developers to handle errors in a clean, synchronous style without using `try/catch` or providing callbacks. For example:
18+
This allows developers to handle errors in a clean, synchronous style without using `try/catch` or providing callbacks. For example:
19+
1920
**v2.x.x**
2021
```js
2122
const value = storage.getItem('key', value, (err) => {

README.md

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,44 +83,66 @@ WebStorage.isAvailable('localStorage');
8383

8484
## Instance methods
8585

86-
### getItem(key)
86+
### setItem(key, value)
8787

88-
Gets the saved item for the specified key from the storage for a specific datastore.
88+
Saves an item to storage with the specified key. You can store items of any of the following data types as long as data can be serialized to JSON.
89+
90+
- String
91+
- Number
92+
- Array
93+
- Object
8994

9095
**Throws:** `TypeError` - Throws if `key` is not a string.
91-
**Returns:** `[any, 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.
96+
**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.
9297

9398
| Param | Type | Default | Description |
9499
| ----- | ---- | ------- | ----------- |
95-
| key | `string` | - | The key of the item to retrieve. |
100+
| key | `string` | - | The key under which to store the item. |
101+
| value | `any` | - | The item to save to the selected storage. |
96102

97103
**Usage**
98104

99105
```js
100-
const [value, error] = myStore.getItem('somekey');
106+
const [saved, error] = myStore.setItem('somekey', { foo: 'bar' });
101107
```
102108

103-
### setItem(key, value)
109+
#### Note on value serialization
104110

105-
Saves an item to storage with the specified key. You can store items of any of the following data types as long as data can be serialized to JSON.
111+
WebStorage uses `JSON.stringify()` internally to serialize values before saving them. While this supports most common JavaScript types, some special values are silently converted:
106112

107-
- String
108-
- Number
109-
- Array
110-
- Object
113+
- `NaN`, `Infinity`, `-Infinity`, and `undefined` → become null
114+
- Functions and symbols → are omitted or stored as `null/undefined`
115+
- Circular references → will throw a `TypeError`
116+
117+
For example:
118+
119+
```js
120+
storage.setItem('foo', NaN);
121+
// Will be stored as: "null"
122+
123+
storage.getItem('foo');
124+
// => [null, null]
125+
```
126+
127+
**Why this matters:**
128+
129+
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.
130+
131+
### getItem(key)
132+
133+
Gets the saved item for the specified key from the storage for a specific datastore.
111134

112135
**Throws:** `TypeError` - Throws if `key` is not a string.
113-
**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.
136+
**Returns:** `[any, 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.
114137

115138
| Param | Type | Default | Description |
116139
| ----- | ---- | ------- | ----------- |
117-
| key | `string` | - | The key under which to store the item. |
118-
| value | `any` | - | The item to save to the selected storage. |
140+
| key | `string` | - | The key of the item to retrieve. |
119141

120142
**Usage**
121143

122144
```js
123-
const [saved, error] = myStore.setItem('somekey', { foo: 'bar' });
145+
const [value, error] = myStore.getItem('somekey');
124146
```
125147

126148
### removeItem(key)

src/web-storage.js

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -98,45 +98,45 @@ class WebStorage {
9898
}
9999

100100
/**
101-
* Gets the saved item for the specified key from the storage for a specific datastore.
101+
* Saves an item to storage with the specified key.
102102
*
103-
* @param {string} key - The key of the item to retrieve.
103+
* @param {string} key - The key under which to store the item.
104+
* @param {any} value - The item to save to the selected storage.
104105
* @throws {TypeError} - Throws if `key` is not a string.
105-
* @returns {Result<unknown>} - 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.
106+
* @returns {Result<boolean>} - 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.
106107
*/
107-
getItem(key) {
108+
setItem(key, value) {
108109
if (typeof key !== 'string') {
109-
throw new TypeError("Failed to execute 'getItem' on 'Storage': The first argument must be a string.");
110+
throw new TypeError("Failed to execute 'setItem' on 'Storage': The first argument must be a string.");
110111
}
111112

112113
try {
113-
const raw = this.#driver.getItem(this.#keyPrefix + key);
114-
return raw === null ? [null, null] : [JSON.parse(raw), null];
114+
const storageKey = this.#keyPrefix + key;
115+
const safeValue = value == null || typeof value === 'function' ? null : value;
116+
this.#driver.setItem(storageKey, JSON.stringify(safeValue));
117+
return [true, null];
115118
} catch (error) {
116-
return [null, error instanceof Error ? error : new Error(String(error))];
119+
return [false, error instanceof Error ? error : new Error(String(error))];
117120
}
118121
}
119122

120123
/**
121-
* Saves an item to storage with the specified key.
124+
* Gets the saved item for the specified key from the storage for a specific datastore.
122125
*
123-
* @param {string} key - The key under which to store the item.
124-
* @param {any} value - The item to save to the selected storage.
126+
* @param {string} key - The key of the item to retrieve.
125127
* @throws {TypeError} - Throws if `key` is not a string.
126-
* @returns {Result<boolean>} - 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.
128+
* @returns {Result<unknown>} - 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.
127129
*/
128-
setItem(key, value) {
130+
getItem(key) {
129131
if (typeof key !== 'string') {
130-
throw new TypeError("Failed to execute 'setItem' on 'Storage': The first argument must be a string.");
132+
throw new TypeError("Failed to execute 'getItem' on 'Storage': The first argument must be a string.");
131133
}
132134

133135
try {
134-
const storageKey = this.#keyPrefix + key;
135-
const safeValue = value == null || typeof value === 'function' ? null : value;
136-
this.#driver.setItem(storageKey, JSON.stringify(safeValue));
137-
return [true, null];
136+
const raw = this.#driver.getItem(this.#keyPrefix + key);
137+
return raw === null ? [null, null] : [JSON.parse(raw), null];
138138
} catch (error) {
139-
return [false, error instanceof Error ? error : new Error(String(error))];
139+
return [null, error instanceof Error ? error : new Error(String(error))];
140140
}
141141
}
142142

test/web-storage.test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ describe('WebStorage', () => {
7575
store.setItem('p7', Infinity);
7676
store.setItem('p8', -Infinity);
7777
store.setItem('p9', -0);
78+
store.setItem('p10', [{ foo: 'bar' }, 'foo', [1, 2, 3]]);
7879

7980
expect(store.getItem('p1')).to.deep.equal([{ foo: 'bar' }, null]);
8081
expect(store.getItem('p2')).to.deep.equal([[1, 2, 3], null]);
@@ -85,6 +86,7 @@ describe('WebStorage', () => {
8586
expect(store.getItem('p7')).to.deep.equal([null, null]);
8687
expect(store.getItem('p8')).to.deep.equal([null, null]);
8788
expect(store.getItem('p9')).to.deep.equal([0, null]);
89+
expect(store.getItem('p10')).to.deep.equal([[{ foo: 'bar' }, 'foo', [1, 2, 3]], null]);
8890
});
8991

9092
it('Should remove a saved item by its key', () => {

0 commit comments

Comments
 (0)