@yoltra/core 0.3.0 → 0.5.0

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @yoltra/core v0.3.0
2
+ * @yoltra/core v0.5.0
3
3
  * (c) 2026 Manu Ramirez <@pixerael>
4
4
  * License: MIT
5
5
  * Homepage: https://yoltra.dev
@@ -7,5 +7,5 @@
7
7
  * This source code is licensed under the MIT license found in the
8
8
  * LICENSE file in the root directory of this source tree
9
9
  */
10
- (function(p,m){typeof exports=="object"&&typeof module<"u"?m(exports):typeof define=="function"&&define.amd?define(["exports"],m):(p=typeof globalThis<"u"?globalThis:p||self,m(p.yoltra={}))})(this,(function(p){"use strict";var B=Object.defineProperty;var T=(p,m,g)=>m in p?B(p,m,{enumerable:!0,configurable:!0,writable:!0,value:g}):p[m]=g;var d=(p,m,g)=>T(p,typeof m!="symbol"?m+"":m,g);class m{constructor(){d(this,"handlers",new Map)}on(e,t,r){let n=this.handlers.get(e);n||(n=new Map,this.handlers.set(e,n));let s=n.get(t);return s||(s=new Set,n.set(t,s)),s.add(r),()=>this.off(e,t,r)}off(e,t,r){const n=this.handlers.get(e);if(!n)return;const s=n.get(t);s&&(s.delete(r),s.size===0&&n.delete(t),n.size===0&&this.handlers.delete(e))}emit(e,t,r){const n=this.handlers.get(e);if(!n)return;const s=n.get(t);if(!(!s||s.size===0))for(const c of[...s])try{c(r)}catch(i){console.error("EventBus handler error:",i)}}clear(){this.handlers.clear()}}class g{constructor(){d(this,"handlers",new Map);d(this,"patternHandlers",new Map)}on(e,t,r){const n=String(t);if(this.isPattern(n)){const s=n;this.patternHandlers.has(e)||this.patternHandlers.set(e,new Map);const c=this.patternHandlers.get(e);return c.has(s)||c.set(s,[]),c.get(s).push(r),()=>this.offPattern(e,s,r)}else{const s=this.normalizeTypeKey(n);this.handlers.has(e)||this.handlers.set(e,new Map);const c=this.handlers.get(e);return c.has(s)||c.set(s,[]),c.get(s).push(r),()=>this.offExactNormalized(e,s,r)}}off(e,t,r){const n=this.normalizeTypeKey(String(t));this.offExactNormalized(e,n,r)}offExactNormalized(e,t,r){const n=this.handlers.get(e);if(!n)return;const s=n.get(t);if(!s)return;const c=s.indexOf(r);c!==-1&&s.splice(c,1),s.length===0&&n.delete(t),n.size===0&&this.handlers.delete(e)}offPattern(e,t,r){const n=this.patternHandlers.get(e);if(!n)return;const s=n.get(t);if(!s)return;const c=s.indexOf(r);c!==-1&&s.splice(c,1),s.length===0&&n.delete(t),n.size===0&&this.patternHandlers.delete(e)}emit(e,t,r){const n=String(t),s=this.normalizeTypeKey(n),c=this.handlers.get(e)?.get(s)??[],i=this.patternHandlers.get(e),o=[];if(i&&i.size){const l=this.normalizeTypeKey(n);for(const[u,y]of i.entries())this.matchPattern(u,l)&&o.push(y)}const h=new Set,f=l=>{for(const u of[...l])if(!h.has(u)){h.add(u);try{u(r)}catch(y){console.error(y);continue}}};f(c);for(const l of o)f(l)}isPattern(e){return e.includes("*")}normalizeTypeKey(e){return e.replace(/^\./,"")}splitPath(e){return this.normalizeTypeKey(e).split(".").filter(Boolean)}matchPattern(e,t){const r=this.splitPath(e),n=this.splitPath(t);let s=0,c=0,i=-1,o=0;for(;c<n.length;)if(s<r.length&&(r[s]==="*"||r[s]===n[c]))s++,c++;else if(s<r.length&&r[s]==="**")i=s,o=c,s++;else if(i!==-1)s=i+1,c=++o;else return!1;for(;s<r.length&&r[s]==="**";)s++;return s===r.length}clear(){this.handlers.clear(),this.patternHandlers.clear()}__introspect(){const e=[];for(const[t,r]of this.handlers)for(const[n,s]of r)s.length>0&&e.push({channel:t,type:n,count:s.length});for(const[t,r]of this.patternHandlers)for(const[n,s]of r)s.length>0&&e.push({channel:t,type:n,count:s.length});return e}}class P{constructor(e){d(this,"_reduce");this._reduce=e}reduce(e,t){return this._reduce(e,t)}}function v(a,e,t="",r=new Map){if(a===e)return[];if(typeof a!="object"||typeof e!="object"||a===null||e===null)return typeof a=="number"&&Number.isNaN(a)&&Number.isNaN(e)?[]:[t];if(a instanceof Date&&e instanceof Date)return a.getTime()===e.getTime()?[]:[t];if(a instanceof RegExp&&e instanceof RegExp)return a.source===e.source&&e.flags===a.flags?[]:[t];const n=a,s=e,c=r.get(n);if(c?.has(s))return[];const i=c??new Set;i.add(s),c||r.set(n,i);try{const o=Array.isArray(a),h=Array.isArray(e);if(o!==h)return[t];const f=[];if(o){const u=a,y=e;if(u.length!==y.length)return[t];for(let E=0;E<u.length;E++){const S=t?`${t}.${E}`:`${E}`;f.push(...v(u[E],y[E],S,r))}return f.filter(Boolean)}const l=new Set([...Object.keys(a),...Object.keys(e)]);for(const u of l){const y=t?`${t}.${u}`:u,E=Object.prototype.hasOwnProperty.call(a,u),S=Object.prototype.hasOwnProperty.call(e,u);if(!E||!S){f.push(y);continue}f.push(...v(a[u],e[u],y,r))}return f.filter(Boolean)}finally{i.delete(s),i.size===0&&r.delete(n)}}function b(a,e=new WeakSet){if(a===null||typeof a!="object"||e.has(a)||Object.isFrozen(a))return a;if(e.add(a),Array.isArray(a)){const t=a;for(let r=0;r<t.length;r++)t[r]=b(t[r],e);return Object.freeze(t)}for(const t of Object.getOwnPropertyNames(a)){const r=Object.getOwnPropertyDescriptor(a,t);!r||!("value"in r)||(a[t]=b(a[t],e))}for(const t of Object.getOwnPropertySymbols(a)){const r=Object.getOwnPropertyDescriptor(a,t);!r||!("value"in r)||(a[t]=b(a[t],e))}return Object.freeze(a)}function M(a){return process.env.NODE_ENV==="production"?a:b(a)}const z=100,O=()=>typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();class w{constructor(e){d(this,"name");d(this,"middleware");d(this,"reducers");d(this,"state");d(this,"reducerBus");d(this,"connectorBus");d(this,"listeners",new Set);d(this,"effects",new Map);d(this,"patternEffects",new Set);d(this,"committedEventSubscribers",new Map);d(this,"uncommittedEventSubscribers",new Map);d(this,"allEventSubscribers",new Map);d(this,"sliceUnsubs",new Map);d(this,"patternReducers",new Map);d(this,"replayEnabled");d(this,"onEffectError");d(this,"reduceQueue",[]);d(this,"isReducing",!1);d(this,"instrumentObservers",new Set);d(this,"changedPathSink",null);d(this,"inFlightEffects",0);d(this,"processedEvents",new Map);d(this,"dedupCount",0);d(this,"effectMeta",new WeakMap);d(this,"dedupConfig");d(this,"eventCleanupTimer",null);if(this.name=e.name??"yoltra Store",this.reducerBus=new m,this.connectorBus=new g,this.middleware=[...e.middleware??[]],this.reducers={},this.state={},this.replayEnabled=e.devtools?.allowReplay??!1,this.onEffectError=e.onEffectError,this.dedupConfig={windowMs:e.dedupWindowMs??0,maxCacheSize:1e3},Object.entries(e.reducer).forEach(([t,r])=>{this.mountSlice(t,r,{preserveState:!1})}),e.effects?.length)for(const t of e.effects)this.registerEffect(t);this.dispose=this.dispose.bind(this),this.notifyEffects=this.notifyEffects.bind(this),this.forwardEvent=this.forwardEvent.bind(this),this.__applyExternalState=this.__applyExternalState.bind(this),this.__replayEvents=this.__replayEvents.bind(this),this.__devtoolsIntrospect=this.__devtoolsIntrospect.bind(this),this.mountSlice=this.mountSlice.bind(this),this.unmountSlice=this.unmountSlice.bind(this),this.getAtPath=this.getAtPath.bind(this),this.emit=this.emit.bind(this),this.subscribe=this.subscribe.bind(this),this.connect=this.connect.bind(this),this.onEffect=this.onEffect.bind(this),this.onEvent=this.onEvent.bind(this),this.getState=this.getState.bind(this),this.registerEffect=this.registerEffect.bind(this),this.registerMiddleware=this.registerMiddleware.bind(this),this.registerReducer=this.registerReducer.bind(this),this.replaceMiddleware=this.replaceMiddleware.bind(this),this.replaceEffects=this.replaceEffects.bind(this),this.replaceReducers=this.replaceReducers.bind(this),this.hotReplace=this.hotReplace.bind(this)}dispose(){this.eventCleanupTimer&&(clearInterval(this.eventCleanupTimer),this.eventCleanupTimer=null),this.processedEvents.clear(),this.effects.clear(),this.patternEffects.clear(),this.effectMeta=new WeakMap,this.listeners.clear(),this.committedEventSubscribers.clear(),this.uncommittedEventSubscribers.clear(),this.allEventSubscribers.clear(),this.instrumentObservers.clear(),this.connectorBus.clear(),this.reducerBus.clear(),this.patternReducers.clear(),this.sliceUnsubs.clear(),this.changedPathSink=null}fingerprint(e,t,r){const n=`${e}::${t}`;try{if(r==null)return`${n}::null`;if(typeof r!="object")return`${n}::${String(r)}`;const s=JSON.stringify(r);return`${n}::${s}`}catch{return`${n}::${Date.now()}::${Math.random()}`}}shouldDedupe(e,t){const r=Date.now(),n=this.processedEvents.get(e);return n!==void 0&&r-n<t?(this.dedupCount++,!0):(this.processedEvents.set(e,r),this.ensureCleanupTimer(),this.processedEvents.size>this.dedupConfig.maxCacheSize&&this.pruneProcessedEvents(r),!1)}ensureCleanupTimer(){this.eventCleanupTimer===null&&(this.eventCleanupTimer=setInterval(()=>{this.pruneProcessedEvents(Date.now())},5e3),this.eventCleanupTimer.unref?.())}pruneProcessedEvents(e){const t=Math.max(this.dedupConfig.windowMs,z),r=e-t*2;for(const[n,s]of this.processedEvents)s<r&&this.processedEvents.delete(n);this.processedEvents.size===0&&this.eventCleanupTimer!==null&&(clearInterval(this.eventCleanupTimer),this.eventCleanupTimer=null)}matchesWhen(e,t){return!e||"any"in e&&e.any===!0?!0:"keys"in e?e.keys.some(([r,n])=>t.channel===r&&t.type===n):"channel"in e?t.channel===e.channel:"channels"in e?e.channels.includes(t.channel):!1}getMiddlewareFunction(e){return typeof e=="function"?e:e.middleware}getMiddlewareWhen(e){if(typeof e!="function")return e.when}async notifyEffects(e){const t=`${String(e.channel)}::${String(e.type)}`,r=this.effects.get(t);if(r&&r.size>0)for(const n of[...r])try{await n(e,this.getState,this.emit)}catch(s){console.error("Effect error:",s),this.onEffectError?.(s,e)}for(const{effect:n,when:s}of this.patternEffects)if(this.matchesWhen(s,e))try{await n(e,this.getState,this.emit)}catch(c){console.error("Effect error:",c),this.onEffectError?.(c,e)}}notifyEventSubscribers(e,t){const r=`${String(e.channel)}::${String(e.type)}`,s=(t==="committed"?this.committedEventSubscribers:this.uncommittedEventSubscribers).get(r);if(s?.size)for(const i of[...s])this.invokeEventSubscriber(i,e,t);const c=this.allEventSubscribers.get(r);if(c?.size)for(const i of[...c])this.invokeEventSubscriber(i,e,t)}invokeEventSubscriber(e,t,r){try{const n=e(t,this.getState,this.emit,r);n&&typeof n.then=="function"&&n.catch(s=>console.error("Event subscription error:",s))}catch(n){console.error("Event subscription error:",n)}}forwardEvent(e,t){const r=this.state[e],n=this.reducers[e].reduce(r,t);if(r===n)return!1;const s=v(r,n).filter(Boolean);if(s.length===0)return!1;const c=M(n);if(this.state={...this.state,[e]:c},this.changedPathSink)for(const o of s)this.changedPathSink.push(o?`${e}.${o}`:e);const i=new Set;for(const o of s)for(const h of w.buildAncestorPaths(o))i.add(h);for(const o of i){const h=this.getAtPath(r,o),f=this.getAtPath(c,o);this.connectorBus.emit(e,o,{oldValue:h,newValue:f,path:o})}return!0}__devtoolsIntrospect(){const e=Object.keys(this.reducers).map(i=>{const o=this.patternReducers.get(i);return{name:i,when:o}}),t=[];for(const[i,o]of this.effects){if(o.size===0)continue;const[h,f]=i.split("::");for(const l of o){const u=this.effectMeta.get(l);t.push({channel:h,type:f,name:u?.name,description:u?.description})}}for(const i of this.patternEffects){const o=this.effectMeta.get(i.effect);t.push({channel:"*",type:"*",name:o?.name,description:o?.description})}const r=[];for(const i of this.middleware)typeof i=="function"?r.push({name:i.name||void 0}):r.push({name:i.meta?.name,description:i.meta?.description,when:i.when});const n=[];for(const i of this.connectorBus.__introspect())for(let o=0;o<i.count;o++)n.push({reducer:i.channel,property:i.type});const s=[];for(const[i,o]of this.committedEventSubscribers){if(o.size===0)continue;const[h,f]=i.split("::");for(let l=0;l<o.size;l++)s.push({channel:h,type:f,phase:"committed"})}for(const[i,o]of this.uncommittedEventSubscribers){if(o.size===0)continue;const[h,f]=i.split("::");for(let l=0;l<o.size;l++)s.push({channel:h,type:f,phase:"uncommitted"})}for(const[i,o]of this.allEventSubscribers){if(o.size===0)continue;const[h,f]=i.split("::");for(let l=0;l<o.size;l++)s.push({channel:h,type:f,phase:"all"})}const c=this.listeners.size;return{reducers:e,effects:t,middleware:r,atomic:n,event:s,coarse:c,dedupHits:this.dedupCount,queueDepth:this.reduceQueue.length+this.inFlightEffects}}__applyExternalState(e){if(!this.replayEnabled){console.warn("[yoltra] External state apply (time-travel) is disabled. Enable it with createStore({ devtools: { allowReplay: true } })");return}const t=this.state,r=e,n={...this.state};let s=!1;Object.keys(this.reducers).forEach(c=>{const i=t?.[c],o=r?.[c];if(o===void 0){process.env.NODE_ENV!=="production"&&console.warn(`[yoltra] External state is missing slice "${String(c)}"; retaining its current value. Time-travel snapshots should contain all slices.`);return}if(i===o)return;const h=M(o);n[c]=h,s=!0;const f=v(i,o).filter(Boolean);if(f.length===0)return;const l=new Set;for(const u of f)for(const y of w.buildAncestorPaths(u))l.add(y);for(const u of l){const y=this.getAtPath(i,u),E=this.getAtPath(h,u);this.connectorBus.emit(c,u,{oldValue:y,newValue:E,path:u})}}),s&&(this.state=n),s&&this.listeners.forEach(c=>c())}__replayEvents(e,t){if(!this.replayEnabled)throw new Error("[yoltra] Event replay is disabled. Enable it with createStore({ devtools: { allowReplay: true } })");this.__applyExternalState(e);for(const r of t){const n=r,s=this.state;this.reducerBus.emit(n.channel,n.type,n.payload);for(const[o,h]of this.patternReducers)this.matchesWhen(h,n)&&this.forwardEvent(o,n);const c=this.state,i=s!==c;this.notifyEventSubscribers(n,"committed"),i&&this.listeners.forEach(o=>o())}}async emit(e,t,r,n){const s=n?.dedupKey,c=this.dedupConfig.windowMs;if(c>0||s!==void 0){const f=s!==void 0&&c<=0?z:c,l=s!==void 0?`${e}::${t}::#${s}`:this.fingerprint(e,t,r);if(this.shouldDedupe(l,f))return}const i=crypto.randomUUID();let o;const h=new Promise(f=>{o=f});return this.reduceQueue.push({channel:e,type:t,payload:r,id:i,resolve:o}),this.drainReduce(),h}drainReduce(){if(!this.isReducing){this.isReducing=!0;try{for(;this.reduceQueue.length>0;){const{channel:e,type:t,payload:r,id:n,resolve:s}=this.reduceQueue.shift(),c={channel:e,type:t,payload:r,id:n},i=this.instrumentObservers.size>0,o=i?this.state:void 0,h=[];i&&(this.changedPathSink=h);const f=i?O():0;let l=!1;try{l=this.applyEventSync(c)}catch(u){console.error("Emit reduce error:",u)}finally{i&&(this.changedPathSink=null)}i&&this.emitInstrumentation(c,l,h,o,O()-f),this.runEventEffects(c,l,s)}}finally{this.isReducing=!1}}}applyEventSync(e){for(const n of this.middleware){const s=this.getMiddlewareWhen(n);if(!this.matchesWhen(s,e))continue;const c=this.getMiddlewareFunction(n);let i;try{i=c(this.state,e,this.emit)}catch(o){console.error("Middleware error:",o),i=!1}if(!i)return this.notifyEventSubscribers(e,"uncommitted"),!1}const t=this.state;this.reducerBus.emit(e.channel,e.type,e.payload);for(const[n,s]of this.patternReducers)this.matchesWhen(s,e)&&this.forwardEvent(n,e);const r=t!==this.state;return this.notifyEventSubscribers(e,"committed"),r&&this.listeners.forEach(n=>n()),!0}async runEventEffects(e,t,r){this.inFlightEffects++;try{t&&await this.notifyEffects(e)}catch(n){console.error("Effect error:",n)}finally{this.inFlightEffects--,r()}}instrument(e){return this.instrumentObservers.add(e),()=>{this.instrumentObservers.delete(e)}}emitInstrumentation(e,t,r,n,s){const c={},i={};for(const h of r)c[h]=this.getAtPath(n,h),i[h]=this.getAtPath(this.state,h);const o={event:{id:e.id,channel:e.channel,type:e.type,payload:e.payload},committed:t,changedPaths:r,prevValues:c,nextValues:i,reduceTimeMs:s};for(const h of[...this.instrumentObservers])try{h(o)}catch(f){console.error("Instrumentation observer error:",f)}}connect(e,t){return this.connectorBus.on(e.reducer,e.property,t)}onEvent(e,t,r,n="committed"){const s=`${e}::${String(t)}`,c=n==="committed"?this.committedEventSubscribers:n==="uncommitted"?this.uncommittedEventSubscribers:this.allEventSubscribers;return c.has(s)||c.set(s,new Set),c.get(s).add(r),()=>{const i=c.get(s);i&&(i.delete(r),i.size===0&&c.delete(s))}}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}getState(){return this.state}registerMiddleware(e){return this.middleware.push(e),()=>{const t=this.middleware.indexOf(e);t!==-1&&this.middleware.splice(t,1)}}registerReducer(e,t){if(e in this.reducers)throw new Error(`Reducer ${e} already exists`);return this.mountSlice(e,t,{preserveState:!1}),this.listeners.forEach(r=>r()),()=>{this.unmountSlice(e,{deleteState:!0}),this.listeners.forEach(r=>r())}}registerEffect(e){const{effect:t,meta:r,when:n}=e,s=[];if(r&&this.effectMeta.set(t,r),n&&("any"in n&&n.any===!0||"channel"in n||"channels"in n)){const o={effect:t,when:n};return this.patternEffects.add(o),()=>{this.patternEffects.delete(o)}}const i=this.normalizeEventKeys(e);if(i.length===0&&!n&&!e.events){const o={effect:t,when:{any:!0}};return this.patternEffects.add(o),()=>{this.patternEffects.delete(o)}}for(const[o,h]of i){const f=`${String(o)}::${String(h)}`;this.effects.has(f)||this.effects.set(f,new Set),this.effects.get(f).add(t),s.push(()=>{const l=this.effects.get(f);l&&(l.delete(t),l.size===0&&this.effects.delete(f))})}return()=>{for(const o of s)o()}}onEffect(e,t,r){const n=async(s,c,i)=>{if(s.channel!==e||s.type!==t)return;const o=s;return r(o.payload,c,i,o)};return this.registerEffect({events:[[e,t]],effect:n})}replaceMiddleware(e){this.middleware.length=0;for(const t of e)this.middleware.push(t)}replaceEffects(e){this.effects.clear(),this.patternEffects.clear();for(const t of e)this.registerEffect(t)}replaceReducers(e,t={}){const r=t.preserveState!==!1,n=new Set(Object.keys(this.reducers)),s=Object.entries(e),c=new Set(s.map(([i])=>i));for(const i of n)c.has(i)||this.unmountSlice(i,{deleteState:!0});for(const[i,o]of s)n.has(i)?(this.unmountSlice(i,{deleteState:!1}),this.mountSlice(i,o,{preserveState:r})):this.mountSlice(i,o,{preserveState:!1})}hotReplace(e){e.middleware&&this.replaceMiddleware(e.middleware),e.effects&&this.replaceEffects(e.effects),e.reducer&&this.replaceReducers(e.reducer,{preserveState:e.preserveState})}mountSlice(e,t,r){const n=e,{events:s,reducer:c,state:i,when:o}=t;if(this.reducers[e]=new P(c),(!r.preserveState||this.state[n]===void 0)&&(this.state[n]=M(structuredClone(i))),o&&("any"in o&&o.any===!0||"channel"in o||"channels"in o)){this.patternReducers.set(e,o),this.sliceUnsubs.set(n,[]);return}const f=this.normalizeEventKeys(t);if(f.length===0&&!o&&!s){this.patternReducers.set(e,{any:!0}),this.sliceUnsubs.set(n,[]);return}const l=[];for(const[u,y]of f){const E=this.reducerBus.on(u,y,S=>{const $={channel:u,type:y,payload:S,id:crypto.randomUUID()};this.forwardEvent(e,$)});l.push(E)}this.sliceUnsubs.set(n,l)}unmountSlice(e,t){const r=e;this.patternReducers.delete(e);const n=this.sliceUnsubs.get(r);if(n){for(const s of n)try{s()}catch(c){console.error(`[Store error]: ${c}`)}this.sliceUnsubs.delete(r)}delete this.reducers[e],t.deleteState&&delete this.state[r]}normalizeEventKeys(e){if(e.when){const t=e.when;if("any"in t&&t.any===!0)return[];if("keys"in t)return t.keys;if("channel"in t)return[];if("channels"in t)return[]}return e.events?e.events:[]}getAtPath(e,t){if(!t)return e;const n=(t[0]==="."?t.slice(1):t).split(".");let s=e;for(const c of n){if(s==null)return;s=s[c]}return s}static buildAncestorPaths(e){if(!e)return[];const r=(e[0]==="."?e.slice(1):e).split("."),n=[];for(let s=0;s<r.length;s++)n.push(r.slice(0,s+1).join("."));return n}}function k(a){return new w({name:a.name,reducer:a.reducer??{},middleware:a.middleware??[],effects:a.effects??[],dedupWindowMs:a.dedupWindowMs,devtools:a.devtools,onEffectError:a.onEffectError})}const R=a=>(e,t)=>t.map(r=>[e,r]),_=()=>a=>a;p.EventBus=m,p.LooseEventBus=g,p.Reducer=P,p.Store=w,p.createStore=k,p.detectChangedProps=v,p.eventKeys=_,p.freezeState=b,p.typedEvents=R,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})}));
10
+ (function(m,v){typeof exports=="object"&&typeof module<"u"?v(exports):typeof define=="function"&&define.amd?define(["exports"],v):(m=typeof globalThis<"u"?globalThis:m||self,v(m.yoltra={}))})(this,(function(m){"use strict";var te=Object.defineProperty;var ne=(m,v,S)=>v in m?te(m,v,{enumerable:!0,configurable:!0,writable:!0,value:S}):m[v]=S;var p=(m,v,S)=>ne(m,typeof v!="symbol"?v+"":v,S);class v{constructor(){p(this,"handlers",new Map)}on(e,n,s){let t=this.handlers.get(e);t||(t=new Map,this.handlers.set(e,t));let i=t.get(n);return i||(i=new Set,t.set(n,i)),i.add(s),()=>this.off(e,n,s)}off(e,n,s){const t=this.handlers.get(e);if(!t)return;const i=t.get(n);i&&(i.delete(s),i.size===0&&t.delete(n),t.size===0&&this.handlers.delete(e))}emit(e,n,s,t){const i=this.handlers.get(e);if(!i)return;const d=i.get(n);if(!(!d||d.size===0))for(const a of[...d])try{a(s,t)}catch(r){console.error("EventBus handler error:",r)}}clear(){this.handlers.clear()}}class S{constructor(){p(this,"handlers",new Map);p(this,"patternHandlers",new Map);p(this,"patternIndex",new Map)}on(e,n,s){const t=String(n);if(this.isPattern(t)){const i=t;this.patternHandlers.has(e)||this.patternHandlers.set(e,new Map);const d=this.patternHandlers.get(e);return d.has(i)||(d.set(i,[]),this.indexPattern(e,i)),d.get(i).push(s),()=>this.offPattern(e,i,s)}else{const i=this.normalizeTypeKey(t);this.handlers.has(e)||this.handlers.set(e,new Map);const d=this.handlers.get(e);return d.has(i)||d.set(i,[]),d.get(i).push(s),()=>this.offExactNormalized(e,i,s)}}off(e,n,s){const t=this.normalizeTypeKey(String(n));this.offExactNormalized(e,t,s)}offExactNormalized(e,n,s){const t=this.handlers.get(e);if(!t)return;const i=t.get(n);if(!i)return;const d=i.indexOf(s);d!==-1&&i.splice(d,1),i.length===0&&t.delete(n),t.size===0&&this.handlers.delete(e)}offPattern(e,n,s){const t=this.patternHandlers.get(e);if(!t)return;const i=t.get(n);if(!i)return;const d=i.indexOf(s);d!==-1&&i.splice(d,1),i.length===0&&(t.delete(n),this.unindexPattern(e,n)),t.size===0&&(this.patternHandlers.delete(e),this.patternIndex.delete(e))}emit(e,n,s){const t=String(n),i=this.normalizeTypeKey(t),d=this.handlers.get(e)?.get(i)??[],a=this.matchingPatternHandlers(e,t),r=new Set,f=o=>{for(const u of[...o])if(!r.has(u)){r.add(u);try{u(s)}catch(l){console.error(l);continue}}};f(d);for(const o of a)f(o)}emitWith(e,n,s){const t=String(n),i=this.normalizeTypeKey(t),d=this.handlers.get(e)?.get(i)??[],a=this.matchingPatternHandlers(e,t);if(d.length===0&&a.length===0)return;const r=s(),f=new Set,o=u=>{for(const l of[...u])if(!f.has(l)){f.add(l);try{l(r)}catch(y){console.error(y);continue}}};o(d);for(const u of a)o(u)}isPattern(e){return e.includes("*")}normalizeTypeKey(e){return e.replace(/^\./,"")}splitPath(e){return this.normalizeTypeKey(e).split(".").filter(Boolean)}indexPattern(e,n){let s=this.patternIndex.get(e);s===void 0&&(s={byHead:new Map,anyHead:[]},this.patternIndex.set(e,s));const t=this.splitPath(n),i={pattern:n,segments:t},d=t[0];if(d===void 0||d==="*"||d==="**"){s.anyHead.push(i);return}const a=s.byHead.get(d);a===void 0?s.byHead.set(d,[i]):a.push(i)}unindexPattern(e,n){const s=this.patternIndex.get(e);if(s===void 0)return;const t=this.splitPath(n)[0],i=t===void 0||t==="*"||t==="**"?s.anyHead:s.byHead.get(t);if(i===void 0)return;const d=i.findIndex(a=>a.pattern===n);d!==-1&&i.splice(d,1),i.length===0&&i!==s.anyHead&&t!==void 0&&s.byHead.delete(t)}matchingPatternHandlers(e,n){const s=this.patternHandlers.get(e),t=this.patternIndex.get(e);if(s===void 0||s.size===0||t===void 0)return[];const i=this.splitPath(n),d=[],a=f=>{for(const o of f){if(!this.matchSegments(o.segments,i))continue;const u=s.get(o.pattern);u!==void 0&&d.push(u)}},r=i[0];if(r!==void 0){const f=t.byHead.get(r);f!==void 0&&a(f)}return a(t.anyHead),d}matchSegments(e,n){let s=0,t=0,i=-1,d=0;for(;t<n.length;)if(s<e.length&&(e[s]==="*"||e[s]===n[t]))s++,t++;else if(s<e.length&&e[s]==="**")i=s,d=t,s++;else if(i!==-1)s=i+1,t=++d;else return!1;for(;s<e.length&&e[s]==="**";)s++;return s===e.length}clear(){this.handlers.clear(),this.patternHandlers.clear(),this.patternIndex.clear()}__introspect(){const e=[];for(const[n,s]of this.handlers)for(const[t,i]of s)i.length>0&&e.push({channel:n,type:t,count:i.length});for(const[n,s]of this.patternHandlers)for(const[t,i]of s)i.length>0&&e.push({channel:n,type:t,count:i.length});return e}}class A{constructor(e){p(this,"_reduce");this._reduce=e}reduce(e,n){return this._reduce(e,n)}}const _=new Set;function O(c,e){const n=c?`${c}.${e}`:e;_.has(n)||(_.add(n),console.warn(`[yoltra] State key "${e}"${c?` under "${c}"`:""} contains a dot. Paths are dotted, so this key is indistinguishable from nested objects of the same name: a subscription to "${n}" may match the wrong value, and DevTools patches for it will address the wrong node. Rename the key, or nest it.`))}function z(c,e,n="",s=new Map){const t=[];return k(c,e,n,s,t),t}function k(c,e,n,s,t){if(c===e)return;if(typeof c!="object"||typeof e!="object"||c===null||e===null){if(typeof c=="number"&&Number.isNaN(c)&&Number.isNaN(e))return;t.push(n);return}if(c instanceof Date&&e instanceof Date){c.getTime()!==e.getTime()&&t.push(n);return}if(c instanceof RegExp&&e instanceof RegExp){(c.source!==e.source||e.flags!==c.flags)&&t.push(n);return}if(c instanceof Map||e instanceof Map){t.push(n);return}if(c instanceof Set||e instanceof Set){t.push(n);return}const i=c,d=e,a=s.get(i);if(a?.has(d))return;const r=a??new Set;r.add(d),a||s.set(i,r);try{const f=Array.isArray(c),o=Array.isArray(e);if(f!==o){t.push(n);return}if(f){const h=c,g=e;h.length!==g.length&&n&&t.push(n);const E=Math.min(h.length,g.length);for(let b=0;b<E;b++)h[b]!==g[b]&&k(h[b],g[b],n?`${n}.${b}`:`${b}`,s,t);for(let b=E;b<Math.max(h.length,g.length);b++)t.push(n?`${n}.${b}`:`${b}`);return}const u=Object.keys(c),l=Object.keys(e);if(u.length===0&&l.length===0){t.push(n);return}let y=u.length===l.length;if(y){for(let h=0;h<l.length;h++)if(!Object.prototype.hasOwnProperty.call(c,l[h])){y=!1;break}}if(y){for(const h of l)c[h]!==e[h]&&(process.env.NODE_ENV!=="production"&&h.includes(".")&&O(n,h),k(c[h],e[h],n?`${n}.${h}`:h,s,t));return}for(const h of l){const g=Object.prototype.hasOwnProperty.call(c,h);if(g&&c[h]===e[h])continue;process.env.NODE_ENV!=="production"&&h.includes(".")&&O(n,h);const E=n?`${n}.${h}`:h;if(!g){t.push(E);continue}k(c[h],e[h],E,s,t)}for(const h of u)Object.prototype.hasOwnProperty.call(e,h)||(process.env.NODE_ENV!=="production"&&h.includes(".")&&O(n,h),t.push(n?`${n}.${h}`:h))}finally{r.delete(d),r.size===0&&s.delete(i)}}function M(c,e=new WeakSet,n){if(c===null||typeof c!="object"||e.has(c)||(n!==void 0&&c===n.watch&&n.onFound(),Object.isFrozen(c)))return c;if(e.add(c),Array.isArray(c)){const s=c;for(let t=0;t<s.length;t++)s[t]=M(s[t],e,n);return Object.freeze(s)}for(const s of Object.getOwnPropertyNames(c)){const t=Object.getOwnPropertyDescriptor(c,s);!t||!("value"in t)||(c[s]=M(c[s],e,n))}for(const s of Object.getOwnPropertySymbols(c)){const t=Object.getOwnPropertyDescriptor(c,s);!t||!("value"in t)||(c[s]=M(c[s],e,n))}return Object.freeze(c)}function K(c,e){try{return structuredClone(e)}catch(n){throw new Error(`[yoltra] Initial state for slice "${String(c)}" could not be copied: ${n instanceof Error?n.message:String(n)}. State must be structured-cloneable — functions, class instances and DOM nodes are not. Keep behaviour out of state and store plain data.`)}}function I(c,e){return process.env.NODE_ENV==="production"?c:M(c,new WeakSet,e)}const x=100,N=()=>typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();class P{constructor(e){p(this,"name");p(this,"middleware");p(this,"reducers");p(this,"state");p(this,"reducerBus");p(this,"connectorBus");p(this,"listeners",new Set);p(this,"effects",new Map);p(this,"patternEffects",new Set);p(this,"committedEventSubscribers",new Map);p(this,"uncommittedEventSubscribers",new Map);p(this,"allEventSubscribers",new Map);p(this,"sliceUnsubs",new Map);p(this,"patternReducers",new Map);p(this,"replayEnabled");p(this,"idFactory");p(this,"onEffectError");p(this,"onReducerError");p(this,"warnedPayloadAliases",new Set);p(this,"reduceQueue",[]);p(this,"isReducing",!1);p(this,"instrumentObservers",new Set);p(this,"changedPathSink",null);p(this,"inFlightEffects",0);p(this,"processedEvents",new Map);p(this,"dedupCount",0);p(this,"effectMeta",new WeakMap);p(this,"dedupConfig");p(this,"eventCleanupTimer",null);if(this.name=e.name??"yoltra Store",this.reducerBus=new v,this.connectorBus=new S,this.middleware=[...e.middleware??[]],this.reducers={},this.state={},this.replayEnabled=e.devtools?.allowReplay??!1,this.idFactory=e.idFactory??(()=>crypto.randomUUID()),this.onEffectError=e.onEffectError,this.onReducerError=e.onReducerError,this.dedupConfig={windowMs:e.dedupWindowMs??0,maxCacheSize:1e3},Object.entries(e.reducer).forEach(([n,s])=>{this.mountSlice(n,s,{preserveState:!1})}),e.effects?.length)for(const n of e.effects)this.registerEffect(n);this.dispose=this.dispose.bind(this),this.notifyEffects=this.notifyEffects.bind(this),this.forwardEvent=this.forwardEvent.bind(this),this.__applyExternalState=this.__applyExternalState.bind(this),this.__replayEvents=this.__replayEvents.bind(this),this.__devtoolsIntrospect=this.__devtoolsIntrospect.bind(this),this.mountSlice=this.mountSlice.bind(this),this.unmountSlice=this.unmountSlice.bind(this),this.getAtPath=this.getAtPath.bind(this),this.emit=this.emit.bind(this),this.subscribe=this.subscribe.bind(this),this.connect=this.connect.bind(this),this.onEffect=this.onEffect.bind(this),this.onEvent=this.onEvent.bind(this),this.getState=this.getState.bind(this),this.registerEffect=this.registerEffect.bind(this),this.registerMiddleware=this.registerMiddleware.bind(this),this.registerReducer=this.registerReducer.bind(this),this.replaceMiddleware=this.replaceMiddleware.bind(this),this.replaceEffects=this.replaceEffects.bind(this),this.replaceReducers=this.replaceReducers.bind(this),this.hotReplace=this.hotReplace.bind(this)}dispose(){this.eventCleanupTimer&&(clearInterval(this.eventCleanupTimer),this.eventCleanupTimer=null),this.processedEvents.clear(),this.effects.clear(),this.patternEffects.clear(),this.effectMeta=new WeakMap,this.warnedPayloadAliases.clear(),this.listeners.clear(),this.committedEventSubscribers.clear(),this.uncommittedEventSubscribers.clear(),this.allEventSubscribers.clear(),this.instrumentObservers.clear(),this.connectorBus.clear(),this.reducerBus.clear(),this.patternReducers.clear(),this.sliceUnsubs.clear(),this.changedPathSink=null}fingerprint(e,n,s){const t=`${e}::${n}`;try{if(s==null)return`${t}::null`;if(typeof s!="object")return`${t}::${String(s)}`;const i=JSON.stringify(s);return`${t}::${i}`}catch{return`${t}::${Date.now()}::${Math.random()}`}}shouldDedupe(e,n){const s=Date.now(),t=this.processedEvents.get(e);return t!==void 0&&s-t<n?(this.dedupCount++,!0):(this.processedEvents.set(e,s),this.ensureCleanupTimer(),this.processedEvents.size>this.dedupConfig.maxCacheSize&&this.pruneProcessedEvents(s),!1)}ensureCleanupTimer(){this.eventCleanupTimer===null&&(this.eventCleanupTimer=setInterval(()=>{this.pruneProcessedEvents(Date.now())},5e3),this.eventCleanupTimer.unref?.())}pruneProcessedEvents(e){const n=Math.max(this.dedupConfig.windowMs,x),s=e-n*2;for(const[t,i]of this.processedEvents)i<s&&this.processedEvents.delete(t);this.processedEvents.size===0&&this.eventCleanupTimer!==null&&(clearInterval(this.eventCleanupTimer),this.eventCleanupTimer=null)}matchesWhen(e,n){return!e||"any"in e&&e.any===!0?!0:"keys"in e?e.keys.some(([s,t])=>n.channel===s&&n.type===t):"channel"in e?n.channel===e.channel:"channels"in e?e.channels.includes(n.channel):!1}getMiddlewareFunction(e){return typeof e=="function"?e:e.middleware}getMiddlewareWhen(e){if(typeof e!="function")return e.when}async notifyEffects(e){const n=`${String(e.channel)}::${String(e.type)}`,s=this.effects.get(n);if(s&&s.size>0)for(const t of[...s])try{await t(e,this.getState,this.emit)}catch(i){console.error("Effect error:",i),this.onEffectError?.(i,e)}for(const{effect:t,when:i}of this.patternEffects)if(this.matchesWhen(i,e))try{await t(e,this.getState,this.emit)}catch(d){console.error("Effect error:",d),this.onEffectError?.(d,e)}}notifyEventSubscribers(e,n){const s=`${String(e.channel)}::${String(e.type)}`,i=(n==="committed"?this.committedEventSubscribers:this.uncommittedEventSubscribers).get(s);if(i?.size)for(const a of[...i])this.invokeEventSubscriber(a,e,n);const d=this.allEventSubscribers.get(s);if(d?.size)for(const a of[...d])this.invokeEventSubscriber(a,e,n)}invokeEventSubscriber(e,n,s){try{const t=e(n,this.getState,this.emit,s);t&&typeof t.then=="function"&&t.catch(i=>console.error("Event subscription error:",i))}catch(t){console.error("Event subscription error:",t)}}forwardEventGuarded(e,n){try{return this.forwardEvent(e,n)}catch(s){return console.error(`Reducer error in slice "${e}":`,s),this.onReducerError?.(s,n,e),!1}}forwardEvent(e,n){const s=this.state[e],t=this.reducers[e].reduce(s,n);if(s===t)return!1;const i=z(s,t);if(i.length===0)return!1;const d=n.payload,a=process.env.NODE_ENV!=="production"&&d!==null&&typeof d=="object"?{watch:d,onFound:()=>{const o=`${e}:${n.channel}:${n.type}`;this.warnedPayloadAliases.has(o)||(this.warnedPayloadAliases.add(o),console.warn(`[yoltra] Slice "${e}" stored the payload of "${n.channel}/${n.type}" by reference. It is now frozen along with the rest of the state, so the emitter mutating it later will throw in development and silently corrupt state in production. Copy the payload in the reducer instead.`))}}:void 0,r=I(t,a);if(this.state={...this.state,[e]:r},this.changedPathSink)for(const o of i)this.changedPathSink.push(o?`${e}.${o}`:e);const f=new Set;for(const o of i){if(o===""){f.add("");continue}for(const u of P.buildAncestorPaths(o))f.add(u)}for(const o of f)this.connectorBus.emitWith(e,o,()=>({oldValue:this.getAtPath(s,o),newValue:this.getAtPath(r,o),path:o}));return!0}__devtoolsIntrospect(){const e=Object.keys(this.reducers).map(a=>{const r=this.patternReducers.get(a);return{name:a,when:r}}),n=[];for(const[a,r]of this.effects){if(r.size===0)continue;const[f,o]=a.split("::");for(const u of r){const l=this.effectMeta.get(u);n.push({channel:f,type:o,name:l?.name,description:l?.description})}}for(const a of this.patternEffects){const r=this.effectMeta.get(a.effect);n.push({channel:"*",type:"*",name:r?.name,description:r?.description})}const s=[];for(const a of this.middleware)typeof a=="function"?s.push({name:a.name||void 0}):s.push({name:a.meta?.name,description:a.meta?.description,when:a.when});const t=[];for(const a of this.connectorBus.__introspect())for(let r=0;r<a.count;r++)t.push({reducer:a.channel,property:a.type});const i=[];for(const[a,r]of this.committedEventSubscribers){if(r.size===0)continue;const[f,o]=a.split("::");for(let u=0;u<r.size;u++)i.push({channel:f,type:o,phase:"committed"})}for(const[a,r]of this.uncommittedEventSubscribers){if(r.size===0)continue;const[f,o]=a.split("::");for(let u=0;u<r.size;u++)i.push({channel:f,type:o,phase:"uncommitted"})}for(const[a,r]of this.allEventSubscribers){if(r.size===0)continue;const[f,o]=a.split("::");for(let u=0;u<r.size;u++)i.push({channel:f,type:o,phase:"all"})}const d=this.listeners.size;return{reducers:e,effects:n,middleware:s,atomic:t,event:i,coarse:d,dedupHits:this.dedupCount,queueDepth:this.reduceQueue.length+this.inFlightEffects}}__applyExternalState(e){if(!this.replayEnabled)throw new Error("[yoltra] External state apply (time-travel) is disabled. Enable it with createStore({ devtools: { allowReplay: true } })");const n=this.state,s=e,t={...this.state};let i=!1;Object.keys(this.reducers).forEach(d=>{const a=n?.[d],r=s?.[d];if(r===void 0){process.env.NODE_ENV!=="production"&&console.warn(`[yoltra] External state is missing slice "${String(d)}"; retaining its current value. Time-travel snapshots should contain all slices.`);return}if(a===r)return;const f=I(r);t[d]=f,i=!0;const o=z(a,r);if(o.length===0)return;const u=new Set;for(const l of o){if(l===""){u.add("");continue}for(const y of P.buildAncestorPaths(l))u.add(y)}for(const l of u){const y=this.getAtPath(a,l),h=this.getAtPath(f,l);this.connectorBus.emit(d,l,{oldValue:y,newValue:h,path:l})}}),i&&(this.state=t),i&&this.listeners.forEach(d=>d())}__replayEvents(e,n){if(!this.replayEnabled)throw new Error("[yoltra] Event replay is disabled. Enable it with createStore({ devtools: { allowReplay: true } })");this.__applyExternalState(e);for(const s of n){const t=s,i=this.state;this.reducerBus.emit(t.channel,t.type,t.payload,t);for(const[r,f]of this.patternReducers)this.matchesWhen(f,t)&&this.forwardEventGuarded(r,t);const d=this.state,a=i!==d;this.notifyEventSubscribers(t,"committed"),a&&this.listeners.forEach(r=>r())}}async emit(e,n,s,t){const i=t?.dedupKey,d=this.dedupConfig.windowMs;if(t?.skipDedup!==!0&&(d>0||i!==void 0)){const o=i!==void 0&&d<=0?x:d,u=i!==void 0?`${e}::${n}::#${i}`:this.fingerprint(e,n,s);if(this.shouldDedupe(u,o))return}const a=t?.id??this.idFactory();let r;const f=new Promise(o=>{r=o});return this.reduceQueue.push({channel:e,type:n,payload:s,id:a,meta:t?.meta,resolve:r}),this.drainReduce(),f}drainReduce(){if(!this.isReducing){this.isReducing=!0;try{for(;this.reduceQueue.length>0;){const{channel:e,type:n,payload:s,id:t,meta:i,resolve:d}=this.reduceQueue.shift(),a={channel:e,type:n,payload:s,id:t,...i!==void 0?{meta:i}:{}},r=this.instrumentObservers.size>0,f=r?this.state:void 0,o=r?[]:void 0;o!==void 0&&(this.changedPathSink=o);const u=r?N():0;let l=!1;try{l=this.applyEventSync(a)}catch(y){console.error("Emit reduce error:",y)}finally{r&&(this.changedPathSink=null)}r&&this.emitInstrumentation(a,l,o??[],f,N()-u),this.runEventEffects(a,l,d)}}finally{this.isReducing=!1}}}applyEventSync(e){for(const t of this.middleware){const i=this.getMiddlewareWhen(t);if(!this.matchesWhen(i,e))continue;const d=this.getMiddlewareFunction(t);let a;try{a=d(this.state,e,this.emit),process.env.NODE_ENV!=="production"&&typeof a?.then=="function"&&console.error(`[yoltra] Middleware for "${e.channel}/${e.type}" returned a Promise. Middleware is synchronous: a Promise is truthy, so this event was allowed without waiting and a "return false" inside it can never veto. Do the check synchronously, and put anything that must await in an effect.`)}catch(r){console.error("Middleware error:",r),a=!1}if(!a)return this.notifyEventSubscribers(e,"uncommitted"),!1}const n=this.state;this.reducerBus.emit(e.channel,e.type,e.payload,e);for(const[t,i]of this.patternReducers)this.matchesWhen(i,e)&&this.forwardEventGuarded(t,e);const s=n!==this.state;return this.notifyEventSubscribers(e,"committed"),s&&this.listeners.forEach(t=>t()),!0}async runEventEffects(e,n,s){this.inFlightEffects++;try{n&&await this.notifyEffects(e)}catch(t){console.error("Effect error:",t)}finally{this.inFlightEffects--,s()}}instrument(e){return this.instrumentObservers.add(e),()=>{this.instrumentObservers.delete(e)}}emitInstrumentation(e,n,s,t,i){const d={},a={};for(const f of s)d[f]=this.getAtPath(t,f),a[f]=this.getAtPath(this.state,f);const r={event:{id:e.id,channel:e.channel,type:e.type,payload:e.payload,...e.meta!==void 0?{meta:e.meta}:{}},committed:n,changedPaths:s,prevValues:d,nextValues:a,reduceTimeMs:i};for(const f of[...this.instrumentObservers])try{f(r)}catch(o){console.error("Instrumentation observer error:",o)}}connect(e,n){return this.connectorBus.on(e.reducer,e.property,n)}onEvent(e,n,s,t="committed"){const i=`${e}::${String(n)}`,d=t==="committed"?this.committedEventSubscribers:t==="uncommitted"?this.uncommittedEventSubscribers:this.allEventSubscribers;return d.has(i)||d.set(i,new Set),d.get(i).add(s),()=>{const a=d.get(i);a&&(a.delete(s),a.size===0&&d.delete(i))}}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}getState(){return this.state}registerMiddleware(e){return this.middleware.push(e),()=>{const n=this.middleware.indexOf(e);n!==-1&&this.middleware.splice(n,1)}}registerReducer(e,n){if(Object.prototype.hasOwnProperty.call(this.reducers,e))throw new Error(`Reducer ${e} already exists`);return this.mountSlice(e,n,{preserveState:!1}),this.listeners.forEach(s=>s()),()=>{this.unmountSlice(e,{deleteState:!0}),this.listeners.forEach(s=>s())}}registerEffect(e){const{effect:n,meta:s,when:t}=e,i=[];if(s&&this.effectMeta.set(n,s),t&&("any"in t&&t.any===!0||"channel"in t||"channels"in t)){const r={effect:n,when:t};return this.patternEffects.add(r),()=>{this.patternEffects.delete(r)}}const a=this.normalizeEventKeys(e);if(a.length===0&&!t){const r={effect:n,when:{any:!0}};return this.patternEffects.add(r),()=>{this.patternEffects.delete(r)}}for(const[r,f]of a){const o=`${String(r)}::${String(f)}`;this.effects.has(o)||this.effects.set(o,new Set),this.effects.get(o).add(n),i.push(()=>{const u=this.effects.get(o);u&&(u.delete(n),u.size===0&&this.effects.delete(o))})}return()=>{for(const r of i)r()}}onEffect(e,n,s){const t=async(i,d,a)=>{if(i.channel!==e||i.type!==n)return;const r=i;return s(r.payload,d,a,r)};return this.registerEffect({when:{keys:[[e,n]]},effect:t})}replaceMiddleware(e){this.middleware.length=0;for(const n of e)this.middleware.push(n)}replaceEffects(e){this.effects.clear(),this.patternEffects.clear();for(const n of e)this.registerEffect(n)}replaceReducers(e,n={}){const s=n.preserveState!==!1,t=new Set(Object.keys(this.reducers)),i=Object.entries(e),d=new Set(i.map(([a])=>a));for(const a of t)d.has(a)||this.unmountSlice(a,{deleteState:!0});for(const[a,r]of i)t.has(a)?(this.unmountSlice(a,{deleteState:!1}),this.mountSlice(a,r,{preserveState:s})):this.mountSlice(a,r,{preserveState:!1})}hotReplace(e){e.middleware&&this.replaceMiddleware(e.middleware),e.effects&&this.replaceEffects(e.effects),e.reducer&&this.replaceReducers(e.reducer,{preserveState:e.preserveState})}mountSlice(e,n,s){const t=e,{reducer:i,state:d,when:a}=n;if(this.reducers[e]=new A(i),(!s.preserveState||this.state[t]===void 0)&&(this.state={...this.state,[t]:I(K(t,d))}),a&&("any"in a&&a.any===!0||"channel"in a||"channels"in a)){this.patternReducers.set(e,a),this.sliceUnsubs.set(t,[]);return}const f=this.normalizeEventKeys(n);if(f.length===0&&!a){this.patternReducers.set(e,{any:!0}),this.sliceUnsubs.set(t,[]);return}const o=[];for(const[u,l]of f){const y=this.reducerBus.on(u,l,(h,g)=>{const E=g??{channel:u,type:l,payload:h,id:this.idFactory()};this.forwardEventGuarded(e,E)});o.push(y)}this.sliceUnsubs.set(t,o)}unmountSlice(e,n){const s=e;this.patternReducers.delete(e);const t=this.sliceUnsubs.get(s);if(t){for(const i of t)try{i()}catch(d){console.error(`[Store error]: ${d}`)}this.sliceUnsubs.delete(s)}if(delete this.reducers[e],n.deleteState){const{[s]:i,...d}=this.state;this.state=d}}normalizeEventKeys(e){if(e.when){const n=e.when;if("keys"in n)return n.keys}return[]}getAtPath(e,n){if(!n)return e;const t=(n[0]==="."?n.slice(1):n).split(".");let i=e;for(const d of t){if(i==null)return;i=i[d]}return i}static buildAncestorPaths(e){if(!e)return[];const s=(e[0]==="."?e.slice(1):e).split("."),t=[];for(let i=0;i<s.length;i++)t.push(s.slice(0,i+1).join("."));return t}}function W(c){return new P({name:c.name,reducer:c.reducer??{},middleware:c.middleware??[],effects:c.effects??[],dedupWindowMs:c.dedupWindowMs,idFactory:c.idFactory,devtools:c.devtools,onEffectError:c.onEffectError,onReducerError:c.onReducerError})}const j=c=>(e,n)=>n.map(s=>[e,s]),F=()=>c=>c,T=new Set;function V(c){const e=String(c);T.has(e)||(T.add(e),console.warn(`[yoltra] Entity id "${e}" contains a dot. Paths are dotted, so a subscription to "entities.${e}" is indistinguishable from one to a nested object of the same name. Use ids without dots.`))}function U(c,e){if(c.length!==e.length)return e;for(let n=0;n<c.length;n++)if(c[n]!==e[n])return e;return c}function L(c={}){const e=c.selectId??(r=>r.id),{sortComparer:n}=c,s=(r,f)=>{if(n===void 0)return f;const o=[...f].sort((u,l)=>{const y=r.entities[u],h=r.entities[l];return y===void 0||h===void 0?0:n(y,h)});return U(f,o)},t=(r,f,o)=>{const u={...r,entities:f,ids:o};return{...u,ids:s(u,o)}},i=(r,f,o)=>{let u=null,l=null;for(const y of f){const h=e(y);process.env.NODE_ENV!=="production"&&String(h).includes(".")&&V(h);const g=(u??r.entities)[h];if(g!==void 0&&o==="add")continue;const E=g!==void 0&&o==="upsert"?{...g,...y}:y;u??(u={...r.entities}),u[h]=E,g===void 0&&(l??(l=[...r.ids]),l.push(h))}return u===null?r:t(r,u,l??r.ids)},d=(r,f)=>{let o=null;for(const{id:u,changes:l}of f){const y=(o??r.entities)[u];y!==void 0&&(o??(o={...r.entities}),o[u]={...y,...l})}return o===null?r:t(r,o,r.ids)},a=(r,f)=>{const o=new Set(f.filter(l=>r.entities[l]!==void 0));if(o.size===0)return r;const u={...r.entities};for(const l of o)delete u[l];return t(r,u,r.ids.filter(l=>!o.has(l)))};return{getInitialState(r){const f={ids:[],entities:{}};return r===void 0?f:{...f,...r}},addOne:(r,f)=>i(r,[f],"add"),addMany:(r,f)=>i(r,f,"add"),setOne:(r,f)=>i(r,[f],"set"),setMany:(r,f)=>i(r,f,"set"),setAll:(r,f)=>{const o={},u=[];for(const l of f){const y=e(l);o[y]===void 0&&u.push(y),o[y]=l}return t(r,o,u)},updateOne:(r,f)=>d(r,[f]),updateMany:(r,f)=>d(r,f),upsertOne:(r,f)=>i(r,[f],"upsert"),upsertMany:(r,f)=>i(r,f,"upsert"),removeOne:(r,f)=>a(r,[f]),removeMany:(r,f)=>a(r,f),removeAll:r=>r.ids.length===0?r:t(r,{},[]),selectIds:r=>r.ids,selectEntities:r=>r.entities,selectAll:r=>r.ids.map(f=>r.entities[f]),selectById:(r,f)=>r.entities[f],selectTotal:r=>r.ids.length,idsPath:"ids",pathTo:(r,f)=>f===void 0?`entities.${r}`:`entities.${r}.${f}`,anyField:r=>`entities.*.${r}`}}const w="$yoltra";function R(c,e={}){const n=e.maxNodes??1e5,s=e.sanitize,t=[],i=new Map;let d=0,a=!1;function r(o,u){if(s!==void 0&&(o=s(u,o)),d+=1,d>n)return a=!0,{[w]:"unsupported",kind:"truncated"};switch(typeof o){case"undefined":return{[w]:"undefined"};case"bigint":return{[w]:"bigint",value:o.toString()};case"number":return Number.isNaN(o)?{[w]:"nan"}:o===1/0?{[w]:"infinity",sign:1}:o===-1/0?{[w]:"infinity",sign:-1}:o;case"function":case"symbol":return t.push(u),{[w]:"unsupported",kind:typeof o};case"string":case"boolean":return o}if(o===null)return null;const l=o,y=i.get(l);if(y!==void 0)return{[w]:"ref",path:y};if(i.set(l,u),o instanceof Date)return{[w]:"date",iso:o.toISOString()};if(o instanceof RegExp)return{[w]:"regexp",source:o.source,flags:o.flags};if(o instanceof Error)return{[w]:"error",name:o.name,message:o.message};if(o instanceof Map){const g=[];let E=0;for(const[b,ee]of o)g.push([r(b,`${u}/@k${E}`),r(ee,`${u}/${E}`)]),E+=1;return{[w]:"map",entries:g}}if(o instanceof Set){const g=[];let E=0;for(const b of o)g.push(r(b,`${u}/${E}`)),E+=1;return{[w]:"set",values:g}}if(Array.isArray(o))return o.map((g,E)=>r(g,`${u}/${E}`));const h={};for(const[g,E]of Object.entries(o))h[g]=r(E,`${u}/${B(g)}`);return w in h?{[w]:"escaped",value:h}:h}return{value:r(c,""),report:{truncated:a,unsupported:t}}}function D(c){const e=new Map,n=[];function s(d,a){if(d===null||typeof d!="object")return d;if(Array.isArray(d)){const f=[];return e.set(a,f),d.forEach((o,u)=>{if(C(o)){n.push({target:f,key:u,path:o.path}),f[u]=void 0;return}f[u]=s(o,`${a}/${u}`)}),f}if(typeof d[w]=="string"){const f=d;switch(f[w]){case"undefined":return;case"nan":return Number.NaN;case"infinity":return f.sign===1?1/0:-1/0;case"bigint":return BigInt(f.value);case"date":return new Date(f.iso);case"regexp":return new RegExp(f.source,f.flags);case"error":{const o=new Error(f.message);return o.name=f.name,o}case"unsupported":return;case"ref":return;case"map":{const o=new Map;return e.set(a,o),f.entries.forEach(([u,l],y)=>{o.set(s(u,`${a}/@k${y}`),s(l,`${a}/${y}`))}),o}case"set":{const o=new Set;return e.set(a,o),f.values.forEach((u,l)=>o.add(s(u,`${a}/${l}`))),o}case"escaped":return t(f.value,a);default:return}}return t(d,a)}function t(d,a){const r={};e.set(a,r);for(const[f,o]of Object.entries(d)){const u=`${a}/${B(f)}`;if(C(o)){n.push({target:r,key:f,path:o.path}),r[f]=void 0;continue}r[f]=s(o,u)}return r}const i=s(c,"");e.set("",i);for(const{target:d,key:a,path:r}of n)d[a]=e.get(r);return i}function C(c){return c!==null&&typeof c=="object"&&c[w]==="ref"&&typeof c.path=="string"}function B(c){return c.replace(/~/g,"~0").replace(/\//g,"~1")}function G(c,e,n={}){let s=n.maxNodes??1e5;for(let t=0;t<8;t+=1){const{value:i,report:d}=R(c,{...n,maxNodes:s});let a;try{a=JSON.stringify(i)?.length??0}catch{a=Number.POSITIVE_INFINITY}if(a<=e)return d.truncated?{value:i,truncated:!0,note:`State was too large to send in full; parts beyond ${s} nodes are omitted.`}:{value:i,truncated:!1};const r=Math.floor(s*e*.8/a);if(s=Math.max(1,Math.min(r,s-1)),s<=1&&t>0)break}return{value:{[w]:"unsupported",kind:"truncated"},truncated:!0,note:`State exceeds the ${e}-byte transport limit and could not be reduced to fit.`}}function $(c,e,n){c.onError?.(e,n)}async function Q(c){const e={slices:{},restored:!1};let n;try{n=c.source??await c.adapter.read(c.key)}catch(t){return $(c,t,"read"),e}if(n==null||n==="")return e;let s;try{s=D(JSON.parse(n))}catch(t){return $(c,t,"decode"),e}if(s===null||typeof s!="object"||typeof s.version!="number")return $(c,new Error("persisted payload is not a recognisable envelope"),"decode"),e;if(s.version!==c.version){if(c.migrate===void 0)return $(c,new Error(`persisted state is version ${s.version}, this build expects ${c.version}, and no migrate was supplied`),"migrate"),e;try{const t=c.migrate(s.slices,s.version);return t===null?e:{slices:t,restored:!0}}catch(t){return $(c,t,"migrate"),e}}return{slices:s.slices??{},restored:!0}}function J(c,e){if(!e.restored)return c;const n={};for(const[s,t]of Object.entries(c)){const i=e.slices[s];n[s]=i===void 0?t:{...t,state:i}}return n}function H(c,e){const n=c??{},s=e.slices===void 0?n:Object.fromEntries(e.slices.filter(t=>t in n).map(t=>[t,n[t]]));return JSON.stringify(R({version:e.version,slices:s}).value)}function Y(c,e){const n=e.throttleMs??250,s=e.slices;let t=null,i=!1;const d=()=>{if(i){i=!1;try{const f=e.adapter.write(e.key,H(c.getState(),e));f instanceof Promise&&f.catch(o=>$(e,o,"write"))}catch(f){$(e,f,"write")}}},a=()=>{if(i=!0,n<=0){d();return}t===null&&(t=setTimeout(()=>{t=null,d()},n),t.unref?.())},r=c.instrument(f=>{if(s===void 0){a();return}(f.changedPaths??[]).some(u=>s.some(l=>u===l||u.startsWith(`${l}.`)))&&a()});return()=>{r(),t!==null&&(clearTimeout(t),t=null),d()}}function q(c,e){return H(c.getState(),e)}function X(c){return{read:e=>c.getItem(e),write:(e,n)=>c.setItem(e,n),remove:e=>c.removeItem(e)}}function Z(c){const e=new Map(Object.entries(c??{}));return{read:n=>e.get(n)??null,write:(n,s)=>{e.set(n,s)},remove:n=>{e.delete(n)}}}m.EventBus=v,m.LooseEventBus=S,m.Reducer=A,m.Store=P,m.createEntityAdapter=L,m.createMemoryAdapter=Z,m.createStore=W,m.createWebStorageAdapter=X,m.decodeState=D,m.dehydrate=q,m.detectChangedProps=z,m.encodeState=R,m.encodeStateBounded=G,m.eventKeys=F,m.freezeState=M,m.hydrate=Q,m.persist=Y,m.typedEvents=j,m.withHydration=J,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"})}));
11
11
  //# sourceMappingURL=yoltra.umd.js.map