synapse-storage
Version:
Набор инструментов для управления состоянием и апи-запросами
1 lines • 83 kB
JavaScript
var Te={debug:(s,...e)=>{process.env.NODE_ENV},log:(s,...e)=>{process.env.NODE_ENV},info:(s,...e)=>{},warn:(s,...e)=>{},error:(s,...e)=>{}};function be(s){return`${s?`${s}|`:""}${Math.random().toString(36).substring(2,9)+Date.now().toString(36)}`}function we(s){let e={};return s.forEach((t,n)=>{e[n.toLowerCase()]=t}),e}function G(s={},e={}){return{...s,...e,getFromStorage:s.getFromStorage||(t=>{try{let n=localStorage.getItem(t);return n?JSON.parse(n):void 0}catch{return}}),getCookie:s.getCookie||(t=>{try{let n=document.cookie.match(new RegExp(`(?:^|; )${t.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,"\\$1")}=([^;]*)`));return n?decodeURIComponent(n[1]):void 0}catch{return}})}}async function Ee(s,e){let t=new Headers,n=e||G({},{});if(s)try{t=await Promise.resolve(s(t,n))}catch{}return t}function Re(s,e){return async(t,n)=>{let r=new Headers(t);if(s)try{r=await Promise.resolve(s(r,n))}catch{}if(e)try{r=await Promise.resolve(e(r,n))}catch{}return r}}var H=(o=>(o.Json="json",o.Blob="blob",o.ArrayBuffer="arrayBuffer",o.Text="text",o.FormData="formData",o.Raw="raw",o))(H||{});function ve(s){let e=s.toLowerCase().split(";")[0].trim();if(e.includes("application/json"))return"json";if(e.includes("text/"))return"text";if(e.includes("multipart/form-data"))return"formData";if(e.includes("application/octet-stream")||e.includes("application/pdf")||e.includes("image/")||e.includes("audio/")||e.includes("video/"))return"blob"}function ie(s){let e=s.get("content-type")||"",t=s.get("content-disposition")||"",n=e.includes("application/octet-stream")||e.includes("application/pdf")||e.includes("image/")||e.includes("audio/")||e.includes("video/"),r=t.includes("attachment")||t.includes("filename=");return n||r}function Ge(s){let e=s.get("content-disposition");if(!e)return;let t=e.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);if(t&&t[1])return t[1].replace(/['"]/g,"").trim()}function xe(s){let e=s.get("content-type")||"",t=s.get("content-disposition")||"",n=s.get("content-length");return ie(s)?{filename:Ge(s),contentType:e,contentDisposition:t,size:n?parseInt(n,10):void 0}:void 0}async function He(s,e){let t=e,n=s.headers.get("content-type")||"";!t&&n&&(ie(s.headers)?t="blob":t=ve(n)),t||(t="json");try{let r;switch((t==="blob"||t==="arrayBuffer")&&(r=xe(s.headers)),t){case"json":try{let o=await s.json();return s.ok?{data:o,fileMetadata:r}:{error:o,fileMetadata:r}}catch{let i=await s.text();return s.ok?{data:i,fileMetadata:r}:{error:i,fileMetadata:r}}case"text":{let o=await s.text();return s.ok?{data:o,fileMetadata:r}:{error:o,fileMetadata:r}}case"blob":{let o=await s.blob();return s.ok?{data:o,fileMetadata:r}:{error:o,fileMetadata:r}}case"arrayBuffer":{let o=await s.arrayBuffer();return s.ok?{data:o,fileMetadata:r}:{error:o,fileMetadata:r}}case"formData":{let o=await s.formData();return s.ok?{data:o,fileMetadata:r}:{error:o,fileMetadata:r}}case"raw":return s.ok?{data:s,fileMetadata:r}:{error:s,fileMetadata:r};default:let a=await s.blob();return s.ok?{data:a,fileMetadata:r}:{error:a,fileMetadata:r}}}catch(r){return s.ok?{data:void 0}:{error:r}}}function Ce(s){let{baseUrl:e,timeout:t=3e4,fetchFn:n=fetch,credentials:r="same-origin"}=s;return async(a,o={},i)=>{let{path:c,method:d,body:l,query:u,responseFormat:g}=a,{signal:p,timeout:f=t,responseFormat:y}=o,b=y||g,h=new URL(c.startsWith("http")?c:`${e}${c}`);u&&Object.entries(u).forEach(([m,w])=>{w!=null&&(Array.isArray(w)?w.forEach(x=>h.searchParams.append(m,String(x))):h.searchParams.append(m,String(w)))});let S;if(l!==void 0)if(l instanceof FormData||l instanceof Blob)S=l;else if(typeof l=="object"&&l!==null)try{S=JSON.stringify(l),i.has("Content-Type")||i.set("Content-Type","application/json")}catch{S=String(l)}else S=String(l);let v,E=new Promise((m,w)=>{f&&(v=window.setTimeout(()=>{w(new Error(`\u041F\u0440\u0435\u0432\u044B\u0448\u0435\u043D\u043E \u0432\u0440\u0435\u043C\u044F \u043E\u0436\u0438\u0434\u0430\u043D\u0438\u044F \u0437\u0430\u043F\u0440\u043E\u0441\u0430 (${f}\u043C\u0441)`))},f))});try{let m=n(h.toString(),{method:d,headers:i,body:S,signal:p,credentials:r}),w=await Promise.race([m,E]),{data:x,error:ae,fileMetadata:ze}=await He(w,b);return{data:x,error:ae,ok:w.ok,status:w.status,statusText:w.statusText,headers:w.headers,fileDownloadResult:ze}}catch(m){let w=m;return{error:w,ok:!1,status:0,statusText:w.message,headers:new Headers}}finally{v&&window.clearTimeout(v)}}}function Pe(s,e=[]){let t={};return!s||e.length===0||e.forEach(n=>{s.has(n)&&(t[n]=s.get(n)||"")}),t}var W=class{constructor(e,t,n,r,a,o){this.name=e;this.queryStorage=t;this.configCurrentEndpoint=n;this.cacheableHeaderKeys=r;this.globalCacheConfig=a;this.baseQueryConfig=o;this.prepareHeaders=Re(o.prepareHeaders,n.prepareHeaders),this.queryFunction=Ce({baseUrl:o.baseUrl,fetchFn:o.fetchFn,timeout:o.timeout,credentials:o.credentials}),this.cacheableHeaders=[...r||[],...n.includeCacheableHeaderKeys||[]].filter(i=>!n.excludeCacheableHeaderKeys?.includes(i)),this.meta.name=e,this.meta.tags=n.tags??this.meta.tags,this.meta.invalidatesTags=n.invalidatesTags??this.meta.invalidatesTags,this.meta.cache=this.queryStorage.createCacheConfig(this.configCurrentEndpoint)??this.meta.cache}endpointSubscribers=new Set;fetchCounts=0;meta={cache:!1,invalidatesTags:[],name:"",tags:[]};queryFunction;cacheableHeaders;prepareHeaders;request(e,t){this.fetchCounts++;let n=be(this.name),r=new AbortController,a=new Set,o={status:"idle",requestParams:e,headers:{},error:void 0,data:void 0,fromCache:!1},i=G({requestParams:e},t?.context||{}),c=l=>{Object.assign(o,l),a.forEach(u=>{u({...o})})},d=new Promise(async(l,u)=>{try{let g=await Ee(this.prepareHeaders,i),p=Pe(g,t?.cacheableHeaderKeys?t.cacheableHeaderKeys:this.cacheableHeaders),f=this.queryStorage.shouldCache(this.configCurrentEndpoint,t),[y,b]=this.queryStorage.createCacheKey(this.name,{...e,...p}),h;if(f&&(h=await this.queryStorage.getCachedResult(y)),h)c({fromCache:!0,status:"success",data:h.data,error:void 0,headers:h.headers,requestParams:e}),l({...h,fromCache:!0});else{c({fromCache:!1,status:"loading"});let S=this.configCurrentEndpoint.request(e,t?.context),v={...t,signal:r.signal},E=await this.queryFunction(S,v,g);if(E.ok){let{headers:m,...w}=E;if(this.configCurrentEndpoint.invalidatesTags?.length&&await this.queryStorage.invalidateCacheByTags(this.configCurrentEndpoint.invalidatesTags),f){let x=this.queryStorage.createCacheConfig(this.configCurrentEndpoint);await this.queryStorage.setCachedResult(y,{...w,headers:we(m)},x,b??{},this.configCurrentEndpoint.tags??[])}c({fromCache:!1,status:"success",data:E.data,error:void 0,headers:E.headers,requestParams:e}),this.endpointSubscribers.forEach(x=>{let ae={status:"success",fetchCounts:this.fetchCounts,meta:this.meta,cacheableHeaders:this.cacheableHeaders,error:void 0};x(ae)}),l({...E,fromCache:!1})}else c({fromCache:!1,status:"error",data:void 0,error:E.error,headers:E.headers,requestParams:e}),this.endpointSubscribers.forEach(m=>{let w={status:"error",fetchCounts:this.fetchCounts,meta:this.meta,cacheableHeaders:this.cacheableHeaders,error:E.error};m(w)}),u(E.error)}}catch(g){c({fromCache:!1,status:"error",data:void 0,error:g,headers:void 0,requestParams:e}),u(g)}});return{id:n,subscribe(l,u={}){let{autoUnsubscribe:g=!0}=u;a.add(l),l(o);let p=()=>a.delete(l);return g&&d.finally(()=>{p()}),p},wait:()=>d,waitWithCallbacks(l={}){let{idle:u,loading:g,success:p,error:f}=l;return this.subscribe(y=>{switch(y.status){case"idle":u?.(y);break;case"loading":g?.(y);break;case"success":p?.(y.data,y);break;case"error":f?.(y.error,y);break}},{autoUnsubscribe:!0}),d},abort:()=>{r&&!r.signal.aborted&&r.abort()},then:(l,u)=>d.then(l,u),catch:l=>d.catch(l),finally:l=>d.finally(l)}}subscribe(e){this.endpointSubscribers.add(e);let t={status:"idle",fetchCounts:this.fetchCounts,meta:this.meta,cacheableHeaders:this.cacheableHeaders,error:void 0};return e(t),()=>this.endpointSubscribers.delete(e)}reset(){return this.fetchCounts=0,Promise.resolve()}destroy(){this.endpointSubscribers.clear()}};var T=class{constructor(e,t=!1){this.value=e;this.isRawKey=t}toString(){return this.value}toJSON(){return this.value}valueOf(){return this.value}isUnparseable(){return this.isRawKey}};var D=class{static createMetadata(e=0,t=[]){let n=Date.now(),r=e>0?n+e:1/0;return{createdAt:n,updatedAt:n,expiresAt:r,tags:t,createdAtDateTime:this.formatDateTime(n),updatedAtDateTime:this.formatDateTime(n),expiresAtDateTime:r===1/0?"never":this.formatDateTime(r)}}static formatDateTime(e){return new Date(e).toISOString()}static isExpired(e){return Date.now()>e.expiresAt}static updateMetadata(e){return{...e,updatedAt:Date.now()}}static createKey(...e){return new T(e.join("_"))}static createApiKey(e,t){if(!t)return[new T(e,!0),t];let n=Object.entries(t).sort(([r],[a])=>r.localeCompare(a)).map(([r,a])=>`${r}=${a}`).join("&");return[new T(`${e}_${n}`,!0),t]}static hasAnyTag(e,t=[]){return!e.tags||!t.length?!1:t.some(n=>e.tags?.includes(n))}};var Q=class{constructor(e,t){this.storageExternal=e;this.globalCacheConfig=t}storage=null;cleanupInterval=null;defaultCacheOptions={ttl:5*60*1e3,cleanup:{enabled:!0,interval:10*60*1e3},invalidateOnError:!0};async initialize(){return await this.createStorage(),this.startCleanupInterval(),this}async createStorage(){try{let e=this.storageExternal;await e.initialize(),this.storage=e}catch(e){throw e}}startCleanupInterval(){this.cleanupInterval&&(clearInterval(this.cleanupInterval),this.cleanupInterval=null);let e=typeof this.globalCacheConfig=="object"?this.globalCacheConfig.cleanup:this.defaultCacheOptions.cleanup;e?.enabled&&e.interval&&(this.cleanupInterval=setInterval(()=>{this.cleanup().catch(t=>{})},e.interval))}getStorage(){return this.storage}createCacheKey(e,t){return D.createApiKey(e,t)}async getCachedResult(e){if(!this.storage)throw new Error("\u0425\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435 \u043D\u0435 \u0438\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u043E");let t=await this.storage.get(e);if(!t)return;if(D.isExpired(t.metadata)){await this.storage.delete(e);return}let n={...t,metadata:D.updateMetadata(t.metadata)};return await this.storage.set(e,n),t.data}async setCachedResult(e,t,n,r,a){if(!this.storage)throw new Error("\u0425\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435 \u043D\u0435 \u0438\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u043E");let o=D.createMetadata(n.ttl,a),i={data:t,metadata:o,params:r};await this.storage.set(e,i)}shouldCache(e,t){return!(this.globalCacheConfig===!1||e?.cache===!1||typeof e?.cache=="object"&&e?.cache.ttl===0||t?.disableCache===!0||this.globalCacheConfig===void 0&&e?.cache===void 0)}createCacheConfig(e){let t=this.defaultCacheOptions;if(typeof this.globalCacheConfig=="object"&&(t=this.globalCacheConfig),typeof e?.cache=="object"){let n=e.cache;t={...t,...n}}return t}async invalidateCacheByTags(e){if(!this.storage)throw new Error("\u0425\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435 \u043D\u0435 \u0438\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u043E");let t=await this.storage.keys();for(let n of t){let r=await this.storage.get(n);r&&D.hasAnyTag(r.metadata,e)&&await this.storage.delete(n)}}async invalidateCache(e){if(!this.storage)throw new Error("\u0425\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435 \u043D\u0435 \u0438\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u043E");await this.storage.delete(e)}async cleanup(){if(!this.storage)throw new Error("\u0425\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435 \u043D\u0435 \u0438\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u043E");let e=await this.storage.keys();for(let t of e){let n=await this.storage.get(t);n&&D.isExpired(n.metadata)&&await this.storage.delete(t)}}async destroy(){this.cleanupInterval&&(window.clearInterval(this.cleanupInterval),this.cleanupInterval=null),this.storage&&(await this.storage.destroy(),this.storage=null)}};var Ae=class{queryStorage;cacheableHeaderKeys;globalCacheConfig;baseQueryConfig;storageExternal;createEndpoints;endpoints={};constructor(e){this.cacheableHeaderKeys=e.cacheableHeaderKeys,this.globalCacheConfig=e.cache,this.baseQueryConfig=e.baseQuery,this.storageExternal=e.storage,this.createEndpoints=e.endpoints}async init(){return this.queryStorage=await new Q(this.storageExternal,this.globalCacheConfig).initialize(),await this.initializeEndpoints(),this}async initializeEndpoints(){let e=n=>n,t=await this.createEndpoints(e)||{};for(let[n,r]of Object.entries(t)){let a=n;this.endpoints[a]=new W(n,this.queryStorage,r,this.cacheableHeaderKeys,this.globalCacheConfig,this.baseQueryConfig)}}getEndpoints(){return this.endpoints}async request(e,t,n){let a=this.getEndpoints()[e];if(!a)throw new Error(`\u042D\u043D\u0434\u043F\u043E\u0438\u043D\u0442 ${String(e)} \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D`);try{return await a.request(t,n).wait()}catch(o){throw Te.error(`\u041E\u0448\u0438\u0431\u043A\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u043A ${String(e)}`,{error:o,params:t}),o}}async destroy(){await Promise.all(Object.values(this.endpoints).map(async e=>(e.destroy(),Promise.resolve()))),this.endpoints={},await this.queryStorage.destroy()}};var R=!1,q=new Map;function Ie(s){let e=0;if(s.length===0)return e.toString(36);for(let t=0;t<s.length;t++){let n=s.charCodeAt(t);e=(e<<5)-e+n,e=e&e}return Math.abs(e).toString(36).substring(0,6)}function I(s,e){if(s===e)return!0;if(s==null||e==null)return!1;if(typeof s!="object"&&typeof s!="function"&&typeof e!="object"&&typeof e!="function")return s===e;if(typeof s!=typeof e)return!1;if(s instanceof Date&&e instanceof Date)return s.getTime()===e.getTime();if(Array.isArray(s)&&Array.isArray(e)){if(s.length!==e.length)return!1;for(let t=0;t<s.length;t++)if(!I(s[t],e[t]))return!1;return!0}if(typeof s=="object"&&typeof e=="object"){let t=Object.keys(s),n=Object.keys(e);return t.length!==n.length?!1:t.every(r=>Object.prototype.hasOwnProperty.call(e,r)?I(s[r],e[r]):!1)}return!1}function De(s,e=I){let t,n,r=!1;return function(o){if(!r||t!==o){let i=s(o);(!r||!e(i,n))&&(n=i),t=o,r=!0}return n}}var Y=class{constructor(e,t,n=I,r){this.name=e;this.equals=n;this.logger=r;this.id=e,this.memoizedGetState=this.createMemoizedGetState(t)}id;subscribers=new Set;lastValue;memoizedGetState;createMemoizedGetState(e){let t=null,n=!1;return async()=>{if(n&&t)return t;n=!0;try{return t=e(),await t}finally{n=!1}}}async notify(){try{let e=await this.memoizedGetState();if(this.lastValue===void 0||!this.equals(e,this.lastValue)){this.lastValue=e;let t=Array.from(this.subscribers).map(async n=>{try{await n.notify(e)}catch(r){this.logger?.error(`[${this.id}] \u041E\u0448\u0438\u0431\u043A\u0430 \u0432 \u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u0438 \u043F\u043E\u0434\u043F\u0438\u0441\u0447\u0438\u043A\u0430`,{error:r})}});await Promise.all(t)}}catch(e){throw this.logger?.error(`[${this.id}] \u041E\u0448\u0438\u0431\u043A\u0430 \u0432 notify()`,{error:e}),e}}subscribe(e){return this.subscribers.add(e),this.lastValue!==void 0?Promise.resolve().then(()=>{try{e.notify(this.lastValue)}catch(t){this.logger?.error(`[${this.id}] \u041E\u0448\u0438\u0431\u043A\u0430 \u0432 \u043F\u0435\u0440\u0432\u043E\u043D\u0430\u0447\u0430\u043B\u044C\u043D\u043E\u043C \u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u0438`,{error:t})}}):this.notify().catch(t=>{this.logger?.error(`[${this.id}] \u041E\u0448\u0438\u0431\u043A\u0430 \u0432 \u043F\u0435\u0440\u0432\u043E\u043D\u0430\u0447\u0430\u043B\u044C\u043D\u043E\u043C \u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u0438`,{error:t})}),()=>{this.subscribers.delete(e)}}cleanup(){this.subscribers.clear(),this.lastValue=void 0}getId(){return this.id}},J=class{constructor(e,t){this.source=e;this.logger=t;this.storageName=e.name,this.source.getState().then(n=>{this.cachedState=n})}storageName;subscriptions=new Map;cachedState;localSelectorCache=new Map;batchUpdateInProgress=!1;pendingUpdates=new Set;generateName(e,t,n){let r=e?"simple":"combined",a="";if(e){let o=t.toString();a=Ie(o)}else{let o=t.map(c=>c.getId()).join("_"),i=n.toString();a=Ie(o+i)}return`${this.storageName}_${r}_${a}`}processPendingUpdates(){this.pendingUpdates.size===0||this.batchUpdateInProgress||(this.batchUpdateInProgress=!0,setTimeout(async()=>{try{let e=Array.from(this.pendingUpdates);this.pendingUpdates.clear(),this.cachedState=await this.source.getState();let t=e.map(async n=>{let r=this.subscriptions.get(n);if(r)try{return await r.notify()}catch(a){this.logger?.error(`\u041E\u0448\u0438\u0431\u043A\u0430 \u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u044F \u043F\u043E\u0434\u043F\u0438\u0441\u0447\u0438\u043A\u0430 ${n}`,{error:a})}return Promise.resolve()});await Promise.all(t)}catch(e){this.logger?.error("\u041E\u0448\u0438\u0431\u043A\u0430 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0438 \u043E\u0436\u0438\u0434\u0430\u044E\u0449\u0438\u0445 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0439",{error:e})}finally{this.batchUpdateInProgress=!1,this.pendingUpdates.size>0&&this.processPendingUpdates()}},0))}createSelector(e,t,n){let r=!Array.isArray(e),a=r?t||{}:n||{},o=a.name||this.generateName(r,e,r?void 0:t);if(this.localSelectorCache.has(o))return this.localSelectorCache.get(o).api;if(q.has(o)){let l=q.get(o);return l.refCount++,l.api}let i,c,d=[];if(r){let l=De(e,a.equals||I),u=this.createSimpleSelector(l,{...a,name:o,equals:a.equals||I});i=u.api,d=u.unsubscribeFunctions}else{c=e;let l=this.createCombinedSelector(c,t,{...a,name:o,equals:a.equals||I});i=l.api,d=l.unsubscribeFunctions}return this.localSelectorCache.set(o,{api:i,dependencies:c,unsubscribeFunctions:d}),q.set(o,{api:i,refCount:1,unsubscribeFunctions:d}),i}createSimpleSelector(e,t){let n=async()=>{if(this.cachedState)return e(this.cachedState);let c=await this.source.getState();return this.cachedState=c,e(c)},r=new Y(t.name,n,t.equals||I,this.logger),a=r.getId();this.subscriptions.set(a,r);let i=[this.source.subscribeToAll(async c=>{c?.type==="storage:update"&&(this.pendingUpdates.add(a),this.processPendingUpdates())})];return{api:{select:()=>n(),subscribe:c=>r.subscribe(c),getId:()=>a},unsubscribeFunctions:i}}createCombinedSelector(e,t,n){let r=De(u=>t(...u),n.equals||I),a=async()=>{let u=await Promise.all(e.map(g=>g.select()));return r(u)},o=new Y(n.name,a,n.equals||I,this.logger),i=o.getId();this.subscriptions.set(i,o);let c=null,d=()=>{c!==null&&clearTimeout(c),c=setTimeout(()=>{c=null,o.notify().catch(u=>this.logger?.error(`[${i}] \u041E\u0448\u0438\u0431\u043A\u0430 \u0432 \u043E\u0431\u044A\u0435\u0434\u0438\u043D\u0435\u043D\u043D\u043E\u043C \u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u0438:`,{error:u}))},10)},l=e.map(u=>u.subscribe({notify:()=>{d()}}));return{api:{select:()=>a(),subscribe:u=>o.subscribe(u),getId:()=>i},unsubscribeFunctions:l}}destroy(){this.subscriptions.forEach(t=>t.cleanup()),this.subscriptions.clear(),this.cachedState=void 0,this.pendingUpdates.clear(),this.localSelectorCache.forEach(t=>{t.unsubscribeFunctions.forEach(n=>n())});let e=new Set;this.localSelectorCache.forEach((t,n)=>{e.add(n)}),this.localSelectorCache.clear(),e.forEach(t=>{let n=q.get(t);n&&(n.refCount--,n.refCount<=0&&(n.unsubscribeFunctions.forEach(r=>r()),q.delete(t)))})}};var Oe=class{constructor(e,t,n="default"){this.parentExecutor=e;this.logger=t;this.storageName=n}plugins=new Map;createContext(e){return{storageName:this.storageName,timestamp:Date.now(),metadata:e}}async add(e){if(this.plugins.has(e.name)){this.logger?.warn(`\u041F\u043B\u0430\u0433\u0438\u043D ${e.name} \u0443\u0436\u0435 \u0431\u044B\u043B \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043D`);return}try{await e.initialize?.(),this.plugins.set(e.name,e),this.logger?.info("\u041F\u043B\u0430\u0433\u0438\u043D \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D",{name:e.name})}catch(t){throw t}}async remove(e){let t=this.plugins.get(e);t&&(await t.destroy?.(),this.plugins.delete(e),this.logger?.info("\u041F\u043B\u0430\u0433\u0438\u043D \u0443\u0434\u0430\u043B\u0435\u043D",{name:e}))}get(e){return this.plugins.get(e)}getAll(){return Array.from(this.plugins.values())}async initialize(){for(let e of this.plugins.values())await e.initialize?.()}async destroy(){await Promise.all(Array.from(this.plugins.values()).map(e=>e.destroy?.()??Promise.resolve())),this.plugins.clear()}async executeBeforeSet(e,t){let n=e,r=this.createContext(t);this.parentExecutor&&(n=await this.parentExecutor.executeBeforeSet(n,r));for(let a of this.plugins.values())if(a.onBeforeSet)try{n=await a.onBeforeSet(n,r)}catch(o){throw this.logger?.error(`\u041E\u0448\u0438\u0431\u043A\u0430 \u0432 \u043F\u043B\u0430\u0433\u0438\u043D\u0435 ${a.name} onBeforeSet`,{error:o}),o}return n}async executeAfterSet(e,t,n){let r=t,a=this.createContext(n);this.parentExecutor&&(r=await this.parentExecutor.executeAfterSet(e,r,a));for(let o of this.plugins.values())if(o.onAfterSet)try{r=await o.onAfterSet(e,r,a)}catch(i){throw this.logger?.error(`\u041E\u0448\u0438\u0431\u043A\u0430 \u0432 \u043F\u043B\u0430\u0433\u0438\u043D\u0435 ${o.name} onAfterSet`,{key:e,error:i}),i}return r}async executeBeforeGet(e,t){let n=e,r=this.createContext(t);this.parentExecutor&&(n=await this.parentExecutor.executeBeforeGet(n,r));for(let a of this.plugins.values())if(a.onBeforeGet)try{n=await a.onBeforeGet(n,r)}catch(o){throw this.logger?.error(`\u041E\u0448\u0438\u0431\u043A\u0430 \u0432 \u043F\u043B\u0430\u0433\u0438\u043D\u0435 ${a.name} onBeforeGet`,{key:e,error:o}),o}return n}async executeAfterGet(e,t,n){let r=t,a=this.createContext(n);this.parentExecutor&&(r=await this.parentExecutor.executeAfterGet(e,r,a));for(let o of this.plugins.values())if(o.onAfterGet)try{r=await o.onAfterGet(e,r,a)}catch(i){throw this.logger?.error(`\u041E\u0448\u0438\u0431\u043A\u0430 \u0432 \u043F\u043B\u0430\u0433\u0438\u043D\u0435 ${o.name} onAfterGet`,{key:e,error:i}),i}return r}async executeBeforeDelete(e,t){let n=!0,r=this.createContext(t);this.parentExecutor&&(n=await this.parentExecutor.executeBeforeDelete(e,r));for(let a of this.plugins.values())if(a.onBeforeDelete)try{n=await a.onBeforeDelete(e,r)&&n}catch(o){throw this.logger?.error(`\u041E\u0448\u0438\u0431\u043A\u0430 \u0432 \u043F\u043B\u0430\u0433\u0438\u043D\u0435 ${a.name} onBeforeDelete`,{key:e,error:o}),o}return n}async executeAfterDelete(e,t){let n=this.createContext(t);this.parentExecutor&&await this.parentExecutor.executeAfterDelete(e,n);for(let r of this.plugins.values())if(r.onAfterDelete)try{await r.onAfterDelete(e,n)}catch(a){throw this.logger?.error(`\u041E\u0448\u0438\u0431\u043A\u0430 \u0432 \u043F\u043B\u0430\u0433\u0438\u043D\u0435 ${r.name} onAfterDelete`,{key:e,error:a}),a}}async executeOnClear(e){let t=this.createContext(e);this.parentExecutor&&await this.parentExecutor.executeOnClear(t);for(let n of this.plugins.values())if(n.onClear)try{await n.onClear(t)}catch(r){throw this.logger?.error(`\u041E\u0448\u0438\u0431\u043A\u0430 \u0432 \u043F\u043B\u0430\u0433\u0438\u043D\u0435 ${n.name} onClear`,{error:r}),r}}};var ce=(a=>(a.STRICT="strict",a.FIRST_WINS="first_wins",a.DEEP_MERGE="deep_merge",a.OVERRIDE="override",a.WARN_AND_USE_FIRST="warn_and_use_first",a))(ce||{});var le=(r=>(r.IDLE="idle",r.LOADING="loading",r.READY="ready",r.ERROR="error",r))(le||{}),de=(o=>(o.STORAGE_UPDATE="storage:update",o.STORAGE_DELETE="storage:delete",o.STORAGE_PATCH="storage:patch",o.STORAGE_SELECT="storage:select",o.STORAGE_CLEAR="storage:clear",o.STORAGE_DESTROY="storage:destroy",o))(de||{});var X=class{channel;tabId;messageHandlers;syncHandler;debug;syncTimeoutMs=1e3;pendingSyncRequests;constructor(e,t={}){this.channel=new BroadcastChannel(e),this.tabId=crypto.randomUUID(),this.messageHandlers=new Set,this.debug=t.debug??!1,this.pendingSyncRequests=new Map,this.channel.onmessage=this.handleMessage.bind(this),this.channel.onmessageerror=this.handleError.bind(this)}log(...e){this.debug}error(...e){}async handleMessage(e){let t=e.data;if(t.senderId!==this.tabId){if(t.type==="SYNC_REQUEST"){if(this.syncHandler)try{let n=await this.syncHandler();this.postMessage("SYNC_RESPONSE",n,t.senderId)}catch(n){this.error("Error handling sync request:",n)}return}if(t.type==="SYNC_RESPONSE"){let n=this.pendingSyncRequests.get(this.tabId);n&&(clearTimeout(n.timeout),this.pendingSyncRequests.delete(this.tabId),n.resolve(t.payload));return}for(let n of this.messageHandlers)try{await n(t)}catch(r){this.error("Error in message handler:",r)}}}handleError(e){this.error("Channel error:",e)}postMessage(e,t,n){let r={type:e,payload:t,senderId:this.tabId,timestamp:Date.now()};this.channel.postMessage(r)}subscribe(e){return this.messageHandlers.add(e),()=>this.messageHandlers.delete(e)}setSyncHandler(e){this.syncHandler=e}broadcast(e,t){this.postMessage(e,t)}async requestSync(){return new Promise((e,t)=>{let n=setTimeout(()=>{this.pendingSyncRequests.delete(this.tabId),e(null)},this.syncTimeoutMs);this.pendingSyncRequests.set(this.tabId,{resolve:e,reject:t,timeout:n}),this.postMessage("SYNC_REQUEST",{type:"sync"})})}close(){for(let[,e]of this.pendingSyncRequests)clearTimeout(e.timeout),e.reject(new Error("Channel closed"));this.pendingSyncRequests.clear(),this.messageHandlers.clear(),this.syncHandler=void 0,this.channel.close()}};async function We(s,e,t){switch(e){case"set":t?.key!==void 0&&t?.value!==void 0&&(await s.storage.doSet(t.key,t.value),s.storage.notifySubscribers(t.key,t.value));break;case"update":Array.isArray(t?.value)&&(await s.storage.doUpdate(t.value),t.value.forEach(({key:n,value:r})=>{s.storage.notifySubscribers(n,r)}));break;case"delete":t?.key!==void 0&&(await s.storage.doDelete(t.key),s.storage.notifySubscribers(t.key,void 0));break;case"clear":await s.storage.doClear(),s.storage.notifySubscribers("*",{type:"storage:update",value:{},source:"broadcast"});break}s.storage.notifySubscribers("*",{type:"storage:update",key:t?.key,value:t?.value,source:"broadcast"})}async function Qe(s,e,t){switch(e){case"set":if(t?.key!==void 0){let n=await s.storage.doGet(t.key);s.storage.notifySubscribers(t.key,n)}break;case"update":if(Array.isArray(t?.value)){for(let{key:n}of t.value){let r=await s.storage.doGet(n);s.storage.notifySubscribers(n,r)}s.storage.notifySubscribers("*",{type:"storage:update",key:t.value.map(({key:n})=>n),value:t.value,source:"broadcast"})}break;case"delete":t?.key!==void 0&&s.storage.notifySubscribers(t.key,void 0);break;case"clear":s.storage.notifySubscribers("*",{type:"storage:update",value:{},source:"broadcast"});break}e!=="update"&&s.storage.notifySubscribers("*",{type:"storage:update",key:t?.key,value:e==="delete"?void 0:t?.value,source:"broadcast"})}var Me=s=>{let{storageName:e,storageType:t}=s,n=`${t}-${e}`,r=new X(n,{debug:!0});return{name:"broadcast",setup:a=>(t==="memory"&&(r.setSyncHandler(async()=>{let o=await a.getState();return{type:"update",key:"*",value:Object.entries(o).map(([d,l])=>({key:d,value:l})),metadata:{batchUpdate:!0,timestamp:Date.now()}}}),r.requestSync().then(async o=>{if(o?.type==="update"&&Array.isArray(o.value))try{if(!o.value.every(c=>c&&typeof c=="object"&&"key"in c&&"value"in c))return;await a.storage.doUpdate(o.value),o.value.forEach(({key:c,value:d})=>{a.storage.notifySubscribers(c,d)}),a.storage.notifySubscribers("*",{type:"storage:update",value:o.value,source:"broadcast"})}catch{}})),r.subscribe(async o=>{let{type:i,payload:c}=o;t==="memory"?await We(a,i,c):await Qe(a,i,c)})),reducer:a=>o=>async i=>{let c=await o(i);return["set","delete","clear","update"].includes(i.type)&&r.broadcast(i.type,i),c},cleanup:()=>{r.close()}}};var $=class{static instances=new Map;static configs=new Map;static logger;static setLogger(e){this.logger=e}static getOrCreate(e,t,n){let r=this.configs.get(e),a=this.instances.get(e);if(a&&r){let i=this.mergeConfigurations(r,t);return{instance:a,isNewInstance:!1,appliedConfig:i.finalConfig,conflicts:i.conflicts}}let o=n(t);return this.instances.set(e,o),this.configs.set(e,{...t}),this.logger?.debug(`Created new singleton instance: ${e}`),{instance:o,isNewInstance:!0,appliedConfig:t,conflicts:[]}}static exists(e){return this.instances.has(e)}static getConfig(e){return this.configs.get(e)}static remove(e){let t=this.instances.get(e);return t?(typeof t.destroy=="function"&&t.destroy(),this.instances.delete(e),this.configs.delete(e),this.logger?.debug(`Removed singleton instance: ${e}`),!0):!1}static clear(){for(let[e,t]of this.instances)typeof t.destroy=="function"&&t.destroy();this.instances.clear(),this.configs.clear(),this.logger?.debug("Cleared all singleton instances")}static getStats(){return{instanceCount:this.instances.size,instances:Array.from(this.instances.keys())}}static mergeConfigurations(e,t){let n=t.singleton?.mergeStrategy||"first_wins",r=t.singleton?.warnOnConflict??!0;switch(n){case"strict":return this.strictMerge(e,t);case"first_wins":return this.firstWinsMerge(e,t,r);case"deep_merge":return this.deepMerge(e,t);case"override":return this.overrideMerge(e,t);case"warn_and_use_first":return this.warnAndUseFirst(e,t);default:return this.firstWinsMerge(e,t,r)}}static strictMerge(e,t){let n=this.findConflicts(e,t);if(n.length>0)throw new Error(`Strict singleton validation failed for "${e.name}". Conflicts: ${n.join(", ")}`);return{finalConfig:e,conflicts:[]}}static firstWinsMerge(e,t,n){let r=this.findConflicts(e,t);return n&&r.length>0&&(this.logger?.warn(`Singleton config conflicts for "${e.name}":`,r),this.logger?.warn("Using existing configuration")),{finalConfig:e,conflicts:r}}static deepMerge(e,t){let n=this.findConflicts(e,t),r={...e,initialState:this.deepMergeObjects(e.initialState||{},t.initialState||{})};return this.logger?.debug(`Deep merged singleton config for "${e.name}"`),{finalConfig:r,conflicts:n}}static overrideMerge(e,t){let n=this.findConflicts(e,t),r={...t,name:e.name};return this.logger?.warn(`Overriding singleton config for "${e.name}"`),{finalConfig:r,conflicts:n}}static warnAndUseFirst(e,t){let n=this.findConflicts(e,t);return n.length>0&&(this.logger?.warn(`Configuration conflicts detected for singleton "${e.name}":`),this.logger?.warn("Existing config:",e),this.logger?.warn("Incoming config:",t),this.logger?.warn("Using existing configuration")),{finalConfig:e,conflicts:n}}static findConflicts(e,t){let n=[];if(e.initialState&&t.initialState){let r=this.findObjectConflicts(e.initialState,t.initialState,"initialState");n.push(...r)}else e.initialState!==t.initialState&&n.push("initialState: one is undefined");return!!e.middlewares!=!!t.middlewares&&n.push("middlewares: configuration differs"),n}static findObjectConflicts(e,t,n){let r=[],a=new Set([...Object.keys(e||{}),...Object.keys(t||{})]);for(let o of a){let i=`${n}.${o}`,c=e?.[o],d=t?.[o];c!==d&&(c===void 0||d===void 0?r.push(`${i}: missing in one config`):typeof c!=typeof d?r.push(`${i}: type mismatch (${typeof c} vs ${typeof d})`):typeof c=="object"&&c!==null&&d!==null?r.push(...this.findObjectConflicts(c,d,i)):r.push(`${i}: value mismatch (${c} vs ${d})`))}return r}static deepMergeObjects(e,t){let n={...e};for(let r in t)t[r]!==null&&typeof t[r]=="object"&&!Array.isArray(t[r])?n[r]=this.deepMergeObjects(e[r]||{},t[r]):n[r]=t[r];return n}},K=class{static generate(e,t){return e.singleton?.key?e.singleton.key:`${t}_${e.name}`}};var M=class{static handleSingletonCreation(e,t,n,r){if(!e.singleton?.enabled)return n(e);r&&$.setLogger(r);let a=K.generate(e,t),o=$.getOrCreate(a,e,n);return o.isNewInstance?r?.debug(`Created new singleton storage: ${a}`):(r?.debug(`Reusing existing singleton storage: ${a}`),o.conflicts&&o.conflicts.length>0&&r?.debug(`Configuration conflicts detected: ${o.conflicts.join(", ")}`)),o.instance}};var Fe=(s={})=>{let e=s.batchSize??10,t=s.batchDelay??10,n=new Map,r=new Map,a=g=>g.type==="set"||g.type==="update",o=g=>`${g.type}_${g.key?.toString()||"default"}`,i=g=>{let p=new Map;for(let f of g){let y=`${f.type}_${f.key?.toString()||"default"}`;p.set(y,f)}return Array.from(p.values())},c=g=>{let p=r.get(g);p&&(globalThis.clearTimeout(p),r.delete(g))},d=(g,p)=>{let f=globalThis.setTimeout(p,t);r.set(g,f)},l=async(g,p,f)=>{let y=n.get(g);if(!(!y||y.length===0)){n.delete(g),c(g);try{let b=y.map(S=>S.action),h=i(b);for(let S of h)try{let v=await f(S);y.filter(m=>m.action.type===S.type&&m.action.key?.toString()===S.key?.toString()).forEach(m=>m.resolve(v))}catch(v){y.filter(m=>m.action.type===S.type&&m.action.key?.toString()===S.key?.toString()).forEach(m=>m.reject(v))}}catch(b){y.forEach(h=>h.reject(b))}}},u=async(g,p,f)=>new Promise((y,b)=>{let h=o(g),S=n.get(h);S||(S=[],n.set(h,S)),S.push({action:g,resolve:y,reject:b,timestamp:Date.now()}),c(h),S.length>=e?setImmediate(()=>l(h,p,f)):d(h,()=>l(h,p,f))});return{name:"batching",setup:()=>{},cleanup:async()=>{r.forEach(g=>globalThis.clearTimeout(g)),r.clear(),n.clear()},reducer:g=>p=>async f=>a(f)?u(f,g,p):p(f)}};var $e=(s={})=>{let{comparator:e=(r,a)=>{if(r===a)return!0;if(typeof r!="object"||typeof a!="object"||r===null||a===null)return r===a;let o=Object.keys(r),i=Object.keys(a);return o.length!==i.length?!1:o.every(c=>Object.prototype.hasOwnProperty.call(a,c)&&r[c]===a[c])},segments:t=[]}=s,n=new Map;return{name:"shallow-compare",setup:r=>{},reducer:r=>a=>async o=>{if(o.type!=="set"||t.length&&!t.includes(o.metadata?.segment??"default"))return a(o);let i=o.key,c=n.get(i),d=o.value;if(c!==void 0&&e(c,d))return{...c,t:{valueNotChanged:!0,originalValue:c}};let l=await a(o);return n.set(i,d),l}}};var Z=class{middlewares=[];api;initialized=!1;dispatchFn;constructor(e){this.api={dispatch:async t=>this.dispatch(t),getState:()=>e.getState(),storage:{doGet:e.doGet.bind(e),doSet:e.doSet.bind(e),doUpdate:e.doUpdate.bind(e),doDelete:e.doDelete.bind(e),doClear:e.doClear.bind(e),doKeys:e.doKeys.bind(e),notifySubscribers:e.notifySubscribers.bind(e)}}}async baseOperation(e){let{processed:t,...n}=e.metadata||{},r={...e,metadata:n};switch(r.type){case"get":return this.api.storage.doGet(r.key);case"set":return await this.api.storage.doSet(r.key,r.value),this.api.storage.doGet(r.key);case"update":return Array.isArray(r.value)?(await this.api.storage.doUpdate(r.value),this.api.storage.doGet("")):r.value;case"delete":return this.api.storage.doDelete(r.key);case"clear":return this.api.storage.doClear();case"init":{let a=await this.api.storage.doGet("");return Object.keys(a||{}).length>0?a:r.value?(await this.api.storage.doSet("",r.value),this.api.storage.doGet("")):a}case"keys":return this.api.storage.doKeys();default:throw new Error(`Unknown action type: ${r.type}`)}}initializeMiddlewares(){if(this.initialized)return;let e=this.baseOperation.bind(this);for(let t of[...this.middlewares].reverse()){let n=e;e=async r=>{if(r.metadata?.processed)return n(r);let a={...r,metadata:{...r.metadata,processed:!0,timestamp:r.metadata?.timestamp||Date.now()}};return t.reducer(this.api)(n)(a)}}this.dispatchFn=e,this.initialized=!0}use(e){e.setup&&e.setup(this.api),this.middlewares.push(e),this.initialized=!1}async dispatch(e){this.initialized||this.initializeMiddlewares();try{return this.dispatchFn(e)}catch(t){throw t}}};function P(s){return s instanceof T&&s.isUnparseable()?[s.toString()]:s.toString().replace(/\[/g,".").replace(/\]/g,"").split(".").filter(Boolean)}function A(s,e){return P(e).reduce((n,r)=>n===void 0?void 0:n[r],s)}function O(s,e,t){if(e==="")return t;let n=P(e);if(e instanceof T&&e.isUnparseable())return s[e.toString()]=t,s;let r=n.pop(),a=n.reduce((o,i)=>{let c=n[n.indexOf(i)+1],d=!Number.isNaN(Number(c));return i in o||(o[i]=d?[]:{}),o[i]},s);return a[r]=t,s}var F=class s{constructor(e,t,n,r){this.config=e;this.pluginExecutor=t;this.eventEmitter=n;this.logger=r;this.name=e.name,this.middlewareModule=new Z({getState:this.getState.bind(this),doGet:this.doGet.bind(this),doSet:this.doSet.bind(this),doUpdate:this.doUpdate.bind(this),doDelete:this.doDelete.bind(this),doClear:this.doClear.bind(this),doKeys:this.doKeys.bind(this),notifySubscribers:this.notifySubscribers.bind(this),pluginExecutor:this.pluginExecutor,eventEmitter:this.eventEmitter,logger:this.logger}),this.initializeMiddlewares()}static GLOBAL_SUBSCRIPTION_KEY="*";static STORAGE_TYPE;name;e={status:"idle"};statusSubscribers=new Set;selectorPathCache=new WeakMap;middlewareModule;initializedMiddlewares=null;subscribers=new Map;get initStatus(){return{...this.e}}async waitForReady(){if(this.e.status==="ready")return this;if(this.e.status==="error")throw this.e.error||new Error("Storage initialization failed");return new Promise((e,t)=>{let n=this.onStatusChange(r=>{r.status==="ready"?(n(),e(this)):r.status==="error"&&(n(),t(r.error||new Error("Storage initialization failed")))})})}onStatusChange(e){return this.statusSubscribers.add(e),e(this.initStatus),()=>{this.statusSubscribers.delete(e)}}updateInitStatus(e){let t=this.e.status;this.e={...this.e,...e},t!==this.e.status&&this.logger?.debug(`Storage "${this.name}" status changed: ${t} -> ${this.e.status}`);let n=this.initStatus;this.statusSubscribers.forEach(r=>{try{r(n)}catch(a){this.logger?.error("Error in status change callback",{error:a})}})}async initialize(){if(this.e.status==="ready")return this;if(this.e.status==="loading")return this.waitForReady();this.updateInitStatus({status:"loading",error:void 0});try{let e=await this.doInitialize();return this.updateInitStatus({status:"ready",error:void 0}),e}catch(e){throw this.updateInitStatus({status:"error",error:e instanceof Error?e:new Error(String(e))}),e}}ensureReady(){if(this.e.status!=="ready")throw new Error(`Storage "${this.name}" is not ready. Current status: ${this.e.status}`)}initializeMiddlewares(){this.config.middlewares&&!this.initializedMiddlewares&&(this.initializedMiddlewares=this.config.middlewares(()=>this.getDefaultMiddleware()),this.initializedMiddlewares.forEach(e=>this.middlewareModule.use(e)))}getDefaultMiddleware(){return{batching:(e={})=>Fe(e),shallowCompare:(e={})=>$e(e)}}async initializeWithMiddlewares(){try{let e=await this.getState();!(Object.keys(e).length>0)&&this.config.initialState&&await this.middlewareModule.dispatch({type:"init",value:this.config.initialState})}catch(e){throw this.logger?.error("\u041E\u0448\u0438\u0431\u043A\u0430 \u0438\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0438 \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0430",{error:e}),e}}async get(e){this.ensureReady();try{let t={operation:"get",timestamp:Date.now(),key:e},n=await this.middlewareModule.dispatch({type:"get",key:e,metadata:t}),r=await this.pluginExecutor?.executeAfterGet(e,n,t)??n;return await this.emitEvent({type:"storage:select",payload:{key:e,value:r}}),r}catch(t){throw this.logger?.error("Error getting value",{key:e,error:t}),t}}async set(e,t){this.ensureReady();try{let n={operation:"set",timestamp:Date.now(),key:e},r=await this.pluginExecutor?.executeBeforeSet(t,n)??t,a=await this.middlewareModule.dispatch({type:"set",key:e,value:r,metadata:n}),o=a?.t?.valueNotChanged===!0,i;if(o&&a?.t?.originalValue!==void 0?i=a.t.originalValue:i=await this.pluginExecutor?.executeAfterSet(e,a,n)??a,!o){let d=[e.toString()];this.notifySubscribers(e,i),this.notifySubscribers(s.GLOBAL_SUBSCRIPTION_KEY,{type:"storage:update",key:e,value:i,changedPaths:d}),await this.emitEvent({type:"storage:update",payload:{key:e,value:i,changedPaths:d}})}}catch(n){throw this.logger?.error("Error setting value",{key:e,error:n}),n}}async update(e){this.ensureReady();try{let t={operation:"update",timestamp:Date.now()},n=await this.getState(),r=structuredClone(n);e(r);let a=this.findChangedPaths(n,r);if(a.size===0){this.logger?.debug&&this.logger.debug("No changes detected in update");return}this.logger?.debug&&this.logger.debug("Changed paths:",{paths:Array.from(a)});let o=new Set;for(let g of a){let p=g.split(".")[0];o.add(p)}let i=await Promise.all(Array.from(o).map(async g=>{let p={...t,key:g},f=await this.pluginExecutor?.executeBeforeSet(r[g],p)??r[g];return{key:g,value:f}})),c=await this.middlewareModule.dispatch({type:"update",value:i,metadata:{...t,batchUpdate:!0,changedPaths:Array.from(a)}}),d={};Array.isArray(c)?c.forEach(g=>{g&&typeof g=="object"&&"key"in g&&"value"in g&&(d[g.key]=g.value)}):c&&typeof c=="object"&&(d={...c});let l=Object.keys(d).filter(g=>!this.isEqual(n[g],d[g]));if(l.length===0){this.logger?.debug&&this.logger.debug("No actual changes after middleware processing");return}let u={};l.forEach(g=>{u[g]=d[g]}),this.logger?.debug&&this.logger.debug("Notifying subscribers about changes:",{keys:l}),this.notifySubscribers(s.GLOBAL_SUBSCRIPTION_KEY,{type:"storage:update",key:l,value:u,changedPaths:Array.from(a)});for(let g of a)try{let p=g.split(".")[0];if(p in u){let f;if(g===p)f=u[p];else{let y=g.substring(p.length+1);f=A(u[p],y)}f!==void 0&&this.notifySubscribers(g,f)}}catch(p){this.logger?.error("Error notifying path subscribers",{path:g,error:p})}await this.emitEvent({type:"storage:update",payload:{state:u,key:l,changedPaths:Array.from(a)}})}catch(t){throw this.logger?.error("Error updating state",{error:t}),t}}async delete(e){this.ensureReady();try{let t={operation:"delete",timestamp:Date.now(),key:e};if(await this.pluginExecutor?.executeBeforeDelete(e,t)===!1)return;let r=await this.middlewareModule.dispatch({type:"delete",key:e,metadata:t});if(r===!1)return;await this.pluginExecutor?.executeAfterDelete(e,t);let o=[e.toString()];this.notifySubscribers(e,void 0),this.notifySubscribers(s.GLOBAL_SUBSCRIPTION_KEY,{type:"storage:update",key:e,value:void 0,result:r,changedPaths:o}),await this.emitEvent({type:"storage:update",payload:{key:e,value:void 0,result:r,changedPaths:o}})}catch(t){throw this.logger?.error("Error deleting value",{key:e,error:t}),t}}async clear(){this.ensureReady();try{this.pluginExecutor?.executeOnClear(),await this.middlewareModule.dispatch({type:"clear"})}catch(e){throw this.logger?.error("Error clearing storage",{error:e}),e}}async keys(){this.ensureReady();try{return await this.middlewareModule.dispatch({type:"keys"})}catch(e){throw this.logger?.error("Error getting keys",{error:e}),e}}async has(e){this.ensureReady();try{return await this.doHas(e)}catch(t){throw this.logger?.error("Error checking value existence",{key:e,error:t}),t}}async getState(){try{return await this.doGet("")||{}}catch(e){throw this.logger?.error("Error getting state",{error:e}),e}}subscribeToAll(e){return this.subscribers.has(s.GLOBAL_SUBSCRIPTION_KEY)||this.subscribers.set(s.GLOBAL_SUBSCRIPTION_KEY,new Set),this.subscribers.get(s.GLOBAL_SUBSCRIPTION_KEY).add(e),()=>{let t=this.subscribers.get(s.GLOBAL_SUBSCRIPTION_KEY);t&&(t.delete(e),t.size===0&&this.subscribers.delete(s.GLOBAL_SUBSCRIPTION_KEY))}}subscribe(e,t){return typeof e=="string"?this.subscribeByKey(e,t):this.subscribeBySelector(e,t)}async destroy(){try{if(await this.clear(),await this.doDestroy(),this.initializedMiddlewares&&(await Promise.all(this.initializedMiddlewares.map(async e=>{"cleanup"in e&&await e.cleanup?.()})),this.initializedMiddlewares=null),this.statusSubscribers.clear(),this.config.singleton?.enabled){let e=this.constructor.STORAGE_TYPE,t=K.generate(this.config,e);$.remove(t)}this.updateInitStatus({status:"idle"}),await this.emitEvent({type:"storage:destroy"})}catch(e){throw this.logger?.error("Error destroying storage",{error:e}),e}}subscribeByKey(e,t){this.subscribers.has(e)||this.subscribers.set(e,new Set);let n=!1;return this.subscribers.get(e).add(t),this.get(e).then(r=>{try{n||(n=!0,t(r))}catch(a){this.logger?.error("Error in initial callback",{key:e,error:a})}}),()=>{let r=this.subscribers.get(e);r&&(r.delete(t),r.size===0&&this.subscribers.delete(e))}}createDummyState(){let e={get:(t,n)=>(t[n]=t[n]||new Proxy({},e),t[n])};return new Proxy({},e)}isEqual(e,t){if(e===t)return!0;if(e==null||t==null)return e===t;let n=typeof e;if(n!==typeof t)return!1;if(n!=="object")return e===t;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let i=0;i<e.length;i++)if(!this.isEqual(e[i],t[i]))return!1;return!0}let a=Object.keys(e),o=Object.keys(t);return a.length!==o.length?!1:a.every(i=>Object.prototype.hasOwnProperty.call(t,i)&&this.isEqual(e[i],t[i]))}extractPath(e,t){if(this.selectorPathCache.has(e))return this.selectorPathCache.get(e);let n=[],r=(a="")=>({get:(o,i)=>{if(typeof i=="symbol")return Reflect.get(o,i);let c=a?`${a}.${i}`:i;return n.push(c),new Proxy({},r(c))},has:(o,i)=>!0,ownKeys:()=>[],getOwnPropertyDescriptor:()=>({configurable:!0,enumerable:!0}),apply:(o,i,c)=>new Proxy(()=>{},r(a))});try{e(new Proxy(t,r()))}catch{}return n.length===0?"":(n.sort((a,o)=>o.length-a.length),this.selectorPathCache.set(e,n[0]),n[0])}notifySubscribers(e,t){let n=e.toString(),r=this.subscribers.get(n);r?.size&&new Set(r).forEach(o=>{try{o(t)}catch(i){this.logger?.error("\u041E\u0448\u0438\u0431\u043A\u0430 \u0432 \u043F\u043E\u0434\u043F\u0438\u0441\u0447\u0438\u043A\u0435 \u043D\u0430 \u043A\u043E\u043B\u0431\u044D\u043A",{key:n,error:i})}})}findChangedPaths(e,t,n="",r=new Set,a=new WeakMap){if(e===t)return r;if(typeof e!="object"||typeof t!="object"||e===null||t===null)return e!==t&&r.add(n||""),r;if(a.has(e))return r;a.set(e,!0);let o=new Set([...Object.keys(e||{}),...Object.keys(t||{})]);for(let i of o){let c=e[i],d=t[i];if(c===d)continue;let l=n?`${n}.${i}`:i;c&&d&&typeof c=="object"&&typeof d=="object"&&!Array.isArray(c)&&!Array.isArray(d)?this.findChangedPaths(c,d,l,r,a):Array.isArray(c)&&Array.isArray(d)?this.isEqual(c,d)||r.add(l):this.isEqual(c,d)||r.add(l)}return r}subscribeBySelector(e,t){let n=this.createDummyState(),r=this.extractPath(e,n);this.logger?.debug&&this.logger.debug("Subscribing to path:",{path:r});let a=async o=>{try{if(o==null){let d=await this.getState(),l=e(d);t(l);return}if(typeof o!="object"||o===null){t(o);return}let i=await this.getState(),c=e(i);t(c)}catch(i){this.logger?.error("Error in selector callback",{path:r,error:i}),t(o)}};return r?this.subscribeByKey(r,a):this.subscribeToAll(()=>{this.getState().then(o=>{t(e(o))})})}async emitEvent(e){try{await this.eventEmitter?.emit({...e,metadata:{...e.metadata||{},timestamp:Date.now(),storageName:this.name}})}catch(t){this.logger?.error("Error emitting event",{event:e,error:t})}}};var ue=class s{constructor(e,t,n){this.dbName=e;this.logger=n;this.dbVersion=t}static instances=new Map;db=null;initPromise=null;storeNames=new Set;dbVersion;static getInstance(e,t=1,n){s.instances.has(e)||s.instances.set(e,new s(e,t,n));let r=s.instances.get(e);return t>r.dbVersion&&(r.dbVersion=t),r}async initialize(){return this.db?this.db:(this.initPromise||(this.initPromise=this.openDatabase()),this.initPromise)}async ensureStoreExists(e){if(await this.initialize(),this.db.objectStoreNames.contains(e))return this.storeNames.add(e),this.db;this.logger?.debug(`Store "${e}" not found, upgrading database`,{dbName:this.dbName,currentStores:Array.from(this.db.objectStoreNames)}),this.db.close(),this.db=null,this.dbVersion++,this.initPromise=this.openDatabase([e]);let t=await this.initPromise;return this.storeNames.add(e),t}async openDatabase(e=[]){return new Promise((t,n)=>{this.logger?.debug(`Opening database "${this.dbName}" with version ${this.dbVersion}`);let r=indexedDB.open(this.dbName,this.dbVersion);r.onerror=()=>{this.logger?.error(`Failed to open database "${this.dbName}"`,{error:r.error}),n(r.error)},r.onsuccess=()=>{this.db=r.result;for(let a=0;a<this.db.objectStoreNames.length;a++)this.storeNames.add(this.db.objectStoreNames[a]);this.logger?.debug(`Database "${this.dbName}" opened successfully`,{version:this.db.version,stores:Array.from(this.db.objectStoreNames)}),t(this.db)},r.onupgradeneeded=a=>{let o=a.target.result;this.logger?.debug(`Upgrading database "${this.dbName}" to version ${this.dbVersion}`);for(let i of e)o.objectStoreNames.contains(i)||(this.logger?.debug(`Creating store "${i}"`),o.createObjectStore(i))}})}closeDatabase(){this.db&&(this.db.close(),this.db=null,this.initPromise=null)}async deleteDatabase(){return this.closeDatabase(),new Promise((e,t)=>{let n=indexedDB.deleteDatabase(this.dbName);n.onsuccess=()=>{this.logger?.debug(`Database "${this.dbName}" deleted successfully`),s.instances.delete(this.dbName),this.storeNames.clear(),e()},n.onerror=()=>{this.logger?.error(`Failed to delete database "${this.dbName}"`,{error:n.error}),t(n.error)}})}async ensureStoresExist(e){await this.initialize();let t=e.filter(n=>!this.db.objectStoreNames.contains(n));return t.length===0?this.db:(this.logger?.debug(`\u0421\u043E\u0437\u0434\u0430\u043D\u0438\u0435 \u043D\u0435\u0434\u043E\u0441\u0442\u0430\u044E\u0449\u0438\u0445 \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449: ${t.join(", ")}`,{dbName:this.dbName,currentStores:Array.from(this.db.objectStoreNames)}),this.db.close(),this.db=null,this.dbVersion++,this.initPromise=this.openDatabase(t),this.initPromise)}getCurrentVersion(){return this.dbVersion}},ge=class{constructor(e,t=1,n){this.dbName=e;this.logger=n;this.version=t}db=null;version;getCurrentVersion(){return this.version}openDatabase(e,t=[]){return new Promise((n,r)=>{this.logger?.debug(`\u041E\u0442\u043A\u0440\u044B\u0442\u0438\u0435 \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445 "${this.dbName}" \u0441 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 ${e}`);let a=indexedDB.open(this.dbName,e);a.onerror=()=>{this.logger?.error(`\u041E\u0448\u0438\u0431\u043A\u0430 \u043F\u0440\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u0438 \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445 "${this.dbName}"`,{error:a.error}),r(a.error)},a.onsuccess=()=>{this.db=a.result,this.version=this.db.version,this.logger?.debug(`\u0411\u0430\u0437\u0430 \u0434\u0430\u043D\u043D\u044B\u0445 "${this.dbName}" \u0443\u0441\u043F\u0435\u0448\u043D\u043E \u043E\u0442\u043A\u0440\u044B\u0442\u0430`,{version:this.db.version,stores:Array.from(this.db.objectStoreNames)}),n(this.db)}