hyperstorage-js 6.0.6 → 6.0.7

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 CHANGED
@@ -44,7 +44,7 @@ The biggest burdens of working with the **Storage API** is verifying values on e
44
44
 
45
45
  ```bash
46
46
  # npm
47
- npm install hyperstorage-js
47
+ npm i hyperstorage-js
48
48
 
49
49
  # pnpm
50
50
  pnpm add hyperstorage-js
@@ -101,10 +101,10 @@ The default method that works for all use cases is the `value` setter.
101
101
  store.value = 'anything'
102
102
  ```
103
103
 
104
- The [`set()` (click)](#setkeyorcallback-keyof-t--value-t--t-value-tkeyof-t-t) method is a handy wrapper for assigning and can be used as shown in the examples below, which are sorted from best to worst practice.
104
+ The [`set()`](#setkeyorcallback-keyof-t--value-t--t-value-tkeyof-t-t) method is a handy wrapper for assigning and can be used as shown in the examples below, which are sorted from best to worst practice.
105
105
 
106
106
  <details>
107
- <summary><strong>Object: Change Only One Property</strong></summary>
107
+ <summary><strong>Object: Change Single Property</strong></summary>
108
108
 
109
109
  ```js
110
110
  // Property setter
@@ -140,18 +140,18 @@ numberStore.value = numberStore.value + 2
140
140
  Use `sessionStorage` to only remember data for the duration of a session.
141
141
 
142
142
  ```js
143
- const sessionStore = new HyperStorage('sessionData', 'none', {
143
+ const sessionStore = new HyperStorage('session', 'none', {
144
144
  storage: window.sessionStorage,
145
145
  })
146
146
 
147
147
  sessionStore.value = 'temporary'
148
148
  console.log(sessionStore.value) // 'temporary'
149
- console.log(sessionStore.storage) // Storage {sessionData: '{"json":"temporary"}', length: 1}
149
+ console.log(sessionStore.storage) // Storage {session: '{"json":"temporary"}', length: 1}
150
150
  ```
151
151
 
152
- ### Using Encoding and Decoding Functions
152
+ ### Using the Encoding and Decoding Functions
153
153
 
154
- If you want to make stored data harder to reverse-engineer, use the `encodeFn` and `decodeFn` options.
154
+ If you want to make stored data harder to reverse-engineer or change the parser, use the `encodeFn` and `decodeFn` options.
155
155
 
156
156
  The default values for `encodeFn` and `decodeFn` are:
157
157
 
@@ -163,17 +163,17 @@ decodeFn = (value) => HyperStorage.superjson.parse(value)
163
163
  <details>
164
164
  <summary><strong>Base64 Example</strong></summary>
165
165
 
166
- Apply Base64 encoding using JavaScript's `btoa` (String to Base64) and `atob` (Base64 to String).
166
+ Apply Base64 encoding on top of superjson using JavaScript's `btoa` (String to Base64) and `atob` (Base64 to String) functions.
167
167
 
168
168
  ```js
169
- const sessionStore = new HyperStorage('sessionData', 'none', {
170
- encodeFn: (value) => btoa(value),
171
- decodeFn: (value) => atob(value),
169
+ const sessionStore = new HyperStorage('session', 'none', {
170
+ encodeFn: (value) => btoa(HyperStorage.superjson.stringify(value)),
171
+ decodeFn: (value) => HyperStorage.superjson.parse(atob(value)),
172
172
  })
173
173
 
174
174
  sessionStore.value = 'temporary'
175
175
  console.log(sessionStore.value) // 'temporary'
176
- console.log(sessionStore.storage) // Storage  {sessionData: 'dGVtcG9yYXJ5', length: 1}
176
+ console.log(sessionStore.storage) // Storage  {session: 'eyJqc29uIjoidGVtcG9yYXJ5In0=', length: 1}
177
177
  ```
178
178
 
179
179
  </details>
@@ -201,10 +201,10 @@ interface Settings {
201
201
  }
202
202
 
203
203
  const defaultValue: Settings = { theme: 'system', language: 'en' }
204
- const userStore = new HyperStorage<Settings>('userSettings', defaultValue)
204
+ const settingsStore = new HyperStorage<Settings>('userSettings', defaultValue)
205
205
 
206
206
  // Property 'language' is missing in type '{ theme: "dark"; }' but required in type 'Settings'. ts(2741)
207
- userStore.value = { theme: 'dark' }
207
+ settingsStore.value = { theme: 'dark' }
208
208
  ```
209
209
 
210
210
  ### Using `sync()`
@@ -214,14 +214,14 @@ Safe usage of `sync()` requires explicit runtime validation before accessing any
214
214
  ```ts
215
215
  // ... continues from the above example
216
216
 
217
- const result = userStore.sync() // (method): unknown
218
- // Right now, 'result' equals 'userStore.value' exactly
217
+ const result = settingsStore.sync() // (method): unknown
218
+ // Right now, 'result' equals 'settingsStore.value' exactly
219
219
 
220
220
  // 'result' is of type 'unknown'. ts(18046)
221
221
  console.log(result.theme) // 'dark'
222
222
 
223
223
  // No error, but unsafe
224
- console.log(userStore.value.theme) // 'dark'
224
+ console.log(settingsStore.value.theme) // 'dark'
225
225
 
226
226
  // Must narrow down to be safe
227
227
  if (result && typeof result === 'object' && 'theme' in result) {
@@ -288,7 +288,7 @@ if (result && typeof result === 'object' && 'theme' in result) {
288
288
  - Returns `true` if the current value matches the default, otherwise `false`.
289
289
 
290
290
  ```js
291
- if (userStore.isDefault()) {
291
+ if (settingsStore.isDefault()) {
292
292
  console.log('value equals the default value.')
293
293
  }
294
294
  ```
@@ -307,13 +307,13 @@ The return type is `unknown` because data read from `Storage` cannot be type-che
307
307
 
308
308
  ```js
309
309
  // External change to storage (to be avoided)
310
- localStorage.setItem('userSettings', '{"theme":"dark"}')
310
+ localStorage.setItem('settings', '{"theme":"dark"}')
311
311
 
312
312
  // Resynchronize the cache, optionally with a custom decoder
313
- userStore.sync((value) => JSON.parse(value))
313
+ settingsStore.sync((value) => JSON.parse(value))
314
314
 
315
- console.log(userStore.value) // { theme: 'dark' }
316
- console.log(userStore.storage) // Storage {userSettings: '{"json":{"theme":"dark"}}', length: 1}
315
+ console.log(settingsStore.value) // { theme: 'dark' }
316
+ console.log(settingsStore.storage) // Storage {settings: '{"json":{"theme":"dark"}}', length: 1}
317
317
  ```
318
318
 
319
319
  <br>
@@ -324,31 +324,31 @@ console.log(userStore.storage) // Storage {userSettings: '{"json":{"theme":"dark
324
324
  1. The item in `Storage` is undecodable by the `decodeFn` passed to `sync()`.
325
325
 
326
326
  ```js
327
- localStorage.setItem('userSettings', 'not an object')
327
+ localStorage.setItem('settings', 'not an object')
328
328
 
329
329
  // SyntaxError: Unexpected token 'o', "not an object" is not valid JSON
330
- const result = userStore.sync((value) => JSON.parse(value))
330
+ const result = settingsStore.sync((value) => JSON.parse(value))
331
331
  // Execution continues because sync() uses a try-catch
332
332
 
333
333
  console.log(result) // instance of SyntaxError
334
334
 
335
335
  // Reset to default value
336
- console.log(userStore.value) // {theme: 'system', language: 'en'}
336
+ console.log(settingsStore.value) // {theme: 'system', language: 'en'}
337
337
  ```
338
338
 
339
339
  2. The item in `Storage`, after being decoded, is not of type `T`.
340
340
 
341
341
  ```js
342
- localStorage.setItem('userSettings', '{"not":"valid"}')
342
+ localStorage.setItem('settings', '{"not":"valid"}')
343
343
 
344
- const result = userStore.sync((value) => JSON.parse(value))
344
+ const result = settingsStore.sync((value) => JSON.parse(value))
345
345
  console.log(result) // {not: 'valid'}
346
- console.log(userStore.value) // {not: 'valid'}
346
+ console.log(settingsStore.value) // {not: 'valid'}
347
347
  ```
348
348
 
349
- No errors, but `result` and `userStore.value` are both not of type `T`.
349
+ No errors, but `result` and `settingsStore.value` are both not of type `T`.
350
350
 
351
- This **must** be manually checked and `userStore.reset()` should be called if the check fails.
351
+ This **must** be manually checked and `settingsStore.reset()` should be called if the check fails.
352
352
 
353
353
  ```js
354
354
  // This example is specifically for type 'Settings'
@@ -363,11 +363,11 @@ if (
363
363
  // 'result' is of type 'T'
364
364
  } else {
365
365
  // 'result' is not of type 'T'
366
- userStore.reset()
367
- console.log(userStore.value) // {theme: 'system', language: 'en'}
366
+ settingsStore.reset()
367
+ console.log(settingsStore.value) // {theme: 'system', language: 'en'}
368
368
  }
369
369
 
370
- // 'userStore.value' is of type 'T'
370
+ // 'settingsStore.value' is of type 'T'
371
371
  ```
372
372
 
373
373
  </details>
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.6";
870
+ static version = "6.0.7";
871
871
  static superjson = SuperJSON;
872
872
  /** Key name under which the data is stored. */
873
873
  itemName;
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.6";
868
+ static version = "6.0.7";
869
869
  static superjson = SuperJSON;
870
870
  /** Key name under which the data is stored. */
871
871
  itemName;
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 DoubleIndexedKV{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 Registry{constructor(e){this.generateIdentifier=e,this.kv=new DoubleIndexedKV}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 ClassRegistry extends Registry{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 e(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 t(e,t){Object.entries(e).forEach(([e,r])=>t(r,e))}function r(e,t){return-1!==e.indexOf(t)}function n(e,t){for(let r=0;r<e.length;r++){const n=e[r];if(t(n))return n}}class CustomTransformerRegistry{constructor(){this.transfomers={}}register(e){this.transfomers[e.name]=e}findApplicable(t){return e(this.transfomers,e=>e.isApplicable(t))}findByName(e){return this.transfomers[e]}}const s=e=>void 0===e,o=e=>"object"==typeof e&&null!==e&&(e!==Object.prototype&&(null===Object.getPrototypeOf(e)||Object.getPrototypeOf(e)===Object.prototype)),i=e=>o(e)&&0===Object.keys(e).length,a=e=>Array.isArray(e),u=e=>e instanceof Map,l=e=>e instanceof Set,c=e=>"Symbol"===(e=>Object.prototype.toString.call(e).slice(8,-1))(e),f=e=>e instanceof Error,p=e=>"number"==typeof e&&isNaN(e),d=e=>(e=>"boolean"==typeof e)(e)||(e=>null===e)(e)||s(e)||(e=>"number"==typeof e&&!isNaN(e))(e)||(e=>"string"==typeof e)(e)||c(e),y=e=>e.replace(/\\/g,"\\\\").replace(/\./g,"\\."),g=e=>e.map(String).map(y).join("."),m=(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 h(e,t,r,n){return{isApplicable:e,annotation:t,transform:r,untransform:n}}const S=[h(s,"undefined",()=>null,()=>{}),h(e=>"bigint"==typeof e,"bigint",e=>e.toString(),e=>"undefined"!=typeof BigInt?BigInt(e):(console.error("Please add a BigInt polyfill."),e)),h(e=>e instanceof Date&&!isNaN(e.valueOf()),"Date",e=>e.toISOString(),e=>new Date(e)),h(f,"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}),h(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)}),h(l,"set",e=>[...e.values()],e=>new Set(e)),h(u,"map",e=>[...e.entries()],e=>new Map(e)),h(e=>{return p(e)||((t=e)===1/0||t===-1/0);var t},"number",e=>p(e)?"NaN":e>0?"Infinity":"-Infinity",Number),h(e=>0===e&&1/e==-1/0,"number",()=>"-0",Number),h(e=>e instanceof URL,"URL",e=>e.toString(),e=>new URL(e))];function b(e,t,r,n){return{isApplicable:e,annotation:t,transform:r,untransform:n}}const w=b((e,t)=>{if(c(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}),O=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,Uint8ClampedArray].reduce((e,t)=>(e[t.name]=t,e),{}),N=b(e=>ArrayBuffer.isView(e)&&!(e instanceof DataView),e=>["typed-array",e.constructor.name],e=>[...e],(e,t)=>{const r=O[t[1]];if(!r)throw new Error("Trying to deserialize unknown typed array");return new r(e)});function v(e,t){if(e?.constructor){return!!t.classRegistry.getIdentifier(e.constructor)}return!1}const E=b(v,(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)}),I=b((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)}),J=[E,w,I,N],k=(e,t)=>{const r=n(J,r=>r.isApplicable(e,t));if(r)return{value:r.transform(e,t),type:r.annotation(e,t)};const s=n(S,r=>r.isApplicable(e,t));return s?{value:s.transform(e,t),type:s.annotation}:void 0},j={};S.forEach(e=>{j[e.annotation]=e});const A=(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 T(e){if(r(e,"__proto__"))throw new Error("__proto__ is not allowed as a property");if(r(e,"prototype"))throw new Error("prototype is not allowed as a property");if(r(e,"constructor"))throw new Error("constructor is not allowed as a property")}const R=(e,t,r)=>{if(T(t),0===t.length)return r(e);let n=e;for(let e=0;e<t.length-1;e++){const r=t[e];if(a(n)){n=n[+r]}else if(o(n))n=n[r];else if(l(n)){n=A(n,+r)}else if(u(n)){if(e===t.length-2)break;const s=+r,o=0===+t[++e]?"key":"value",i=A(n,s);switch(o){case"key":n=i;break;case"value":n=n.get(i)}}}const s=t[t.length-1];if(a(n)?n[+s]=r(n[+s]):o(n)&&(n[s]=r(n[s])),l(n)){const e=A(n,+s),t=r(e);e!==t&&(n.delete(e),n.add(t))}if(u(n)){const e=+t[t.length-2],o=A(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},V=e=>e<1;function P(e,r,n,s=[]){if(!e)return;const o=V(n);if(!a(e))return void t(e,(e,t)=>P(e,r,n,[...s,...m(t,o)]));const[i,u]=e;u&&t(u,(e,t)=>{P(e,r,n,[...s,...m(t,o)])}),r(i,s)}function z(e,t,r,n){return P(t,(t,r)=>{e=R(e,r,e=>((e,t,r)=>{if(!a(t)){const n=j[t];if(!n)throw new Error("Unknown transformation: "+t);return n.untransform(e,r)}switch(t[0]){case"symbol":return w.untransform(e,t,r);case"class":return E.untransform(e,t,r);case"custom":return I.untransform(e,t,r);case"typed-array":return N.untransform(e,t,r);default:throw new Error("Unknown transformation: "+t)}})(e,t,n))},r),e}function _(e,r,n){const s=V(n);function o(t,r){const n=((e,t)=>{T(t);for(let r=0;r<t.length;r++){const n=t[r];if(l(e))e=A(e,+n);else if(u(e)){const s=+n,o=0===+t[++r]?"key":"value",i=A(e,s);switch(o){case"key":e=i;break;case"value":e=e.get(i)}}else e=e[n]}return e})(e,m(r,s));t.map(e=>m(e,s)).forEach(t=>{e=R(e,t,()=>n)})}if(a(r)){const[n,i]=r;n.forEach(t=>{e=R(e,m(t,s),()=>e)}),i&&t(i,o)}else t(r,o);return e}const x=(e,n,s,c,p=[],g=[],m=new Map)=>{const h=d(e);if(!h){!function(e,t,r){const n=r.get(e);n?n.push(t):r.set(e,[t])}(e,p,n);const t=m.get(e);if(t)return c?{transformedValue:null}:t}if(!((e,t)=>o(e)||a(e)||u(e)||l(e)||f(e)||v(e,t))(e,s)){const t=k(e,s),r=t?{transformedValue:t.value,annotations:[t.type]}:{transformedValue:e};return h||m.set(e,r),r}if(r(g,e))return{transformedValue:null};const S=k(e,s),b=S?.value??e,w=a(b)?[]:{},O={};t(b,(r,i)=>{if("__proto__"===i||"constructor"===i||"prototype"===i)throw new Error(`Detected property ${i}. This is a prototype pollution risk, please remove it from your object.`);const u=x(r,n,s,c,[...p,i],[...g,e],m);w[i]=u.transformedValue,a(u.annotations)?O[y(i)]=u.annotations:o(u.annotations)&&t(u.annotations,(e,t)=>{O[y(i)+"."+t]=e})});const N=i(O)?{transformedValue:w,annotations:S?[S.type]:void 0}:{transformedValue:w,annotations:S?[S.type,O]:O};return h||m.set(e,N),N};function C(e){return Object.prototype.toString.call(e).slice(8,-1)}function F(e){return"Array"===C(e)}function B(e,t={}){if(F(e))return e.map(e=>B(e,t));if(!function(e){if("Object"!==C(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(F(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,B(e[n],t),e,t.nonenumerable),r},{})}class SuperJSON{constructor({dedupe:e=!1}={}){this.classRegistry=new ClassRegistry,this.symbolRegistry=new Registry(e=>e.description??""),this.customTransformerRegistry=new CustomTransformerRegistry,this.allowedErrorProps=[],this.dedupe=e}serialize(e){const t=new Map,r=x(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(g):r[g(s)]=o.map(g)}),n?i(r)?[n]:[n,r]:i(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:B(r);return n?.values&&(s=z(s,n.values,n.v??0,this)),n?.referentialEqualities&&(s=_(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)}}SuperJSON.defaultInstance=new SuperJSON,SuperJSON.serialize=SuperJSON.defaultInstance.serialize.bind(SuperJSON.defaultInstance),SuperJSON.deserialize=SuperJSON.defaultInstance.deserialize.bind(SuperJSON.defaultInstance),SuperJSON.stringify=SuperJSON.defaultInstance.stringify.bind(SuperJSON.defaultInstance),SuperJSON.parse=SuperJSON.defaultInstance.parse.bind(SuperJSON.defaultInstance),SuperJSON.registerClass=SuperJSON.defaultInstance.registerClass.bind(SuperJSON.defaultInstance),SuperJSON.registerSymbol=SuperJSON.defaultInstance.registerSymbol.bind(SuperJSON.defaultInstance),SuperJSON.registerCustom=SuperJSON.defaultInstance.registerCustom.bind(SuperJSON.defaultInstance),SuperJSON.allowErrorProps=SuperJSON.defaultInstance.allowErrorProps.bind(SuperJSON.defaultInstance),SuperJSON.serialize,SuperJSON.deserialize,SuperJSON.stringify,SuperJSON.parse,SuperJSON.registerClass,SuperJSON.registerCustom,SuperJSON.registerSymbol,SuperJSON.allowErrorProps;class HyperStorage{static version="6.0.6";static superjson=SuperJSON;itemName;defaultValue;#e;#t;storage;#r;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.#e=n||(e=>HyperStorage.superjson.stringify(e)),s&&"function"!=typeof s)throw new TypeError("decodeFn is defined but is not a function");if(this.#t=s||(e=>HyperStorage.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.#r=e,this.storage.setItem(this.itemName,this.#e(e))}get value(){return this.#r}set(e,t){return this.value="function"==typeof e?e(this.#r):{...this.#r,[e]:t}}sync(e=this.#t){const t=this.storage.getItem(this.itemName);if(null===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.#r===this.defaultValue}}return HyperStorage});
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 DoubleIndexedKV{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 Registry{constructor(e){this.generateIdentifier=e,this.kv=new DoubleIndexedKV}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 ClassRegistry extends Registry{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 e(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 t(e,t){Object.entries(e).forEach(([e,r])=>t(r,e))}function r(e,t){return-1!==e.indexOf(t)}function n(e,t){for(let r=0;r<e.length;r++){const n=e[r];if(t(n))return n}}class CustomTransformerRegistry{constructor(){this.transfomers={}}register(e){this.transfomers[e.name]=e}findApplicable(t){return e(this.transfomers,e=>e.isApplicable(t))}findByName(e){return this.transfomers[e]}}const s=e=>void 0===e,o=e=>"object"==typeof e&&null!==e&&(e!==Object.prototype&&(null===Object.getPrototypeOf(e)||Object.getPrototypeOf(e)===Object.prototype)),i=e=>o(e)&&0===Object.keys(e).length,a=e=>Array.isArray(e),u=e=>e instanceof Map,l=e=>e instanceof Set,c=e=>"Symbol"===(e=>Object.prototype.toString.call(e).slice(8,-1))(e),f=e=>e instanceof Error,p=e=>"number"==typeof e&&isNaN(e),d=e=>(e=>"boolean"==typeof e)(e)||(e=>null===e)(e)||s(e)||(e=>"number"==typeof e&&!isNaN(e))(e)||(e=>"string"==typeof e)(e)||c(e),y=e=>e.replace(/\\/g,"\\\\").replace(/\./g,"\\."),g=e=>e.map(String).map(y).join("."),m=(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 h(e,t,r,n){return{isApplicable:e,annotation:t,transform:r,untransform:n}}const S=[h(s,"undefined",()=>null,()=>{}),h(e=>"bigint"==typeof e,"bigint",e=>e.toString(),e=>"undefined"!=typeof BigInt?BigInt(e):(console.error("Please add a BigInt polyfill."),e)),h(e=>e instanceof Date&&!isNaN(e.valueOf()),"Date",e=>e.toISOString(),e=>new Date(e)),h(f,"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}),h(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)}),h(l,"set",e=>[...e.values()],e=>new Set(e)),h(u,"map",e=>[...e.entries()],e=>new Map(e)),h(e=>{return p(e)||((t=e)===1/0||t===-1/0);var t},"number",e=>p(e)?"NaN":e>0?"Infinity":"-Infinity",Number),h(e=>0===e&&1/e==-1/0,"number",()=>"-0",Number),h(e=>e instanceof URL,"URL",e=>e.toString(),e=>new URL(e))];function b(e,t,r,n){return{isApplicable:e,annotation:t,transform:r,untransform:n}}const w=b((e,t)=>{if(c(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}),O=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,Uint8ClampedArray].reduce((e,t)=>(e[t.name]=t,e),{}),N=b(e=>ArrayBuffer.isView(e)&&!(e instanceof DataView),e=>["typed-array",e.constructor.name],e=>[...e],(e,t)=>{const r=O[t[1]];if(!r)throw new Error("Trying to deserialize unknown typed array");return new r(e)});function v(e,t){if(e?.constructor){return!!t.classRegistry.getIdentifier(e.constructor)}return!1}const E=b(v,(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)}),I=b((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)}),J=[E,w,I,N],k=(e,t)=>{const r=n(J,r=>r.isApplicable(e,t));if(r)return{value:r.transform(e,t),type:r.annotation(e,t)};const s=n(S,r=>r.isApplicable(e,t));return s?{value:s.transform(e,t),type:s.annotation}:void 0},j={};S.forEach(e=>{j[e.annotation]=e});const A=(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 T(e){if(r(e,"__proto__"))throw new Error("__proto__ is not allowed as a property");if(r(e,"prototype"))throw new Error("prototype is not allowed as a property");if(r(e,"constructor"))throw new Error("constructor is not allowed as a property")}const R=(e,t,r)=>{if(T(t),0===t.length)return r(e);let n=e;for(let e=0;e<t.length-1;e++){const r=t[e];if(a(n)){n=n[+r]}else if(o(n))n=n[r];else if(l(n)){n=A(n,+r)}else if(u(n)){if(e===t.length-2)break;const s=+r,o=0===+t[++e]?"key":"value",i=A(n,s);switch(o){case"key":n=i;break;case"value":n=n.get(i)}}}const s=t[t.length-1];if(a(n)?n[+s]=r(n[+s]):o(n)&&(n[s]=r(n[s])),l(n)){const e=A(n,+s),t=r(e);e!==t&&(n.delete(e),n.add(t))}if(u(n)){const e=+t[t.length-2],o=A(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},V=e=>e<1;function P(e,r,n,s=[]){if(!e)return;const o=V(n);if(!a(e))return void t(e,(e,t)=>P(e,r,n,[...s,...m(t,o)]));const[i,u]=e;u&&t(u,(e,t)=>{P(e,r,n,[...s,...m(t,o)])}),r(i,s)}function z(e,t,r,n){return P(t,(t,r)=>{e=R(e,r,e=>((e,t,r)=>{if(!a(t)){const n=j[t];if(!n)throw new Error("Unknown transformation: "+t);return n.untransform(e,r)}switch(t[0]){case"symbol":return w.untransform(e,t,r);case"class":return E.untransform(e,t,r);case"custom":return I.untransform(e,t,r);case"typed-array":return N.untransform(e,t,r);default:throw new Error("Unknown transformation: "+t)}})(e,t,n))},r),e}function _(e,r,n){const s=V(n);function o(t,r){const n=((e,t)=>{T(t);for(let r=0;r<t.length;r++){const n=t[r];if(l(e))e=A(e,+n);else if(u(e)){const s=+n,o=0===+t[++r]?"key":"value",i=A(e,s);switch(o){case"key":e=i;break;case"value":e=e.get(i)}}else e=e[n]}return e})(e,m(r,s));t.map(e=>m(e,s)).forEach(t=>{e=R(e,t,()=>n)})}if(a(r)){const[n,i]=r;n.forEach(t=>{e=R(e,m(t,s),()=>e)}),i&&t(i,o)}else t(r,o);return e}const x=(e,n,s,c,p=[],g=[],m=new Map)=>{const h=d(e);if(!h){!function(e,t,r){const n=r.get(e);n?n.push(t):r.set(e,[t])}(e,p,n);const t=m.get(e);if(t)return c?{transformedValue:null}:t}if(!((e,t)=>o(e)||a(e)||u(e)||l(e)||f(e)||v(e,t))(e,s)){const t=k(e,s),r=t?{transformedValue:t.value,annotations:[t.type]}:{transformedValue:e};return h||m.set(e,r),r}if(r(g,e))return{transformedValue:null};const S=k(e,s),b=S?.value??e,w=a(b)?[]:{},O={};t(b,(r,i)=>{if("__proto__"===i||"constructor"===i||"prototype"===i)throw new Error(`Detected property ${i}. This is a prototype pollution risk, please remove it from your object.`);const u=x(r,n,s,c,[...p,i],[...g,e],m);w[i]=u.transformedValue,a(u.annotations)?O[y(i)]=u.annotations:o(u.annotations)&&t(u.annotations,(e,t)=>{O[y(i)+"."+t]=e})});const N=i(O)?{transformedValue:w,annotations:S?[S.type]:void 0}:{transformedValue:w,annotations:S?[S.type,O]:O};return h||m.set(e,N),N};function C(e){return Object.prototype.toString.call(e).slice(8,-1)}function F(e){return"Array"===C(e)}function B(e,t={}){if(F(e))return e.map(e=>B(e,t));if(!function(e){if("Object"!==C(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(F(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,B(e[n],t),e,t.nonenumerable),r},{})}class SuperJSON{constructor({dedupe:e=!1}={}){this.classRegistry=new ClassRegistry,this.symbolRegistry=new Registry(e=>e.description??""),this.customTransformerRegistry=new CustomTransformerRegistry,this.allowedErrorProps=[],this.dedupe=e}serialize(e){const t=new Map,r=x(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(g):r[g(s)]=o.map(g)}),n?i(r)?[n]:[n,r]:i(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:B(r);return n?.values&&(s=z(s,n.values,n.v??0,this)),n?.referentialEqualities&&(s=_(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)}}SuperJSON.defaultInstance=new SuperJSON,SuperJSON.serialize=SuperJSON.defaultInstance.serialize.bind(SuperJSON.defaultInstance),SuperJSON.deserialize=SuperJSON.defaultInstance.deserialize.bind(SuperJSON.defaultInstance),SuperJSON.stringify=SuperJSON.defaultInstance.stringify.bind(SuperJSON.defaultInstance),SuperJSON.parse=SuperJSON.defaultInstance.parse.bind(SuperJSON.defaultInstance),SuperJSON.registerClass=SuperJSON.defaultInstance.registerClass.bind(SuperJSON.defaultInstance),SuperJSON.registerSymbol=SuperJSON.defaultInstance.registerSymbol.bind(SuperJSON.defaultInstance),SuperJSON.registerCustom=SuperJSON.defaultInstance.registerCustom.bind(SuperJSON.defaultInstance),SuperJSON.allowErrorProps=SuperJSON.defaultInstance.allowErrorProps.bind(SuperJSON.defaultInstance),SuperJSON.serialize,SuperJSON.deserialize,SuperJSON.stringify,SuperJSON.parse,SuperJSON.registerClass,SuperJSON.registerCustom,SuperJSON.registerSymbol,SuperJSON.allowErrorProps;class HyperStorage{static version="6.0.7";static superjson=SuperJSON;itemName;defaultValue;#e;#t;storage;#r;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.#e=n||(e=>HyperStorage.superjson.stringify(e)),s&&"function"!=typeof s)throw new TypeError("decodeFn is defined but is not a function");if(this.#t=s||(e=>HyperStorage.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.#r=e,this.storage.setItem(this.itemName,this.#e(e))}get value(){return this.#r}set(e,t){return this.value="function"==typeof e?e(this.#r):{...this.#r,[e]:t}}sync(e=this.#t){const t=this.storage.getItem(this.itemName);if(null===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.#r===this.defaultValue}}return HyperStorage});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyperstorage-js",
3
- "version": "6.0.6",
3
+ "version": "6.0.7",
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,8 +34,8 @@
34
34
  "@rollup/plugin-replace": "^6.0.3",
35
35
  "@rollup/plugin-terser": "^1.0.0",
36
36
  "@rollup/plugin-typescript": "^12.3.0",
37
- "@types/node": "^25.3.5",
38
- "pnpm": "^10.30.3",
37
+ "@types/node": "^25.4.0",
38
+ "pnpm": "^10.32.0",
39
39
  "prettier": "^3.8.1",
40
40
  "rollup": "^4.59.0",
41
41
  "rollup-plugin-delete": "^3.0.2",