@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.
- package/README.es.md +1 -1
- package/README.md +169 -7
- package/dist/types/entity/entityAdapter.d.ts +118 -0
- package/dist/types/eventBus/EventBus.d.ts +18 -5
- package/dist/types/eventBus/LooseEventBus.d.ts +72 -49
- package/dist/types/eventBus/index.d.ts +2 -2
- package/dist/types/index.d.ts +16 -8
- package/dist/types/persistence/adapters.d.ts +33 -0
- package/dist/types/persistence/persist.d.ts +126 -0
- package/dist/types/reducer/Reducer.d.ts +1 -1
- package/dist/types/serialize/codec.d.ts +119 -0
- package/dist/types/store/Store.d.ts +78 -15
- package/dist/types/types.d.ts +164 -32
- package/dist/types/utils/detectChangedProps.d.ts +6 -0
- package/dist/types/utils/immutability.d.ts +25 -2
- 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 +2391 -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 +33 -13
- package/dist/yoltra.cjs.js +0 -11
- package/dist/yoltra.esm.js +0 -1744
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yoltra/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "A modern predictable state container built on the idea of channels, events, and payloads, giving you strongly typed, expressive actions",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -23,16 +23,15 @@
|
|
|
23
23
|
"bugs": {
|
|
24
24
|
"url": "https://github.com/yoltra/yoltra/issues"
|
|
25
25
|
},
|
|
26
|
-
"main": "dist/yoltra.cjs
|
|
27
|
-
"module": "dist/yoltra.
|
|
26
|
+
"main": "dist/yoltra.cjs",
|
|
27
|
+
"module": "dist/yoltra.mjs",
|
|
28
28
|
"types": "dist/types/index.d.ts",
|
|
29
29
|
"unpkg": "dist/yoltra.umd.js",
|
|
30
30
|
"jsdelivr": "dist/yoltra.umd.js",
|
|
31
31
|
"files": [
|
|
32
32
|
"dist/",
|
|
33
33
|
"LICENSE",
|
|
34
|
-
"README.md"
|
|
35
|
-
"!dist/**/*.map"
|
|
34
|
+
"README.md"
|
|
36
35
|
],
|
|
37
36
|
"private": false,
|
|
38
37
|
"sideEffects": false,
|
|
@@ -45,9 +44,9 @@
|
|
|
45
44
|
"exports": {
|
|
46
45
|
".": {
|
|
47
46
|
"types": "./dist/types/index.d.ts",
|
|
48
|
-
"import": "./dist/yoltra.
|
|
49
|
-
"require": "./dist/yoltra.cjs
|
|
50
|
-
"default": "./dist/yoltra.
|
|
47
|
+
"import": "./dist/yoltra.mjs",
|
|
48
|
+
"require": "./dist/yoltra.cjs",
|
|
49
|
+
"default": "./dist/yoltra.mjs"
|
|
51
50
|
},
|
|
52
51
|
"./package.json": "./package.json"
|
|
53
52
|
},
|
|
@@ -66,17 +65,38 @@
|
|
|
66
65
|
"vite-plugin-dts": "^4.5.4",
|
|
67
66
|
"vitest": "3.2.4"
|
|
68
67
|
},
|
|
68
|
+
"sizeLimit": [
|
|
69
|
+
{
|
|
70
|
+
"name": "createStore",
|
|
71
|
+
"import": "{ createStore }",
|
|
72
|
+
"limitKb": 8
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"name": "with persistence",
|
|
76
|
+
"import": "{ createStore, hydrate, persist }",
|
|
77
|
+
"limitKb": 10
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"name": "barrel",
|
|
81
|
+
"limitKb": 11
|
|
82
|
+
}
|
|
83
|
+
],
|
|
69
84
|
"scripts": {
|
|
70
85
|
"dev": "vite",
|
|
71
86
|
"lint": "node ../../tools/repo-tools/bin/repo-eslint.cjs --report-unused-disable-directives --max-warnings 0",
|
|
72
87
|
"lint:fix": "node ../../tools/repo-tools/bin/repo-eslint.cjs --fix",
|
|
73
88
|
"test": "vitest --coverage --watch=false",
|
|
74
|
-
"build": "vite build",
|
|
75
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
89
|
+
"build": "vite build && node ../../tools/repo-tools/bin/dts-extensions.mjs dist/types",
|
|
90
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.vitest.json --noEmit && tsc -p tsconfig.tools.json --noEmit",
|
|
76
91
|
"typecheck:tools": "tsc -p tsconfig.tools.json --noEmit",
|
|
77
92
|
"preview": "vite preview",
|
|
78
|
-
"docs": "rushx docs:js && rushx docs:md",
|
|
79
|
-
"docs:
|
|
80
|
-
"docs:
|
|
93
|
+
"docs": "rushx docs:js && rushx docs:md && rushx docs:stamp",
|
|
94
|
+
"docs:stamp": "node ../../tools/repo-tools/bin/docs-stamp.mjs docs",
|
|
95
|
+
"docs:md": "typedoc --options ./typedoc.core.json",
|
|
96
|
+
"docs:js": "typedoc --options ./typedoc.core.json --json ./.typedoc/core-en.json",
|
|
97
|
+
"size": "node ../../tools/repo-tools/bin/size-check.cjs",
|
|
98
|
+
"bench": "vitest bench --run",
|
|
99
|
+
"bench:check": "node ../../tools/repo-tools/bin/bench-check.cjs",
|
|
100
|
+
"bench:record": "node ../../tools/repo-tools/bin/bench-check.cjs --record"
|
|
81
101
|
}
|
|
82
102
|
}
|
package/dist/yoltra.cjs.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* @yoltra/core v0.3.0
|
|
3
|
-
* (c) 2026 Manu Ramirez <@pixerael>
|
|
4
|
-
* License: MIT
|
|
5
|
-
* Homepage: https://yoltra.dev
|
|
6
|
-
*
|
|
7
|
-
* This source code is licensed under the MIT license found in the
|
|
8
|
-
* LICENSE file in the root directory of this source tree
|
|
9
|
-
*/
|
|
10
|
-
"use strict";var k=Object.defineProperty;var R=(a,e,t)=>e in a?k(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var d=(a,e,t)=>R(a,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});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 P{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,p]of i.entries())this.matchPattern(u,l)&&o.push(p)}const f=new Set,h=l=>{for(const u of[...l])if(!f.has(u)){f.add(u);try{u(r)}catch(p){console.error(p);continue}}};h(c);for(const l of o)h(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 z{constructor(e){d(this,"_reduce");this._reduce=e}reduce(e,t){return this._reduce(e,t)}}function g(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),f=Array.isArray(e);if(o!==f)return[t];const h=[];if(o){const u=a,p=e;if(u.length!==p.length)return[t];for(let y=0;y<u.length;y++){const m=t?`${t}.${y}`:`${y}`;h.push(...g(u[y],p[y],m,r))}return h.filter(Boolean)}const l=new Set([...Object.keys(a),...Object.keys(e)]);for(const u of l){const p=t?`${t}.${u}`:u,y=Object.prototype.hasOwnProperty.call(a,u),m=Object.prototype.hasOwnProperty.call(e,u);if(!y||!m){h.push(p);continue}h.push(...g(a[u],e[u],p,r))}return h.filter(Boolean)}finally{i.delete(s),i.size===0&&r.delete(n)}}function E(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]=E(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]=E(a[t],e))}for(const t of Object.getOwnPropertySymbols(a)){const r=Object.getOwnPropertyDescriptor(a,t);!r||!("value"in r)||(a[t]=E(a[t],e))}return Object.freeze(a)}function b(a){return process.env.NODE_ENV==="production"?a:E(a)}const w=100,S=()=>typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();class v{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 P,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,w),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=g(r,n).filter(Boolean);if(s.length===0)return!1;const c=b(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 f of v.buildAncestorPaths(o))i.add(f);for(const o of i){const f=this.getAtPath(r,o),h=this.getAtPath(c,o);this.connectorBus.emit(e,o,{oldValue:f,newValue:h,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[f,h]=i.split("::");for(const l of o){const u=this.effectMeta.get(l);t.push({channel:f,type:h,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[f,h]=i.split("::");for(let l=0;l<o.size;l++)s.push({channel:f,type:h,phase:"committed"})}for(const[i,o]of this.uncommittedEventSubscribers){if(o.size===0)continue;const[f,h]=i.split("::");for(let l=0;l<o.size;l++)s.push({channel:f,type:h,phase:"uncommitted"})}for(const[i,o]of this.allEventSubscribers){if(o.size===0)continue;const[f,h]=i.split("::");for(let l=0;l<o.size;l++)s.push({channel:f,type:h,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 f=b(o);n[c]=f,s=!0;const h=g(i,o).filter(Boolean);if(h.length===0)return;const l=new Set;for(const u of h)for(const p of v.buildAncestorPaths(u))l.add(p);for(const u of l){const p=this.getAtPath(i,u),y=this.getAtPath(f,u);this.connectorBus.emit(c,u,{oldValue:p,newValue:y,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,f]of this.patternReducers)this.matchesWhen(f,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 h=s!==void 0&&c<=0?w:c,l=s!==void 0?`${e}::${t}::#${s}`:this.fingerprint(e,t,r);if(this.shouldDedupe(l,h))return}const i=crypto.randomUUID();let o;const f=new Promise(h=>{o=h});return this.reduceQueue.push({channel:e,type:t,payload:r,id:i,resolve:o}),this.drainReduce(),f}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,f=[];i&&(this.changedPathSink=f);const h=i?S():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,f,o,S()-h),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 f of r)c[f]=this.getAtPath(n,f),i[f]=this.getAtPath(this.state,f);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 f of[...this.instrumentObservers])try{f(o)}catch(h){console.error("Instrumentation observer error:",h)}}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,f]of i){const h=`${String(o)}::${String(f)}`;this.effects.has(h)||this.effects.set(h,new Set),this.effects.get(h).add(t),s.push(()=>{const l=this.effects.get(h);l&&(l.delete(t),l.size===0&&this.effects.delete(h))})}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 z(c),(!r.preserveState||this.state[n]===void 0)&&(this.state[n]=b(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 h=this.normalizeEventKeys(t);if(h.length===0&&!o&&!s){this.patternReducers.set(e,{any:!0}),this.sliceUnsubs.set(n,[]);return}const l=[];for(const[u,p]of h){const y=this.reducerBus.on(u,p,m=>{const O={channel:u,type:p,payload:m,id:crypto.randomUUID()};this.forwardEvent(e,O)});l.push(y)}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 _(a){return new v({name:a.name,reducer:a.reducer??{},middleware:a.middleware??[],effects:a.effects??[],dedupWindowMs:a.dedupWindowMs,devtools:a.devtools,onEffectError:a.onEffectError})}const $=a=>(e,t)=>t.map(r=>[e,r]),x=()=>a=>a;exports.EventBus=M;exports.LooseEventBus=P;exports.Reducer=z;exports.Store=v;exports.createStore=_;exports.detectChangedProps=g;exports.eventKeys=x;exports.freezeState=E;exports.typedEvents=$;
|
|
11
|
-
//# sourceMappingURL=yoltra.cjs.js.map
|