hyperstorage-js 5.1.0 → 6.0.1
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 +47 -20
- package/dist/index.cjs +872 -46
- package/dist/index.d.ts +8 -5
- package/dist/index.mjs +872 -46
- package/dist/index.umd.js +1 -1
- package/package.json +7 -2
- package/src/index.ts +27 -54
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).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}}});
|
|
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";class e{constructor(){this.keyToValue=new Map,this.valueToKey=new Map}set(e,t){this.keyToValue.set(e,t),this.valueToKey.set(t,e)}getByKey(e){return this.keyToValue.get(e)}getByValue(e){return this.valueToKey.get(e)}clear(){this.keyToValue.clear(),this.valueToKey.clear()}}class t{constructor(t){this.generateIdentifier=t,this.kv=new e}register(e,t){this.kv.getByValue(e)||(t||(t=this.generateIdentifier(e)),this.kv.set(t,e))}clear(){this.kv.clear()}getIdentifier(e){return this.kv.getByValue(e)}getValue(e){return this.kv.getByKey(e)}}class r extends t{constructor(){super(e=>e.name),this.classToAllowedProps=new Map}register(e,t){"object"==typeof t?(t.allowProps&&this.classToAllowedProps.set(e,t.allowProps),super.register(e,t.identifier)):super.register(e,t)}getAllowedProps(e){return this.classToAllowedProps.get(e)}}function n(e,t){const r=function(e){if("values"in Object)return Object.values(e);const t=[];for(const r in e)e.hasOwnProperty(r)&&t.push(e[r]);return t}(e);if("find"in r)return r.find(t);const n=r;for(let e=0;e<n.length;e++){const r=n[e];if(t(r))return r}}function s(e,t){Object.entries(e).forEach(([e,r])=>t(r,e))}function o(e,t){return-1!==e.indexOf(t)}function i(e,t){for(let r=0;r<e.length;r++){const n=e[r];if(t(n))return n}}class a{constructor(){this.transfomers={}}register(e){this.transfomers[e.name]=e}findApplicable(e){return n(this.transfomers,t=>t.isApplicable(e))}findByName(e){return this.transfomers[e]}}const l=e=>void 0===e,u=e=>"object"==typeof e&&null!==e&&(e!==Object.prototype&&(null===Object.getPrototypeOf(e)||Object.getPrototypeOf(e)===Object.prototype)),c=e=>u(e)&&0===Object.keys(e).length,f=e=>Array.isArray(e),p=e=>e instanceof Map,d=e=>e instanceof Set,y=e=>"Symbol"===(e=>Object.prototype.toString.call(e).slice(8,-1))(e),g=e=>e instanceof Error,m=e=>"number"==typeof e&&isNaN(e),h=e=>(e=>"boolean"==typeof e)(e)||(e=>null===e)(e)||l(e)||(e=>"number"==typeof e&&!isNaN(e))(e)||(e=>"string"==typeof e)(e)||y(e),b=e=>e.replace(/\\/g,"\\\\").replace(/\./g,"\\."),w=e=>e.map(String).map(b).join("."),v=(e,t)=>{const r=[];let n="";for(let s=0;s<e.length;s++){let o=e.charAt(s);if(!t&&"\\"===o){const t=e.charAt(s+1);if("\\"===t){n+="\\",s++;continue}if("."!==t)throw Error("invalid path")}if("\\"===o&&"."===e.charAt(s+1)){n+=".",s++;continue}"."===o?(r.push(n),n=""):n+=o}const s=n;return r.push(s),r};function E(e,t,r,n){return{isApplicable:e,annotation:t,transform:r,untransform:n}}const I=[E(l,"undefined",()=>null,()=>{}),E(e=>"bigint"==typeof e,"bigint",e=>e.toString(),e=>"undefined"!=typeof BigInt?BigInt(e):(console.error("Please add a BigInt polyfill."),e)),E(e=>e instanceof Date&&!isNaN(e.valueOf()),"Date",e=>e.toISOString(),e=>new Date(e)),E(g,"Error",(e,t)=>{const r={name:e.name,message:e.message};return"cause"in e&&(r.cause=e.cause),t.allowedErrorProps.forEach(t=>{r[t]=e[t]}),r},(e,t)=>{const r=new Error(e.message,{cause:e.cause});return r.name=e.name,r.stack=e.stack,t.allowedErrorProps.forEach(t=>{r[t]=e[t]}),r}),E(e=>e instanceof RegExp,"regexp",e=>""+e,e=>{const t=e.slice(1,e.lastIndexOf("/")),r=e.slice(e.lastIndexOf("/")+1);return new RegExp(t,r)}),E(d,"set",e=>[...e.values()],e=>new Set(e)),E(p,"map",e=>[...e.entries()],e=>new Map(e)),E(e=>{return m(e)||((t=e)===1/0||t===-1/0);var t},"number",e=>m(e)?"NaN":e>0?"Infinity":"-Infinity",Number),E(e=>0===e&&1/e==-1/0,"number",()=>"-0",Number),E(e=>e instanceof URL,"URL",e=>e.toString(),e=>new URL(e))];function k(e,t,r,n){return{isApplicable:e,annotation:t,transform:r,untransform:n}}const O=k((e,t)=>{if(y(e)){return!!t.symbolRegistry.getIdentifier(e)}return!1},(e,t)=>["symbol",t.symbolRegistry.getIdentifier(e)],e=>e.description,(e,t,r)=>{const n=r.symbolRegistry.getValue(t[1]);if(!n)throw new Error("Trying to deserialize unknown symbol");return n}),j=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,Uint8ClampedArray].reduce((e,t)=>(e[t.name]=t,e),{}),A=k(e=>ArrayBuffer.isView(e)&&!(e instanceof DataView),e=>["typed-array",e.constructor.name],e=>[...e],(e,t)=>{const r=j[t[1]];if(!r)throw new Error("Trying to deserialize unknown typed array");return new r(e)});function T(e,t){if(e?.constructor){return!!t.classRegistry.getIdentifier(e.constructor)}return!1}const P=k(T,(e,t)=>["class",t.classRegistry.getIdentifier(e.constructor)],(e,t)=>{const r=t.classRegistry.getAllowedProps(e.constructor);if(!r)return{...e};const n={};return r.forEach(t=>{n[t]=e[t]}),n},(e,t,r)=>{const n=r.classRegistry.getValue(t[1]);if(!n)throw new Error(`Trying to deserialize unknown class '${t[1]}' - check https://github.com/blitz-js/superjson/issues/116#issuecomment-773996564`);return Object.assign(Object.create(n.prototype),e)}),V=k((e,t)=>!!t.customTransformerRegistry.findApplicable(e),(e,t)=>["custom",t.customTransformerRegistry.findApplicable(e).name],(e,t)=>t.customTransformerRegistry.findApplicable(e).serialize(e),(e,t,r)=>{const n=r.customTransformerRegistry.findByName(t[1]);if(!n)throw new Error("Trying to deserialize unknown custom value");return n.deserialize(e)}),R=[P,O,V,A],S=(e,t)=>{const r=i(R,r=>r.isApplicable(e,t));if(r)return{value:r.transform(e,t),type:r.annotation(e,t)};const n=i(I,r=>r.isApplicable(e,t));return n?{value:n.transform(e,t),type:n.annotation}:void 0},N={};I.forEach(e=>{N[e.annotation]=e});const z=(e,t)=>{if(t>e.size)throw new Error("index out of bounds");const r=e.keys();for(;t>0;)r.next(),t--;return r.next().value};function _(e){if(o(e,"__proto__"))throw new Error("__proto__ is not allowed as a property");if(o(e,"prototype"))throw new Error("prototype is not allowed as a property");if(o(e,"constructor"))throw new Error("constructor is not allowed as a property")}const x=(e,t,r)=>{if(_(t),0===t.length)return r(e);let n=e;for(let e=0;e<t.length-1;e++){const r=t[e];if(f(n)){n=n[+r]}else if(u(n))n=n[r];else if(d(n)){n=z(n,+r)}else if(p(n)){if(e===t.length-2)break;const s=+r,o=0===+t[++e]?"key":"value",i=z(n,s);switch(o){case"key":n=i;break;case"value":n=n.get(i)}}}const s=t[t.length-1];if(f(n)?n[+s]=r(n[+s]):u(n)&&(n[s]=r(n[s])),d(n)){const e=z(n,+s),t=r(e);e!==t&&(n.delete(e),n.add(t))}if(p(n)){const e=+t[t.length-2],o=z(n,e);switch(0===+s?"key":"value"){case"key":{const e=r(o);n.set(e,n.get(o)),e!==o&&n.delete(o);break}case"value":n.set(o,r(n.get(o)))}}return e},F=e=>e<1;function B(e,t,r,n=[]){if(!e)return;const o=F(r);if(!f(e))return void s(e,(e,s)=>B(e,t,r,[...n,...v(s,o)]));const[i,a]=e;a&&s(a,(e,s)=>{B(e,t,r,[...n,...v(s,o)])}),t(i,n)}function C(e,t,r,n){return B(t,(t,r)=>{e=x(e,r,e=>((e,t,r)=>{if(!f(t)){const n=N[t];if(!n)throw new Error("Unknown transformation: "+t);return n.untransform(e,r)}switch(t[0]){case"symbol":return O.untransform(e,t,r);case"class":return P.untransform(e,t,r);case"custom":return V.untransform(e,t,r);case"typed-array":return A.untransform(e,t,r);default:throw new Error("Unknown transformation: "+t)}})(e,t,n))},r),e}function U(e,t,r){const n=F(r);function o(t,r){const s=((e,t)=>{_(t);for(let r=0;r<t.length;r++){const n=t[r];if(d(e))e=z(e,+n);else if(p(e)){const s=+n,o=0===+t[++r]?"key":"value",i=z(e,s);switch(o){case"key":e=i;break;case"value":e=e.get(i)}}else e=e[n]}return e})(e,v(r,n));t.map(e=>v(e,n)).forEach(t=>{e=x(e,t,()=>s)})}if(f(t)){const[r,i]=t;r.forEach(t=>{e=x(e,v(t,n),()=>e)}),i&&s(i,o)}else s(t,o);return e}const M=(e,t,r,n,i=[],a=[],l=new Map)=>{const y=h(e);if(!y){!function(e,t,r){const n=r.get(e);n?n.push(t):r.set(e,[t])}(e,i,t);const r=l.get(e);if(r)return n?{transformedValue:null}:r}if(!((e,t)=>u(e)||f(e)||p(e)||d(e)||g(e)||T(e,t))(e,r)){const t=S(e,r),n=t?{transformedValue:t.value,annotations:[t.type]}:{transformedValue:e};return y||l.set(e,n),n}if(o(a,e))return{transformedValue:null};const m=S(e,r),w=m?.value??e,v=f(w)?[]:{},E={};s(w,(o,c)=>{if("__proto__"===c||"constructor"===c||"prototype"===c)throw new Error(`Detected property ${c}. This is a prototype pollution risk, please remove it from your object.`);const p=M(o,t,r,n,[...i,c],[...a,e],l);v[c]=p.transformedValue,f(p.annotations)?E[b(c)]=p.annotations:u(p.annotations)&&s(p.annotations,(e,t)=>{E[b(c)+"."+t]=e})});const I=c(E)?{transformedValue:v,annotations:m?[m.type]:void 0}:{transformedValue:v,annotations:m?[m.type,E]:E};return y||l.set(e,I),I};function D(e){return Object.prototype.toString.call(e).slice(8,-1)}function K(e){return"Array"===D(e)}function q(e,t={}){if(K(e))return e.map(e=>q(e,t));if(!function(e){if("Object"!==D(e))return!1;const t=Object.getPrototypeOf(e);return!!t&&t.constructor===Object&&t===Object.prototype}(e))return e;return[...Object.getOwnPropertyNames(e),...Object.getOwnPropertySymbols(e)].reduce((r,n)=>{if("__proto__"===n)return r;if(K(t.props)&&!t.props.includes(n))return r;return function(e,t,r,n,s){const o={}.propertyIsEnumerable.call(n,t)?"enumerable":"nonenumerable";"enumerable"===o&&(e[t]=r),s&&"nonenumerable"===o&&Object.defineProperty(e,t,{value:r,enumerable:!1,writable:!0,configurable:!0})}(r,n,q(e[n],t),e,t.nonenumerable),r},{})}class L{constructor({dedupe:e=!1}={}){this.classRegistry=new r,this.symbolRegistry=new t(e=>e.description??""),this.customTransformerRegistry=new a,this.allowedErrorProps=[],this.dedupe=e}serialize(e){const t=new Map,r=M(e,t,this,this.dedupe),n={json:r.transformedValue};r.annotations&&(n.meta={...n.meta,values:r.annotations});const s=function(e,t){const r={};let n;return e.forEach(e=>{if(e.length<=1)return;t||(e=e.map(e=>e.map(String)).sort((e,t)=>e.length-t.length));const[s,...o]=e;0===s.length?n=o.map(w):r[w(s)]=o.map(w)}),n?c(r)?[n]:[n,r]:c(r)?void 0:r}(t,this.dedupe);return s&&(n.meta={...n.meta,referentialEqualities:s}),n.meta&&(n.meta.v=1),n}deserialize(e,t){const{json:r,meta:n}=e;let s=t?.inPlace?r:q(r);return n?.values&&(s=C(s,n.values,n.v??0,this)),n?.referentialEqualities&&(s=U(s,n.referentialEqualities,n.v??0)),s}stringify(e){return JSON.stringify(this.serialize(e))}parse(e){return this.deserialize(JSON.parse(e),{inPlace:!0})}registerClass(e,t){this.classRegistry.register(e,t)}registerSymbol(e,t){this.symbolRegistry.register(e,t)}registerCustom(e,t){this.customTransformerRegistry.register({name:t,...e})}allowErrorProps(...e){this.allowedErrorProps.push(...e)}}L.defaultInstance=new L,L.serialize=L.defaultInstance.serialize.bind(L.defaultInstance),L.deserialize=L.defaultInstance.deserialize.bind(L.defaultInstance),L.stringify=L.defaultInstance.stringify.bind(L.defaultInstance),L.parse=L.defaultInstance.parse.bind(L.defaultInstance),L.registerClass=L.defaultInstance.registerClass.bind(L.defaultInstance),L.registerSymbol=L.defaultInstance.registerSymbol.bind(L.defaultInstance),L.registerCustom=L.defaultInstance.registerCustom.bind(L.defaultInstance),L.allowErrorProps=L.defaultInstance.allowErrorProps.bind(L.defaultInstance),L.serialize,L.deserialize,L.stringify,L.parse,L.registerClass,L.registerCustom,L.registerSymbol,L.allowErrorProps;class J{static version="6.0.1";static superjson=L;itemName;defaultValue;encodeFn;decodeFn;storage;#e;constructor(e,t,r={}){const{encodeFn:n,decodeFn:s,storage:o=window.localStorage}=r;if("string"!=typeof e)throw new TypeError("itemName is not a string");if(this.itemName=e,this.defaultValue=t,n&&"function"!=typeof n)throw new TypeError("encodeFn is defined but is not a function");if(this.encodeFn=n||(e=>J.superjson.stringify(e)),s&&"function"!=typeof s)throw new TypeError("decodeFn is defined but is not a function");if(this.decodeFn=s||(e=>J.superjson.parse(e)),!(o instanceof Storage))throw new TypeError("storage must be an instance of Storage");this.storage=o,this.sync()}set value(e){this.#e=e,this.storage.setItem(this.itemName,this.encodeFn(e))}get value(){return this.#e??this.defaultValue}set(e,t){return"function"==typeof e?this.value=e(this.value):(this.value[e]=t,this.value)}sync(e=this.decodeFn){let t=this.storage.getItem(this.itemName);if("string"!=typeof t)return this.reset();try{return this.value=e(t)}catch(e){return this.reset(),console.error(e),e}}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}}return J});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hyperstorage-js",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"description": "A lightweight wrapper for localStorage/sessionStorage with efficient caching and type-preserving serialization.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Khoeckman",
|
|
@@ -25,7 +25,12 @@
|
|
|
25
25
|
"build": "rollup -c rollup.config.js",
|
|
26
26
|
"prepack": "npm run build"
|
|
27
27
|
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"superjson": "^2.2.6"
|
|
30
|
+
},
|
|
28
31
|
"devDependencies": {
|
|
32
|
+
"@rollup/plugin-commonjs": "^29.0.0",
|
|
33
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
29
34
|
"@rollup/plugin-replace": "^6.0.3",
|
|
30
35
|
"@rollup/plugin-terser": "^0.4.4",
|
|
31
36
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
@@ -34,7 +39,7 @@
|
|
|
34
39
|
"prettier": "^3.7.4",
|
|
35
40
|
"rollup": "^4.55.1",
|
|
36
41
|
"rollup-plugin-delete": "^3.0.2",
|
|
37
|
-
"rollup-plugin-prettier": "^4.1.
|
|
42
|
+
"rollup-plugin-prettier": "^4.1.2",
|
|
38
43
|
"tslib": "^2.8.1",
|
|
39
44
|
"typescript": "^5.9.3"
|
|
40
45
|
},
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import superjson from 'superjson'
|
|
2
|
+
|
|
1
3
|
// Injected by Rollup
|
|
2
4
|
declare const __VERSION__: string
|
|
3
5
|
|
|
@@ -12,6 +14,8 @@ class HyperStorage<T> {
|
|
|
12
14
|
/** Version of the library, injected via Rollup replace plugin. */
|
|
13
15
|
static readonly version: string = __VERSION__
|
|
14
16
|
|
|
17
|
+
static readonly superjson = superjson
|
|
18
|
+
|
|
15
19
|
/** Key name under which the data is stored. */
|
|
16
20
|
readonly itemName: string
|
|
17
21
|
|
|
@@ -19,10 +23,10 @@ class HyperStorage<T> {
|
|
|
19
23
|
private readonly defaultValue: T
|
|
20
24
|
|
|
21
25
|
/** Function to encode values before storing. */
|
|
22
|
-
private readonly encodeFn: (value:
|
|
26
|
+
private readonly encodeFn: (value: T) => string
|
|
23
27
|
|
|
24
28
|
/** Function to decode values when reading. */
|
|
25
|
-
private readonly decodeFn: (value: string) =>
|
|
29
|
+
private readonly decodeFn: (value: string) => T
|
|
26
30
|
|
|
27
31
|
/** The underlying storage backend (defaults to `window.localStorage`). */
|
|
28
32
|
readonly storage: Storage
|
|
@@ -36,7 +40,7 @@ class HyperStorage<T> {
|
|
|
36
40
|
* @param {string} itemName - The key name under which the data will be stored.
|
|
37
41
|
* @param {T} [defaultValue] - Default value assigned to the key if it does not exist yet.
|
|
38
42
|
* @param {Object} [options={}] - Optional configuration parameters.
|
|
39
|
-
* @param {(value:
|
|
43
|
+
* @param {(value: T) => string} [options.encodeFn] - Optional function to encode stored values.
|
|
40
44
|
* @param {(value: string) => string} [options.decodeFn] - Optional function to decode stored values.
|
|
41
45
|
* @param {Storage} [options.storage=window.localStorage] - Optional custom storage backend.
|
|
42
46
|
*
|
|
@@ -48,28 +52,24 @@ class HyperStorage<T> {
|
|
|
48
52
|
itemName: string,
|
|
49
53
|
defaultValue: T,
|
|
50
54
|
options: {
|
|
51
|
-
encodeFn?: (value:
|
|
52
|
-
decodeFn?: (value: string) =>
|
|
55
|
+
encodeFn?: (value: T) => string
|
|
56
|
+
decodeFn?: (value: string) => T
|
|
53
57
|
storage?: Storage
|
|
54
58
|
} = {}
|
|
55
59
|
) {
|
|
56
60
|
const { encodeFn, decodeFn, storage = window.localStorage } = options
|
|
57
61
|
|
|
58
|
-
if (typeof itemName !== 'string')
|
|
59
|
-
throw new TypeError('itemName is not a string')
|
|
62
|
+
if (typeof itemName !== 'string') throw new TypeError('itemName is not a string')
|
|
60
63
|
this.itemName = itemName
|
|
61
64
|
this.defaultValue = defaultValue
|
|
62
65
|
|
|
63
|
-
if (encodeFn && typeof encodeFn !== 'function')
|
|
64
|
-
|
|
65
|
-
this.encodeFn = encodeFn || ((v) => v)
|
|
66
|
+
if (encodeFn && typeof encodeFn !== 'function') throw new TypeError('encodeFn is defined but is not a function')
|
|
67
|
+
this.encodeFn = encodeFn || ((v) => HyperStorage.superjson.stringify(v))
|
|
66
68
|
|
|
67
|
-
if (decodeFn && typeof decodeFn !== 'function')
|
|
68
|
-
|
|
69
|
-
this.decodeFn = decodeFn || ((v) => v)
|
|
69
|
+
if (decodeFn && typeof decodeFn !== 'function') throw new TypeError('decodeFn is defined but is not a function')
|
|
70
|
+
this.decodeFn = decodeFn || ((v) => HyperStorage.superjson.parse<T>(v))
|
|
70
71
|
|
|
71
|
-
if (!(storage instanceof Storage))
|
|
72
|
-
throw new TypeError('storage must be an instance of Storage')
|
|
72
|
+
if (!(storage instanceof Storage)) throw new TypeError('storage must be an instance of Storage')
|
|
73
73
|
this.storage = storage
|
|
74
74
|
|
|
75
75
|
this.sync()
|
|
@@ -83,24 +83,7 @@ class HyperStorage<T> {
|
|
|
83
83
|
// Cache real value
|
|
84
84
|
this.#value = value
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
let stringValue: string
|
|
88
|
-
|
|
89
|
-
if (typeof value === 'string') {
|
|
90
|
-
if (value[0] === '\0') stringValue = '\0' + value
|
|
91
|
-
else stringValue = value
|
|
92
|
-
} else if (
|
|
93
|
-
value === undefined ||
|
|
94
|
-
(typeof value === 'number' &&
|
|
95
|
-
(isNaN(value) || value === Infinity || value === -Infinity))
|
|
96
|
-
) {
|
|
97
|
-
// Manually stringify non-JSON values
|
|
98
|
-
stringValue = '\0' + String(value)
|
|
99
|
-
} else {
|
|
100
|
-
stringValue = '\0' + JSON.stringify(value)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
this.storage.setItem(this.itemName, this.encodeFn(stringValue))
|
|
86
|
+
this.storage.setItem(this.itemName, this.encodeFn(value))
|
|
104
87
|
}
|
|
105
88
|
|
|
106
89
|
/**
|
|
@@ -111,10 +94,15 @@ class HyperStorage<T> {
|
|
|
111
94
|
}
|
|
112
95
|
|
|
113
96
|
/**
|
|
114
|
-
* Allows using the setter with a callback.
|
|
97
|
+
* Allows using the setter with property assignment or a callback.
|
|
115
98
|
*/
|
|
116
|
-
set(
|
|
117
|
-
|
|
99
|
+
set<K extends keyof T>(key: K, value: T[K]): T
|
|
100
|
+
set(callback: (value: T) => T): T
|
|
101
|
+
set(keyOrCallback: keyof T | ((value: T) => T), value?: T[keyof T]): T {
|
|
102
|
+
if (typeof keyOrCallback === 'function') return (this.value = keyOrCallback(this.value))
|
|
103
|
+
|
|
104
|
+
this.value[keyOrCallback] = value!
|
|
105
|
+
return this.value
|
|
118
106
|
}
|
|
119
107
|
|
|
120
108
|
/**
|
|
@@ -124,34 +112,19 @@ class HyperStorage<T> {
|
|
|
124
112
|
* Using this function should be avoided when possible and is not type safe.
|
|
125
113
|
*/
|
|
126
114
|
sync(decodeFn = this.decodeFn): unknown {
|
|
127
|
-
let
|
|
115
|
+
let json = this.storage.getItem(this.itemName)
|
|
128
116
|
|
|
129
117
|
// Reset value to defaultValue if it does not exist in storage
|
|
130
|
-
if (typeof
|
|
118
|
+
if (typeof json !== 'string') return this.reset()
|
|
131
119
|
|
|
132
120
|
// Reset value to defaultValue if the incoming value is not properly encoded
|
|
133
121
|
try {
|
|
134
|
-
value = decodeFn(
|
|
122
|
+
return (this.value = decodeFn(json))
|
|
135
123
|
} catch (err) {
|
|
136
124
|
this.reset()
|
|
137
125
|
console.error(err)
|
|
138
126
|
return err
|
|
139
127
|
}
|
|
140
|
-
|
|
141
|
-
if (value[0] !== '\0') return (this.value = value as T) // Raw string value
|
|
142
|
-
|
|
143
|
-
// Slice off '\0' prefix
|
|
144
|
-
value = value.slice(1)
|
|
145
|
-
|
|
146
|
-
if (value[0] === '\0') return (this.value = value as T) // Raw string value that started with '\0'
|
|
147
|
-
|
|
148
|
-
// Parse non JSON
|
|
149
|
-
if (value === 'undefined') return (this.value = undefined as any)
|
|
150
|
-
if (value === 'NaN') return (this.value = NaN as any)
|
|
151
|
-
if (value === 'Infinity') return (this.value = Infinity as any)
|
|
152
|
-
if (value === '-Infinity') return (this.value = -Infinity as any)
|
|
153
|
-
|
|
154
|
-
return (this.value = JSON.parse(value) as any)
|
|
155
128
|
}
|
|
156
129
|
|
|
157
130
|
/**
|