hyperstorage-js 6.0.2 → 6.0.3
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 +4 -24
- package/dist/index.cjs +6 -28
- package/dist/index.d.ts +0 -15
- package/dist/index.mjs +6 -28
- package/dist/index.umd.js +1 -1
- package/package.json +1 -1
- package/src/index.ts +7 -31
package/README.md
CHANGED
|
@@ -102,7 +102,7 @@ console.log(userStore.storage) // Storage {userSettings: '{"json":{"theme":"dar
|
|
|
102
102
|
### Advanced Ways to Assign a New Value
|
|
103
103
|
|
|
104
104
|
```js
|
|
105
|
-
//
|
|
105
|
+
// Overwrite entirely
|
|
106
106
|
userStore.value = { theme: 'dark', language: 'en' }
|
|
107
107
|
|
|
108
108
|
// Change single property using the setter
|
|
@@ -161,16 +161,6 @@ console.log(sessionStore.defaultValue) // 'none'
|
|
|
161
161
|
console.log(sessionStore.value) // 'none'
|
|
162
162
|
```
|
|
163
163
|
|
|
164
|
-
### Removing Values
|
|
165
|
-
|
|
166
|
-
Internally uses `Storage.removeItem()` to remove the item from storage and sets the cached value to `undefined`.
|
|
167
|
-
|
|
168
|
-
```js
|
|
169
|
-
sessionStore.remove()
|
|
170
|
-
console.log(sessionStore.value) // 'none'
|
|
171
|
-
console.log(sessionStore.storage) // Storage {length: 0}
|
|
172
|
-
```
|
|
173
|
-
|
|
174
164
|
<br>
|
|
175
165
|
|
|
176
166
|
## TypeScript Usage
|
|
@@ -243,18 +233,6 @@ if (result && typeof result === 'object' && 'theme' in result) {
|
|
|
243
233
|
- Updates both `Storage` and internal cache.
|
|
244
234
|
- Returns the restored default value.
|
|
245
235
|
|
|
246
|
-
### `remove(): void`
|
|
247
|
-
|
|
248
|
-
- Removes the key and its value from `Storage`.
|
|
249
|
-
- Sets the internal cache to `undefined`.
|
|
250
|
-
- Returns nothing.
|
|
251
|
-
|
|
252
|
-
### `clear(): void`
|
|
253
|
-
|
|
254
|
-
- Clears **all keys** in `Storage`.
|
|
255
|
-
- Affects all stored data, not just this key.
|
|
256
|
-
- Returns nothing.
|
|
257
|
-
|
|
258
236
|
### `isDefault(): boolean`
|
|
259
237
|
|
|
260
238
|
- Checks whether the cached value equals the configured default.
|
|
@@ -275,7 +253,9 @@ If the underlying `Storage` is not modified through the value setter, the intern
|
|
|
275
253
|
- Reads the value from storage.
|
|
276
254
|
- Decodes it using `decodeFn`.
|
|
277
255
|
- Updates the internal cache.
|
|
278
|
-
- Returns the synchronized value.
|
|
256
|
+
- Returns the synchronized value.
|
|
257
|
+
|
|
258
|
+
The return type is `unknown` because data read from `Storage` cannot be type-checked or trusted at compile time because it may have been modified externally.
|
|
279
259
|
|
|
280
260
|
```js
|
|
281
261
|
// External change to storage (to be avoided)
|
package/dist/index.cjs
CHANGED
|
@@ -867,7 +867,7 @@ SuperJSON.allowErrorProps;
|
|
|
867
867
|
*/
|
|
868
868
|
class HyperStorage {
|
|
869
869
|
/** Version of the library, injected via Rollup replace plugin. */
|
|
870
|
-
static version = "6.0.
|
|
870
|
+
static version = "6.0.3";
|
|
871
871
|
static superjson = SuperJSON;
|
|
872
872
|
/** Key name under which the data is stored. */
|
|
873
873
|
itemName;
|
|
@@ -917,21 +917,20 @@ class HyperStorage {
|
|
|
917
917
|
* Automatically caches, stringifies and encodes the value.
|
|
918
918
|
*/
|
|
919
919
|
set value(value) {
|
|
920
|
-
// Cache real value
|
|
921
|
-
this.#value = value;
|
|
920
|
+
this.#value = value; // Cache real value
|
|
922
921
|
this.storage.setItem(this.itemName, this.encodeFn(value));
|
|
923
922
|
}
|
|
924
923
|
/**
|
|
925
924
|
* Gets the current cached value.
|
|
926
925
|
*/
|
|
927
926
|
get value() {
|
|
928
|
-
return this.#value
|
|
927
|
+
return this.#value;
|
|
929
928
|
}
|
|
930
929
|
set(keyOrCallback, value) {
|
|
931
930
|
if (typeof keyOrCallback === 'function')
|
|
932
|
-
return (this.value = keyOrCallback(this
|
|
931
|
+
return (this.value = keyOrCallback(this.#value));
|
|
933
932
|
return (this.value = {
|
|
934
|
-
...this
|
|
933
|
+
...this.#value,
|
|
935
934
|
[keyOrCallback]: value,
|
|
936
935
|
});
|
|
937
936
|
}
|
|
@@ -951,41 +950,20 @@ class HyperStorage {
|
|
|
951
950
|
return (this.value = decodeFn(json));
|
|
952
951
|
}
|
|
953
952
|
catch (err) {
|
|
954
|
-
this.reset();
|
|
955
953
|
console.error(err);
|
|
954
|
+
this.reset();
|
|
956
955
|
return err;
|
|
957
956
|
}
|
|
958
957
|
}
|
|
959
958
|
/**
|
|
960
959
|
* Resets the stored value to its configured default.
|
|
961
|
-
*
|
|
962
960
|
* Updates both the underlying storage and the internal cache.
|
|
963
961
|
*/
|
|
964
962
|
reset() {
|
|
965
963
|
return (this.value = this.defaultValue);
|
|
966
964
|
}
|
|
967
|
-
/**
|
|
968
|
-
* Removes this specific key and its value from storage.
|
|
969
|
-
*
|
|
970
|
-
* Also clears the internal cache to prevent stale data access.
|
|
971
|
-
*/
|
|
972
|
-
remove() {
|
|
973
|
-
this.#value = undefined;
|
|
974
|
-
this.storage.removeItem(this.itemName);
|
|
975
|
-
}
|
|
976
|
-
/**
|
|
977
|
-
* Clears **all** data fromstorage.
|
|
978
|
-
*
|
|
979
|
-
* This affects every key in the storage.
|
|
980
|
-
* Also clears the internal cache to prevent stale data access.
|
|
981
|
-
*/
|
|
982
|
-
clear() {
|
|
983
|
-
this.#value = undefined;
|
|
984
|
-
this.storage.clear();
|
|
985
|
-
}
|
|
986
965
|
/**
|
|
987
966
|
* Checks whether the current cached value matches the configured default value.
|
|
988
|
-
*
|
|
989
967
|
* Uses reference comparison for objects and strict equality for primitives.
|
|
990
968
|
*/
|
|
991
969
|
isDefault() {
|
package/dist/index.d.ts
CHANGED
|
@@ -63,26 +63,11 @@ declare class HyperStorage<T> {
|
|
|
63
63
|
sync(decodeFn?: (value: string) => T): unknown;
|
|
64
64
|
/**
|
|
65
65
|
* Resets the stored value to its configured default.
|
|
66
|
-
*
|
|
67
66
|
* Updates both the underlying storage and the internal cache.
|
|
68
67
|
*/
|
|
69
68
|
reset(): T;
|
|
70
|
-
/**
|
|
71
|
-
* Removes this specific key and its value from storage.
|
|
72
|
-
*
|
|
73
|
-
* Also clears the internal cache to prevent stale data access.
|
|
74
|
-
*/
|
|
75
|
-
remove(): void;
|
|
76
|
-
/**
|
|
77
|
-
* Clears **all** data fromstorage.
|
|
78
|
-
*
|
|
79
|
-
* This affects every key in the storage.
|
|
80
|
-
* Also clears the internal cache to prevent stale data access.
|
|
81
|
-
*/
|
|
82
|
-
clear(): void;
|
|
83
69
|
/**
|
|
84
70
|
* Checks whether the current cached value matches the configured default value.
|
|
85
|
-
*
|
|
86
71
|
* Uses reference comparison for objects and strict equality for primitives.
|
|
87
72
|
*/
|
|
88
73
|
isDefault(): boolean;
|
package/dist/index.mjs
CHANGED
|
@@ -865,7 +865,7 @@ SuperJSON.allowErrorProps;
|
|
|
865
865
|
*/
|
|
866
866
|
class HyperStorage {
|
|
867
867
|
/** Version of the library, injected via Rollup replace plugin. */
|
|
868
|
-
static version = "6.0.
|
|
868
|
+
static version = "6.0.3";
|
|
869
869
|
static superjson = SuperJSON;
|
|
870
870
|
/** Key name under which the data is stored. */
|
|
871
871
|
itemName;
|
|
@@ -915,21 +915,20 @@ class HyperStorage {
|
|
|
915
915
|
* Automatically caches, stringifies and encodes the value.
|
|
916
916
|
*/
|
|
917
917
|
set value(value) {
|
|
918
|
-
// Cache real value
|
|
919
|
-
this.#value = value;
|
|
918
|
+
this.#value = value; // Cache real value
|
|
920
919
|
this.storage.setItem(this.itemName, this.encodeFn(value));
|
|
921
920
|
}
|
|
922
921
|
/**
|
|
923
922
|
* Gets the current cached value.
|
|
924
923
|
*/
|
|
925
924
|
get value() {
|
|
926
|
-
return this.#value
|
|
925
|
+
return this.#value;
|
|
927
926
|
}
|
|
928
927
|
set(keyOrCallback, value) {
|
|
929
928
|
if (typeof keyOrCallback === 'function')
|
|
930
|
-
return (this.value = keyOrCallback(this
|
|
929
|
+
return (this.value = keyOrCallback(this.#value));
|
|
931
930
|
return (this.value = {
|
|
932
|
-
...this
|
|
931
|
+
...this.#value,
|
|
933
932
|
[keyOrCallback]: value,
|
|
934
933
|
});
|
|
935
934
|
}
|
|
@@ -949,41 +948,20 @@ class HyperStorage {
|
|
|
949
948
|
return (this.value = decodeFn(json));
|
|
950
949
|
}
|
|
951
950
|
catch (err) {
|
|
952
|
-
this.reset();
|
|
953
951
|
console.error(err);
|
|
952
|
+
this.reset();
|
|
954
953
|
return err;
|
|
955
954
|
}
|
|
956
955
|
}
|
|
957
956
|
/**
|
|
958
957
|
* Resets the stored value to its configured default.
|
|
959
|
-
*
|
|
960
958
|
* Updates both the underlying storage and the internal cache.
|
|
961
959
|
*/
|
|
962
960
|
reset() {
|
|
963
961
|
return (this.value = this.defaultValue);
|
|
964
962
|
}
|
|
965
|
-
/**
|
|
966
|
-
* Removes this specific key and its value from storage.
|
|
967
|
-
*
|
|
968
|
-
* Also clears the internal cache to prevent stale data access.
|
|
969
|
-
*/
|
|
970
|
-
remove() {
|
|
971
|
-
this.#value = undefined;
|
|
972
|
-
this.storage.removeItem(this.itemName);
|
|
973
|
-
}
|
|
974
|
-
/**
|
|
975
|
-
* Clears **all** data fromstorage.
|
|
976
|
-
*
|
|
977
|
-
* This affects every key in the storage.
|
|
978
|
-
* Also clears the internal cache to prevent stale data access.
|
|
979
|
-
*/
|
|
980
|
-
clear() {
|
|
981
|
-
this.#value = undefined;
|
|
982
|
-
this.storage.clear();
|
|
983
|
-
}
|
|
984
963
|
/**
|
|
985
964
|
* Checks whether the current cached value matches the configured default value.
|
|
986
|
-
*
|
|
987
965
|
* Uses reference comparison for objects and strict equality for primitives.
|
|
988
966
|
*/
|
|
989
967
|
isDefault() {
|
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";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.2";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 this.value="function"==typeof e?e(this.value):{...this.value,[e]:t}}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});
|
|
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.3";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}set(e,t){return this.value="function"==typeof e?e(this.#e):{...this.#e,[e]:t}}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 console.error(e),this.reset(),e}}reset(){return this.value=this.defaultValue}isDefault(){return this.#e===this.defaultValue}}return J});
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -32,7 +32,7 @@ class HyperStorage<T> {
|
|
|
32
32
|
readonly storage: Storage
|
|
33
33
|
|
|
34
34
|
/** Internal cached value to improve access speed. */
|
|
35
|
-
#value
|
|
35
|
+
#value!: T
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Creates a new HyperStorage instance.
|
|
@@ -61,6 +61,7 @@ class HyperStorage<T> {
|
|
|
61
61
|
|
|
62
62
|
if (typeof itemName !== 'string') throw new TypeError('itemName is not a string')
|
|
63
63
|
this.itemName = itemName
|
|
64
|
+
|
|
64
65
|
this.defaultValue = defaultValue
|
|
65
66
|
|
|
66
67
|
if (encodeFn && typeof encodeFn !== 'function') throw new TypeError('encodeFn is defined but is not a function')
|
|
@@ -80,9 +81,7 @@ class HyperStorage<T> {
|
|
|
80
81
|
* Automatically caches, stringifies and encodes the value.
|
|
81
82
|
*/
|
|
82
83
|
set value(value: T) {
|
|
83
|
-
// Cache real value
|
|
84
|
-
this.#value = value
|
|
85
|
-
|
|
84
|
+
this.#value = value // Cache real value
|
|
86
85
|
this.storage.setItem(this.itemName, this.encodeFn(value))
|
|
87
86
|
}
|
|
88
87
|
|
|
@@ -90,7 +89,7 @@ class HyperStorage<T> {
|
|
|
90
89
|
* Gets the current cached value.
|
|
91
90
|
*/
|
|
92
91
|
get value(): T {
|
|
93
|
-
return this.#value
|
|
92
|
+
return this.#value
|
|
94
93
|
}
|
|
95
94
|
|
|
96
95
|
/**
|
|
@@ -99,10 +98,10 @@ class HyperStorage<T> {
|
|
|
99
98
|
set<K extends keyof T>(key: K, value: T[K]): T
|
|
100
99
|
set(callback: (value: T) => T): T
|
|
101
100
|
set(keyOrCallback: keyof T | ((value: T) => T), value?: T[keyof T]): T {
|
|
102
|
-
if (typeof keyOrCallback === 'function') return (this.value = keyOrCallback(this
|
|
101
|
+
if (typeof keyOrCallback === 'function') return (this.value = keyOrCallback(this.#value))
|
|
103
102
|
|
|
104
103
|
return (this.value = {
|
|
105
|
-
...this
|
|
104
|
+
...this.#value,
|
|
106
105
|
[keyOrCallback]: value,
|
|
107
106
|
})
|
|
108
107
|
}
|
|
@@ -123,45 +122,22 @@ class HyperStorage<T> {
|
|
|
123
122
|
try {
|
|
124
123
|
return (this.value = decodeFn(json))
|
|
125
124
|
} catch (err) {
|
|
126
|
-
this.reset()
|
|
127
125
|
console.error(err)
|
|
126
|
+
this.reset()
|
|
128
127
|
return err
|
|
129
128
|
}
|
|
130
129
|
}
|
|
131
130
|
|
|
132
131
|
/**
|
|
133
132
|
* Resets the stored value to its configured default.
|
|
134
|
-
*
|
|
135
133
|
* Updates both the underlying storage and the internal cache.
|
|
136
134
|
*/
|
|
137
135
|
reset(): T {
|
|
138
136
|
return (this.value = this.defaultValue)
|
|
139
137
|
}
|
|
140
138
|
|
|
141
|
-
/**
|
|
142
|
-
* Removes this specific key and its value from storage.
|
|
143
|
-
*
|
|
144
|
-
* Also clears the internal cache to prevent stale data access.
|
|
145
|
-
*/
|
|
146
|
-
remove(): void {
|
|
147
|
-
this.#value = undefined
|
|
148
|
-
this.storage.removeItem(this.itemName)
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Clears **all** data fromstorage.
|
|
153
|
-
*
|
|
154
|
-
* This affects every key in the storage.
|
|
155
|
-
* Also clears the internal cache to prevent stale data access.
|
|
156
|
-
*/
|
|
157
|
-
clear(): void {
|
|
158
|
-
this.#value = undefined
|
|
159
|
-
this.storage.clear()
|
|
160
|
-
}
|
|
161
|
-
|
|
162
139
|
/**
|
|
163
140
|
* Checks whether the current cached value matches the configured default value.
|
|
164
|
-
*
|
|
165
141
|
* Uses reference comparison for objects and strict equality for primitives.
|
|
166
142
|
*/
|
|
167
143
|
isDefault(): boolean {
|