@yoltra/core 0.4.0 → 0.6.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.
- package/README.es.md +214 -7
- package/README.md +315 -13
- package/dist/types/eventBus/EventBus.d.ts +1 -1
- package/dist/types/eventBus/index.d.ts +2 -2
- package/dist/types/index.d.ts +21 -16
- package/dist/types/persistence/adapters.d.ts +1 -1
- package/dist/types/persistence/persist.d.ts +3 -6
- package/dist/types/reducer/Reducer.d.ts +4 -3
- package/dist/types/store/Store.d.ts +252 -17
- package/dist/types/store/call.d.ts +149 -0
- package/dist/types/store/callQueue.d.ts +79 -0
- package/dist/types/store/rejection.d.ts +58 -0
- package/dist/types/types.d.ts +279 -14
- package/dist/types/utils/detectChangedProps.d.ts +6 -0
- package/dist/types/utils/immutability.d.ts +1 -1
- package/dist/types/utils/index.d.ts +2 -2
- package/dist/yoltra.cjs +11 -0
- package/dist/yoltra.cjs.map +1 -0
- package/dist/yoltra.mjs +2902 -0
- package/dist/yoltra.mjs.map +1 -0
- package/dist/yoltra.umd.js +2 -2
- package/dist/yoltra.umd.js.map +1 -0
- package/package.json +21 -21
- package/dist/yoltra.cjs.js +0 -11
- package/dist/yoltra.esm.js +0 -2374
package/dist/yoltra.umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @yoltra/core v0.
|
|
2
|
+
* @yoltra/core v0.6.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(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 _{constructor(e){p(this,"_reduce");this._reduce=e}reduce(e,n){return this._reduce(e,n)}}const A=new Set;function O(c,e){const n=c?`${c}.${e}`:e;A.has(n)||(A.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.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).filter(Boolean);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)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).filter(Boolean);if(o.length===0)return;const u=new Set;for(const l of o)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(e in this.reducers)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 _(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}/${C(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(B(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}/${C(f)}`;if(B(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 B(c){return c!==null&&typeof c=="object"&&c[w]==="ref"&&typeof c.path=="string"}function C(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=_,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"})}));
|
|
10
|
+
(function(y,S){typeof exports=="object"&&typeof module<"u"?S(exports):typeof define=="function"&&define.amd?define(["exports"],S):(y=typeof globalThis<"u"?globalThis:y||self,S(y.yoltra={}))})(this,(function(y){"use strict";var Ee=Object.defineProperty;var we=(y,S,$)=>S in y?Ee(y,S,{enumerable:!0,configurable:!0,writable:!0,value:$}):y[S]=$;var p=(y,S,$)=>we(y,typeof S!="symbol"?S+"":S,$);class S{constructor(){p(this,"handlers",new Map)}on(e,t,s){let n=this.handlers.get(e);n||(n=new Map,this.handlers.set(e,n));let r=n.get(t);return r||(r=new Set,n.set(t,r)),r.add(s),()=>this.off(e,t,s)}off(e,t,s){const n=this.handlers.get(e);if(!n)return;const r=n.get(t);r&&(r.delete(s),r.size===0&&n.delete(t),n.size===0&&this.handlers.delete(e))}emit(e,t,s,n){const r=this.handlers.get(e);if(!r)return;const o=r.get(t);if(!(!o||o.size===0))for(const d of[...o])try{d(s,n)}catch(i){console.error("EventBus handler error:",i)}}clear(){this.handlers.clear()}}class ${constructor(){p(this,"handlers",new Map);p(this,"patternHandlers",new Map);p(this,"patternIndex",new Map)}on(e,t,s){const n=String(t);if(this.isPattern(n)){const r=n;this.patternHandlers.has(e)||this.patternHandlers.set(e,new Map);const o=this.patternHandlers.get(e);return o.has(r)||(o.set(r,[]),this.indexPattern(e,r)),o.get(r).push(s),()=>this.offPattern(e,r,s)}else{const r=this.normalizeTypeKey(n);this.handlers.has(e)||this.handlers.set(e,new Map);const o=this.handlers.get(e);return o.has(r)||o.set(r,[]),o.get(r).push(s),()=>this.offExactNormalized(e,r,s)}}off(e,t,s){const n=this.normalizeTypeKey(String(t));this.offExactNormalized(e,n,s)}offExactNormalized(e,t,s){const n=this.handlers.get(e);if(!n)return;const r=n.get(t);if(!r)return;const o=r.indexOf(s);o!==-1&&r.splice(o,1),r.length===0&&n.delete(t),n.size===0&&this.handlers.delete(e)}offPattern(e,t,s){const n=this.patternHandlers.get(e);if(!n)return;const r=n.get(t);if(!r)return;const o=r.indexOf(s);o!==-1&&r.splice(o,1),r.length===0&&(n.delete(t),this.unindexPattern(e,t)),n.size===0&&(this.patternHandlers.delete(e),this.patternIndex.delete(e))}emit(e,t,s){const n=String(t),r=this.normalizeTypeKey(n),o=this.handlers.get(e)?.get(r)??[],d=this.matchingPatternHandlers(e,n),i=new Set,c=l=>{for(const u of[...l])if(!i.has(u)){i.add(u);try{u(s)}catch(f){console.error(f);continue}}};c(o);for(const l of d)c(l)}emitWith(e,t,s){const n=String(t),r=this.normalizeTypeKey(n),o=this.handlers.get(e)?.get(r)??[],d=this.matchingPatternHandlers(e,n);if(o.length===0&&d.length===0)return;const i=s(),c=new Set,l=u=>{for(const f of[...u])if(!c.has(f)){c.add(f);try{f(i)}catch(m){console.error(m);continue}}};l(o);for(const u of d)l(u)}isPattern(e){return e.includes("*")}normalizeTypeKey(e){return e.replace(/^\./,"")}splitPath(e){return this.normalizeTypeKey(e).split(".").filter(Boolean)}indexPattern(e,t){let s=this.patternIndex.get(e);s===void 0&&(s={byHead:new Map,anyHead:[]},this.patternIndex.set(e,s));const n=this.splitPath(t),r={pattern:t,segments:n},o=n[0];if(o===void 0||o==="*"||o==="**"){s.anyHead.push(r);return}const d=s.byHead.get(o);d===void 0?s.byHead.set(o,[r]):d.push(r)}unindexPattern(e,t){const s=this.patternIndex.get(e);if(s===void 0)return;const n=this.splitPath(t)[0],r=n===void 0||n==="*"||n==="**"?s.anyHead:s.byHead.get(n);if(r===void 0)return;const o=r.findIndex(d=>d.pattern===t);o!==-1&&r.splice(o,1),r.length===0&&r!==s.anyHead&&n!==void 0&&s.byHead.delete(n)}matchingPatternHandlers(e,t){const s=this.patternHandlers.get(e),n=this.patternIndex.get(e);if(s===void 0||s.size===0||n===void 0)return[];const r=this.splitPath(t),o=[],d=c=>{for(const l of c){if(!this.matchSegments(l.segments,r))continue;const u=s.get(l.pattern);u!==void 0&&o.push(u)}},i=r[0];if(i!==void 0){const c=n.byHead.get(i);c!==void 0&&d(c)}return d(n.anyHead),o}matchSegments(e,t){let s=0,n=0,r=-1,o=0;for(;n<t.length;)if(s<e.length&&(e[s]==="*"||e[s]===t[n]))s++,n++;else if(s<e.length&&e[s]==="**")r=s,o=n,s++;else if(r!==-1)s=r+1,n=++o;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[t,s]of this.handlers)for(const[n,r]of s)r.length>0&&e.push({channel:t,type:n,count:r.length});for(const[t,s]of this.patternHandlers)for(const[n,r]of s)r.length>0&&e.push({channel:t,type:n,count:r.length});return e}}class x{constructor(e){p(this,"_reduce");this._reduce=e}reduce(e,t){return this._reduce(e,t)}}const _=new Set;function C(a,e){const t=a?`${a}.${e}`:e;_.has(t)||(_.add(t),console.warn(`[yoltra] State key "${e}"${a?` under "${a}"`:""} contains a dot. Paths are dotted, so this key is indistinguishable from nested objects of the same name: a subscription to "${t}" may match the wrong value, and DevTools patches for it will address the wrong node. Rename the key, or nest it.`))}function D(a,e,t="",s=new Map){const n=[];return O(a,e,t,s,n),n}function O(a,e,t,s,n){if(a===e)return;if(typeof a!="object"||typeof e!="object"||a===null||e===null){if(typeof a=="number"&&Number.isNaN(a)&&Number.isNaN(e))return;n.push(t);return}if(a instanceof Date&&e instanceof Date){a.getTime()!==e.getTime()&&n.push(t);return}if(a instanceof RegExp&&e instanceof RegExp){(a.source!==e.source||e.flags!==a.flags)&&n.push(t);return}if(a instanceof Map||e instanceof Map){n.push(t);return}if(a instanceof Set||e instanceof Set){n.push(t);return}const r=a,o=e,d=s.get(r);if(d?.has(o))return;const i=d??new Set;i.add(o),d||s.set(r,i);try{const c=Array.isArray(a),l=Array.isArray(e);if(c!==l){n.push(t);return}if(c){const h=a,g=e;h.length!==g.length&&t&&n.push(t);const E=Math.min(h.length,g.length);for(let w=0;w<E;w++)h[w]!==g[w]&&O(h[w],g[w],t?`${t}.${w}`:`${w}`,s,n);for(let w=E;w<Math.max(h.length,g.length);w++)n.push(t?`${t}.${w}`:`${w}`);return}const u=Object.keys(a),f=Object.keys(e);if(u.length===0&&f.length===0){n.push(t);return}let m=u.length===f.length;if(m){for(let h=0;h<f.length;h++)if(!Object.prototype.hasOwnProperty.call(a,f[h])){m=!1;break}}if(m){for(const h of f)a[h]!==e[h]&&(process.env.NODE_ENV!=="production"&&h.includes(".")&&C(t,h),O(a[h],e[h],t?`${t}.${h}`:h,s,n));return}for(const h of f){const g=Object.prototype.hasOwnProperty.call(a,h);if(g&&a[h]===e[h])continue;process.env.NODE_ENV!=="production"&&h.includes(".")&&C(t,h);const E=t?`${t}.${h}`:h;if(!g){n.push(E);continue}O(a[h],e[h],E,s,n)}for(const h of u)Object.prototype.hasOwnProperty.call(e,h)||(process.env.NODE_ENV!=="production"&&h.includes(".")&&C(t,h),n.push(t?`${t}.${h}`:h))}finally{i.delete(o),i.size===0&&s.delete(r)}}function P(a,e=new WeakSet,t){if(a===null||typeof a!="object"||e.has(a)||(t!==void 0&&a===t.watch&&t.onFound(),Object.isFrozen(a)))return a;if(e.add(a),Array.isArray(a)){const s=a;for(let n=0;n<s.length;n++)s[n]=P(s[n],e,t);return Object.freeze(s)}for(const s of Object.getOwnPropertyNames(a)){const n=Object.getOwnPropertyDescriptor(a,s);!n||!("value"in n)||(a[s]=P(a[s],e,t))}for(const s of Object.getOwnPropertySymbols(a)){const n=Object.getOwnPropertyDescriptor(a,s);!n||!("value"in n)||(a[s]=P(a[s],e,t))}return Object.freeze(a)}const N=Symbol.for("yoltra.rejected");function J(a){return{[N]:!0,reason:a}}function B(a){return typeof a=="object"&&a!==null&&a[N]===!0}class q{constructor(e){p(this,"highWaterMark");p(this,"buffer",[]);p(this,"takers",[]);p(this,"putters",[]);p(this,"consuming",!1);p(this,"ended",!1);p(this,"closed",!1);p(this,"dropped",0);this.highWaterMark=e}get droppedCount(){return this.dropped}beginConsuming(){this.consuming=!0}put(e){if(this.closed||this.ended)return Promise.resolve();const t=this.takers.shift();return t!==void 0?(t({value:e,done:!1}),Promise.resolve()):this.buffer.length<this.highWaterMark?(this.buffer.push(e),Promise.resolve()):this.consuming?new Promise(s=>{this.putters.push({item:e,release:s})}):(this.dropped++,Promise.resolve())}take(){this.consuming=!0;const e=this.buffer.shift();if(e!==void 0){const s=this.putters.shift();return s!==void 0&&(this.buffer.push(s.item),s.release()),Promise.resolve({value:e,done:!1})}const t=this.putters.shift();return t!==void 0?(t.release(),Promise.resolve({value:t.item,done:!1})):this.closed||this.ended?Promise.resolve({value:void 0,done:!0}):new Promise(s=>{this.takers.push(s)})}end(){if(this.ended||this.closed)return;this.ended=!0;let e=this.putters.shift();for(;e!==void 0;)this.buffer.push(e.item),e.release(),e=this.putters.shift();let t=this.takers.shift();for(;t!==void 0;){const s=this.buffer.shift();t(s!==void 0?{value:s,done:!1}:{value:void 0,done:!0}),t=this.takers.shift()}}close(){if(this.closed)return;this.closed=!0,this.buffer.length=0;let e=this.takers.shift();for(;e!==void 0;)e({value:void 0,done:!0}),e=this.takers.shift();let t=this.putters.shift();for(;t!==void 0;)t.release(),t=this.putters.shift()}}class H extends Error{constructor(t,s,n){super(`[yoltra] call to "${t}/${s}" saw no correlated reply for ${n}ms. The timeout is idle rather than total, so this means the responder went quiet, not that it was slow. Check that something handles "${t}/${s}" and that its reply is emitted through the \`emit\` it was handed — a reply emitted from an unrelated context carries no causal link, and needs an explicit correlationId instead.`);p(this,"channel");p(this,"type");p(this,"idleMs");this.name="CallTimeoutError",this.channel=t,this.type=s,this.idleMs=n}}class z extends Error{constructor(e){super(`[yoltra] call aborted: ${e}`),this.name="CallAbortedError"}}function Y(a){const[e,t]=a;if(t===void 0)return{channel:e,isTerminal:()=>!0};if(typeof t=="string")return{channel:e,isTerminal:n=>n===t};const s=new Set(t);return{channel:e,isTerminal:n=>s.has(n)}}function X(a,e,t){return a.parentId===e?!0:t===void 0?!1:a.meta?.correlationId===t}function Z(a,e){try{return structuredClone(e)}catch(t){throw new Error(`[yoltra] Initial state for slice "${String(a)}" could not be copied: ${t instanceof Error?t.message:String(t)}. State must be structured-cloneable — functions, class instances and DOM nodes are not. Keep behaviour out of state and store plain data.`)}}function A(a,e){return process.env.NODE_ENV==="production"?a:P(a,new WeakSet,e)}const W=100,ee=64,K=16,te=3e4,ne=16,M=Object.freeze({committed:!1,written:!1}),se=Object.freeze({committed:!0,written:!1}),re=Object.freeze({committed:!0,written:!0}),F=()=>typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();class T{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,"writtenEventSubscribers",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,"currentEvent",null);p(this,"transitionsThisDrain",0);p(this,"maxReduceDepth");p(this,"maxTransitionsPerDrain");p(this,"onCascade");p(this,"onRejected");p(this,"instrumentObservers",new Set);p(this,"changedPathSink",null);p(this,"stagingSink",null);p(this,"stagedRejection",null);p(this,"stagedRejectedBy","");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 S,this.connectorBus=new $,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.maxReduceDepth=e.maxReduceDepth??ee,this.maxTransitionsPerDrain=e.maxTransitionsPerDrain??1/0,this.onCascade=e.onCascade,this.onRejected=e.onRejected,this.dedupConfig={windowMs:e.dedupWindowMs??0,maxCacheSize:1e3},Object.entries(e.reducer).forEach(([t,s])=>{this.mountSlice(t,s,{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.__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.writtenEventSubscribers.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,s){const n=`${e}::${t}`;try{if(s==null)return`${n}::null`;if(typeof s!="object")return`${n}::${String(s)}`;const r=JSON.stringify(s);return`${n}::${r}`}catch{return`${n}::${Date.now()}::${Math.random()}`}}shouldDedupe(e,t){const s=Date.now(),n=this.processedEvents.get(e);return n!==void 0&&s-n<t?(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 t=Math.max(this.dedupConfig.windowMs,W),s=e-t*2;for(const[n,r]of this.processedEvents)r<s&&this.processedEvents.delete(n);this.processedEvents.size===0&&this.eventCleanupTimer!==null&&(clearInterval(this.eventCleanupTimer),this.eventCleanupTimer=null)}reportCascade(e,t,s,n,r){console.error(`[yoltra] Cascade stopped: "${s.channel}/${s.type}" would exceed ${e} (${t}). This event was refused and the chain ends here. A chain this long is almost always two consumers emitting into each other — check what reacts to "${s.channel}/${s.type}" and what that emits in turn.`+(r.length>0?` Recent causal chain: ${r.join(" → ")} → (refused).`:""));try{this.onCascade?.({limit:e,limitValue:t,event:s,depth:n,chain:r})}catch(o){console.error("onCascade handler error:",o)}}matchesWhen(e,t){return!e||"any"in e&&e.any===!0?!0:"keys"in e?e.keys.some(([s,n])=>t.channel===s&&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=this.scopedEmit(e),s=`${String(e.channel)}::${String(e.type)}`,n=this.effects.get(s);if(n&&n.size>0)for(const r of[...n])try{await r(e,this.getState,t)}catch(o){console.error("Effect error:",o),this.onEffectError?.(o,e)}for(const{effect:r,when:o}of this.patternEffects)if(this.matchesWhen(o,e))try{await r(e,this.getState,t)}catch(d){console.error("Effect error:",d),this.onEffectError?.(d,e)}}scopedEmit(e){const t={id:e.id,depth:e.depth??0,chain:[...this.currentEvent?.chain??[],e.id].slice(-K)};return((s,n,r,o)=>this.emitCaused(t,s,n,r,o))}notifyEventSubscribers(e,t){const s=`${String(e.channel)}::${String(e.type)}`,r=(t==="committed"?this.committedEventSubscribers:t==="written"?this.writtenEventSubscribers:this.uncommittedEventSubscribers).get(s);if(r?.size)for(const d of[...r])this.invokeEventSubscriber(d,e,t);if(t==="written")return;const o=this.allEventSubscribers.get(s);if(o?.size)for(const d of[...o])this.invokeEventSubscriber(d,e,t)}invokeEventSubscriber(e,t,s){try{const n=e(t,this.getState,this.emit,s);n&&typeof n.then=="function"&&n.catch(r=>console.error("Event subscription error:",r))}catch(n){console.error("Event subscription error:",n)}}stageSliceGuarded(e,t,s){try{return this.stageSlice(e,t,s)}catch(n){return console.error(`Reducer error in slice "${e}":`,n),this.onReducerError?.(n,t,e),null}}stageSlice(e,t,s){const n=this.state[e],r=this.reducers[e].reduce(n,t);if(B(r))return r;if(n===r)return null;const o=D(n,r);if(o.length===0)return null;const d=t.payload,i=process.env.NODE_ENV!=="production"&&d!==null&&typeof d=="object"?{watch:d,onFound:()=>{const c=`${e}:${t.channel}:${t.type}`;this.warnedPayloadAliases.has(c)||(this.warnedPayloadAliases.add(c),console.warn(`[yoltra] Slice "${e}" stored the payload of "${t.channel}/${t.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;return s.push({name:e,prev:n,frozen:A(r,i),leafPaths:o}),null}commitStaged(e,t){if(e.length===0)return!1;const s={...this.state};for(const n of e)s[n.name]=n.frozen;if(this.state=s,this.changedPathSink)for(const n of e)for(const r of n.leafPaths)this.changedPathSink.push(r?`${n.name}.${r}`:n.name);for(const n of e){const r=new Set;for(const o of n.leafPaths){if(o===""){r.add("");continue}for(const d of T.buildAncestorPaths(o))r.add(d)}for(const o of r)this.connectorBus.emitWith(n.name,o,()=>({oldValue:this.getAtPath(n.prev,o),newValue:this.getAtPath(n.frozen,o),path:o,eventId:t.id,channel:t.channel,type:t.type}))}return!0}__devtoolsIntrospect(){const e=Object.keys(this.reducers).map(d=>{const i=this.patternReducers.get(d);return{name:d,when:i}}),t=[];for(const[d,i]of this.effects){if(i.size===0)continue;const[c,l]=d.split("::");for(const u of i){const f=this.effectMeta.get(u);t.push({channel:c,type:l,name:f?.name,description:f?.description})}}for(const d of this.patternEffects){const i=this.effectMeta.get(d.effect);t.push({channel:"*",type:"*",name:i?.name,description:i?.description})}const s=[];for(const d of this.middleware)typeof d=="function"?s.push({name:d.name||void 0}):s.push({name:d.meta?.name,description:d.meta?.description,when:d.when});const n=[];for(const d of this.connectorBus.__introspect())for(let i=0;i<d.count;i++)n.push({reducer:d.channel,property:d.type});const r=[];for(const[d,i]of this.committedEventSubscribers){if(i.size===0)continue;const[c,l]=d.split("::");for(let u=0;u<i.size;u++)r.push({channel:c,type:l,phase:"committed"})}for(const[d,i]of this.uncommittedEventSubscribers){if(i.size===0)continue;const[c,l]=d.split("::");for(let u=0;u<i.size;u++)r.push({channel:c,type:l,phase:"uncommitted"})}for(const[d,i]of this.allEventSubscribers){if(i.size===0)continue;const[c,l]=d.split("::");for(let u=0;u<i.size;u++)r.push({channel:c,type:l,phase:"all"})}const o=this.listeners.size;return{reducers:e,effects:t,middleware:s,atomic:n,event:r,coarse:o,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 t=this.state,s=e,n={...this.state};let r=!1;Object.keys(this.reducers).forEach(o=>{const d=t?.[o],i=s?.[o];if(i===void 0){process.env.NODE_ENV!=="production"&&console.warn(`[yoltra] External state is missing slice "${String(o)}"; retaining its current value. Time-travel snapshots should contain all slices.`);return}if(d===i)return;const c=A(i);n[o]=c,r=!0;const l=D(d,i);if(l.length===0)return;const u=new Set;for(const f of l){if(f===""){u.add("");continue}for(const m of T.buildAncestorPaths(f))u.add(m)}for(const f of u){const m=this.getAtPath(d,f),h=this.getAtPath(c,f);this.connectorBus.emit(o,f,{oldValue:m,newValue:h,path:f})}}),r&&(this.state=n),r&&this.listeners.forEach(o=>o())}__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 s of t){const n=s,r=[];this.stagingSink=r;let o=null;try{this.reducerBus.emit(n.channel,n.type,n.payload,n),o=this.stagedRejection;for(const[i,c]of this.patternReducers){if(o!==null)break;if(this.matchesWhen(c,n)){const l=this.stageSliceGuarded(i,n,r);l!==null&&(o=l)}}}finally{this.stagingSink=null,this.stagedRejection=null,this.stagedRejectedBy=""}const d=o===null&&this.commitStaged(r,n);this.notifyEventSubscribers(n,"committed"),d&&(this.notifyEventSubscribers(n,"written"),this.listeners.forEach(i=>i()))}}async emit(e,t,s,n){return this.emitCaused(null,e,t,s,n)}async emitCaused(e,t,s,n,r){const o=r?.dedupKey,d=this.dedupConfig.windowMs;if(r?.skipDedup!==!0&&(d>0||o!==void 0)){const m=o!==void 0&&d<=0?W:d,h=o!==void 0?`${t}::${s}::#${o}`:this.fingerprint(t,s,n);if(this.shouldDedupe(h,m))return M}const i=r?.id??this.idFactory(),c=this.currentEvent??e,l=c===null?0:c.depth+1;if(c!==null&&l>this.maxReduceDepth)return this.reportCascade("maxReduceDepth",this.maxReduceDepth,{channel:t,type:s,payload:n,id:i,...r?.meta!==void 0?{meta:r.meta}:{},parentId:c.id,depth:l},l,c.chain),M;let u;const f=new Promise(m=>{u=m});return this.reduceQueue.push({channel:t,type:s,payload:n,id:i,meta:r?.meta,resolve:u,...c!==null?{parentId:c.id,depth:l,chain:c.chain}:{}}),this.drainReduce(),f}drainReduce(){if(!this.isReducing){this.isReducing=!0,this.transitionsThisDrain=0;try{for(;this.reduceQueue.length>0;){const e=this.reduceQueue.shift(),{channel:t,type:s,payload:n,id:r,meta:o,resolve:d,parentId:i,depth:c,chain:l}=e,u={channel:t,type:s,payload:n,id:r,...o!==void 0?{meta:o}:{},...i!==void 0?{parentId:i,depth:c}:{}};if(i!==void 0&&++this.transitionsThisDrain>this.maxTransitionsPerDrain){this.reportCascade("maxTransitionsPerDrain",this.maxTransitionsPerDrain,u,c,l),d(M);continue}this.currentEvent={id:r,depth:c??0,chain:[...l??[],r].slice(-K)};const f=this.instrumentObservers.size>0,m=f?this.state:void 0,h=f?[]:void 0;h!==void 0&&(this.changedPathSink=h);const g=f?F():0;let E=M;try{E=this.applyEventSync(u)}catch(w){console.error("Emit reduce error:",w)}finally{f&&(this.changedPathSink=null),this.currentEvent=null}f&&this.emitInstrumentation(u,E,h??[],m,F()-g),this.runEventEffects(u,E,d)}}finally{this.isReducing=!1}}}applyEventSync(e){for(const o of this.middleware){const d=this.getMiddlewareWhen(o);if(!this.matchesWhen(d,e))continue;const i=this.getMiddlewareFunction(o);let c;try{c=i(this.state,e,this.emit),process.env.NODE_ENV!=="production"&&typeof c?.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(l){console.error("Middleware error:",l),c=!1}if(!c)return this.notifyEventSubscribers(e,"uncommitted"),M}const t=[];this.stagingSink=t;let s=null,n="";try{this.reducerBus.emit(e.channel,e.type,e.payload,e),s=this.stagedRejection,n=this.stagedRejectedBy;for(const[o,d]of this.patternReducers){if(s!==null)break;if(this.matchesWhen(d,e)){const i=this.stageSliceGuarded(o,e,t);i!==null&&(s=i,n=o)}}}finally{this.stagingSink=null,this.stagedRejection=null,this.stagedRejectedBy=""}if(s!==null)return this.onRejected?.(s,e,n),this.notifyEventSubscribers(e,"committed"),{committed:!0,written:!1,rejected:s};const r=this.commitStaged(t,e);return this.notifyEventSubscribers(e,"committed"),r&&(this.notifyEventSubscribers(e,"written"),this.listeners.forEach(o=>o())),r?re:se}async runEventEffects(e,t,s){this.inFlightEffects++;try{t.committed&&await this.notifyEffects(e)}catch(n){console.error("Effect error:",n)}finally{this.inFlightEffects--,s(t)}}instrument(e){return this.instrumentObservers.add(e),()=>{this.instrumentObservers.delete(e)}}emitInstrumentation(e,t,s,n,r){const o={},d={};for(const c of s)o[c]=this.getAtPath(n,c),d[c]=this.getAtPath(this.state,c);const i={event:{id:e.id,channel:e.channel,type:e.type,payload:e.payload,...e.meta!==void 0?{meta:e.meta}:{}},committed:t.committed,changedPaths:s,prevValues:o,nextValues:d,reduceTimeMs:r,...t.rejected!==void 0?{rejected:t.rejected}:{}};for(const c of[...this.instrumentObservers])try{c(i)}catch(l){console.error("Instrumentation observer error:",l)}}connect(e,t,s){const n=this.connectorBus.on(e.reducer,e.property,t);if(s?.immediate===!0){const r=this.state[e.reducer],o=e.property.includes("*")?"":e.property;t({oldValue:void 0,newValue:this.getAtPath(r,o),path:o})}return n}onEvent(e,t,s,n="committed"){const r=`${e}::${String(t)}`,o=n==="committed"?this.committedEventSubscribers:n==="uncommitted"?this.uncommittedEventSubscribers:n==="written"?this.writtenEventSubscribers:this.allEventSubscribers;return o.has(r)||o.set(r,new Set),o.get(r).add(s),()=>{const d=o.get(r);d&&(d.delete(s),d.size===0&&o.delete(r))}}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(Object.prototype.hasOwnProperty.call(this.reducers,e))throw new Error(`Reducer ${e} already exists`);return this.mountSlice(e,t,{preserveState:!1}),this.listeners.forEach(s=>s()),()=>{this.unmountSlice(e,{deleteState:!0}),this.listeners.forEach(s=>s())}}call(e,t,s,n){const{channel:r,isTerminal:o}=Y(n.reply),d=n.timeoutMs??te,i=new q(n.highWaterMark??ne),c=this.idFactory();let l,u,f=!1;const m=new Promise((v,R)=>{l=v,u=R});m.catch(()=>{});let h=null,g=null;const E=(v,R=!1)=>{f||(f=!0,h!==null&&clearTimeout(h),h=null,g?.(),g=null,R?i.end():i.close(),n.signal?.removeEventListener("abort",w),v())};function w(){E(()=>u(new z(String(n.signal?.reason??"signal aborted"))))}const I=()=>{h!==null&&clearTimeout(h),h=setTimeout(()=>{E(()=>u(new H(e,t,d)))},d),h.unref?.()};return g=this.registerEffect({when:{channel:r},effect:async v=>{if(!f&&X(v,c,n.correlationId)){if(I(),o(String(v.type))){E(()=>l(v),!0);return}await i.put(v)}}}),n.signal!==void 0&&(n.signal.aborted?w():n.signal.addEventListener("abort",w,{once:!0})),I(),this.emit(e,t,s,{id:c,...n.correlationId!==void 0?{meta:{correlationId:n.correlationId}}:{}}),{then:(v,R)=>m.then(v,R),catch:v=>m.catch(v),finally:v=>m.finally(v),get dropped(){return i.droppedCount},cancel:(v="cancelled")=>{E(()=>u(new z(v)))},[Symbol.asyncIterator]:()=>(i.beginConsuming(),{next:()=>i.take(),return:async()=>(i.close(),{value:void 0,done:!0})})}}registerEffect(e){const{effect:t,meta:s,when:n}=e,r=[];if(s&&this.effectMeta.set(t,s),n&&("any"in n&&n.any===!0||"channel"in n||"channels"in n)){const i={effect:t,when:n};return this.patternEffects.add(i),()=>{this.patternEffects.delete(i)}}const d=this.normalizeEventKeys(e);if(d.length===0&&!n){const i={effect:t,when:{any:!0}};return this.patternEffects.add(i),()=>{this.patternEffects.delete(i)}}for(const[i,c]of d){const l=`${String(i)}::${String(c)}`;this.effects.has(l)||this.effects.set(l,new Set),this.effects.get(l).add(t),r.push(()=>{const u=this.effects.get(l);u&&(u.delete(t),u.size===0&&this.effects.delete(l))})}return()=>{for(const i of r)i()}}onEffect(e,t,s){const n=async(r,o,d)=>{if(r.channel!==e||r.type!==t)return;const i=r;return s(i.payload,o,d,i)};return this.registerEffect({when:{keys:[[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 s=t.preserveState!==!1,n=new Set(Object.keys(this.reducers)),r=Object.entries(e),o=new Set(r.map(([d])=>d));for(const d of n)o.has(d)||this.unmountSlice(d,{deleteState:!0});for(const[d,i]of r)n.has(d)?(this.unmountSlice(d,{deleteState:!1}),this.mountSlice(d,i,{preserveState:s})):this.mountSlice(d,i,{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,s){const n=e,{reducer:r,state:o,when:d}=t;if(this.reducers[e]=new x(r),(!s.preserveState||this.state[n]===void 0)&&(this.state={...this.state,[n]:A(Z(n,o))}),d&&("any"in d&&d.any===!0||"channel"in d||"channels"in d)){this.patternReducers.set(e,d),this.sliceUnsubs.set(n,[]);return}const c=this.normalizeEventKeys(t);if(c.length===0&&!d){this.patternReducers.set(e,{any:!0}),this.sliceUnsubs.set(n,[]);return}const l=[];for(const[u,f]of c){const m=this.reducerBus.on(u,f,(h,g)=>{const E=g??{channel:u,type:f,payload:h,id:this.idFactory()};if(this.stagingSink===null)return;const w=this.stageSliceGuarded(e,E,this.stagingSink);w!==null&&this.stagedRejection===null&&(this.stagedRejection=w,this.stagedRejectedBy=e)});l.push(m)}this.sliceUnsubs.set(n,l)}unmountSlice(e,t){const s=e;this.patternReducers.delete(e);const n=this.sliceUnsubs.get(s);if(n){for(const r of n)try{r()}catch(o){console.error(`[Store error]: ${o}`)}this.sliceUnsubs.delete(s)}if(delete this.reducers[e],t.deleteState){const{[s]:r,...o}=this.state;this.state=o}}normalizeEventKeys(e){if(e.when){const t=e.when;if("keys"in t)return t.keys}return[]}getAtPath(e,t){if(!t)return e;const n=(t[0]==="."?t.slice(1):t).split(".");let r=e;for(const o of n){if(r==null)return;r=r[o]}return r}static buildAncestorPaths(e){if(!e)return[];const s=(e[0]==="."?e.slice(1):e).split("."),n=[];for(let r=0;r<s.length;r++)n.push(s.slice(0,r+1).join("."));return n}}function ie(a){return new T({...a,reducer:a.reducer??{},middleware:a.middleware??[],effects:a.effects??[]})}const oe=a=>(e,t)=>t.map(s=>[e,s]),ce=()=>a=>a,U=new Set;function ae(a){const e=String(a);U.has(e)||(U.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 de(a,e){if(a.length!==e.length)return e;for(let t=0;t<a.length;t++)if(a[t]!==e[t])return e;return a}function le(a={}){const e=a.selectId??(i=>i.id),{sortComparer:t}=a,s=(i,c)=>{if(t===void 0)return c;const l=[...c].sort((u,f)=>{const m=i.entities[u],h=i.entities[f];return m===void 0||h===void 0?0:t(m,h)});return de(c,l)},n=(i,c,l)=>{const u={...i,entities:c,ids:l};return{...u,ids:s(u,l)}},r=(i,c,l)=>{let u=null,f=null;for(const m of c){const h=e(m);process.env.NODE_ENV!=="production"&&String(h).includes(".")&&ae(h);const g=(u??i.entities)[h];if(g!==void 0&&l==="add")continue;const E=g!==void 0&&l==="upsert"?{...g,...m}:m;u??(u={...i.entities}),u[h]=E,g===void 0&&(f??(f=[...i.ids]),f.push(h))}return u===null?i:n(i,u,f??i.ids)},o=(i,c)=>{let l=null;for(const{id:u,changes:f}of c){const m=(l??i.entities)[u];m!==void 0&&(l??(l={...i.entities}),l[u]={...m,...f})}return l===null?i:n(i,l,i.ids)},d=(i,c)=>{const l=new Set(c.filter(f=>i.entities[f]!==void 0));if(l.size===0)return i;const u={...i.entities};for(const f of l)delete u[f];return n(i,u,i.ids.filter(f=>!l.has(f)))};return{getInitialState(i){const c={ids:[],entities:{}};return i===void 0?c:{...c,...i}},addOne:(i,c)=>r(i,[c],"add"),addMany:(i,c)=>r(i,c,"add"),setOne:(i,c)=>r(i,[c],"set"),setMany:(i,c)=>r(i,c,"set"),setAll:(i,c)=>{const l={},u=[];for(const f of c){const m=e(f);l[m]===void 0&&u.push(m),l[m]=f}return n(i,l,u)},updateOne:(i,c)=>o(i,[c]),updateMany:(i,c)=>o(i,c),upsertOne:(i,c)=>r(i,[c],"upsert"),upsertMany:(i,c)=>r(i,c,"upsert"),removeOne:(i,c)=>d(i,[c]),removeMany:(i,c)=>d(i,c),removeAll:i=>i.ids.length===0?i:n(i,{},[]),selectIds:i=>i.ids,selectEntities:i=>i.entities,selectAll:i=>i.ids.map(c=>i.entities[c]),selectById:(i,c)=>i.entities[c],selectTotal:i=>i.ids.length,idsPath:"ids",pathTo:(i,c)=>c===void 0?`entities.${i}`:`entities.${i}.${c}`,anyField:i=>`entities.*.${i}`}}const b="$yoltra";function j(a,e={}){const t=e.maxNodes??1e5,s=e.sanitize,n=[],r=new Map;let o=0,d=!1;function i(l,u){if(s!==void 0&&(l=s(u,l)),o+=1,o>t)return d=!0,{[b]:"unsupported",kind:"truncated"};switch(typeof l){case"undefined":return{[b]:"undefined"};case"bigint":return{[b]:"bigint",value:l.toString()};case"number":return Number.isNaN(l)?{[b]:"nan"}:l===1/0?{[b]:"infinity",sign:1}:l===-1/0?{[b]:"infinity",sign:-1}:l;case"function":case"symbol":return n.push(u),{[b]:"unsupported",kind:typeof l};case"string":case"boolean":return l}if(l===null)return null;const f=l,m=r.get(f);if(m!==void 0)return{[b]:"ref",path:m};if(r.set(f,u),l instanceof Date)return{[b]:"date",iso:l.toISOString()};if(l instanceof RegExp)return{[b]:"regexp",source:l.source,flags:l.flags};if(l instanceof Error)return{[b]:"error",name:l.name,message:l.message};if(l instanceof Map){const g=[];let E=0;for(const[w,I]of l)g.push([i(w,`${u}/@k${E}`),i(I,`${u}/${E}`)]),E+=1;return{[b]:"map",entries:g}}if(l instanceof Set){const g=[];let E=0;for(const w of l)g.push(i(w,`${u}/${E}`)),E+=1;return{[b]:"set",values:g}}if(Array.isArray(l))return l.map((g,E)=>i(g,`${u}/${E}`));const h={};for(const[g,E]of Object.entries(l))h[g]=i(E,`${u}/${Q(g)}`);return b in h?{[b]:"escaped",value:h}:h}return{value:i(a,""),report:{truncated:d,unsupported:n}}}function L(a){const e=new Map,t=[];function s(o,d){if(o===null||typeof o!="object")return o;if(Array.isArray(o)){const c=[];return e.set(d,c),o.forEach((l,u)=>{if(V(l)){t.push({target:c,key:u,path:l.path}),c[u]=void 0;return}c[u]=s(l,`${d}/${u}`)}),c}if(typeof o[b]=="string"){const c=o;switch(c[b]){case"undefined":return;case"nan":return Number.NaN;case"infinity":return c.sign===1?1/0:-1/0;case"bigint":return BigInt(c.value);case"date":return new Date(c.iso);case"regexp":return new RegExp(c.source,c.flags);case"error":{const l=new Error(c.message);return l.name=c.name,l}case"unsupported":return;case"ref":return;case"map":{const l=new Map;return e.set(d,l),c.entries.forEach(([u,f],m)=>{l.set(s(u,`${d}/@k${m}`),s(f,`${d}/${m}`))}),l}case"set":{const l=new Set;return e.set(d,l),c.values.forEach((u,f)=>l.add(s(u,`${d}/${f}`))),l}case"escaped":return n(c.value,d);default:return}}return n(o,d)}function n(o,d){const i={};e.set(d,i);for(const[c,l]of Object.entries(o)){const u=`${d}/${Q(c)}`;if(V(l)){t.push({target:i,key:c,path:l.path}),i[c]=void 0;continue}i[c]=s(l,u)}return i}const r=s(a,"");e.set("",r);for(const{target:o,key:d,path:i}of t)o[d]=e.get(i);return r}function V(a){return a!==null&&typeof a=="object"&&a[b]==="ref"&&typeof a.path=="string"}function Q(a){return a.replace(/~/g,"~0").replace(/\//g,"~1")}function ue(a,e,t={}){let s=t.maxNodes??1e5;for(let n=0;n<8;n+=1){const{value:r,report:o}=j(a,{...t,maxNodes:s});let d;try{d=JSON.stringify(r)?.length??0}catch{d=Number.POSITIVE_INFINITY}if(d<=e)return o.truncated?{value:r,truncated:!0,note:`State was too large to send in full; parts beyond ${s} nodes are omitted.`}:{value:r,truncated:!1};const i=Math.floor(s*e*.8/d);if(s=Math.max(1,Math.min(i,s-1)),s<=1&&n>0)break}return{value:{[b]:"unsupported",kind:"truncated"},truncated:!0,note:`State exceeds the ${e}-byte transport limit and could not be reduced to fit.`}}function k(a,e,t){a.onError?.(e,t)}async function fe(a){const e={slices:{},restored:!1};let t;try{t=a.source??await a.adapter.read(a.key)}catch(n){return k(a,n,"read"),e}if(t==null||t==="")return e;let s;try{s=L(JSON.parse(t))}catch(n){return k(a,n,"decode"),e}if(s===null||typeof s!="object"||typeof s.version!="number")return k(a,new Error("persisted payload is not a recognisable envelope"),"decode"),e;if(s.version!==a.version){if(a.migrate===void 0)return k(a,new Error(`persisted state is version ${s.version}, this build expects ${a.version}, and no migrate was supplied`),"migrate"),e;try{const n=a.migrate(s.slices,s.version);return n===null?e:{slices:n,restored:!0}}catch(n){return k(a,n,"migrate"),e}}return{slices:s.slices??{},restored:!0}}function he(a,e){if(!e.restored)return a;const t={};for(const[s,n]of Object.entries(a)){const r=e.slices[s];t[s]=r===void 0?n:{...n,state:r}}return t}function G(a,e){const t=a??{},s=e.slices===void 0?t:Object.fromEntries(e.slices.filter(n=>n in t).map(n=>[n,t[n]]));return JSON.stringify(j({version:e.version,slices:s}).value)}function pe(a,e){const t=e.throttleMs??250,s=e.slices;let n=null,r=!1;const o=()=>{if(r){r=!1;try{const c=e.adapter.write(e.key,G(a.getState(),e));c instanceof Promise&&c.catch(l=>k(e,l,"write"))}catch(c){k(e,c,"write")}}},d=()=>{if(r=!0,t<=0){o();return}n===null&&(n=setTimeout(()=>{n=null,o()},t),n.unref?.())},i=a.instrument(c=>{if(s===void 0){d();return}(c.changedPaths??[]).some(u=>s.some(f=>u===f||u.startsWith(`${f}.`)))&&d()});return()=>{i(),n!==null&&(clearTimeout(n),n=null),o()}}function me(a,e){return G(a.getState(),e)}function ye(a){return{read:e=>a.getItem(e),write:(e,t)=>a.setItem(e,t),remove:e=>a.removeItem(e)}}function ge(a){const e=new Map(Object.entries(a??{}));return{read:t=>e.get(t)??null,write:(t,s)=>{e.set(t,s)},remove:t=>{e.delete(t)}}}y.CallAbortedError=z,y.CallTimeoutError=H,y.EventBus=S,y.LooseEventBus=$,y.Reducer=x,y.Rejected=J,y.Store=T,y.createEntityAdapter=le,y.createMemoryAdapter=ge,y.createStore=ie,y.createWebStorageAdapter=ye,y.decodeState=L,y.dehydrate=me,y.detectChangedProps=D,y.encodeState=j,y.encodeStateBounded=ue,y.eventKeys=ce,y.freezeState=P,y.hydrate=fe,y.isRejected=B,y.persist=pe,y.typedEvents=oe,y.withHydration=he,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"})}));
|
|
11
11
|
//# sourceMappingURL=yoltra.umd.js.map
|