hyperstorage-js 5.0.6 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -35
- package/dist/index.cjs +10 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +10 -6
- package/dist/index.umd.js +1 -1
- package/package.json +2 -2
- package/src/index.ts +19 -10
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A lightweight wrapper for Storage interfaces (e.g., `localStorage` or `sessionStorage`) with **efficient caching** and **type-preserving serialization**.
|
|
4
4
|
|
|
5
|
-
The biggest burdens of working with the **Storage API** is verifying values on every read, providing proper default values and only being able to store strings, having to `JSON.stringify()` and `JSON.parse()` manually everytime. This package eliminates all
|
|
5
|
+
The biggest burdens of working with the **Storage API** is verifying values on every read, providing proper default values and only being able to store strings, having to `JSON.stringify()` and `JSON.parse()` manually everytime. This package eliminates this all by providing a safe, automatic and efficient wrapper that handles everything for you. You can read/store numbers and objects without any extra steps, lose no performance and improve code readability.
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/hyperstorage-js)
|
|
8
8
|
[](https://www.npmjs.com/package/hyperstorage-js)
|
|
@@ -13,7 +13,8 @@ The biggest burdens of working with the **Storage API** is verifying values on e
|
|
|
13
13
|
## Features
|
|
14
14
|
|
|
15
15
|
- 📝 **Default values**: are automatically set when the key is not in Storage.
|
|
16
|
-
- 🧩 **JSON support**: automatically serializes and parses objects or non-string primitives (`undefined`, `NaN`,
|
|
16
|
+
- 🧩 **JSON support**: automatically serializes and parses objects or non-string primitives (numbers, `undefined`, `NaN`, etc.) which the Storage API does not support by default.
|
|
17
|
+
- 🛠️ **Utility helpers**: built-in helper methods (like `.set()` and `.isDefault()`) to simplify storage operations.
|
|
17
18
|
- ⚡ **Fast caching**: memory cache avoids repeated JSON convertions.
|
|
18
19
|
- 🔒 **Optional encoding/decoding** hooks to obfuscate data.
|
|
19
20
|
- 🌐 **Custom storage**: works with any object implementing the standard Storage API. (`localStorage`, `sessionStorage`, ...)
|
|
@@ -38,7 +39,7 @@ yarn add hyperstorage-js
|
|
|
38
39
|
## Constructor Syntax
|
|
39
40
|
|
|
40
41
|
```ts
|
|
41
|
-
class
|
|
42
|
+
class HyperStorage<T> {
|
|
42
43
|
constructor(
|
|
43
44
|
itemName: string,
|
|
44
45
|
defaultValue: T,
|
|
@@ -60,39 +61,38 @@ import HyperStorage from 'hyperstorage-js'
|
|
|
60
61
|
```
|
|
61
62
|
|
|
62
63
|
```js
|
|
63
|
-
const defaultValue = { theme: '
|
|
64
|
+
const defaultValue = { theme: 'light', language: 'en' }
|
|
64
65
|
const userStore = new HyperStorage('userSettings', defaultValue)
|
|
65
66
|
|
|
66
67
|
// If 'userSettings' is not present in the Storage, the defaultValue is set:
|
|
67
|
-
console.log(userStore.value) // { theme: '
|
|
68
|
+
console.log(userStore.value) // { theme: 'light', language: 'en' }
|
|
68
69
|
|
|
69
|
-
// Change theme to
|
|
70
|
-
userStore.value = { theme: '
|
|
70
|
+
// Change theme to dark
|
|
71
|
+
userStore.value = { theme: 'dark', language: 'en' }
|
|
72
|
+
// or
|
|
73
|
+
userStore.set((v) => (v.theme = 'dark'))
|
|
71
74
|
|
|
72
|
-
console.log(userStore.value) // { theme: '
|
|
73
|
-
console.log(userStore.value.theme) // '
|
|
75
|
+
console.log(userStore.value) // { theme: 'dark', language: 'en' }
|
|
76
|
+
console.log(userStore.value.theme) // 'dark'
|
|
74
77
|
|
|
75
|
-
// Present in localStorage
|
|
76
|
-
console.log(userStore.storage) // Storage {userSettings: '\x00{"theme":"
|
|
78
|
+
// Present in localStorage
|
|
79
|
+
console.log(userStore.storage) // Storage {userSettings: '\x00{"theme":"dark","language":"en"}', length: 1}
|
|
77
80
|
```
|
|
78
81
|
|
|
79
82
|
### Different Ways to Assign a New Value
|
|
80
83
|
|
|
81
84
|
```js
|
|
82
|
-
//
|
|
83
|
-
userStore.value = { theme: '
|
|
84
|
-
|
|
85
|
-
// Overwrite specific
|
|
86
|
-
userStore.value = { ...userStore.value, theme: 'light' }
|
|
85
|
+
// Using setter
|
|
86
|
+
userStore.value = { theme: 'dark', language: 'en' }
|
|
87
87
|
|
|
88
|
-
//
|
|
89
|
-
userStore.
|
|
88
|
+
// Change single property using the setter
|
|
89
|
+
userStore.value = { ...userStore.value, theme: 'dark' }
|
|
90
90
|
|
|
91
|
-
//
|
|
92
|
-
userStore.set((v) => (v.theme = '
|
|
91
|
+
// Change single property using a callback
|
|
92
|
+
userStore.set((v) => (v.theme = 'dark'))
|
|
93
93
|
|
|
94
|
-
//
|
|
95
|
-
|
|
94
|
+
// Change single property using a property setter
|
|
95
|
+
userStore.set('theme', 'dark')
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
### Using Another Storage API
|
|
@@ -152,15 +152,15 @@ console.log(sessionStore.storage) // Storage {length: 0}
|
|
|
152
152
|
|
|
153
153
|
```ts
|
|
154
154
|
interface Settings {
|
|
155
|
-
theme: '
|
|
155
|
+
theme: 'system' | 'light' | 'dark'
|
|
156
156
|
language: string
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
const defaultValue: Settings = { theme: '
|
|
159
|
+
const defaultValue: Settings = { theme: 'system', language: 'en' }
|
|
160
160
|
const userStore = new HyperStorage<Settings>('userSettings', defaultValue)
|
|
161
161
|
|
|
162
|
-
// Property 'language' is missing in type '{ theme: "
|
|
163
|
-
userStore.value = { theme: '
|
|
162
|
+
// Property 'language' is missing in type '{ theme: "dark"; }' but required in type 'Settings'. ts(2741)
|
|
163
|
+
userStore.value = { theme: 'dark' }
|
|
164
164
|
```
|
|
165
165
|
|
|
166
166
|
### Using `sync()`
|
|
@@ -168,14 +168,19 @@ userStore.value = { theme: 'light' }
|
|
|
168
168
|
Safe usage of `sync()` requires explicit runtime validation before accessing any properties. It quickly becomes clear how type-unsafe `sync()` is and why it should be avoided.
|
|
169
169
|
|
|
170
170
|
```ts
|
|
171
|
-
const
|
|
171
|
+
const result = userStore.sync() // (method): unknown
|
|
172
|
+
// Right now, 'result' equals 'userStore.value' exactly
|
|
172
173
|
|
|
173
|
-
// '
|
|
174
|
-
console.log(
|
|
174
|
+
// 'result' is of type 'unknown'. ts(18046)
|
|
175
|
+
console.log(result.theme) // 'dark'
|
|
175
176
|
|
|
176
|
-
//
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
// No error, but unsafe
|
|
178
|
+
console.log(userStore.value.theme) // 'dark'
|
|
179
|
+
|
|
180
|
+
// Must narrow down to be safe
|
|
181
|
+
if (result && typeof result === 'object' && 'theme' in result) {
|
|
182
|
+
// No error, safe
|
|
183
|
+
console.log(result.theme) // 'dark'
|
|
179
184
|
}
|
|
180
185
|
```
|
|
181
186
|
|
|
@@ -245,13 +250,66 @@ If the underlying `Storage` is not modified through the value setter, the intern
|
|
|
245
250
|
|
|
246
251
|
```js
|
|
247
252
|
// External change to storage (to be avoided)
|
|
248
|
-
localStorage.setItem('userSettings', '{"theme":"
|
|
253
|
+
localStorage.setItem('userSettings', '{"theme":"dark"}')
|
|
249
254
|
|
|
250
255
|
// Resynchronize the cache, optionally with a custom decoder
|
|
251
256
|
userStore.sync((value) => JSON.parse(value))
|
|
252
257
|
|
|
253
|
-
console.log(userStore.value) // { theme: '
|
|
254
|
-
console.log(userStore.storage) // Storage {userSettings: '\x00{"theme":"
|
|
258
|
+
console.log(userStore.value) // { theme: 'dark' }
|
|
259
|
+
console.log(userStore.storage) // Storage {userSettings: '\x00{"theme":"dark"}', length: 1}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
#### Why `sync()` is unsafe
|
|
263
|
+
|
|
264
|
+
1. The item in `Storage` is undecodable by the `decodeFn` passed to `sync()`.
|
|
265
|
+
|
|
266
|
+
```js
|
|
267
|
+
localStorage.setItem('userSettings', 'not an object')
|
|
268
|
+
|
|
269
|
+
// SyntaxError: Unexpected token 'o', "not an object" is not valid JSON
|
|
270
|
+
const result = userStore.sync((value) => JSON.parse(value))
|
|
271
|
+
// Execution continues because sync() uses a try-catch
|
|
272
|
+
|
|
273
|
+
console.log(result) // instance of SyntaxError
|
|
274
|
+
|
|
275
|
+
// Reset to default value
|
|
276
|
+
console.log(userStore.value) // {theme: 'system', language: 'en'}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
2. The item in `Storage`, after being decoded, is not of type `T`.
|
|
280
|
+
|
|
281
|
+
```js
|
|
282
|
+
localStorage.setItem('userSettings', '{"not":"valid"}')
|
|
283
|
+
|
|
284
|
+
const result = userStore.sync((value) => JSON.parse(value))
|
|
285
|
+
console.log(result) // {not: 'valid'}
|
|
286
|
+
console.log(userStore.value) // {not: 'valid'}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
No errors, but `result` and `userStore.value` are both not of type `T`.
|
|
290
|
+
|
|
291
|
+
This **must** be manually checked and `userStore.reset()` should be called if the check fails.
|
|
292
|
+
|
|
293
|
+
```js
|
|
294
|
+
// This example is specifically for type 'Settings'
|
|
295
|
+
if (
|
|
296
|
+
result &&
|
|
297
|
+
typeof result === 'object' &&
|
|
298
|
+
'theme' in result &&
|
|
299
|
+
'language' in result &&
|
|
300
|
+
(result.theme === 'system' ||
|
|
301
|
+
result.theme === 'light' ||
|
|
302
|
+
result.theme === 'dark') &&
|
|
303
|
+
typeof result.language === 'string'
|
|
304
|
+
) {
|
|
305
|
+
// 'result' is of type 'T'
|
|
306
|
+
} else {
|
|
307
|
+
// 'result' is not of type 'T'
|
|
308
|
+
userStore.reset()
|
|
309
|
+
console.log(userStore.value) // {theme: 'system', language: 'en'}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// 'userStore.value' is of type 'T'
|
|
255
313
|
```
|
|
256
314
|
|
|
257
315
|
<br>
|
package/dist/index.cjs
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
class HyperStorage {
|
|
11
11
|
/** Version of the library, injected via Rollup replace plugin. */
|
|
12
|
-
static version = "5.0
|
|
12
|
+
static version = "5.1.0";
|
|
13
13
|
/** Key name under which the data is stored. */
|
|
14
14
|
itemName;
|
|
15
15
|
/** Default value used when the key does not exist in storage. */
|
|
@@ -26,7 +26,7 @@ class HyperStorage {
|
|
|
26
26
|
* Creates a new HyperStorage instance.
|
|
27
27
|
*
|
|
28
28
|
* @param {string} itemName - The key name under which the data will be stored.
|
|
29
|
-
* @param {T} [defaultValue] - Default value
|
|
29
|
+
* @param {T} [defaultValue] - Default value assigned to the key if it does not exist yet.
|
|
30
30
|
* @param {Object} [options={}] - Optional configuration parameters.
|
|
31
31
|
* @param {(value: string) => string} [options.encodeFn] - Optional function to encode stored values.
|
|
32
32
|
* @param {(value: string) => string} [options.decodeFn] - Optional function to decode stored values.
|
|
@@ -69,11 +69,14 @@ class HyperStorage {
|
|
|
69
69
|
stringValue = value;
|
|
70
70
|
}
|
|
71
71
|
else if (value === undefined ||
|
|
72
|
-
(typeof value === 'number' &&
|
|
72
|
+
(typeof value === 'number' &&
|
|
73
|
+
(isNaN(value) || value === Infinity || value === -Infinity))) {
|
|
73
74
|
// Manually stringify non-JSON values
|
|
74
|
-
stringValue = String(value);
|
|
75
|
-
|
|
75
|
+
stringValue = '\0' + String(value);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
76
78
|
stringValue = '\0' + JSON.stringify(value);
|
|
79
|
+
}
|
|
77
80
|
this.storage.setItem(this.itemName, this.encodeFn(stringValue));
|
|
78
81
|
}
|
|
79
82
|
/**
|
|
@@ -104,8 +107,9 @@ class HyperStorage {
|
|
|
104
107
|
value = decodeFn(value);
|
|
105
108
|
}
|
|
106
109
|
catch (err) {
|
|
110
|
+
this.reset();
|
|
107
111
|
console.error(err);
|
|
108
|
-
return
|
|
112
|
+
return err;
|
|
109
113
|
}
|
|
110
114
|
if (value[0] !== '\0')
|
|
111
115
|
return (this.value = value); // Raw string value
|
package/dist/index.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ declare class HyperStorage<T> {
|
|
|
23
23
|
* Creates a new HyperStorage instance.
|
|
24
24
|
*
|
|
25
25
|
* @param {string} itemName - The key name under which the data will be stored.
|
|
26
|
-
* @param {T} [defaultValue] - Default value
|
|
26
|
+
* @param {T} [defaultValue] - Default value assigned to the key if it does not exist yet.
|
|
27
27
|
* @param {Object} [options={}] - Optional configuration parameters.
|
|
28
28
|
* @param {(value: string) => string} [options.encodeFn] - Optional function to encode stored values.
|
|
29
29
|
* @param {(value: string) => string} [options.decodeFn] - Optional function to decode stored values.
|
package/dist/index.mjs
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
class HyperStorage {
|
|
9
9
|
/** Version of the library, injected via Rollup replace plugin. */
|
|
10
|
-
static version = "5.0
|
|
10
|
+
static version = "5.1.0";
|
|
11
11
|
/** Key name under which the data is stored. */
|
|
12
12
|
itemName;
|
|
13
13
|
/** Default value used when the key does not exist in storage. */
|
|
@@ -24,7 +24,7 @@ class HyperStorage {
|
|
|
24
24
|
* Creates a new HyperStorage instance.
|
|
25
25
|
*
|
|
26
26
|
* @param {string} itemName - The key name under which the data will be stored.
|
|
27
|
-
* @param {T} [defaultValue] - Default value
|
|
27
|
+
* @param {T} [defaultValue] - Default value assigned to the key if it does not exist yet.
|
|
28
28
|
* @param {Object} [options={}] - Optional configuration parameters.
|
|
29
29
|
* @param {(value: string) => string} [options.encodeFn] - Optional function to encode stored values.
|
|
30
30
|
* @param {(value: string) => string} [options.decodeFn] - Optional function to decode stored values.
|
|
@@ -67,11 +67,14 @@ class HyperStorage {
|
|
|
67
67
|
stringValue = value;
|
|
68
68
|
}
|
|
69
69
|
else if (value === undefined ||
|
|
70
|
-
(typeof value === 'number' &&
|
|
70
|
+
(typeof value === 'number' &&
|
|
71
|
+
(isNaN(value) || value === Infinity || value === -Infinity))) {
|
|
71
72
|
// Manually stringify non-JSON values
|
|
72
|
-
stringValue = String(value);
|
|
73
|
-
|
|
73
|
+
stringValue = '\0' + String(value);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
74
76
|
stringValue = '\0' + JSON.stringify(value);
|
|
77
|
+
}
|
|
75
78
|
this.storage.setItem(this.itemName, this.encodeFn(stringValue));
|
|
76
79
|
}
|
|
77
80
|
/**
|
|
@@ -102,8 +105,9 @@ class HyperStorage {
|
|
|
102
105
|
value = decodeFn(value);
|
|
103
106
|
}
|
|
104
107
|
catch (err) {
|
|
108
|
+
this.reset();
|
|
105
109
|
console.error(err);
|
|
106
|
-
return
|
|
110
|
+
return err;
|
|
107
111
|
}
|
|
108
112
|
if (value[0] !== '\0')
|
|
109
113
|
return (this.value = value); // Raw string value
|
package/dist/index.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).HyperStorage=t()}(this,function(){"use strict";return class{static version="5.1.0";itemName;defaultValue;encodeFn;decodeFn;storage;#e;constructor(e,t,i={}){const{encodeFn:s,decodeFn:n,storage:o=window.localStorage}=i;if("string"!=typeof e)throw new TypeError("itemName is not a string");if(this.itemName=e,this.defaultValue=t,s&&"function"!=typeof s)throw new TypeError("encodeFn is defined but is not a function");if(this.encodeFn=s||(e=>e),n&&"function"!=typeof n)throw new TypeError("decodeFn is defined but is not a function");if(this.decodeFn=n||(e=>e),!(o instanceof Storage))throw new TypeError("storage must be an instance of Storage");this.storage=o,this.sync()}set value(e){let t;this.#e=e,t="string"==typeof e?"\0"===e[0]?"\0"+e:e:void 0===e||"number"==typeof e&&(isNaN(e)||e===1/0||e===-1/0)?"\0"+String(e):"\0"+JSON.stringify(e),this.storage.setItem(this.itemName,this.encodeFn(t))}get value(){return this.#e??this.defaultValue}set(e){return this.value=e(this.value)}sync(e=this.decodeFn){let t=this.storage.getItem(this.itemName);if("string"!=typeof t)return this.reset();try{t=e(t)}catch(e){return this.reset(),console.error(e),e}return"\0"!==t[0]?this.value=t:(t=t.slice(1),"\0"===t[0]?this.value=t:this.value="undefined"===t?void 0:"NaN"===t?NaN:"Infinity"===t?1/0:"-Infinity"===t?-1/0:JSON.parse(t))}reset(){return this.value=this.defaultValue}remove(){this.#e=void 0,this.storage.removeItem(this.itemName)}clear(){this.#e=void 0,this.storage.clear()}isDefault(){return this.#e===this.defaultValue}}});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hyperstorage-js",
|
|
3
|
-
"version": "5.0
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "A lightweight wrapper for localStorage/sessionStorage with efficient caching and type-preserving serialization.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Khoeckman",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"prettier": "^3.7.4",
|
|
35
35
|
"rollup": "^4.55.1",
|
|
36
36
|
"rollup-plugin-delete": "^3.0.2",
|
|
37
|
-
"rollup-plugin-prettier": "^4.1.
|
|
37
|
+
"rollup-plugin-prettier": "^4.1.1",
|
|
38
38
|
"tslib": "^2.8.1",
|
|
39
39
|
"typescript": "^5.9.3"
|
|
40
40
|
},
|
package/src/index.ts
CHANGED
|
@@ -34,7 +34,7 @@ class HyperStorage<T> {
|
|
|
34
34
|
* Creates a new HyperStorage instance.
|
|
35
35
|
*
|
|
36
36
|
* @param {string} itemName - The key name under which the data will be stored.
|
|
37
|
-
* @param {T} [defaultValue] - Default value
|
|
37
|
+
* @param {T} [defaultValue] - Default value assigned to the key if it does not exist yet.
|
|
38
38
|
* @param {Object} [options={}] - Optional configuration parameters.
|
|
39
39
|
* @param {(value: string) => string} [options.encodeFn] - Optional function to encode stored values.
|
|
40
40
|
* @param {(value: string) => string} [options.decodeFn] - Optional function to decode stored values.
|
|
@@ -55,17 +55,21 @@ class HyperStorage<T> {
|
|
|
55
55
|
) {
|
|
56
56
|
const { encodeFn, decodeFn, storage = window.localStorage } = options
|
|
57
57
|
|
|
58
|
-
if (typeof itemName !== 'string')
|
|
58
|
+
if (typeof itemName !== 'string')
|
|
59
|
+
throw new TypeError('itemName is not a string')
|
|
59
60
|
this.itemName = itemName
|
|
60
61
|
this.defaultValue = defaultValue
|
|
61
62
|
|
|
62
|
-
if (encodeFn && typeof encodeFn !== 'function')
|
|
63
|
+
if (encodeFn && typeof encodeFn !== 'function')
|
|
64
|
+
throw new TypeError('encodeFn is defined but is not a function')
|
|
63
65
|
this.encodeFn = encodeFn || ((v) => v)
|
|
64
66
|
|
|
65
|
-
if (decodeFn && typeof decodeFn !== 'function')
|
|
67
|
+
if (decodeFn && typeof decodeFn !== 'function')
|
|
68
|
+
throw new TypeError('decodeFn is defined but is not a function')
|
|
66
69
|
this.decodeFn = decodeFn || ((v) => v)
|
|
67
70
|
|
|
68
|
-
if (!(storage instanceof Storage))
|
|
71
|
+
if (!(storage instanceof Storage))
|
|
72
|
+
throw new TypeError('storage must be an instance of Storage')
|
|
69
73
|
this.storage = storage
|
|
70
74
|
|
|
71
75
|
this.sync()
|
|
@@ -87,11 +91,15 @@ class HyperStorage<T> {
|
|
|
87
91
|
else stringValue = value
|
|
88
92
|
} else if (
|
|
89
93
|
value === undefined ||
|
|
90
|
-
(typeof value === 'number' &&
|
|
91
|
-
|
|
94
|
+
(typeof value === 'number' &&
|
|
95
|
+
(isNaN(value) || value === Infinity || value === -Infinity))
|
|
96
|
+
) {
|
|
92
97
|
// Manually stringify non-JSON values
|
|
93
|
-
stringValue = String(value)
|
|
94
|
-
else
|
|
98
|
+
stringValue = '\0' + String(value)
|
|
99
|
+
} else {
|
|
100
|
+
stringValue = '\0' + JSON.stringify(value)
|
|
101
|
+
}
|
|
102
|
+
|
|
95
103
|
this.storage.setItem(this.itemName, this.encodeFn(stringValue))
|
|
96
104
|
}
|
|
97
105
|
|
|
@@ -125,8 +133,9 @@ class HyperStorage<T> {
|
|
|
125
133
|
try {
|
|
126
134
|
value = decodeFn(value)
|
|
127
135
|
} catch (err) {
|
|
136
|
+
this.reset()
|
|
128
137
|
console.error(err)
|
|
129
|
-
return
|
|
138
|
+
return err
|
|
130
139
|
}
|
|
131
140
|
|
|
132
141
|
if (value[0] !== '\0') return (this.value = value as T) // Raw string value
|