UNPKG

@plasmohq/storage

Version:

Safely and securely store data and share them across your extension and websites

2 lines (1 loc) 6.47 kB
var A=Object.create;var p=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var V=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var R=(i,e)=>{for(var t in e)p(i,t,{get:e[t],enumerable:!0})},T=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of M(e))!k.call(i,a)&&a!==t&&p(i,a,{get:()=>e[a],enumerable:!(r=x(e,a))||r.enumerable});return i};var N=(i,e,t)=>(t=i!=null?A(V(i)):{},T(e||!i||!i.__esModule?p(t,"default",{value:i,enumerable:!0}):t,i)),P=i=>T(p({},"__esModule",{value:!0}),i);var L={};R(L,{useStorage:()=>E});module.exports=P(L);var n=require("react");var C=N(require("pify"),1);var v=()=>{try{let e=(globalThis.navigator?.userAgent).match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i)||[];if(e[1]==="Chrome")return parseInt(e[2])<100||globalThis.chrome.runtime?.getManifest()?.manifest_version===2}catch{return!1}return!1};var w=class{#a;#t;get primaryClient(){return this.#t}#e;get secondaryClient(){return this.#e}#s;get area(){return this.#s}get hasWebApi(){try{return typeof window<"u"&&!!window.localStorage}catch(e){return console.error(e),!1}}#r=new Map;#i;get copiedKeySet(){return this.#i}isCopied=e=>this.hasWebApi&&(this.allCopied||this.copiedKeySet.has(e));#n=!1;get allCopied(){return this.#n}getExtStorageApi=()=>globalThis.browser?.storage||globalThis.chrome?.storage;get hasExtensionApi(){try{return!!this.getExtStorageApi()}catch(e){return console.error(e),!1}}isWatchSupported=()=>this.hasExtensionApi;keyNamespace="";isValidKey=e=>e.startsWith(this.keyNamespace);getNamespacedKey=e=>`${this.keyNamespace}${e}`;getUnnamespacedKey=e=>e.slice(this.keyNamespace.length);serde={serializer:JSON.stringify,deserializer:JSON.parse};constructor({area:e="sync",allCopied:t=!1,copiedKeyList:r=[],serde:a={}}={}){this.setCopiedKeySet(r),this.#s=e,this.#n=t,this.serde={...this.serde,...a};try{this.hasWebApi&&(t||r.length>0)&&(this.#e=window.localStorage)}catch{}try{this.hasExtensionApi&&(this.#a=this.getExtStorageApi(),v()?this.#t=(0,C.default)(this.#a[this.area],{exclude:["getBytesInUse"],errorFirst:!1}):this.#t=this.#a[this.area])}catch{}}setCopiedKeySet(e){this.#i=new Set(e)}rawGetAll=()=>this.#t?.get();getAll=async()=>{let e=await this.rawGetAll();return Object.entries(e).filter(([t])=>this.isValidKey(t)).reduce((t,[r,a])=>(t[this.getUnnamespacedKey(r)]=a,t),{})};copy=async e=>{let t=e===void 0;if(!t&&!this.copiedKeySet.has(e)||!this.allCopied||!this.hasExtensionApi)return!1;let r=this.allCopied?await this.rawGetAll():await this.#t.get((t?[...this.copiedKeySet]:[e]).map(this.getNamespacedKey));if(!r)return!1;let a=!1;for(let s in r){let o=r[s],c=this.#e?.getItem(s);this.#e?.setItem(s,o),a||=o!==c}return a};rawGet=async e=>(await this.rawGetMany([e]))[e];rawGetMany=async e=>this.hasExtensionApi?await this.#t.get(e):e.filter(this.isCopied).reduce((t,r)=>(t[r]=this.#e?.getItem(r),t),{});rawSet=async(e,t)=>await this.rawSetMany({[e]:t});rawSetMany=async e=>(this.#e&&Object.entries(e).filter(([t])=>this.isCopied(t)).forEach(([t,r])=>this.#e.setItem(t,r)),this.hasExtensionApi&&await this.#t.set(e),null);clear=async(e=!1)=>{e&&this.#e?.clear(),await this.#t.clear()};rawRemove=async e=>{await this.rawRemoveMany([e])};rawRemoveMany=async e=>{this.#e&&e.filter(this.isCopied).forEach(t=>this.#e.removeItem(t)),this.hasExtensionApi&&await this.#t.remove(e)};removeAll=async()=>{let e=await this.getAll(),t=Object.keys(e);await this.removeMany(t)};watch=e=>{let t=this.isWatchSupported();return t&&this.#o(e),t};#o=e=>{for(let t in e){let r=this.getNamespacedKey(t),a=this.#r.get(r)?.callbackSet||new Set;if(a.add(e[t]),a.size>1)continue;let s=(o,c)=>{if(c!==this.area||!o[r])return;let h=this.#r.get(r);if(!h)throw new Error(`Storage comms does not exist for nsKey: ${r}`);Promise.all([this.parseValue(o[r].newValue),this.parseValue(o[r].oldValue)]).then(([d,g])=>{for(let u of h.callbackSet)u({newValue:d,oldValue:g},c)})};this.#a.onChanged.addListener(s),this.#r.set(r,{callbackSet:a,listener:s})}};unwatch=e=>{let t=this.isWatchSupported();return t&&this.#c(e),t};#c(e){for(let t in e){let r=this.getNamespacedKey(t),a=e[t],s=this.#r.get(r);s&&(s.callbackSet.delete(a),s.callbackSet.size===0&&(this.#r.delete(r),this.#a.onChanged.removeListener(s.listener)))}}unwatchAll=()=>this.#l();#l(){this.#r.forEach(({listener:e})=>this.#a.onChanged.removeListener(e)),this.#r.clear()}async getItem(e){return this.get(e)}async getItems(e){return await this.getMany(e)}async setItem(e,t){await this.set(e,t)}async setItems(e){await await this.setMany(e)}async removeItem(e){return this.remove(e)}async removeItems(e){return await this.removeMany(e)}},m=class extends w{get=async e=>{let t=this.getNamespacedKey(e),r=await this.rawGet(t);return this.parseValue(r)};getMany=async e=>{let t=e.map(this.getNamespacedKey),r=await this.rawGetMany(t),a=await Promise.all(Object.values(r).map(this.parseValue));return Object.keys(r).reduce((s,o,c)=>(s[this.getUnnamespacedKey(o)]=a[c],s),{})};set=async(e,t)=>{let r=this.getNamespacedKey(e),a=this.serde.serializer(t);return this.rawSet(r,a)};setMany=async e=>{let t=Object.entries(e).reduce((r,[a,s])=>(r[this.getNamespacedKey(a)]=this.serde.serializer(s),r),{});return await this.rawSetMany(t)};remove=async e=>{let t=this.getNamespacedKey(e);return this.rawRemove(t)};removeMany=async e=>{let t=e.map(this.getNamespacedKey);return await this.rawRemoveMany(t)};setNamespace=e=>{this.keyNamespace=e};parseValue=async e=>{try{if(e!==void 0)return this.serde.deserializer(e)}catch(t){console.error(t)}}};function E(i,e){let t=typeof i=="object",r=t?i.key:i,[a,s]=(0,n.useState)(e),[o,c]=(0,n.useState)(!0),h=(0,n.useRef)(!1),d=(0,n.useRef)(e instanceof Function?e():e);(0,n.useEffect)(()=>{d.current=a},[a]);let g=(0,n.useRef)(t?i.instance:new m),u=(0,n.useCallback)(l=>g.current.set(r,l!==void 0?l:d.current),[r]),f=(0,n.useCallback)(async l=>{let S=l instanceof Function?l(d.current):l;await u(S),h.current&&s(S)},[u]);(0,n.useEffect)(()=>{h.current=!0;let l={[r]:y=>{h.current&&(s(y.newValue),c(!1))}};return g.current.watch(l),(async()=>{let y=await g.current.get(r);if(e instanceof Function){let b=e?.(y,!0);b!==void 0&&await f(b)}else s(y!==void 0?y:e);c(!1)})(),()=>{h.current=!1,g.current.unwatch(l),e instanceof Function&&s(e)}},[r,f]);let K=(0,n.useCallback)(()=>{g.current.remove(r),s(void 0)},[r]);return[a,f,{setRenderValue:s,setStoreValue:u,remove:K,isLoading:o}]}0&&(module.exports={useStorage});