@recats/cdeebee 3.0.0-beta.12 → 3.0.0-beta.13

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.md CHANGED
@@ -40,14 +40,14 @@ After fetching data from the API (which returns data in the format `{ data: [...
40
40
 
41
41
  ```typescript
42
42
  {
43
- forumList: {
44
- 1: { id: 1, title: 'Milky Way Galaxy' }
43
+ forumList: {
44
+ 1: { id: 1, title: 'Milky Way Galaxy' }
45
45
  },
46
- threadList: {
47
- 10001: { id: 10001, title: 'Solar system', forumID: 1 }
46
+ threadList: {
47
+ 10001: { id: 10001, title: 'Solar system', forumID: 1 }
48
48
  },
49
- postList: {
50
- 2: { id: 2, title: 'Earth', threadID: 10001 }
49
+ postList: {
50
+ 2: { id: 2, title: 'Earth', threadID: 10001 }
51
51
  }
52
52
  }
53
53
  ```
@@ -171,6 +171,7 @@ function ForumsList() {
171
171
  - `useStorage()` - Get the entire storage
172
172
  - `useRequestHistory(api)` - Get successful request history for an API
173
173
  - `useRequestErrors(api)` - Get error history for an API
174
+ - `useLastResultIdList(api)` - Get the IDs returned by the last request to an API (for filtering storage)
174
175
 
175
176
  See the [React Hooks](#react-hooks) section for detailed documentation.
176
177
 
@@ -186,8 +187,8 @@ interface CdeebeeSettings<T> {
186
187
  fileKey: string; // Key name for file uploads in FormData
187
188
  bodyKey: string; // Key name for request body in FormData
188
189
  listStrategy?: CdeebeeListStrategy<T>; // Merge strategy per list: 'merge' | 'replace' | 'skip'
189
- mergeWithData?: unknown; // Data to merge with every request body
190
- mergeWithHeaders?: Record<string, string>; // Headers to merge with every request
190
+ mergeWithData?: Record<string, unknown> | (() => Record<string, unknown>); // Data to merge with every request body (static or dynamic)
191
+ mergeWithHeaders?: Record<string, string> | (() => Record<string, string>); // Headers to merge with every request (static or dynamic)
191
192
  normalize?: (storage, result, strategyList) => T; // Custom normalization function
192
193
  }
193
194
  ```
@@ -228,6 +229,32 @@ listStrategy: {
228
229
  }
229
230
  ```
230
231
 
232
+ ## Dynamic Headers and Data
233
+
234
+ `mergeWithHeaders` and `mergeWithData` support both static objects and dynamic functions. Functions are called on each request, making them ideal for auth tokens:
235
+
236
+ ```typescript
237
+ const cdeebeeSlice = factory<Storage>({
238
+ modules: ['storage', 'history', 'listener'],
239
+
240
+ // Static headers (evaluated once at factory creation)
241
+ mergeWithHeaders: { 'X-App': 'myapp' },
242
+
243
+ // OR Dynamic headers (evaluated on each request)
244
+ mergeWithHeaders: () => ({
245
+ 'Authorization': `Bearer ${getSessionToken()}`,
246
+ }),
247
+
248
+ // Same for mergeWithData
249
+ mergeWithData: () => ({
250
+ timestamp: Date.now(),
251
+ clientVersion: APP_VERSION,
252
+ }),
253
+ });
254
+ ```
255
+
256
+ **Note**: When using functions, Redux will warn about non-serializable values in state. Configure your store's `serializableCheck.ignoredPaths` to include `cdeebee.settings.mergeWithHeaders` and `cdeebee.settings.mergeWithData`.
257
+
231
258
  ## API Response Format
232
259
 
233
260
  cdeebee expects API responses in a format where list data is provided as arrays with a `primaryKey` field. The library automatically normalizes this data into the storage structure.
@@ -621,6 +648,46 @@ function ErrorDisplay({ api }: { api: string }) {
621
648
  }
622
649
  ```
623
650
 
651
+ ### Result ID List Hook
652
+
653
+ #### `useLastResultIdList(api: string)`
654
+
655
+ Get the list of IDs returned by the last successful request to an API. This is useful for filtering storage data when using `merge` strategy, so you can display only the results from the current search/request.
656
+
657
+ ```typescript
658
+ import { useStorageList, useLastResultIdList } from '@recats/cdeebee';
659
+
660
+ interface MyStorage {
661
+ productList: Record<string, { id: string; name: string; price: number }>;
662
+ }
663
+
664
+ function SearchResults() {
665
+ // Get all products from storage (accumulated via merge strategy)
666
+ const products = useStorageList<MyStorage, 'productList'>('productList');
667
+
668
+ // Get only the IDs from the last search request
669
+ const lastSearchIds = useLastResultIdList('/api/search');
670
+
671
+ // Filter to show only results from current search
672
+ const displayResults = lastSearchIds
673
+ .map(id => products[id])
674
+ .filter(Boolean);
675
+
676
+ return (
677
+ <div>
678
+ {displayResults.map(product => (
679
+ <div key={product.id}>{product.name} - ${product.price}</div>
680
+ ))}
681
+ </div>
682
+ );
683
+ }
684
+ ```
685
+
686
+ **Why use this?** When using `replace` strategy with search/filter pages, navigating away and using browser back loses the previous results. With `merge` strategy + `useLastResultIdList`:
687
+ - Data accumulates in storage (never lost on navigation)
688
+ - `lastResultIdList` tracks which IDs belong to the current request
689
+ - Filter storage by those IDs to display the correct results
690
+
624
691
  ### Advanced: Custom State Path
625
692
 
626
693
  If you're **not** using `combineSlices` or have cdeebee at a custom path in your state (not `state.cdeebee`), use `createCdeebeeHooks`:
@@ -638,6 +705,7 @@ export const {
638
705
  useRequestHistory,
639
706
  useRequestErrors,
640
707
  useIsLoading,
708
+ useLastResultIdList,
641
709
  } = createCdeebeeHooks<RootState, MyStorage>(
642
710
  state => state.myCustomPath // Your custom path
643
711
  );
@@ -669,6 +737,7 @@ const users = useSelector(state => state.cdeebee.storage.userList);
669
737
  export { factory } from '@recats/cdeebee'; // Create cdeebee slice
670
738
  export { request } from '@recats/cdeebee'; // Request thunk
671
739
  export { batchingUpdate } from '@recats/cdeebee'; // Batch update helper
740
+ export { defaultNormalize } from '@recats/cdeebee'; // Default normalization function
672
741
 
673
742
  // React hooks
674
743
  export {
@@ -679,6 +748,7 @@ export {
679
748
  useStorage, // Get entire storage
680
749
  useRequestHistory, // Get successful request history
681
750
  useRequestErrors, // Get error history
751
+ useLastResultIdList, // Get IDs from last request (for filtering storage)
682
752
  } from '@recats/cdeebee';
683
753
 
684
754
  // Types
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=require("@reduxjs/toolkit"),d=require("react-redux");function f(e,r,s){e.modules.includes(r)&&s()}function y(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function p(e,r){if(!y(e)||!y(r))return r;const s={...e},o=r;for(const t in o)if(Object.prototype.hasOwnProperty.call(o,t)){const u=s[t],i=o[t];y(u)&&y(i)&&!Array.isArray(u)&&!Array.isArray(i)?s[t]=p(u,i):s[t]=i}return s}function C(e,r){const s={...r};for(const o of e)delete s[o];return s}function D(e,r){for(let s=0;s<r.length;s++){const o=r[s],t=o.key,u=o.value;if(t.length===0)continue;let i=e;for(let n=0;n<t.length-1;n++){const c=t[n];if(Array.isArray(i)){const a=typeof c=="number"?c:Number(c);(!(a in i)||!y(i[a]))&&(i[a]={}),i=i[a]}else{const a=String(c);if(!(a in i)){const g=typeof t[n+1]=="number"||!isNaN(Number(t[n+1]))&&String(Number(t[n+1]))===String(t[n+1]);i[a]=g?[]:{}}const l=i[a];i=Array.isArray(l)||y(l)?l:{}}}Array.isArray(i)||(i[String(t[t.length-1])]=u)}}class E{constructor(){this.byRequestId=new Map,this.byApi=new Map}add(r,s,o){const t={requestId:s,controller:o,api:r};this.byRequestId.set(s,t),this.byApi.has(r)||this.byApi.set(r,new Set),this.byApi.get(r).add(s)}delete(r){const s=this.byRequestId.get(r);if(!s)return;this.byRequestId.delete(r);const o=this.byApi.get(s.api);o&&(o.delete(r),o.size===0&&this.byApi.delete(s.api))}abortAllForApi(r,s){const o=this.byApi.get(r);o&&o.forEach(t=>{if(t!==s){const u=this.byRequestId.get(t);u&&(u.controller.abort(),this.delete(t))}})}}const k=new E;function H(e,r){k.abortAllForApi(e,r)}function T(e,r,s){const o=new AbortController,t=()=>{k.delete(s)};return e.addEventListener("abort",()=>{o.abort(),t()}),{controller:o,init:()=>k.add(r,s,o),drop:t}}class x{constructor(){this.currentPromise=Promise.resolve(),this.queueLength=0}async enqueue(r){this.queueLength++;const s=this.currentPromise;return this.currentPromise=s.then(()=>r(),()=>r()).finally(()=>{this.queueLength--}),this.currentPromise}getQueueLength(){return this.queueLength}clear(){this.queueLength=0}}const N=new x,m=R.createAsyncThunk("cdeebee/request",async(e,{rejectWithValue:r,getState:s,requestId:o,signal:t})=>{const u=new Date().toUTCString(),{cdeebee:{settings:i}}=s(),n=T(t,e.api,o),c=e.onResult&&typeof e.onResult=="function";f(i,"cancelation",n.init);const a=async()=>{try{const{method:l="POST",body:g,headers:I={}}=e,P={...i.mergeWithHeaders??{},...I},z={...i.mergeWithData??{},...g??{}};let q=JSON.stringify(z);if(e.files){const S=new FormData,w=e.fileKey||i.fileKey,v=e.bodyKey||i.bodyKey;for(let A=0;A<e.files.length;A+=1)w&&S.append(w,e.files[A]);v&&S.append(v,q),q=S}const h=await fetch(e.api,{method:l,headers:{"ui-request-id":o,"Content-Type":"application/json",...P},signal:n.controller.signal,body:q});f(i,"cancelation",n.drop);let b;const L=e.responseType||"json";return L==="text"?b=await h.text():L==="blob"?b=await h.blob():b=await h.json(),h.ok?(c&&e.onResult(b),{result:b,startedAt:u,endedAt:new Date().toUTCString()}):(c&&e.onResult(b),r(h))}catch(l){return f(i,"cancelation",n.drop),c&&e.onResult(l),l instanceof Error&&l.name==="AbortError"?r({message:"Request was cancelled",cancelled:!0}):r({message:l instanceof Error?l.message:"Unknown error occurred"})}};return i.modules.includes("queryQueue")?N.enqueue(a):a()});function j(e){return y(e)&&Array.isArray(e.data)&&typeof e.primaryKey=="string"}function O(e,r){const s={};for(const o of e)if(y(o)&&r in o){const t=String(o[r]);s[t]=o}return s}function K(e,r,s,o){return s==="replace"?r:s==="merge"?p(e,r):s==="skip"?e:(console.warn(`Cdeebee: Unknown strategy "${s}" for key "${o}". Skipping normalization.`),p(e,r))}function Q(e,r,s){const o=Object.keys(r),t=y(e.storage)?e.storage:{},u={...t},i=new Set;for(const n of o){const c=r[n];if(c==null||typeof c=="string"){i.add(n);continue}const a=s[n]??"merge";if(a==="skip"&&!(n in t))continue;const l=n in t?t[n]:{};if(j(c)){const g=O(c.data,c.primaryKey);u[n]=K(l,g,a,n);continue}y(c)?u[n]=K(l,c,a,n):u[n]=c}return i.size>0?C(Array.from(i),u):u}const U={settings:{modules:["history","listener","storage","cancelation"],fileKey:"file",bodyKey:"value",listStrategy:{},mergeWithData:{},mergeWithHeaders:{}},storage:{},request:{active:[],errors:{},done:{}}},M=(e,r)=>R.createSlice({name:"cdeebee",initialState:p(U,{settings:e,storage:r??{}}),reducers:{set(o,t){D(o.storage,t.payload)},historyClear(o,t){const u=t.payload;u?(delete o.request.done[u],delete o.request.errors[u]):(o.request.done={},o.request.errors={})}},extraReducers:o=>{o.addCase(m.pending,(t,u)=>{const i=u.meta.arg.api,n=u.meta.requestId;u.meta.arg.historyClear&&f(t.settings,"history",()=>{delete t.request.done[i],delete t.request.errors[i]}),f(t.settings,"cancelation",()=>{H(i,n)}),f(t.settings,"listener",()=>{t.request.active.push({api:i,requestId:n})})}).addCase(m.fulfilled,(t,u)=>{const i=u.meta.requestId,n=u.meta.arg.api;f(t.settings,"listener",()=>{t.request.active=t.request.active.filter(c=>!(c.api===n&&c.requestId===i))}),f(t.settings,"history",()=>{t.request.done[n]||(t.request.done[n]=[]),t.request.done[n].push({api:n,request:u.payload,requestId:i})}),f(t.settings,"storage",()=>{if(u.meta.arg.ignore)return;const c=u.meta.arg.listStrategy??t.settings.listStrategy??{},a=u.meta.arg.normalize??t.settings.normalize??Q,l=R.current(t),g=a(l,u.payload.result,c);t.storage=g})}).addCase(m.rejected,(t,u)=>{const i=u.meta.requestId,n=u.meta.arg.api;f(t.settings,"listener",()=>{t.request.active=t.request.active.filter(c=>!(c.api===n&&c.requestId===i))}),f(t.settings,"history",()=>{t.request.errors[n]||(t.request.errors[n]=[]),t.request.errors[n].push({requestId:i,api:n,request:u.error})})})}});function W(e){function r(n){return d.useSelector(c=>e(c).request.active.some(l=>n.includes(l.api)))}function s(n){return d.useSelector(c=>e(c).request.done[n]??[])}function o(n){return d.useSelector(c=>e(c).request.errors[n]??[])}function t(n){return d.useSelector(c=>e(c).storage[n])}function u(){return d.useSelector(n=>e(n).storage)}function i(){return d.useSelector(n=>e(n).request.active.length>0)}return{useLoading:r,useRequestHistory:s,useRequestErrors:o,useStorageList:t,useStorage:u,useIsLoading:i}}function F(e){return d.useSelector(r=>r.cdeebee.request.active.some(s=>e.includes(s.api)))}function $(e){return d.useSelector(r=>r.cdeebee.request.done[e]??[])}function J(e){return d.useSelector(r=>r.cdeebee.request.errors[e]??[])}function B(e){return d.useSelector(r=>r.cdeebee.storage[e])}function G(){return d.useSelector(e=>e.cdeebee.storage)}function X(){return d.useSelector(e=>e.cdeebee.request.active.length>0)}exports.batchingUpdate=D;exports.createCdeebeeHooks=W;exports.factory=M;exports.request=m;exports.useIsLoading=X;exports.useLoading=F;exports.useRequestErrors=J;exports.useRequestHistory=$;exports.useStorage=G;exports.useStorageList=B;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=require("@reduxjs/toolkit"),d=require("react-redux");function y(e,r,n){e.modules.includes(r)&&n()}function f(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function p(e,r){if(!f(e)||!f(r))return r;const n={...e},s=r;for(const t in s)if(Object.prototype.hasOwnProperty.call(s,t)){const i=n[t],o=s[t];f(i)&&f(o)&&!Array.isArray(i)&&!Array.isArray(o)?n[t]=p(i,o):n[t]=o}return n}function x(e,r){const n={...r};for(const s of e)delete n[s];return n}function N(e){if(!f(e))return[];const r=[];for(const n of Object.keys(e)){const s=e[n];if(f(s)&&Array.isArray(s.data)&&typeof s.primaryKey=="string"){const t=s.primaryKey;for(const i of s.data)f(i)&&t in i&&r.push(String(i[t]))}}return r}function K(e,r){for(let n=0;n<r.length;n++){const s=r[n],t=s.key,i=s.value;if(t.length===0)continue;let o=e;for(let u=0;u<t.length-1;u++){const a=t[u];if(Array.isArray(o)){const c=typeof a=="number"?a:Number(a);(!(c in o)||!f(o[c]))&&(o[c]={}),o=o[c]}else{const c=String(a);if(!(c in o)){const g=typeof t[u+1]=="number"||!isNaN(Number(t[u+1]))&&String(Number(t[u+1]))===String(t[u+1]);o[c]=g?[]:{}}const l=o[c];o=Array.isArray(l)||f(l)?l:{}}}Array.isArray(o)||(o[String(t[t.length-1])]=i)}}class T{constructor(){this.byRequestId=new Map,this.byApi=new Map}add(r,n,s){const t={requestId:n,controller:s,api:r};this.byRequestId.set(n,t),this.byApi.has(r)||this.byApi.set(r,new Set),this.byApi.get(r).add(n)}delete(r){const n=this.byRequestId.get(r);if(!n)return;this.byRequestId.delete(r);const s=this.byApi.get(n.api);s&&(s.delete(r),s.size===0&&this.byApi.delete(n.api))}abortAllForApi(r,n){const s=this.byApi.get(r);s&&s.forEach(t=>{if(t!==n){const i=this.byRequestId.get(t);i&&(i.controller.abort(),this.delete(t))}})}}const L=new T;function j(e,r){L.abortAllForApi(e,r)}function C(e,r,n){const s=new AbortController,t=()=>{L.delete(n)};return e.addEventListener("abort",()=>{s.abort(),t()}),{controller:s,init:()=>L.add(r,n,s),drop:t}}class E{constructor(){this.currentPromise=Promise.resolve(),this.queueLength=0}async enqueue(r){this.queueLength++;const n=this.currentPromise;return this.currentPromise=n.then(()=>r(),()=>r()).finally(()=>{this.queueLength--}),this.currentPromise}getQueueLength(){return this.queueLength}clear(){this.queueLength=0}}const O=new E,h=R.createAsyncThunk("cdeebee/request",async(e,{rejectWithValue:r,getState:n,requestId:s,signal:t})=>{const i=new Date().toUTCString(),{cdeebee:{settings:o}}=n(),u=C(t,e.api,s),a=e.onResult&&typeof e.onResult=="function";y(o,"cancelation",u.init);const c=async()=>{try{const{method:l="POST",body:g,headers:H={}}=e,z={...typeof o.mergeWithHeaders=="function"?o.mergeWithHeaders():o.mergeWithHeaders??{},...H},P={...typeof o.mergeWithData=="function"?o.mergeWithData():o.mergeWithData??{},...g??{}};let q=JSON.stringify(P);if(e.files){const S=new FormData,w=e.fileKey||o.fileKey,I=e.bodyKey||o.bodyKey;for(let A=0;A<e.files.length;A+=1)w&&S.append(w,e.files[A]);I&&S.append(I,q),q=S}const m=await fetch(e.api,{method:l,headers:{"ui-request-id":s,"Content-Type":"application/json",...z},signal:u.controller.signal,body:q});y(o,"cancelation",u.drop);let b;const k=e.responseType||"json";return k==="text"?b=await m.text():k==="blob"?b=await m.blob():b=await m.json(),m.ok?(a&&e.onResult(b),{result:b,startedAt:i,endedAt:new Date().toUTCString()}):(a&&e.onResult(b),r(m))}catch(l){return y(o,"cancelation",u.drop),a&&e.onResult(l),l instanceof Error&&l.name==="AbortError"?r({message:"Request was cancelled",cancelled:!0}):r({message:l instanceof Error?l.message:"Unknown error occurred"})}};return o.modules.includes("queryQueue")?O.enqueue(c):c()});function W(e){return f(e)&&Array.isArray(e.data)&&typeof e.primaryKey=="string"}function Q(e,r){const n={};for(const s of e)if(f(s)&&r in s){const t=String(s[r]);n[t]=s}return n}function D(e,r,n,s){return n==="replace"?r:n==="merge"?p(e,r):n==="skip"?e:(console.warn(`Cdeebee: Unknown strategy "${n}" for key "${s}". Skipping normalization.`),p(e,r))}function v(e,r,n){const s=Object.keys(r),t=f(e.storage)?e.storage:{},i={...t},o=new Set;for(const u of s){const a=r[u];if(a==null||typeof a=="string"){o.add(u);continue}const c=n[u]??"merge";if(c==="skip"&&!(u in t))continue;const l=u in t?t[u]:{};if(W(a)){const g=Q(a.data,a.primaryKey);i[u]=D(l,g,c,u);continue}f(a)?i[u]=D(l,a,c,u):i[u]=a}return o.size>0?x(Array.from(o),i):i}const U={settings:{modules:["history","listener","storage","cancelation"],fileKey:"file",bodyKey:"value",listStrategy:{},mergeWithData:{},mergeWithHeaders:{}},storage:{},request:{active:[],errors:{},done:{},lastResultIdList:{}}},M=(e,r)=>R.createSlice({name:"cdeebee",initialState:p(U,{settings:e,storage:r??{}}),reducers:{set(s,t){K(s.storage,t.payload)},historyClear(s,t){const i=t.payload;i?(delete s.request.done[i],delete s.request.errors[i]):(s.request.done={},s.request.errors={})}},extraReducers:s=>{s.addCase(h.pending,(t,i)=>{const o=i.meta.arg.api,u=i.meta.requestId;i.meta.arg.historyClear&&y(t.settings,"history",()=>{delete t.request.done[o],delete t.request.errors[o]}),y(t.settings,"cancelation",()=>{j(o,u)}),y(t.settings,"listener",()=>{t.request.active.push({api:o,requestId:u})})}).addCase(h.fulfilled,(t,i)=>{const o=i.meta.requestId,u=i.meta.arg.api;y(t.settings,"listener",()=>{t.request.active=t.request.active.filter(a=>!(a.api===u&&a.requestId===o))}),y(t.settings,"history",()=>{t.request.done[u]||(t.request.done[u]=[]),t.request.done[u].push({api:u,request:i.payload,requestId:o})}),y(t.settings,"storage",()=>{if(i.meta.arg.ignore)return;const a=i.meta.arg.listStrategy??t.settings.listStrategy??{},c=i.meta.arg.normalize??t.settings.normalize??v,l=R.current(t),g=c(l,i.payload.result,a);t.storage=g,t.request.lastResultIdList[u]=N(i.payload.result)})}).addCase(h.rejected,(t,i)=>{const o=i.meta.requestId,u=i.meta.arg.api;y(t.settings,"listener",()=>{t.request.active=t.request.active.filter(a=>!(a.api===u&&a.requestId===o))}),y(t.settings,"history",()=>{t.request.errors[u]||(t.request.errors[u]=[]),t.request.errors[u].push({requestId:o,api:u,request:i.error})})})}});function F(e){function r(a){return d.useSelector(c=>e(c).request.active.some(g=>a.includes(g.api)))}function n(a){return d.useSelector(c=>e(c).request.done[a]??[])}function s(a){return d.useSelector(c=>e(c).request.errors[a]??[])}function t(a){return d.useSelector(c=>e(c).storage[a])}function i(){return d.useSelector(a=>e(a).storage)}function o(){return d.useSelector(a=>e(a).request.active.length>0)}function u(a){return d.useSelector(c=>e(c).request.lastResultIdList[a]??[])}return{useLoading:r,useRequestHistory:n,useRequestErrors:s,useStorageList:t,useStorage:i,useIsLoading:o,useLastResultIdList:u}}function $(e){return d.useSelector(r=>r.cdeebee.request.active.some(n=>e.includes(n.api)))}function J(e){return d.useSelector(r=>r.cdeebee.request.done[e]??[])}function B(e){return d.useSelector(r=>r.cdeebee.request.errors[e]??[])}function G(e){return d.useSelector(r=>r.cdeebee.storage[e])}function X(){return d.useSelector(e=>e.cdeebee.storage)}function Y(){return d.useSelector(e=>e.cdeebee.request.active.length>0)}function Z(e){return d.useSelector(r=>r.cdeebee.request.lastResultIdList[e]??[])}exports.batchingUpdate=K;exports.createCdeebeeHooks=F;exports.defaultNormalize=v;exports.factory=M;exports.request=h;exports.useIsLoading=Y;exports.useLastResultIdList=Z;exports.useLoading=$;exports.useRequestErrors=B;exports.useRequestHistory=J;exports.useStorage=X;exports.useStorageList=G;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../lib/reducer/helpers.ts","../lib/reducer/abortController.ts","../lib/reducer/queryQueue.ts","../lib/reducer/request.ts","../lib/reducer/storage.ts","../lib/reducer/index.ts","../lib/hooks.ts"],"sourcesContent":["import { type WritableDraft } from '@reduxjs/toolkit';\nimport { type CdeebeeSettings, type CdeebeeModule, CdeebeeValueList } from './types';\n\nexport function checkModule(settings: CdeebeeSettings<unknown> | WritableDraft<CdeebeeSettings<unknown>>, module: CdeebeeModule, result: () => void) {\n if (settings.modules.includes(module)) {\n result();\n }\n}\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport function hasDataProperty(value: unknown): value is Record<string, unknown> & { data: unknown[] } {\n return isRecord(value) && Array.isArray(value.data);\n}\n\nexport function hasProperty(value: unknown, prop: string): boolean {\n return isRecord(value) && Object.prototype.hasOwnProperty.call(value, prop);\n}\n\nexport function mergeDeepRight<T>(\n left: T,\n right: Partial<T> | Record<string, unknown>\n): T {\n if (!isRecord(left) || !isRecord(right)) {\n return right as T;\n }\n\n const result = { ...left } as Record<string, unknown>;\n const rightRecord = right as Record<string, unknown>;\n\n for (const key in rightRecord) {\n if (Object.prototype.hasOwnProperty.call(rightRecord, key)) {\n const leftValue = result[key];\n const rightValue = rightRecord[key];\n\n if (\n isRecord(leftValue) &&\n isRecord(rightValue) &&\n !Array.isArray(leftValue) &&\n !Array.isArray(rightValue)\n ) {\n result[key] = mergeDeepRight(leftValue, rightValue);\n } else {\n result[key] = rightValue;\n }\n }\n }\n\n return result as T;\n}\n\nexport function omit<T extends Record<string, unknown>>(keys: string[], obj: T): Omit<T, keyof T> {\n const result = { ...obj };\n for (const key of keys) {\n delete result[key];\n }\n return result as Omit<T, keyof T>;\n}\n\nexport function assocPath<T>(path: (string | number)[], value: unknown, obj: T): T {\n if (path.length === 0) {\n return value as T;\n }\n\n const [first, ...rest] = path;\n const firstKey = String(first);\n const result = Array.isArray(obj) ? [...obj] : { ...obj } as Record<string, unknown>;\n\n if (rest.length === 0) {\n (result as Record<string, unknown>)[firstKey] = value;\n } else {\n const currentValue = (result as Record<string, unknown>)[firstKey];\n (result as Record<string, unknown>)[firstKey] = assocPath(rest, value, currentValue ?? {});\n }\n\n return result as T;\n}\n\nexport function batchingUpdate<T extends Record<string, unknown>>(\n state: T,\n valueList: CdeebeeValueList<T>\n): void {\n for (let i = 0; i < valueList.length; i++) {\n const item = valueList[i] as { key: readonly (string | number)[]; value: unknown };\n const path = item.key;\n const value = item.value;\n \n if (path.length === 0) {\n continue;\n }\n\n let current: Record<string, unknown> | unknown[] = state as Record<string, unknown>;\n \n for (let j = 0; j < path.length - 1; j++) {\n const pathKey = path[j];\n \n if (Array.isArray(current)) {\n const index = typeof pathKey === 'number' ? pathKey : Number(pathKey);\n if (!(index in current) || !isRecord(current[index])) {\n current[index] = {};\n }\n current = current[index] as Record<string, unknown>;\n } else {\n const key = String(pathKey);\n if (!(key in current)) {\n const nextIsNumeric = typeof path[j + 1] === 'number' || (!isNaN(Number(path[j + 1])) && String(Number(path[j + 1])) === String(path[j + 1]));\n current[key] = nextIsNumeric ? [] : {};\n }\n const next = current[key];\n current = (Array.isArray(next) ? next : (isRecord(next) ? next : {})) as Record<string, unknown> | unknown[];\n }\n }\n \n if (Array.isArray(current)) {\n continue; // Can't update array element directly\n }\n current[String(path[path.length - 1])] = value;\n }\n}\n","interface RequestController {\n requestId: string;\n controller: AbortController;\n api: string;\n}\n\nclass AbortControllerStore {\n private byRequestId = new Map<string, RequestController>();\n private byApi = new Map<string, Set<string>>();\n\n add(api: string, requestId: string, controller: AbortController): void {\n const item: RequestController = { requestId, controller, api };\n this.byRequestId.set(requestId, item);\n\n if (!this.byApi.has(api)) {\n this.byApi.set(api, new Set());\n }\n this.byApi.get(api)!.add(requestId);\n }\n\n delete(requestId: string): void {\n const item = this.byRequestId.get(requestId);\n if (!item) return;\n\n this.byRequestId.delete(requestId);\n const apiSet = this.byApi.get(item.api);\n if (apiSet) {\n apiSet.delete(requestId);\n if (apiSet.size === 0) {\n this.byApi.delete(item.api);\n }\n }\n }\n\n abortAllForApi(api: string, excludeRequestId: string): void {\n const requestIds = this.byApi.get(api);\n if (!requestIds) return;\n\n requestIds.forEach(requestId => {\n if (requestId !== excludeRequestId) {\n const item = this.byRequestId.get(requestId);\n if (item) {\n item.controller.abort();\n this.delete(requestId);\n }\n }\n });\n }\n}\n\nconst abortStore = new AbortControllerStore();\n\nexport function abortQuery(api: string, currentRequestId: string): void {\n abortStore.abortAllForApi(api, currentRequestId);\n}\n\nexport function abortManager(signal: AbortSignal, api: string, requestId: string) {\n const controller = new AbortController();\n\n const cleanup = () => {\n abortStore.delete(requestId);\n };\n\n signal.addEventListener('abort', () => {\n controller.abort();\n cleanup();\n });\n\n return {\n controller,\n init: () => abortStore.add(api, requestId, controller),\n drop: cleanup,\n };\n}\n","class QueryQueue {\n private currentPromise: Promise<unknown> = Promise.resolve();\n private queueLength = 0;\n\n async enqueue<T>(task: () => Promise<T>): Promise<T> {\n this.queueLength++;\n \n const previousPromise = this.currentPromise;\n \n this.currentPromise = previousPromise\n .then(() => task(), () => task())\n .finally(() => {\n this.queueLength--;\n });\n\n return this.currentPromise as Promise<T>;\n }\n\n getQueueLength(): number {\n return this.queueLength;\n }\n\n clear(): void {\n this.queueLength = 0;\n }\n}\n\nexport const queryQueue = new QueryQueue();\n\n","import { createAsyncThunk } from '@reduxjs/toolkit';\nimport { checkModule } from './helpers';\nimport { abortManager } from './abortController';\nimport { queryQueue } from './queryQueue';\nimport { type CdeebeeState, type CdeebeeRequestOptions } from './types';\n\nexport const request = createAsyncThunk(\n 'cdeebee/request',\n async (options: CdeebeeRequestOptions<unknown>, { rejectWithValue, getState, requestId, signal }) => {\n const startedAt = new Date().toUTCString();\n const { cdeebee: { settings } } = getState() as { cdeebee: CdeebeeState<unknown> };\n\n const abort = abortManager(signal, options.api, requestId);\n const withCallback = options.onResult && typeof options.onResult === 'function';\n\n checkModule(settings, 'cancelation', abort.init);\n\n const executeRequest = async () => {\n try {\n const { method = 'POST', body, headers = {} } = options;\n const extraHeaders: Record<string, string> = { ...(settings.mergeWithHeaders ?? {}), ...headers };\n\n const b = { ...(settings.mergeWithData ?? {}), ...(body ?? {}) };\n let requestData: FormData | string = JSON.stringify(b);\n\n // handling files\n if (options.files) {\n const formData = new FormData();\n const fileKey = options.fileKey || settings.fileKey;\n const bodyKey = options.bodyKey || settings.bodyKey;\n\n for (let i = 0; i < options.files.length; i += 1) {\n if (fileKey) {\n formData.append(fileKey, options.files[i]);\n }\n }\n\n if (bodyKey) {\n formData.append(bodyKey, requestData);\n }\n requestData = formData;\n }\n // [end] handling files\n \n const response = await fetch(options.api, {\n method,\n headers: {\n 'ui-request-id': requestId,\n 'Content-Type': 'application/json',\n ...extraHeaders,\n },\n signal: abort.controller.signal,\n body: requestData,\n });\n\n checkModule(settings, 'cancelation', abort.drop);\n\n let result: unknown;\n const responseType = options.responseType || 'json';\n \n if (responseType === 'text') {\n result = await response.text();\n } else if (responseType === 'blob') {\n result = await response.blob();\n } else {\n // default: json\n result = await response.json();\n }\n\n if (!response.ok) {\n if (withCallback) options.onResult!(result);\n return rejectWithValue(response);\n }\n\n if (withCallback) options.onResult!(result);\n return { result, startedAt, endedAt: new Date().toUTCString() };\n } catch (error) {\n checkModule(settings, 'cancelation', abort.drop);\n\n if (withCallback) options.onResult!(error); \n\n if (error instanceof Error && error.name === 'AbortError') {\n return rejectWithValue({ message: 'Request was cancelled', cancelled: true });\n }\n\n return rejectWithValue({ message: error instanceof Error ? error.message : 'Unknown error occurred' });\n }\n };\n\n if (settings.modules.includes('queryQueue')) {\n return queryQueue.enqueue(executeRequest);\n }\n\n return executeRequest();\n },\n);\n\n","import { type CdeebeeListStrategy, type CdeebeeState } from './types';\nimport { isRecord, mergeDeepRight, omit } from './helpers';\n\ntype ResponseValue = Record<string, unknown>;\n\ntype IResponse = Record<string, ResponseValue>;\n\ntype StorageData = Record<string, unknown>;\n\nfunction isDataWithPrimaryKey(value: unknown): value is { data: unknown[]; primaryKey: string } {\n return (\n isRecord(value) &&\n Array.isArray(value.data) &&\n typeof value.primaryKey === 'string'\n );\n}\nfunction normalizeDataWithPrimaryKey(data: unknown[], primaryKey: string): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n \n for (const item of data) {\n if (isRecord(item) && primaryKey in item) {\n const key = String(item[primaryKey]);\n result[key] = item;\n }\n }\n \n return result;\n}\n\nfunction applyStrategy(\n existingValue: StorageData,\n newValue: StorageData | ResponseValue,\n strategy: string,\n key: string\n): ResponseValue {\n if (strategy === 'replace') {\n return newValue as ResponseValue;\n } else if (strategy === 'merge') {\n return mergeDeepRight(existingValue, newValue as StorageData) as ResponseValue;\n } else if (strategy === 'skip') {\n return existingValue as ResponseValue;\n } else {\n console.warn(`Cdeebee: Unknown strategy \"${strategy}\" for key \"${key}\". Skipping normalization.`);\n return mergeDeepRight(existingValue, newValue as StorageData) as ResponseValue;\n }\n}\n\nexport function defaultNormalize<T>(\n cdeebee: CdeebeeState<T>,\n response: IResponse,\n strategyList: CdeebeeListStrategy<T> \n): Record<string, ResponseValue> {\n const keyList = Object.keys(response);\n const currentStorage = isRecord(cdeebee.storage) ? (cdeebee.storage as Record<string, unknown>) : {};\n \n const result = { ...currentStorage } as Record<string, ResponseValue>;\n const keyListToOmit = new Set<string>();\n\n for (const key of keyList) {\n const responseValue = response[key];\n\n if (responseValue === null || responseValue === undefined || typeof responseValue === 'string') {\n keyListToOmit.add(key);\n continue;\n }\n\n const strategy = strategyList[key as keyof T] ?? 'merge';\n \n // For 'skip' strategy, if key doesn't exist in storage, skip it entirely\n if (strategy === 'skip' && !(key in currentStorage)) {\n continue;\n }\n \n const existingValue = key in currentStorage ? (currentStorage[key] as StorageData) : {};\n\n if (isDataWithPrimaryKey(responseValue)) {\n const normalizedValue = normalizeDataWithPrimaryKey(responseValue.data, responseValue.primaryKey);\n result[key] = applyStrategy(existingValue, normalizedValue, strategy, key);\n continue;\n }\n\n if (isRecord(responseValue)) {\n result[key] = applyStrategy(existingValue, responseValue as StorageData, strategy, key);\n } else {\n result[key] = responseValue;\n }\n }\n\n return keyListToOmit.size > 0 ? omit(Array.from(keyListToOmit), result) : result;\n}\n","import { createSlice, current, type PayloadAction } from '@reduxjs/toolkit';\n\nimport { type CdeebeeSettings, type CdeebeeState, type CdeebeeValueList, type CdeebeeListStrategy } from './types';\nimport { checkModule, mergeDeepRight, batchingUpdate } from './helpers';\nimport { abortQuery } from './abortController';\nimport { request } from './request';\nimport { defaultNormalize } from './storage';\n\nconst initialState: CdeebeeState<unknown> = {\n settings: {\n modules: ['history', 'listener', 'storage', 'cancelation'],\n fileKey: 'file',\n bodyKey: 'value',\n listStrategy: {},\n mergeWithData: {},\n mergeWithHeaders: {},\n },\n storage: {},\n request: {\n active: [],\n errors: {},\n done: {}\n },\n};\n\nexport const factory = <T>(settings: CdeebeeSettings<T>, storage?: T) => {\n const slice = createSlice({\n name: 'cdeebee',\n initialState: mergeDeepRight(initialState, { settings, storage: storage ?? {} }) as CdeebeeState<T>,\n reducers: {\n set(state, action: { payload: CdeebeeValueList<T> }) {\n // Directly mutate state.storage using Immer Draft\n // This is more performant than creating a new object\n // Immer will track changes and create minimal updates\n batchingUpdate(state.storage as Record<string, unknown>, action.payload);\n },\n historyClear(state, action: PayloadAction<string | undefined>) {\n const api = action.payload;\n\n if (api) {\n delete state.request.done[api];\n delete state.request.errors[api];\n } else {\n state.request.done = {};\n state.request.errors = {};\n }\n }\n },\n extraReducers: builder => {\n builder\n .addCase(request.pending, (state, action) => {\n const api = action.meta.arg.api;\n const requestId = action.meta.requestId;\n\n if (action.meta.arg.historyClear) {\n checkModule(state.settings, 'history', () => {\n delete state.request.done[api];\n delete state.request.errors[api];\n });\n }\n\n checkModule(state.settings, 'cancelation', () => {\n abortQuery(api, requestId);\n });\n checkModule(state.settings, 'listener', () => {\n state.request.active.push({ api, requestId });\n });\n })\n .addCase(request.fulfilled, (state, action) => {\n const requestId = action.meta.requestId;\n const api = action.meta.arg.api;\n\n checkModule(state.settings, 'listener', () => {\n state.request.active = state.request.active.filter(q => !(q.api === api && q.requestId === requestId));\n });\n checkModule(state.settings, 'history', () => {\n if (!state.request.done[api]) state.request.done[api] = [];\n state.request.done[api].push({ api, request: action.payload, requestId });\n });\n checkModule(state.settings, 'storage', () => {\n if (action.meta.arg.ignore) {\n return;\n }\n \n const strategyList = (action.meta.arg.listStrategy ?? state.settings.listStrategy ?? {}) as CdeebeeListStrategy<T>;\n const normalize = action.meta.arg.normalize ?? state.settings.normalize ?? defaultNormalize;\n\n const currentState = current(state) as CdeebeeState<T>;\n // Type assertion is safe here because we've already checked isRecord\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const normalizedData = normalize(currentState, action.payload.result as any, strategyList);\n\n // Normalize already handles merge/replace/skip and preserves keys not in response\n // Simply apply the result\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (state.storage as any) = normalizedData;\n });\n })\n .addCase(request.rejected, (state, action) => {\n const requestId = action.meta.requestId;\n const api = action.meta.arg.api;\n\n checkModule(state.settings, 'listener', () => {\n state.request.active = state.request.active.filter(q => !(q.api === api && q.requestId === requestId));\n });\n checkModule(state.settings, 'history', () => {\n if (!state.request.errors[api]) state.request.errors[api] = [];\n state.request.errors[api].push({ requestId: requestId, api, request: action.error });\n });\n });\n },\n });\n\n return slice;\n};\n","import { useSelector } from 'react-redux';\nimport { type CdeebeeState } from './reducer/types';\n\n/**\n * Generic hook factory that creates a selector hook for cdeebee state.\n * This allows the hooks to work with any Redux root state structure.\n *\n * @template RootState - The shape of the Redux root state\n * @template Storage - The shape of the cdeebee storage\n * @param selectCdeebee - Function to select the cdeebee slice from root state\n * @returns An object containing all cdeebee hooks\n */\nexport function createCdeebeeHooks<RootState, Storage>(\n selectCdeebee: (state: RootState) => CdeebeeState<Storage>\n) {\n /**\n * Check if any of the specified APIs are currently loading.\n *\n * @param apiList - Array of API endpoints to check\n * @returns true if any of the APIs are currently active/loading\n *\n * @example\n * const isLoading = useLoading(['/api/forums', '/api/threads']);\n * if (isLoading) return <Spinner />;\n */\n function useLoading(apiList: string[]): boolean {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.active.some(q => apiList.includes(q.api));\n });\n }\n\n /**\n * Get the successful request history for a specific API endpoint.\n *\n * @param api - The API endpoint\n * @returns Array of successful request history entries\n *\n * @example\n * const history = useRequestHistory('/api/forums');\n * console.log(`Made ${history.length} successful requests`);\n */\n function useRequestHistory(api: string) {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.done[api] ?? [];\n });\n }\n\n /**\n * Get the error history for a specific API endpoint.\n *\n * @param api - The API endpoint\n * @returns Array of error history entries\n *\n * @example\n * const errors = useRequestErrors('/api/forums');\n * if (errors.length > 0) {\n * console.error('Last error:', errors[errors.length - 1]);\n * }\n */\n function useRequestErrors(api: string) {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.errors[api] ?? [];\n });\n }\n\n /**\n * Get a specific list from storage with full type safety.\n *\n * @param listName - The name of the list in storage\n * @returns The list data\n *\n * @example\n * const forums = useStorageList('forumList');\n * const forumArray = Object.values(forums);\n */\n function useStorageList<K extends keyof Storage>(listName: K): Storage[K] {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.storage[listName];\n });\n }\n\n /**\n * Get the entire cdeebee storage.\n *\n * @returns The complete storage object\n *\n * @example\n * const storage = useStorage();\n * console.log(Object.keys(storage)); // ['forumList', 'threadList', ...]\n */\n function useStorage(): Storage {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.storage;\n });\n }\n\n /**\n * Check if any request is currently loading (across all APIs).\n *\n * @returns true if any request is active\n *\n * @example\n * const isAnythingLoading = useIsLoading();\n * if (isAnythingLoading) return <GlobalSpinner />;\n */\n function useIsLoading(): boolean {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.active.length > 0;\n });\n }\n\n return {\n useLoading,\n useRequestHistory,\n useRequestErrors,\n useStorageList,\n useStorage,\n useIsLoading,\n };\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param apiList - Array of API endpoints to check\n * @returns true if any of the APIs are currently active/loading\n *\n * @example\n * const isLoading = useLoading(['/api/forums', '/api/threads']);\n */\nexport function useLoading<Storage = unknown>(apiList: string[]): boolean {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.active.some(q => apiList.includes(q.api));\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param api - The API endpoint\n * @returns Array of successful request history entries\n */\nexport function useRequestHistory<Storage = unknown>(api: string) {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.done[api] ?? [];\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param api - The API endpoint\n * @returns Array of error history entries\n */\nexport function useRequestErrors<Storage = unknown>(api: string) {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.errors[api] ?? [];\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param listName - The name of the list in storage\n * @returns The list data\n */\nexport function useStorageList<Storage, K extends keyof Storage>(listName: K): Storage[K] {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.storage[listName];\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @returns The complete storage object\n */\nexport function useStorage<Storage>(): Storage {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.storage;\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @returns true if any request is active\n */\nexport function useIsLoading<Storage = unknown>(): boolean {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.active.length > 0;\n });\n}\n"],"names":["checkModule","settings","module","result","isRecord","value","mergeDeepRight","left","right","rightRecord","key","leftValue","rightValue","omit","keys","obj","batchingUpdate","state","valueList","i","item","path","current","j","pathKey","index","nextIsNumeric","next","AbortControllerStore","api","requestId","controller","apiSet","excludeRequestId","requestIds","abortStore","abortQuery","currentRequestId","abortManager","signal","cleanup","QueryQueue","task","previousPromise","queryQueue","request","createAsyncThunk","options","rejectWithValue","getState","startedAt","abort","withCallback","executeRequest","method","body","headers","extraHeaders","b","requestData","formData","fileKey","bodyKey","response","responseType","error","isDataWithPrimaryKey","normalizeDataWithPrimaryKey","data","primaryKey","applyStrategy","existingValue","newValue","strategy","defaultNormalize","cdeebee","strategyList","keyList","currentStorage","keyListToOmit","responseValue","normalizedValue","initialState","factory","storage","createSlice","action","builder","q","normalize","currentState","normalizedData","createCdeebeeHooks","selectCdeebee","useLoading","apiList","useSelector","useRequestHistory","useRequestErrors","useStorageList","listName","useStorage","useIsLoading"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../lib/reducer/helpers.ts","../lib/reducer/abortController.ts","../lib/reducer/queryQueue.ts","../lib/reducer/request.ts","../lib/reducer/storage.ts","../lib/reducer/index.ts","../lib/hooks/createCdeebeeHooks.ts","../lib/hooks/selectors.ts"],"sourcesContent":["import { type WritableDraft } from '@reduxjs/toolkit';\nimport { type CdeebeeSettings, type CdeebeeModule, CdeebeeValueList } from './types';\n\nexport function checkModule(settings: CdeebeeSettings<unknown> | WritableDraft<CdeebeeSettings<unknown>>, module: CdeebeeModule, result: () => void) {\n if (settings.modules.includes(module)) {\n result();\n }\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport function mergeDeepRight<T>(\n left: T,\n right: Partial<T> | Record<string, unknown>\n): T {\n if (!isRecord(left) || !isRecord(right)) {\n return right as T;\n }\n\n const result = { ...left } as Record<string, unknown>;\n const rightRecord = right as Record<string, unknown>;\n\n for (const key in rightRecord) {\n if (Object.prototype.hasOwnProperty.call(rightRecord, key)) {\n const leftValue = result[key];\n const rightValue = rightRecord[key];\n\n if (\n isRecord(leftValue) &&\n isRecord(rightValue) &&\n !Array.isArray(leftValue) &&\n !Array.isArray(rightValue)\n ) {\n result[key] = mergeDeepRight(leftValue, rightValue);\n } else {\n result[key] = rightValue;\n }\n }\n }\n\n return result as T;\n}\n\nexport function omit<T extends Record<string, unknown>>(keys: string[], obj: T): Omit<T, keyof T> {\n const result = { ...obj };\n for (const key of keys) {\n delete result[key];\n }\n return result as Omit<T, keyof T>;\n}\n\n/**\n * Extract primary key values from API response data.\n * Handles responses with format: { listName: { data: [...], primaryKey: 'id' } }\n * Returns a flat array of all extracted IDs from all lists.\n */\nexport function extractResultIdList(response: unknown): string[] {\n if (!isRecord(response)) {\n return [];\n }\n\n const ids: string[] = [];\n\n for (const key of Object.keys(response)) {\n const value = response[key];\n\n if (\n isRecord(value) &&\n Array.isArray(value.data) &&\n typeof value.primaryKey === 'string'\n ) {\n const primaryKey = value.primaryKey;\n for (const item of value.data) {\n if (isRecord(item) && primaryKey in item) {\n ids.push(String(item[primaryKey]));\n }\n }\n }\n }\n\n return ids;\n}\n\nexport function batchingUpdate<T extends Record<string, unknown>>(\n state: T,\n valueList: CdeebeeValueList<T>\n): void {\n for (let i = 0; i < valueList.length; i++) {\n const item = valueList[i] as { key: readonly (string | number)[]; value: unknown };\n const path = item.key;\n const value = item.value;\n\n if (path.length === 0) {\n continue;\n }\n\n let current: Record<string, unknown> | unknown[] = state as Record<string, unknown>;\n\n for (let j = 0; j < path.length - 1; j++) {\n const pathKey = path[j];\n\n if (Array.isArray(current)) {\n const index = typeof pathKey === 'number' ? pathKey : Number(pathKey);\n if (!(index in current) || !isRecord(current[index])) {\n current[index] = {};\n }\n current = current[index] as Record<string, unknown>;\n } else {\n const key = String(pathKey);\n if (!(key in current)) {\n const nextIsNumeric = typeof path[j + 1] === 'number' || (!isNaN(Number(path[j + 1])) && String(Number(path[j + 1])) === String(path[j + 1]));\n current[key] = nextIsNumeric ? [] : {};\n }\n const next = current[key];\n current = (Array.isArray(next) ? next : (isRecord(next) ? next : {})) as Record<string, unknown> | unknown[];\n }\n }\n\n if (Array.isArray(current)) {\n continue; // Can't update array element directly\n }\n current[String(path[path.length - 1])] = value;\n }\n}\n","interface RequestController {\n requestId: string;\n controller: AbortController;\n api: string;\n}\n\nclass AbortControllerStore {\n private byRequestId = new Map<string, RequestController>();\n private byApi = new Map<string, Set<string>>();\n\n add(api: string, requestId: string, controller: AbortController): void {\n const item: RequestController = { requestId, controller, api };\n this.byRequestId.set(requestId, item);\n\n if (!this.byApi.has(api)) {\n this.byApi.set(api, new Set());\n }\n this.byApi.get(api)!.add(requestId);\n }\n\n delete(requestId: string): void {\n const item = this.byRequestId.get(requestId);\n if (!item) return;\n\n this.byRequestId.delete(requestId);\n const apiSet = this.byApi.get(item.api);\n if (apiSet) {\n apiSet.delete(requestId);\n if (apiSet.size === 0) {\n this.byApi.delete(item.api);\n }\n }\n }\n\n abortAllForApi(api: string, excludeRequestId: string): void {\n const requestIds = this.byApi.get(api);\n if (!requestIds) return;\n\n requestIds.forEach(requestId => {\n if (requestId !== excludeRequestId) {\n const item = this.byRequestId.get(requestId);\n if (item) {\n item.controller.abort();\n this.delete(requestId);\n }\n }\n });\n }\n}\n\nconst abortStore = new AbortControllerStore();\n\nexport function abortQuery(api: string, currentRequestId: string): void {\n abortStore.abortAllForApi(api, currentRequestId);\n}\n\nexport function abortManager(signal: AbortSignal, api: string, requestId: string) {\n const controller = new AbortController();\n\n const cleanup = () => {\n abortStore.delete(requestId);\n };\n\n signal.addEventListener('abort', () => {\n controller.abort();\n cleanup();\n });\n\n return {\n controller,\n init: () => abortStore.add(api, requestId, controller),\n drop: cleanup,\n };\n}\n","class QueryQueue {\n private currentPromise: Promise<unknown> = Promise.resolve();\n private queueLength = 0;\n\n async enqueue<T>(task: () => Promise<T>): Promise<T> {\n this.queueLength++;\n\n const previousPromise = this.currentPromise;\n\n this.currentPromise = previousPromise\n .then(() => task(), () => task())\n .finally(() => {\n this.queueLength--;\n });\n\n return this.currentPromise as Promise<T>;\n }\n\n getQueueLength(): number {\n return this.queueLength;\n }\n\n clear(): void {\n this.queueLength = 0;\n }\n}\n\nexport const queryQueue = new QueryQueue();\n\n","import { createAsyncThunk } from '@reduxjs/toolkit';\nimport { checkModule } from './helpers';\nimport { abortManager } from './abortController';\nimport { queryQueue } from './queryQueue';\nimport { type CdeebeeState, type CdeebeeRequestOptions } from './types';\n\nexport const request = createAsyncThunk(\n 'cdeebee/request',\n async (options: CdeebeeRequestOptions<unknown>, { rejectWithValue, getState, requestId, signal }) => {\n const startedAt = new Date().toUTCString();\n const { cdeebee: { settings } } = getState() as { cdeebee: CdeebeeState<unknown> };\n\n const abort = abortManager(signal, options.api, requestId);\n const withCallback = options.onResult && typeof options.onResult === 'function';\n\n checkModule(settings, 'cancelation', abort.init);\n\n const executeRequest = async () => {\n try {\n const { method = 'POST', body, headers = {} } = options;\n const baseHeaders = typeof settings.mergeWithHeaders === 'function'\n ? settings.mergeWithHeaders()\n : (settings.mergeWithHeaders ?? {});\n\n const extraHeaders: Record<string, string> = { ...baseHeaders, ...headers };\n\n const baseData = typeof settings.mergeWithData === 'function'\n ? settings.mergeWithData()\n : (settings.mergeWithData ?? {});\n\n const b = { ...baseData, ...(body ?? {}) };\n let requestData: FormData | string = JSON.stringify(b);\n\n // handling files\n if (options.files) {\n const formData = new FormData();\n const fileKey = options.fileKey || settings.fileKey;\n const bodyKey = options.bodyKey || settings.bodyKey;\n\n for (let i = 0; i < options.files.length; i += 1) {\n if (fileKey) {\n formData.append(fileKey, options.files[i]);\n }\n }\n\n if (bodyKey) {\n formData.append(bodyKey, requestData);\n }\n requestData = formData;\n }\n // [end] handling files\n\n const response = await fetch(options.api, {\n method,\n headers: {\n 'ui-request-id': requestId,\n 'Content-Type': 'application/json',\n ...extraHeaders,\n },\n signal: abort.controller.signal,\n body: requestData,\n });\n\n checkModule(settings, 'cancelation', abort.drop);\n\n let result: unknown;\n const responseType = options.responseType || 'json';\n\n if (responseType === 'text') {\n result = await response.text();\n } else if (responseType === 'blob') {\n result = await response.blob();\n } else {\n // default: json\n result = await response.json();\n }\n\n if (!response.ok) {\n if (withCallback) options.onResult!(result);\n return rejectWithValue(response);\n }\n\n if (withCallback) options.onResult!(result);\n return { result, startedAt, endedAt: new Date().toUTCString() };\n } catch (error) {\n checkModule(settings, 'cancelation', abort.drop);\n\n if (withCallback) options.onResult!(error);\n\n if (error instanceof Error && error.name === 'AbortError') {\n return rejectWithValue({ message: 'Request was cancelled', cancelled: true });\n }\n\n return rejectWithValue({ message: error instanceof Error ? error.message : 'Unknown error occurred' });\n }\n };\n\n if (settings.modules.includes('queryQueue')) {\n return queryQueue.enqueue(executeRequest);\n }\n\n return executeRequest();\n },\n);\n\n","import { type CdeebeeListStrategy, type CdeebeeState } from './types';\nimport { isRecord, mergeDeepRight, omit } from './helpers';\n\ntype ResponseValue = Record<string, unknown>;\n\ntype IResponse = Record<string, ResponseValue>;\n\ntype StorageData = Record<string, unknown>;\n\nfunction isDataWithPrimaryKey(value: unknown): value is { data: unknown[]; primaryKey: string } {\n return (\n isRecord(value) &&\n Array.isArray(value.data) &&\n typeof value.primaryKey === 'string'\n );\n}\nfunction normalizeDataWithPrimaryKey(data: unknown[], primaryKey: string): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n \n for (const item of data) {\n if (isRecord(item) && primaryKey in item) {\n const key = String(item[primaryKey]);\n result[key] = item;\n }\n }\n \n return result;\n}\n\nfunction applyStrategy(\n existingValue: StorageData,\n newValue: StorageData | ResponseValue,\n strategy: string,\n key: string\n): ResponseValue {\n if (strategy === 'replace') {\n return newValue as ResponseValue;\n } else if (strategy === 'merge') {\n return mergeDeepRight(existingValue, newValue as StorageData) as ResponseValue;\n } else if (strategy === 'skip') {\n return existingValue as ResponseValue;\n } else {\n console.warn(`Cdeebee: Unknown strategy \"${strategy}\" for key \"${key}\". Skipping normalization.`);\n return mergeDeepRight(existingValue, newValue as StorageData) as ResponseValue;\n }\n}\n\nexport function defaultNormalize<T>(\n cdeebee: CdeebeeState<T>,\n response: IResponse,\n strategyList: CdeebeeListStrategy<T> \n): Record<string, ResponseValue> {\n const keyList = Object.keys(response);\n const currentStorage = isRecord(cdeebee.storage) ? (cdeebee.storage as Record<string, unknown>) : {};\n \n const result = { ...currentStorage } as Record<string, ResponseValue>;\n const keyListToOmit = new Set<string>();\n\n for (const key of keyList) {\n const responseValue = response[key];\n\n if (responseValue === null || responseValue === undefined || typeof responseValue === 'string') {\n keyListToOmit.add(key);\n continue;\n }\n\n const strategy = strategyList[key as keyof T] ?? 'merge';\n \n // For 'skip' strategy, if key doesn't exist in storage, skip it entirely\n if (strategy === 'skip' && !(key in currentStorage)) {\n continue;\n }\n \n const existingValue = key in currentStorage ? (currentStorage[key] as StorageData) : {};\n\n if (isDataWithPrimaryKey(responseValue)) {\n const normalizedValue = normalizeDataWithPrimaryKey(responseValue.data, responseValue.primaryKey);\n result[key] = applyStrategy(existingValue, normalizedValue, strategy, key);\n continue;\n }\n\n if (isRecord(responseValue)) {\n result[key] = applyStrategy(existingValue, responseValue as StorageData, strategy, key);\n } else {\n result[key] = responseValue;\n }\n }\n\n return keyListToOmit.size > 0 ? omit(Array.from(keyListToOmit), result) : result;\n}\n","import { createSlice, current, type PayloadAction } from '@reduxjs/toolkit';\n\nimport { type CdeebeeSettings, type CdeebeeState, type CdeebeeValueList, type CdeebeeListStrategy } from './types';\nimport { checkModule, mergeDeepRight, batchingUpdate, extractResultIdList } from './helpers';\nimport { abortQuery } from './abortController';\nimport { request } from './request';\nimport { defaultNormalize } from './storage';\n\nconst initialState: CdeebeeState<unknown> = {\n settings: {\n modules: ['history', 'listener', 'storage', 'cancelation'],\n fileKey: 'file',\n bodyKey: 'value',\n listStrategy: {},\n mergeWithData: {},\n mergeWithHeaders: {},\n },\n storage: {},\n request: {\n active: [],\n errors: {},\n done: {},\n lastResultIdList: {},\n },\n};\n\nexport const factory = <T>(settings: CdeebeeSettings<T>, storage?: T) => {\n const slice = createSlice({\n name: 'cdeebee',\n initialState: mergeDeepRight(initialState, { settings, storage: storage ?? {} }) as CdeebeeState<T>,\n reducers: {\n set(state, action: { payload: CdeebeeValueList<T> }) {\n // Directly mutate state.storage using Immer Draft\n // This is more performant than creating a new object\n // Immer will track changes and create minimal updates\n batchingUpdate(state.storage as Record<string, unknown>, action.payload);\n },\n historyClear(state, action: PayloadAction<string | undefined>) {\n const api = action.payload;\n\n if (api) {\n delete state.request.done[api];\n delete state.request.errors[api];\n } else {\n state.request.done = {};\n state.request.errors = {};\n }\n }\n },\n extraReducers: builder => {\n builder\n .addCase(request.pending, (state, action) => {\n const api = action.meta.arg.api;\n const requestId = action.meta.requestId;\n\n if (action.meta.arg.historyClear) {\n checkModule(state.settings, 'history', () => {\n delete state.request.done[api];\n delete state.request.errors[api];\n });\n }\n\n checkModule(state.settings, 'cancelation', () => {\n abortQuery(api, requestId);\n });\n checkModule(state.settings, 'listener', () => {\n state.request.active.push({ api, requestId });\n });\n })\n .addCase(request.fulfilled, (state, action) => {\n const requestId = action.meta.requestId;\n const api = action.meta.arg.api;\n\n checkModule(state.settings, 'listener', () => {\n state.request.active = state.request.active.filter(q => !(q.api === api && q.requestId === requestId));\n });\n checkModule(state.settings, 'history', () => {\n if (!state.request.done[api]) state.request.done[api] = [];\n state.request.done[api].push({ api, request: action.payload, requestId });\n });\n checkModule(state.settings, 'storage', () => {\n if (action.meta.arg.ignore) {\n return;\n }\n\n const strategyList = (action.meta.arg.listStrategy ?? state.settings.listStrategy ?? {}) as CdeebeeListStrategy<T>;\n const normalize = action.meta.arg.normalize ?? state.settings.normalize ?? defaultNormalize;\n\n const currentState = current(state) as CdeebeeState<T>;\n // Type assertion is safe here because we've already checked isRecord\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const normalizedData = normalize(currentState, action.payload.result as any, strategyList);\n\n // Normalize already handles merge/replace/skip and preserves keys not in response\n // Simply apply the result\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (state.storage as any) = normalizedData;\n\n // Extract and store result IDs for filtering\n state.request.lastResultIdList[api] = extractResultIdList(action.payload.result);\n });\n })\n .addCase(request.rejected, (state, action) => {\n const requestId = action.meta.requestId;\n const api = action.meta.arg.api;\n\n checkModule(state.settings, 'listener', () => {\n state.request.active = state.request.active.filter(q => !(q.api === api && q.requestId === requestId));\n });\n checkModule(state.settings, 'history', () => {\n if (!state.request.errors[api]) state.request.errors[api] = [];\n state.request.errors[api].push({ requestId: requestId, api, request: action.error });\n });\n });\n },\n });\n\n return slice;\n};\n","import { useSelector } from 'react-redux';\nimport { type CdeebeeState } from '../reducer/types';\n\n/**\n * Generic hook factory that creates a selector hook for cdeebee state.\n * This allows the hooks to work with any Redux root state structure.\n *\n * @template RootState - The shape of the Redux root state\n * @template Storage - The shape of the cdeebee storage\n * @param selectCdeebee - Function to select the cdeebee slice from root state\n * @returns An object containing all cdeebee hooks\n */\nexport function createCdeebeeHooks<RootState, Storage>(\n selectCdeebee: (state: RootState) => CdeebeeState<Storage>\n) {\n /**\n * Check if any of the specified APIs are currently loading.\n *\n * @param apiList - Array of API endpoints to check\n * @returns true if any of the APIs are currently active/loading\n *\n * @example\n * const isLoading = useLoading(['/api/forums', '/api/threads']);\n * if (isLoading) return <Spinner />;\n */\n function useLoading(apiList: string[]): boolean {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.active.some(q => apiList.includes(q.api));\n });\n }\n\n /**\n * Get the successful request history for a specific API endpoint.\n *\n * @param api - The API endpoint\n * @returns Array of successful request history entries\n *\n * @example\n * const history = useRequestHistory('/api/forums');\n * console.log(`Made ${history.length} successful requests`);\n */\n function useRequestHistory(api: string) {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.done[api] ?? [];\n });\n }\n\n /**\n * Get the error history for a specific API endpoint.\n *\n * @param api - The API endpoint\n * @returns Array of error history entries\n *\n * @example\n * const errors = useRequestErrors('/api/forums');\n * if (errors.length > 0) {\n * console.error('Last error:', errors[errors.length - 1]);\n * }\n */\n function useRequestErrors(api: string) {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.errors[api] ?? [];\n });\n }\n\n /**\n * Get a specific list from storage with full type safety.\n *\n * @param listName - The name of the list in storage\n * @returns The list data\n *\n * @example\n * const forums = useStorageList('forumList');\n * const forumArray = Object.values(forums);\n */\n function useStorageList<K extends keyof Storage>(listName: K): Storage[K] {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.storage[listName];\n });\n }\n\n /**\n * Get the entire cdeebee storage.\n *\n * @returns The complete storage object\n *\n * @example\n * const storage = useStorage();\n * console.log(Object.keys(storage)); // ['forumList', 'threadList', ...]\n */\n function useStorage(): Storage {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.storage;\n });\n }\n\n /**\n * Check if any request is currently loading (across all APIs).\n *\n * @returns true if any request is active\n *\n * @example\n * const isAnythingLoading = useIsLoading();\n * if (isAnythingLoading) return <GlobalSpinner />;\n */\n function useIsLoading(): boolean {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.active.length > 0;\n });\n }\n\n /**\n * Get the list of IDs returned by the last successful request to an API.\n * Useful for filtering storage data to show only results from a specific request.\n *\n * @param api - The API endpoint\n * @returns Array of primary key IDs from the last response\n *\n * @example\n * const productList = useStorageList('productList');\n * const lastIds = useLastResultIdList('/api/search');\n * const displayResults = lastIds.map(id => productList[id]).filter(Boolean);\n */\n function useLastResultIdList(api: string): string[] {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.lastResultIdList[api] ?? [];\n });\n }\n\n return {\n useLoading,\n useRequestHistory,\n useRequestErrors,\n useStorageList,\n useStorage,\n useIsLoading,\n useLastResultIdList,\n };\n}\n","import { useSelector } from 'react-redux';\nimport { type CdeebeeState } from '../reducer/types';\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param apiList - Array of API endpoints to check\n * @returns true if any of the APIs are currently active/loading\n *\n * @example\n * const isLoading = useLoading(['/api/forums', '/api/threads']);\n */\nexport function useLoading<Storage = unknown>(apiList: string[]): boolean {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.active.some(q => apiList.includes(q.api));\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param api - The API endpoint\n * @returns Array of successful request history entries\n */\nexport function useRequestHistory<Storage = unknown>(api: string) {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.done[api] ?? [];\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param api - The API endpoint\n * @returns Array of error history entries\n */\nexport function useRequestErrors<Storage = unknown>(api: string) {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.errors[api] ?? [];\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param listName - The name of the list in storage\n * @returns The list data\n */\nexport function useStorageList<Storage, K extends keyof Storage>(listName: K): Storage[K] {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.storage[listName];\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @returns The complete storage object\n */\nexport function useStorage<Storage>(): Storage {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.storage;\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @returns true if any request is active\n */\nexport function useIsLoading<Storage = unknown>(): boolean {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.active.length > 0;\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * Get the list of IDs returned by the last successful request to an API.\n * Useful for filtering storage data to show only results from a specific request.\n *\n * @param api - The API endpoint\n * @returns Array of primary key IDs from the last response\n *\n * @example\n * const productList = useStorageList('productList');\n * const lastIds = useLastResultIdList('/api/search');\n * const displayResults = lastIds.map(id => productList[id]).filter(Boolean);\n */\nexport function useLastResultIdList<Storage = unknown>(api: string): string[] {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.lastResultIdList[api] ?? [];\n });\n}\n"],"names":["checkModule","settings","module","result","isRecord","value","mergeDeepRight","left","right","rightRecord","key","leftValue","rightValue","omit","keys","obj","extractResultIdList","response","ids","primaryKey","item","batchingUpdate","state","valueList","i","path","current","j","pathKey","index","nextIsNumeric","next","AbortControllerStore","api","requestId","controller","apiSet","excludeRequestId","requestIds","abortStore","abortQuery","currentRequestId","abortManager","signal","cleanup","QueryQueue","task","previousPromise","queryQueue","request","createAsyncThunk","options","rejectWithValue","getState","startedAt","abort","withCallback","executeRequest","method","body","headers","extraHeaders","b","requestData","formData","fileKey","bodyKey","responseType","error","isDataWithPrimaryKey","normalizeDataWithPrimaryKey","data","applyStrategy","existingValue","newValue","strategy","defaultNormalize","cdeebee","strategyList","keyList","currentStorage","keyListToOmit","responseValue","normalizedValue","initialState","factory","storage","createSlice","action","builder","q","normalize","currentState","normalizedData","createCdeebeeHooks","selectCdeebee","useLoading","apiList","useSelector","useRequestHistory","useRequestErrors","useStorageList","listName","useStorage","useIsLoading","useLastResultIdList"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -43,14 +43,15 @@ declare interface CdeebeeRequestState {
43
43
  active: CdeebeeActiveRequest[];
44
44
  errors: Record<string, CdeebeeHistoryState[]>;
45
45
  done: Record<string, CdeebeeHistoryState[]>;
46
+ lastResultIdList: Record<string, string[]>;
46
47
  }
47
48
 
48
49
  declare interface CdeebeeSettings<T> {
49
50
  modules: CdeebeeModule[];
50
51
  fileKey: string;
51
52
  bodyKey: string;
52
- mergeWithData: unknown;
53
- mergeWithHeaders: unknown;
53
+ mergeWithData: Record<string, unknown> | (() => Record<string, unknown>);
54
+ mergeWithHeaders: Record<string, string> | (() => Record<string, string>);
54
55
  listStrategy?: CdeebeeListStrategy<T>;
55
56
  normalize?: <T>(storage: CdeebeeState<T>, result: T, strategyList: CdeebeeListStrategy<T>) => T;
56
57
  }
@@ -86,16 +87,23 @@ export declare function createCdeebeeHooks<RootState, Storage>(selectCdeebee: (s
86
87
  useStorageList: <K extends keyof Storage>(listName: K) => Storage[K];
87
88
  useStorage: () => Storage;
88
89
  useIsLoading: () => boolean;
90
+ useLastResultIdList: (api: string) => string[];
89
91
  };
90
92
 
93
+ export declare function defaultNormalize<T>(cdeebee: CdeebeeState<T>, response: IResponse, strategyList: CdeebeeListStrategy<T>): Record<string, ResponseValue>;
94
+
91
95
  export declare const factory: <T>(settings: CdeebeeSettings<T>, storage?: T) => Slice<CdeebeeState<T>, {
92
96
  set(state: {
93
97
  settings: {
94
98
  modules: CdeebeeModule[];
95
99
  fileKey: string;
96
100
  bodyKey: string;
97
- mergeWithData: unknown;
98
- mergeWithHeaders: unknown;
101
+ mergeWithData: (() => Record<string, unknown>) | {
102
+ [x: string]: unknown;
103
+ };
104
+ mergeWithHeaders: (() => Record<string, string>) | {
105
+ [x: string]: string;
106
+ };
99
107
  listStrategy?: (CdeebeeListStrategy<T> | undefined extends infer V ? V extends object ? Draft<V> : V : never) | undefined;
100
108
  normalize?: (<T_1>(storage: CdeebeeState<T_1>, result: T_1, strategyList: CdeebeeListStrategy<T_1>) => T_1) | undefined;
101
109
  };
@@ -119,6 +127,9 @@ api: string;
119
127
  request: unknown;
120
128
  }[];
121
129
  };
130
+ lastResultIdList: {
131
+ [x: string]: string[];
132
+ };
122
133
  };
123
134
  }, action: {
124
135
  payload: CdeebeeValueList<T>;
@@ -128,8 +139,12 @@ settings: {
128
139
  modules: CdeebeeModule[];
129
140
  fileKey: string;
130
141
  bodyKey: string;
131
- mergeWithData: unknown;
132
- mergeWithHeaders: unknown;
142
+ mergeWithData: (() => Record<string, unknown>) | {
143
+ [x: string]: unknown;
144
+ };
145
+ mergeWithHeaders: (() => Record<string, string>) | {
146
+ [x: string]: string;
147
+ };
133
148
  listStrategy?: (CdeebeeListStrategy<T> | undefined extends infer V ? V extends object ? Draft<V> : V : never) | undefined;
134
149
  normalize?: (<T_1>(storage: CdeebeeState<T_1>, result: T_1, strategyList: CdeebeeListStrategy<T_1>) => T_1) | undefined;
135
150
  };
@@ -153,10 +168,15 @@ api: string;
153
168
  request: unknown;
154
169
  }[];
155
170
  };
171
+ lastResultIdList: {
172
+ [x: string]: string[];
173
+ };
156
174
  };
157
175
  }, action: PayloadAction<string | undefined>): void;
158
176
  }, "cdeebee", "cdeebee", SliceSelectors<CdeebeeState<T>>>;
159
177
 
178
+ declare type IResponse = Record<string, ResponseValue>;
179
+
160
180
  declare type IsArray<T> = T extends readonly unknown[] ? true : T extends unknown[] ? true : false;
161
181
 
162
182
  declare type KeyOf<T> = Extract<keyof T, string | number>;
@@ -173,6 +193,8 @@ startedAt: string;
173
193
  endedAt: string;
174
194
  }, CdeebeeRequestOptions<unknown>, AsyncThunkConfig>;
175
195
 
196
+ declare type ResponseValue = Record<string, unknown>;
197
+
176
198
  /**
177
199
  * Standalone hook that can be used without createCdeebeeHooks.
178
200
  * Assumes the cdeebee slice is at state.cdeebee.
@@ -181,6 +203,23 @@ endedAt: string;
181
203
  */
182
204
  export declare function useIsLoading<Storage = unknown>(): boolean;
183
205
 
206
+ /**
207
+ * Standalone hook that can be used without createCdeebeeHooks.
208
+ * Assumes the cdeebee slice is at state.cdeebee.
209
+ *
210
+ * Get the list of IDs returned by the last successful request to an API.
211
+ * Useful for filtering storage data to show only results from a specific request.
212
+ *
213
+ * @param api - The API endpoint
214
+ * @returns Array of primary key IDs from the last response
215
+ *
216
+ * @example
217
+ * const productList = useStorageList('productList');
218
+ * const lastIds = useLastResultIdList('/api/search');
219
+ * const displayResults = lastIds.map(id => productList[id]).filter(Boolean);
220
+ */
221
+ export declare function useLastResultIdList<Storage = unknown>(api: string): string[];
222
+
184
223
  /**
185
224
  * Standalone hook that can be used without createCdeebeeHooks.
186
225
  * Assumes the cdeebee slice is at state.cdeebee.
package/dist/index.js CHANGED
@@ -1,94 +1,108 @@
1
- import { createAsyncThunk as I, createSlice as P, current as x } from "@reduxjs/toolkit";
1
+ import { createAsyncThunk as z, createSlice as H, current as P } from "@reduxjs/toolkit";
2
2
  import { useSelector as d } from "react-redux";
3
- function f(e, r, s) {
3
+ function y(e, r, s) {
4
4
  e.modules.includes(r) && s();
5
5
  }
6
- function y(e) {
6
+ function f(e) {
7
7
  return e !== null && typeof e == "object" && !Array.isArray(e);
8
8
  }
9
- function b(e, r) {
10
- if (!y(e) || !y(r))
9
+ function h(e, r) {
10
+ if (!f(e) || !f(r))
11
11
  return r;
12
- const s = { ...e }, o = r;
13
- for (const t in o)
14
- if (Object.prototype.hasOwnProperty.call(o, t)) {
15
- const u = s[t], i = o[t];
16
- y(u) && y(i) && !Array.isArray(u) && !Array.isArray(i) ? s[t] = b(u, i) : s[t] = i;
12
+ const s = { ...e }, n = r;
13
+ for (const t in n)
14
+ if (Object.prototype.hasOwnProperty.call(n, t)) {
15
+ const o = s[t], i = n[t];
16
+ f(o) && f(i) && !Array.isArray(o) && !Array.isArray(i) ? s[t] = h(o, i) : s[t] = i;
17
17
  }
18
18
  return s;
19
19
  }
20
- function C(e, r) {
20
+ function x(e, r) {
21
21
  const s = { ...r };
22
- for (const o of e)
23
- delete s[o];
22
+ for (const n of e)
23
+ delete s[n];
24
24
  return s;
25
25
  }
26
- function E(e, r) {
26
+ function N(e) {
27
+ if (!f(e))
28
+ return [];
29
+ const r = [];
30
+ for (const s of Object.keys(e)) {
31
+ const n = e[s];
32
+ if (f(n) && Array.isArray(n.data) && typeof n.primaryKey == "string") {
33
+ const t = n.primaryKey;
34
+ for (const o of n.data)
35
+ f(o) && t in o && r.push(String(o[t]));
36
+ }
37
+ }
38
+ return r;
39
+ }
40
+ function T(e, r) {
27
41
  for (let s = 0; s < r.length; s++) {
28
- const o = r[s], t = o.key, u = o.value;
42
+ const n = r[s], t = n.key, o = n.value;
29
43
  if (t.length === 0)
30
44
  continue;
31
45
  let i = e;
32
- for (let n = 0; n < t.length - 1; n++) {
33
- const c = t[n];
46
+ for (let u = 0; u < t.length - 1; u++) {
47
+ const a = t[u];
34
48
  if (Array.isArray(i)) {
35
- const a = typeof c == "number" ? c : Number(c);
36
- (!(a in i) || !y(i[a])) && (i[a] = {}), i = i[a];
49
+ const c = typeof a == "number" ? a : Number(a);
50
+ (!(c in i) || !f(i[c])) && (i[c] = {}), i = i[c];
37
51
  } else {
38
- const a = String(c);
39
- if (!(a in i)) {
40
- const g = typeof t[n + 1] == "number" || !isNaN(Number(t[n + 1])) && String(Number(t[n + 1])) === String(t[n + 1]);
41
- i[a] = g ? [] : {};
52
+ const c = String(a);
53
+ if (!(c in i)) {
54
+ const g = typeof t[u + 1] == "number" || !isNaN(Number(t[u + 1])) && String(Number(t[u + 1])) === String(t[u + 1]);
55
+ i[c] = g ? [] : {};
42
56
  }
43
- const l = i[a];
44
- i = Array.isArray(l) || y(l) ? l : {};
57
+ const l = i[c];
58
+ i = Array.isArray(l) || f(l) ? l : {};
45
59
  }
46
60
  }
47
- Array.isArray(i) || (i[String(t[t.length - 1])] = u);
61
+ Array.isArray(i) || (i[String(t[t.length - 1])] = o);
48
62
  }
49
63
  }
50
- class N {
64
+ class W {
51
65
  constructor() {
52
66
  this.byRequestId = /* @__PURE__ */ new Map(), this.byApi = /* @__PURE__ */ new Map();
53
67
  }
54
- add(r, s, o) {
55
- const t = { requestId: s, controller: o, api: r };
68
+ add(r, s, n) {
69
+ const t = { requestId: s, controller: n, api: r };
56
70
  this.byRequestId.set(s, t), this.byApi.has(r) || this.byApi.set(r, /* @__PURE__ */ new Set()), this.byApi.get(r).add(s);
57
71
  }
58
72
  delete(r) {
59
73
  const s = this.byRequestId.get(r);
60
74
  if (!s) return;
61
75
  this.byRequestId.delete(r);
62
- const o = this.byApi.get(s.api);
63
- o && (o.delete(r), o.size === 0 && this.byApi.delete(s.api));
76
+ const n = this.byApi.get(s.api);
77
+ n && (n.delete(r), n.size === 0 && this.byApi.delete(s.api));
64
78
  }
65
79
  abortAllForApi(r, s) {
66
- const o = this.byApi.get(r);
67
- o && o.forEach((t) => {
80
+ const n = this.byApi.get(r);
81
+ n && n.forEach((t) => {
68
82
  if (t !== s) {
69
- const u = this.byRequestId.get(t);
70
- u && (u.controller.abort(), this.delete(t));
83
+ const o = this.byRequestId.get(t);
84
+ o && (o.controller.abort(), this.delete(t));
71
85
  }
72
86
  });
73
87
  }
74
88
  }
75
- const R = new N();
76
- function T(e, r) {
89
+ const R = new W();
90
+ function j(e, r) {
77
91
  R.abortAllForApi(e, r);
78
92
  }
79
- function H(e, r, s) {
80
- const o = new AbortController(), t = () => {
93
+ function C(e, r, s) {
94
+ const n = new AbortController(), t = () => {
81
95
  R.delete(s);
82
96
  };
83
97
  return e.addEventListener("abort", () => {
84
- o.abort(), t();
98
+ n.abort(), t();
85
99
  }), {
86
- controller: o,
87
- init: () => R.add(r, s, o),
100
+ controller: n,
101
+ init: () => R.add(r, s, n),
88
102
  drop: t
89
103
  };
90
104
  }
91
- class j {
105
+ class E {
92
106
  constructor() {
93
107
  this.currentPromise = Promise.resolve(), this.queueLength = 0;
94
108
  }
@@ -106,79 +120,79 @@ class j {
106
120
  this.queueLength = 0;
107
121
  }
108
122
  }
109
- const O = new j(), S = I(
123
+ const O = new E(), S = z(
110
124
  "cdeebee/request",
111
- async (e, { rejectWithValue: r, getState: s, requestId: o, signal: t }) => {
112
- const u = (/* @__PURE__ */ new Date()).toUTCString(), { cdeebee: { settings: i } } = s(), n = H(t, e.api, o), c = e.onResult && typeof e.onResult == "function";
113
- f(i, "cancelation", n.init);
114
- const a = async () => {
125
+ async (e, { rejectWithValue: r, getState: s, requestId: n, signal: t }) => {
126
+ const o = (/* @__PURE__ */ new Date()).toUTCString(), { cdeebee: { settings: i } } = s(), u = C(t, e.api, n), a = e.onResult && typeof e.onResult == "function";
127
+ y(i, "cancelation", u.init);
128
+ const c = async () => {
115
129
  try {
116
- const { method: l = "POST", body: g, headers: K = {} } = e, D = { ...i.mergeWithHeaders ?? {}, ...K }, z = { ...i.mergeWithData ?? {}, ...g ?? {} };
117
- let p = JSON.stringify(z);
130
+ const { method: l = "POST", body: g, headers: D = {} } = e, K = { ...typeof i.mergeWithHeaders == "function" ? i.mergeWithHeaders() : i.mergeWithHeaders ?? {}, ...D }, v = { ...typeof i.mergeWithData == "function" ? i.mergeWithData() : i.mergeWithData ?? {}, ...g ?? {} };
131
+ let p = JSON.stringify(v);
118
132
  if (e.files) {
119
- const q = new FormData(), w = e.fileKey || i.fileKey, L = e.bodyKey || i.bodyKey;
133
+ const q = new FormData(), k = e.fileKey || i.fileKey, w = e.bodyKey || i.bodyKey;
120
134
  for (let A = 0; A < e.files.length; A += 1)
121
- w && q.append(w, e.files[A]);
122
- L && q.append(L, p), p = q;
135
+ k && q.append(k, e.files[A]);
136
+ w && q.append(w, p), p = q;
123
137
  }
124
- const h = await fetch(e.api, {
138
+ const b = await fetch(e.api, {
125
139
  method: l,
126
140
  headers: {
127
- "ui-request-id": o,
141
+ "ui-request-id": n,
128
142
  "Content-Type": "application/json",
129
- ...D
143
+ ...K
130
144
  },
131
- signal: n.controller.signal,
145
+ signal: u.controller.signal,
132
146
  body: p
133
147
  });
134
- f(i, "cancelation", n.drop);
148
+ y(i, "cancelation", u.drop);
135
149
  let m;
136
- const k = e.responseType || "json";
137
- return k === "text" ? m = await h.text() : k === "blob" ? m = await h.blob() : m = await h.json(), h.ok ? (c && e.onResult(m), { result: m, startedAt: u, endedAt: (/* @__PURE__ */ new Date()).toUTCString() }) : (c && e.onResult(m), r(h));
150
+ const L = e.responseType || "json";
151
+ return L === "text" ? m = await b.text() : L === "blob" ? m = await b.blob() : m = await b.json(), b.ok ? (a && e.onResult(m), { result: m, startedAt: o, endedAt: (/* @__PURE__ */ new Date()).toUTCString() }) : (a && e.onResult(m), r(b));
138
152
  } catch (l) {
139
- return f(i, "cancelation", n.drop), c && e.onResult(l), l instanceof Error && l.name === "AbortError" ? r({ message: "Request was cancelled", cancelled: !0 }) : r({ message: l instanceof Error ? l.message : "Unknown error occurred" });
153
+ return y(i, "cancelation", u.drop), a && e.onResult(l), l instanceof Error && l.name === "AbortError" ? r({ message: "Request was cancelled", cancelled: !0 }) : r({ message: l instanceof Error ? l.message : "Unknown error occurred" });
140
154
  }
141
155
  };
142
- return i.modules.includes("queryQueue") ? O.enqueue(a) : a();
156
+ return i.modules.includes("queryQueue") ? O.enqueue(c) : c();
143
157
  }
144
158
  );
145
159
  function Q(e) {
146
- return y(e) && Array.isArray(e.data) && typeof e.primaryKey == "string";
160
+ return f(e) && Array.isArray(e.data) && typeof e.primaryKey == "string";
147
161
  }
148
162
  function U(e, r) {
149
163
  const s = {};
150
- for (const o of e)
151
- if (y(o) && r in o) {
152
- const t = String(o[r]);
153
- s[t] = o;
164
+ for (const n of e)
165
+ if (f(n) && r in n) {
166
+ const t = String(n[r]);
167
+ s[t] = n;
154
168
  }
155
169
  return s;
156
170
  }
157
- function v(e, r, s, o) {
158
- return s === "replace" ? r : s === "merge" ? b(e, r) : s === "skip" ? e : (console.warn(`Cdeebee: Unknown strategy "${s}" for key "${o}". Skipping normalization.`), b(e, r));
171
+ function I(e, r, s, n) {
172
+ return s === "replace" ? r : s === "merge" ? h(e, r) : s === "skip" ? e : (console.warn(`Cdeebee: Unknown strategy "${s}" for key "${n}". Skipping normalization.`), h(e, r));
159
173
  }
160
174
  function M(e, r, s) {
161
- const o = Object.keys(r), t = y(e.storage) ? e.storage : {}, u = { ...t }, i = /* @__PURE__ */ new Set();
162
- for (const n of o) {
163
- const c = r[n];
164
- if (c == null || typeof c == "string") {
165
- i.add(n);
175
+ const n = Object.keys(r), t = f(e.storage) ? e.storage : {}, o = { ...t }, i = /* @__PURE__ */ new Set();
176
+ for (const u of n) {
177
+ const a = r[u];
178
+ if (a == null || typeof a == "string") {
179
+ i.add(u);
166
180
  continue;
167
181
  }
168
- const a = s[n] ?? "merge";
169
- if (a === "skip" && !(n in t))
182
+ const c = s[u] ?? "merge";
183
+ if (c === "skip" && !(u in t))
170
184
  continue;
171
- const l = n in t ? t[n] : {};
172
- if (Q(c)) {
173
- const g = U(c.data, c.primaryKey);
174
- u[n] = v(l, g, a, n);
185
+ const l = u in t ? t[u] : {};
186
+ if (Q(a)) {
187
+ const g = U(a.data, a.primaryKey);
188
+ o[u] = I(l, g, c, u);
175
189
  continue;
176
190
  }
177
- y(c) ? u[n] = v(l, c, a, n) : u[n] = c;
191
+ f(a) ? o[u] = I(l, a, c, u) : o[u] = a;
178
192
  }
179
- return i.size > 0 ? C(Array.from(i), u) : u;
193
+ return i.size > 0 ? x(Array.from(i), o) : o;
180
194
  }
181
- const W = {
195
+ const F = {
182
196
  settings: {
183
197
  modules: ["history", "listener", "storage", "cancelation"],
184
198
  fileKey: "file",
@@ -191,108 +205,118 @@ const W = {
191
205
  request: {
192
206
  active: [],
193
207
  errors: {},
194
- done: {}
208
+ done: {},
209
+ lastResultIdList: {}
195
210
  }
196
- }, J = (e, r) => P({
211
+ }, X = (e, r) => H({
197
212
  name: "cdeebee",
198
- initialState: b(W, { settings: e, storage: r ?? {} }),
213
+ initialState: h(F, { settings: e, storage: r ?? {} }),
199
214
  reducers: {
200
- set(o, t) {
201
- E(o.storage, t.payload);
215
+ set(n, t) {
216
+ T(n.storage, t.payload);
202
217
  },
203
- historyClear(o, t) {
204
- const u = t.payload;
205
- u ? (delete o.request.done[u], delete o.request.errors[u]) : (o.request.done = {}, o.request.errors = {});
218
+ historyClear(n, t) {
219
+ const o = t.payload;
220
+ o ? (delete n.request.done[o], delete n.request.errors[o]) : (n.request.done = {}, n.request.errors = {});
206
221
  }
207
222
  },
208
- extraReducers: (o) => {
209
- o.addCase(S.pending, (t, u) => {
210
- const i = u.meta.arg.api, n = u.meta.requestId;
211
- u.meta.arg.historyClear && f(t.settings, "history", () => {
223
+ extraReducers: (n) => {
224
+ n.addCase(S.pending, (t, o) => {
225
+ const i = o.meta.arg.api, u = o.meta.requestId;
226
+ o.meta.arg.historyClear && y(t.settings, "history", () => {
212
227
  delete t.request.done[i], delete t.request.errors[i];
213
- }), f(t.settings, "cancelation", () => {
214
- T(i, n);
215
- }), f(t.settings, "listener", () => {
216
- t.request.active.push({ api: i, requestId: n });
228
+ }), y(t.settings, "cancelation", () => {
229
+ j(i, u);
230
+ }), y(t.settings, "listener", () => {
231
+ t.request.active.push({ api: i, requestId: u });
217
232
  });
218
- }).addCase(S.fulfilled, (t, u) => {
219
- const i = u.meta.requestId, n = u.meta.arg.api;
220
- f(t.settings, "listener", () => {
221
- t.request.active = t.request.active.filter((c) => !(c.api === n && c.requestId === i));
222
- }), f(t.settings, "history", () => {
223
- t.request.done[n] || (t.request.done[n] = []), t.request.done[n].push({ api: n, request: u.payload, requestId: i });
224
- }), f(t.settings, "storage", () => {
225
- if (u.meta.arg.ignore)
233
+ }).addCase(S.fulfilled, (t, o) => {
234
+ const i = o.meta.requestId, u = o.meta.arg.api;
235
+ y(t.settings, "listener", () => {
236
+ t.request.active = t.request.active.filter((a) => !(a.api === u && a.requestId === i));
237
+ }), y(t.settings, "history", () => {
238
+ t.request.done[u] || (t.request.done[u] = []), t.request.done[u].push({ api: u, request: o.payload, requestId: i });
239
+ }), y(t.settings, "storage", () => {
240
+ if (o.meta.arg.ignore)
226
241
  return;
227
- const c = u.meta.arg.listStrategy ?? t.settings.listStrategy ?? {}, a = u.meta.arg.normalize ?? t.settings.normalize ?? M, l = x(t), g = a(l, u.payload.result, c);
228
- t.storage = g;
242
+ const a = o.meta.arg.listStrategy ?? t.settings.listStrategy ?? {}, c = o.meta.arg.normalize ?? t.settings.normalize ?? M, l = P(t), g = c(l, o.payload.result, a);
243
+ t.storage = g, t.request.lastResultIdList[u] = N(o.payload.result);
229
244
  });
230
- }).addCase(S.rejected, (t, u) => {
231
- const i = u.meta.requestId, n = u.meta.arg.api;
232
- f(t.settings, "listener", () => {
233
- t.request.active = t.request.active.filter((c) => !(c.api === n && c.requestId === i));
234
- }), f(t.settings, "history", () => {
235
- t.request.errors[n] || (t.request.errors[n] = []), t.request.errors[n].push({ requestId: i, api: n, request: u.error });
245
+ }).addCase(S.rejected, (t, o) => {
246
+ const i = o.meta.requestId, u = o.meta.arg.api;
247
+ y(t.settings, "listener", () => {
248
+ t.request.active = t.request.active.filter((a) => !(a.api === u && a.requestId === i));
249
+ }), y(t.settings, "history", () => {
250
+ t.request.errors[u] || (t.request.errors[u] = []), t.request.errors[u].push({ requestId: i, api: u, request: o.error });
236
251
  });
237
252
  });
238
253
  }
239
254
  });
240
- function B(e) {
241
- function r(n) {
242
- return d((c) => e(c).request.active.some((l) => n.includes(l.api)));
255
+ function Y(e) {
256
+ function r(a) {
257
+ return d((c) => e(c).request.active.some((g) => a.includes(g.api)));
243
258
  }
244
- function s(n) {
245
- return d((c) => e(c).request.done[n] ?? []);
259
+ function s(a) {
260
+ return d((c) => e(c).request.done[a] ?? []);
246
261
  }
247
- function o(n) {
248
- return d((c) => e(c).request.errors[n] ?? []);
262
+ function n(a) {
263
+ return d((c) => e(c).request.errors[a] ?? []);
249
264
  }
250
- function t(n) {
251
- return d((c) => e(c).storage[n]);
265
+ function t(a) {
266
+ return d((c) => e(c).storage[a]);
252
267
  }
253
- function u() {
254
- return d((n) => e(n).storage);
268
+ function o() {
269
+ return d((a) => e(a).storage);
255
270
  }
256
271
  function i() {
257
- return d((n) => e(n).request.active.length > 0);
272
+ return d((a) => e(a).request.active.length > 0);
273
+ }
274
+ function u(a) {
275
+ return d((c) => e(c).request.lastResultIdList[a] ?? []);
258
276
  }
259
277
  return {
260
278
  useLoading: r,
261
279
  useRequestHistory: s,
262
- useRequestErrors: o,
280
+ useRequestErrors: n,
263
281
  useStorageList: t,
264
- useStorage: u,
265
- useIsLoading: i
282
+ useStorage: o,
283
+ useIsLoading: i,
284
+ useLastResultIdList: u
266
285
  };
267
286
  }
268
- function G(e) {
287
+ function Z(e) {
269
288
  return d((r) => r.cdeebee.request.active.some((s) => e.includes(s.api)));
270
289
  }
271
- function X(e) {
290
+ function _(e) {
272
291
  return d((r) => r.cdeebee.request.done[e] ?? []);
273
292
  }
274
- function Y(e) {
293
+ function V(e) {
275
294
  return d((r) => r.cdeebee.request.errors[e] ?? []);
276
295
  }
277
- function Z(e) {
296
+ function ee(e) {
278
297
  return d((r) => r.cdeebee.storage[e]);
279
298
  }
280
- function _() {
299
+ function te() {
281
300
  return d((e) => e.cdeebee.storage);
282
301
  }
283
- function V() {
302
+ function re() {
284
303
  return d((e) => e.cdeebee.request.active.length > 0);
285
304
  }
305
+ function ne(e) {
306
+ return d((r) => r.cdeebee.request.lastResultIdList[e] ?? []);
307
+ }
286
308
  export {
287
- E as batchingUpdate,
288
- B as createCdeebeeHooks,
289
- J as factory,
309
+ T as batchingUpdate,
310
+ Y as createCdeebeeHooks,
311
+ M as defaultNormalize,
312
+ X as factory,
290
313
  S as request,
291
- V as useIsLoading,
292
- G as useLoading,
293
- Y as useRequestErrors,
294
- X as useRequestHistory,
295
- _ as useStorage,
296
- Z as useStorageList
314
+ re as useIsLoading,
315
+ ne as useLastResultIdList,
316
+ Z as useLoading,
317
+ V as useRequestErrors,
318
+ _ as useRequestHistory,
319
+ te as useStorage,
320
+ ee as useStorageList
297
321
  };
298
322
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../lib/reducer/helpers.ts","../lib/reducer/abortController.ts","../lib/reducer/queryQueue.ts","../lib/reducer/request.ts","../lib/reducer/storage.ts","../lib/reducer/index.ts","../lib/hooks.ts"],"sourcesContent":["import { type WritableDraft } from '@reduxjs/toolkit';\nimport { type CdeebeeSettings, type CdeebeeModule, CdeebeeValueList } from './types';\n\nexport function checkModule(settings: CdeebeeSettings<unknown> | WritableDraft<CdeebeeSettings<unknown>>, module: CdeebeeModule, result: () => void) {\n if (settings.modules.includes(module)) {\n result();\n }\n}\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport function hasDataProperty(value: unknown): value is Record<string, unknown> & { data: unknown[] } {\n return isRecord(value) && Array.isArray(value.data);\n}\n\nexport function hasProperty(value: unknown, prop: string): boolean {\n return isRecord(value) && Object.prototype.hasOwnProperty.call(value, prop);\n}\n\nexport function mergeDeepRight<T>(\n left: T,\n right: Partial<T> | Record<string, unknown>\n): T {\n if (!isRecord(left) || !isRecord(right)) {\n return right as T;\n }\n\n const result = { ...left } as Record<string, unknown>;\n const rightRecord = right as Record<string, unknown>;\n\n for (const key in rightRecord) {\n if (Object.prototype.hasOwnProperty.call(rightRecord, key)) {\n const leftValue = result[key];\n const rightValue = rightRecord[key];\n\n if (\n isRecord(leftValue) &&\n isRecord(rightValue) &&\n !Array.isArray(leftValue) &&\n !Array.isArray(rightValue)\n ) {\n result[key] = mergeDeepRight(leftValue, rightValue);\n } else {\n result[key] = rightValue;\n }\n }\n }\n\n return result as T;\n}\n\nexport function omit<T extends Record<string, unknown>>(keys: string[], obj: T): Omit<T, keyof T> {\n const result = { ...obj };\n for (const key of keys) {\n delete result[key];\n }\n return result as Omit<T, keyof T>;\n}\n\nexport function assocPath<T>(path: (string | number)[], value: unknown, obj: T): T {\n if (path.length === 0) {\n return value as T;\n }\n\n const [first, ...rest] = path;\n const firstKey = String(first);\n const result = Array.isArray(obj) ? [...obj] : { ...obj } as Record<string, unknown>;\n\n if (rest.length === 0) {\n (result as Record<string, unknown>)[firstKey] = value;\n } else {\n const currentValue = (result as Record<string, unknown>)[firstKey];\n (result as Record<string, unknown>)[firstKey] = assocPath(rest, value, currentValue ?? {});\n }\n\n return result as T;\n}\n\nexport function batchingUpdate<T extends Record<string, unknown>>(\n state: T,\n valueList: CdeebeeValueList<T>\n): void {\n for (let i = 0; i < valueList.length; i++) {\n const item = valueList[i] as { key: readonly (string | number)[]; value: unknown };\n const path = item.key;\n const value = item.value;\n \n if (path.length === 0) {\n continue;\n }\n\n let current: Record<string, unknown> | unknown[] = state as Record<string, unknown>;\n \n for (let j = 0; j < path.length - 1; j++) {\n const pathKey = path[j];\n \n if (Array.isArray(current)) {\n const index = typeof pathKey === 'number' ? pathKey : Number(pathKey);\n if (!(index in current) || !isRecord(current[index])) {\n current[index] = {};\n }\n current = current[index] as Record<string, unknown>;\n } else {\n const key = String(pathKey);\n if (!(key in current)) {\n const nextIsNumeric = typeof path[j + 1] === 'number' || (!isNaN(Number(path[j + 1])) && String(Number(path[j + 1])) === String(path[j + 1]));\n current[key] = nextIsNumeric ? [] : {};\n }\n const next = current[key];\n current = (Array.isArray(next) ? next : (isRecord(next) ? next : {})) as Record<string, unknown> | unknown[];\n }\n }\n \n if (Array.isArray(current)) {\n continue; // Can't update array element directly\n }\n current[String(path[path.length - 1])] = value;\n }\n}\n","interface RequestController {\n requestId: string;\n controller: AbortController;\n api: string;\n}\n\nclass AbortControllerStore {\n private byRequestId = new Map<string, RequestController>();\n private byApi = new Map<string, Set<string>>();\n\n add(api: string, requestId: string, controller: AbortController): void {\n const item: RequestController = { requestId, controller, api };\n this.byRequestId.set(requestId, item);\n\n if (!this.byApi.has(api)) {\n this.byApi.set(api, new Set());\n }\n this.byApi.get(api)!.add(requestId);\n }\n\n delete(requestId: string): void {\n const item = this.byRequestId.get(requestId);\n if (!item) return;\n\n this.byRequestId.delete(requestId);\n const apiSet = this.byApi.get(item.api);\n if (apiSet) {\n apiSet.delete(requestId);\n if (apiSet.size === 0) {\n this.byApi.delete(item.api);\n }\n }\n }\n\n abortAllForApi(api: string, excludeRequestId: string): void {\n const requestIds = this.byApi.get(api);\n if (!requestIds) return;\n\n requestIds.forEach(requestId => {\n if (requestId !== excludeRequestId) {\n const item = this.byRequestId.get(requestId);\n if (item) {\n item.controller.abort();\n this.delete(requestId);\n }\n }\n });\n }\n}\n\nconst abortStore = new AbortControllerStore();\n\nexport function abortQuery(api: string, currentRequestId: string): void {\n abortStore.abortAllForApi(api, currentRequestId);\n}\n\nexport function abortManager(signal: AbortSignal, api: string, requestId: string) {\n const controller = new AbortController();\n\n const cleanup = () => {\n abortStore.delete(requestId);\n };\n\n signal.addEventListener('abort', () => {\n controller.abort();\n cleanup();\n });\n\n return {\n controller,\n init: () => abortStore.add(api, requestId, controller),\n drop: cleanup,\n };\n}\n","class QueryQueue {\n private currentPromise: Promise<unknown> = Promise.resolve();\n private queueLength = 0;\n\n async enqueue<T>(task: () => Promise<T>): Promise<T> {\n this.queueLength++;\n \n const previousPromise = this.currentPromise;\n \n this.currentPromise = previousPromise\n .then(() => task(), () => task())\n .finally(() => {\n this.queueLength--;\n });\n\n return this.currentPromise as Promise<T>;\n }\n\n getQueueLength(): number {\n return this.queueLength;\n }\n\n clear(): void {\n this.queueLength = 0;\n }\n}\n\nexport const queryQueue = new QueryQueue();\n\n","import { createAsyncThunk } from '@reduxjs/toolkit';\nimport { checkModule } from './helpers';\nimport { abortManager } from './abortController';\nimport { queryQueue } from './queryQueue';\nimport { type CdeebeeState, type CdeebeeRequestOptions } from './types';\n\nexport const request = createAsyncThunk(\n 'cdeebee/request',\n async (options: CdeebeeRequestOptions<unknown>, { rejectWithValue, getState, requestId, signal }) => {\n const startedAt = new Date().toUTCString();\n const { cdeebee: { settings } } = getState() as { cdeebee: CdeebeeState<unknown> };\n\n const abort = abortManager(signal, options.api, requestId);\n const withCallback = options.onResult && typeof options.onResult === 'function';\n\n checkModule(settings, 'cancelation', abort.init);\n\n const executeRequest = async () => {\n try {\n const { method = 'POST', body, headers = {} } = options;\n const extraHeaders: Record<string, string> = { ...(settings.mergeWithHeaders ?? {}), ...headers };\n\n const b = { ...(settings.mergeWithData ?? {}), ...(body ?? {}) };\n let requestData: FormData | string = JSON.stringify(b);\n\n // handling files\n if (options.files) {\n const formData = new FormData();\n const fileKey = options.fileKey || settings.fileKey;\n const bodyKey = options.bodyKey || settings.bodyKey;\n\n for (let i = 0; i < options.files.length; i += 1) {\n if (fileKey) {\n formData.append(fileKey, options.files[i]);\n }\n }\n\n if (bodyKey) {\n formData.append(bodyKey, requestData);\n }\n requestData = formData;\n }\n // [end] handling files\n \n const response = await fetch(options.api, {\n method,\n headers: {\n 'ui-request-id': requestId,\n 'Content-Type': 'application/json',\n ...extraHeaders,\n },\n signal: abort.controller.signal,\n body: requestData,\n });\n\n checkModule(settings, 'cancelation', abort.drop);\n\n let result: unknown;\n const responseType = options.responseType || 'json';\n \n if (responseType === 'text') {\n result = await response.text();\n } else if (responseType === 'blob') {\n result = await response.blob();\n } else {\n // default: json\n result = await response.json();\n }\n\n if (!response.ok) {\n if (withCallback) options.onResult!(result);\n return rejectWithValue(response);\n }\n\n if (withCallback) options.onResult!(result);\n return { result, startedAt, endedAt: new Date().toUTCString() };\n } catch (error) {\n checkModule(settings, 'cancelation', abort.drop);\n\n if (withCallback) options.onResult!(error); \n\n if (error instanceof Error && error.name === 'AbortError') {\n return rejectWithValue({ message: 'Request was cancelled', cancelled: true });\n }\n\n return rejectWithValue({ message: error instanceof Error ? error.message : 'Unknown error occurred' });\n }\n };\n\n if (settings.modules.includes('queryQueue')) {\n return queryQueue.enqueue(executeRequest);\n }\n\n return executeRequest();\n },\n);\n\n","import { type CdeebeeListStrategy, type CdeebeeState } from './types';\nimport { isRecord, mergeDeepRight, omit } from './helpers';\n\ntype ResponseValue = Record<string, unknown>;\n\ntype IResponse = Record<string, ResponseValue>;\n\ntype StorageData = Record<string, unknown>;\n\nfunction isDataWithPrimaryKey(value: unknown): value is { data: unknown[]; primaryKey: string } {\n return (\n isRecord(value) &&\n Array.isArray(value.data) &&\n typeof value.primaryKey === 'string'\n );\n}\nfunction normalizeDataWithPrimaryKey(data: unknown[], primaryKey: string): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n \n for (const item of data) {\n if (isRecord(item) && primaryKey in item) {\n const key = String(item[primaryKey]);\n result[key] = item;\n }\n }\n \n return result;\n}\n\nfunction applyStrategy(\n existingValue: StorageData,\n newValue: StorageData | ResponseValue,\n strategy: string,\n key: string\n): ResponseValue {\n if (strategy === 'replace') {\n return newValue as ResponseValue;\n } else if (strategy === 'merge') {\n return mergeDeepRight(existingValue, newValue as StorageData) as ResponseValue;\n } else if (strategy === 'skip') {\n return existingValue as ResponseValue;\n } else {\n console.warn(`Cdeebee: Unknown strategy \"${strategy}\" for key \"${key}\". Skipping normalization.`);\n return mergeDeepRight(existingValue, newValue as StorageData) as ResponseValue;\n }\n}\n\nexport function defaultNormalize<T>(\n cdeebee: CdeebeeState<T>,\n response: IResponse,\n strategyList: CdeebeeListStrategy<T> \n): Record<string, ResponseValue> {\n const keyList = Object.keys(response);\n const currentStorage = isRecord(cdeebee.storage) ? (cdeebee.storage as Record<string, unknown>) : {};\n \n const result = { ...currentStorage } as Record<string, ResponseValue>;\n const keyListToOmit = new Set<string>();\n\n for (const key of keyList) {\n const responseValue = response[key];\n\n if (responseValue === null || responseValue === undefined || typeof responseValue === 'string') {\n keyListToOmit.add(key);\n continue;\n }\n\n const strategy = strategyList[key as keyof T] ?? 'merge';\n \n // For 'skip' strategy, if key doesn't exist in storage, skip it entirely\n if (strategy === 'skip' && !(key in currentStorage)) {\n continue;\n }\n \n const existingValue = key in currentStorage ? (currentStorage[key] as StorageData) : {};\n\n if (isDataWithPrimaryKey(responseValue)) {\n const normalizedValue = normalizeDataWithPrimaryKey(responseValue.data, responseValue.primaryKey);\n result[key] = applyStrategy(existingValue, normalizedValue, strategy, key);\n continue;\n }\n\n if (isRecord(responseValue)) {\n result[key] = applyStrategy(existingValue, responseValue as StorageData, strategy, key);\n } else {\n result[key] = responseValue;\n }\n }\n\n return keyListToOmit.size > 0 ? omit(Array.from(keyListToOmit), result) : result;\n}\n","import { createSlice, current, type PayloadAction } from '@reduxjs/toolkit';\n\nimport { type CdeebeeSettings, type CdeebeeState, type CdeebeeValueList, type CdeebeeListStrategy } from './types';\nimport { checkModule, mergeDeepRight, batchingUpdate } from './helpers';\nimport { abortQuery } from './abortController';\nimport { request } from './request';\nimport { defaultNormalize } from './storage';\n\nconst initialState: CdeebeeState<unknown> = {\n settings: {\n modules: ['history', 'listener', 'storage', 'cancelation'],\n fileKey: 'file',\n bodyKey: 'value',\n listStrategy: {},\n mergeWithData: {},\n mergeWithHeaders: {},\n },\n storage: {},\n request: {\n active: [],\n errors: {},\n done: {}\n },\n};\n\nexport const factory = <T>(settings: CdeebeeSettings<T>, storage?: T) => {\n const slice = createSlice({\n name: 'cdeebee',\n initialState: mergeDeepRight(initialState, { settings, storage: storage ?? {} }) as CdeebeeState<T>,\n reducers: {\n set(state, action: { payload: CdeebeeValueList<T> }) {\n // Directly mutate state.storage using Immer Draft\n // This is more performant than creating a new object\n // Immer will track changes and create minimal updates\n batchingUpdate(state.storage as Record<string, unknown>, action.payload);\n },\n historyClear(state, action: PayloadAction<string | undefined>) {\n const api = action.payload;\n\n if (api) {\n delete state.request.done[api];\n delete state.request.errors[api];\n } else {\n state.request.done = {};\n state.request.errors = {};\n }\n }\n },\n extraReducers: builder => {\n builder\n .addCase(request.pending, (state, action) => {\n const api = action.meta.arg.api;\n const requestId = action.meta.requestId;\n\n if (action.meta.arg.historyClear) {\n checkModule(state.settings, 'history', () => {\n delete state.request.done[api];\n delete state.request.errors[api];\n });\n }\n\n checkModule(state.settings, 'cancelation', () => {\n abortQuery(api, requestId);\n });\n checkModule(state.settings, 'listener', () => {\n state.request.active.push({ api, requestId });\n });\n })\n .addCase(request.fulfilled, (state, action) => {\n const requestId = action.meta.requestId;\n const api = action.meta.arg.api;\n\n checkModule(state.settings, 'listener', () => {\n state.request.active = state.request.active.filter(q => !(q.api === api && q.requestId === requestId));\n });\n checkModule(state.settings, 'history', () => {\n if (!state.request.done[api]) state.request.done[api] = [];\n state.request.done[api].push({ api, request: action.payload, requestId });\n });\n checkModule(state.settings, 'storage', () => {\n if (action.meta.arg.ignore) {\n return;\n }\n \n const strategyList = (action.meta.arg.listStrategy ?? state.settings.listStrategy ?? {}) as CdeebeeListStrategy<T>;\n const normalize = action.meta.arg.normalize ?? state.settings.normalize ?? defaultNormalize;\n\n const currentState = current(state) as CdeebeeState<T>;\n // Type assertion is safe here because we've already checked isRecord\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const normalizedData = normalize(currentState, action.payload.result as any, strategyList);\n\n // Normalize already handles merge/replace/skip and preserves keys not in response\n // Simply apply the result\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (state.storage as any) = normalizedData;\n });\n })\n .addCase(request.rejected, (state, action) => {\n const requestId = action.meta.requestId;\n const api = action.meta.arg.api;\n\n checkModule(state.settings, 'listener', () => {\n state.request.active = state.request.active.filter(q => !(q.api === api && q.requestId === requestId));\n });\n checkModule(state.settings, 'history', () => {\n if (!state.request.errors[api]) state.request.errors[api] = [];\n state.request.errors[api].push({ requestId: requestId, api, request: action.error });\n });\n });\n },\n });\n\n return slice;\n};\n","import { useSelector } from 'react-redux';\nimport { type CdeebeeState } from './reducer/types';\n\n/**\n * Generic hook factory that creates a selector hook for cdeebee state.\n * This allows the hooks to work with any Redux root state structure.\n *\n * @template RootState - The shape of the Redux root state\n * @template Storage - The shape of the cdeebee storage\n * @param selectCdeebee - Function to select the cdeebee slice from root state\n * @returns An object containing all cdeebee hooks\n */\nexport function createCdeebeeHooks<RootState, Storage>(\n selectCdeebee: (state: RootState) => CdeebeeState<Storage>\n) {\n /**\n * Check if any of the specified APIs are currently loading.\n *\n * @param apiList - Array of API endpoints to check\n * @returns true if any of the APIs are currently active/loading\n *\n * @example\n * const isLoading = useLoading(['/api/forums', '/api/threads']);\n * if (isLoading) return <Spinner />;\n */\n function useLoading(apiList: string[]): boolean {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.active.some(q => apiList.includes(q.api));\n });\n }\n\n /**\n * Get the successful request history for a specific API endpoint.\n *\n * @param api - The API endpoint\n * @returns Array of successful request history entries\n *\n * @example\n * const history = useRequestHistory('/api/forums');\n * console.log(`Made ${history.length} successful requests`);\n */\n function useRequestHistory(api: string) {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.done[api] ?? [];\n });\n }\n\n /**\n * Get the error history for a specific API endpoint.\n *\n * @param api - The API endpoint\n * @returns Array of error history entries\n *\n * @example\n * const errors = useRequestErrors('/api/forums');\n * if (errors.length > 0) {\n * console.error('Last error:', errors[errors.length - 1]);\n * }\n */\n function useRequestErrors(api: string) {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.errors[api] ?? [];\n });\n }\n\n /**\n * Get a specific list from storage with full type safety.\n *\n * @param listName - The name of the list in storage\n * @returns The list data\n *\n * @example\n * const forums = useStorageList('forumList');\n * const forumArray = Object.values(forums);\n */\n function useStorageList<K extends keyof Storage>(listName: K): Storage[K] {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.storage[listName];\n });\n }\n\n /**\n * Get the entire cdeebee storage.\n *\n * @returns The complete storage object\n *\n * @example\n * const storage = useStorage();\n * console.log(Object.keys(storage)); // ['forumList', 'threadList', ...]\n */\n function useStorage(): Storage {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.storage;\n });\n }\n\n /**\n * Check if any request is currently loading (across all APIs).\n *\n * @returns true if any request is active\n *\n * @example\n * const isAnythingLoading = useIsLoading();\n * if (isAnythingLoading) return <GlobalSpinner />;\n */\n function useIsLoading(): boolean {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.active.length > 0;\n });\n }\n\n return {\n useLoading,\n useRequestHistory,\n useRequestErrors,\n useStorageList,\n useStorage,\n useIsLoading,\n };\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param apiList - Array of API endpoints to check\n * @returns true if any of the APIs are currently active/loading\n *\n * @example\n * const isLoading = useLoading(['/api/forums', '/api/threads']);\n */\nexport function useLoading<Storage = unknown>(apiList: string[]): boolean {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.active.some(q => apiList.includes(q.api));\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param api - The API endpoint\n * @returns Array of successful request history entries\n */\nexport function useRequestHistory<Storage = unknown>(api: string) {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.done[api] ?? [];\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param api - The API endpoint\n * @returns Array of error history entries\n */\nexport function useRequestErrors<Storage = unknown>(api: string) {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.errors[api] ?? [];\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param listName - The name of the list in storage\n * @returns The list data\n */\nexport function useStorageList<Storage, K extends keyof Storage>(listName: K): Storage[K] {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.storage[listName];\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @returns The complete storage object\n */\nexport function useStorage<Storage>(): Storage {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.storage;\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @returns true if any request is active\n */\nexport function useIsLoading<Storage = unknown>(): boolean {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.active.length > 0;\n });\n}\n"],"names":["checkModule","settings","module","result","isRecord","value","mergeDeepRight","left","right","rightRecord","key","leftValue","rightValue","omit","keys","obj","batchingUpdate","state","valueList","i","item","path","current","j","pathKey","index","nextIsNumeric","next","AbortControllerStore","api","requestId","controller","apiSet","excludeRequestId","requestIds","abortStore","abortQuery","currentRequestId","abortManager","signal","cleanup","QueryQueue","task","previousPromise","queryQueue","request","createAsyncThunk","options","rejectWithValue","getState","startedAt","abort","withCallback","executeRequest","method","body","headers","extraHeaders","b","requestData","formData","fileKey","bodyKey","response","responseType","error","isDataWithPrimaryKey","normalizeDataWithPrimaryKey","data","primaryKey","applyStrategy","existingValue","newValue","strategy","defaultNormalize","cdeebee","strategyList","keyList","currentStorage","keyListToOmit","responseValue","normalizedValue","initialState","factory","storage","createSlice","action","builder","q","normalize","currentState","normalizedData","createCdeebeeHooks","selectCdeebee","useLoading","apiList","useSelector","useRequestHistory","useRequestErrors","useStorageList","listName","useStorage","useIsLoading"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../lib/reducer/helpers.ts","../lib/reducer/abortController.ts","../lib/reducer/queryQueue.ts","../lib/reducer/request.ts","../lib/reducer/storage.ts","../lib/reducer/index.ts","../lib/hooks/createCdeebeeHooks.ts","../lib/hooks/selectors.ts"],"sourcesContent":["import { type WritableDraft } from '@reduxjs/toolkit';\nimport { type CdeebeeSettings, type CdeebeeModule, CdeebeeValueList } from './types';\n\nexport function checkModule(settings: CdeebeeSettings<unknown> | WritableDraft<CdeebeeSettings<unknown>>, module: CdeebeeModule, result: () => void) {\n if (settings.modules.includes(module)) {\n result();\n }\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport function mergeDeepRight<T>(\n left: T,\n right: Partial<T> | Record<string, unknown>\n): T {\n if (!isRecord(left) || !isRecord(right)) {\n return right as T;\n }\n\n const result = { ...left } as Record<string, unknown>;\n const rightRecord = right as Record<string, unknown>;\n\n for (const key in rightRecord) {\n if (Object.prototype.hasOwnProperty.call(rightRecord, key)) {\n const leftValue = result[key];\n const rightValue = rightRecord[key];\n\n if (\n isRecord(leftValue) &&\n isRecord(rightValue) &&\n !Array.isArray(leftValue) &&\n !Array.isArray(rightValue)\n ) {\n result[key] = mergeDeepRight(leftValue, rightValue);\n } else {\n result[key] = rightValue;\n }\n }\n }\n\n return result as T;\n}\n\nexport function omit<T extends Record<string, unknown>>(keys: string[], obj: T): Omit<T, keyof T> {\n const result = { ...obj };\n for (const key of keys) {\n delete result[key];\n }\n return result as Omit<T, keyof T>;\n}\n\n/**\n * Extract primary key values from API response data.\n * Handles responses with format: { listName: { data: [...], primaryKey: 'id' } }\n * Returns a flat array of all extracted IDs from all lists.\n */\nexport function extractResultIdList(response: unknown): string[] {\n if (!isRecord(response)) {\n return [];\n }\n\n const ids: string[] = [];\n\n for (const key of Object.keys(response)) {\n const value = response[key];\n\n if (\n isRecord(value) &&\n Array.isArray(value.data) &&\n typeof value.primaryKey === 'string'\n ) {\n const primaryKey = value.primaryKey;\n for (const item of value.data) {\n if (isRecord(item) && primaryKey in item) {\n ids.push(String(item[primaryKey]));\n }\n }\n }\n }\n\n return ids;\n}\n\nexport function batchingUpdate<T extends Record<string, unknown>>(\n state: T,\n valueList: CdeebeeValueList<T>\n): void {\n for (let i = 0; i < valueList.length; i++) {\n const item = valueList[i] as { key: readonly (string | number)[]; value: unknown };\n const path = item.key;\n const value = item.value;\n\n if (path.length === 0) {\n continue;\n }\n\n let current: Record<string, unknown> | unknown[] = state as Record<string, unknown>;\n\n for (let j = 0; j < path.length - 1; j++) {\n const pathKey = path[j];\n\n if (Array.isArray(current)) {\n const index = typeof pathKey === 'number' ? pathKey : Number(pathKey);\n if (!(index in current) || !isRecord(current[index])) {\n current[index] = {};\n }\n current = current[index] as Record<string, unknown>;\n } else {\n const key = String(pathKey);\n if (!(key in current)) {\n const nextIsNumeric = typeof path[j + 1] === 'number' || (!isNaN(Number(path[j + 1])) && String(Number(path[j + 1])) === String(path[j + 1]));\n current[key] = nextIsNumeric ? [] : {};\n }\n const next = current[key];\n current = (Array.isArray(next) ? next : (isRecord(next) ? next : {})) as Record<string, unknown> | unknown[];\n }\n }\n\n if (Array.isArray(current)) {\n continue; // Can't update array element directly\n }\n current[String(path[path.length - 1])] = value;\n }\n}\n","interface RequestController {\n requestId: string;\n controller: AbortController;\n api: string;\n}\n\nclass AbortControllerStore {\n private byRequestId = new Map<string, RequestController>();\n private byApi = new Map<string, Set<string>>();\n\n add(api: string, requestId: string, controller: AbortController): void {\n const item: RequestController = { requestId, controller, api };\n this.byRequestId.set(requestId, item);\n\n if (!this.byApi.has(api)) {\n this.byApi.set(api, new Set());\n }\n this.byApi.get(api)!.add(requestId);\n }\n\n delete(requestId: string): void {\n const item = this.byRequestId.get(requestId);\n if (!item) return;\n\n this.byRequestId.delete(requestId);\n const apiSet = this.byApi.get(item.api);\n if (apiSet) {\n apiSet.delete(requestId);\n if (apiSet.size === 0) {\n this.byApi.delete(item.api);\n }\n }\n }\n\n abortAllForApi(api: string, excludeRequestId: string): void {\n const requestIds = this.byApi.get(api);\n if (!requestIds) return;\n\n requestIds.forEach(requestId => {\n if (requestId !== excludeRequestId) {\n const item = this.byRequestId.get(requestId);\n if (item) {\n item.controller.abort();\n this.delete(requestId);\n }\n }\n });\n }\n}\n\nconst abortStore = new AbortControllerStore();\n\nexport function abortQuery(api: string, currentRequestId: string): void {\n abortStore.abortAllForApi(api, currentRequestId);\n}\n\nexport function abortManager(signal: AbortSignal, api: string, requestId: string) {\n const controller = new AbortController();\n\n const cleanup = () => {\n abortStore.delete(requestId);\n };\n\n signal.addEventListener('abort', () => {\n controller.abort();\n cleanup();\n });\n\n return {\n controller,\n init: () => abortStore.add(api, requestId, controller),\n drop: cleanup,\n };\n}\n","class QueryQueue {\n private currentPromise: Promise<unknown> = Promise.resolve();\n private queueLength = 0;\n\n async enqueue<T>(task: () => Promise<T>): Promise<T> {\n this.queueLength++;\n\n const previousPromise = this.currentPromise;\n\n this.currentPromise = previousPromise\n .then(() => task(), () => task())\n .finally(() => {\n this.queueLength--;\n });\n\n return this.currentPromise as Promise<T>;\n }\n\n getQueueLength(): number {\n return this.queueLength;\n }\n\n clear(): void {\n this.queueLength = 0;\n }\n}\n\nexport const queryQueue = new QueryQueue();\n\n","import { createAsyncThunk } from '@reduxjs/toolkit';\nimport { checkModule } from './helpers';\nimport { abortManager } from './abortController';\nimport { queryQueue } from './queryQueue';\nimport { type CdeebeeState, type CdeebeeRequestOptions } from './types';\n\nexport const request = createAsyncThunk(\n 'cdeebee/request',\n async (options: CdeebeeRequestOptions<unknown>, { rejectWithValue, getState, requestId, signal }) => {\n const startedAt = new Date().toUTCString();\n const { cdeebee: { settings } } = getState() as { cdeebee: CdeebeeState<unknown> };\n\n const abort = abortManager(signal, options.api, requestId);\n const withCallback = options.onResult && typeof options.onResult === 'function';\n\n checkModule(settings, 'cancelation', abort.init);\n\n const executeRequest = async () => {\n try {\n const { method = 'POST', body, headers = {} } = options;\n const baseHeaders = typeof settings.mergeWithHeaders === 'function'\n ? settings.mergeWithHeaders()\n : (settings.mergeWithHeaders ?? {});\n\n const extraHeaders: Record<string, string> = { ...baseHeaders, ...headers };\n\n const baseData = typeof settings.mergeWithData === 'function'\n ? settings.mergeWithData()\n : (settings.mergeWithData ?? {});\n\n const b = { ...baseData, ...(body ?? {}) };\n let requestData: FormData | string = JSON.stringify(b);\n\n // handling files\n if (options.files) {\n const formData = new FormData();\n const fileKey = options.fileKey || settings.fileKey;\n const bodyKey = options.bodyKey || settings.bodyKey;\n\n for (let i = 0; i < options.files.length; i += 1) {\n if (fileKey) {\n formData.append(fileKey, options.files[i]);\n }\n }\n\n if (bodyKey) {\n formData.append(bodyKey, requestData);\n }\n requestData = formData;\n }\n // [end] handling files\n\n const response = await fetch(options.api, {\n method,\n headers: {\n 'ui-request-id': requestId,\n 'Content-Type': 'application/json',\n ...extraHeaders,\n },\n signal: abort.controller.signal,\n body: requestData,\n });\n\n checkModule(settings, 'cancelation', abort.drop);\n\n let result: unknown;\n const responseType = options.responseType || 'json';\n\n if (responseType === 'text') {\n result = await response.text();\n } else if (responseType === 'blob') {\n result = await response.blob();\n } else {\n // default: json\n result = await response.json();\n }\n\n if (!response.ok) {\n if (withCallback) options.onResult!(result);\n return rejectWithValue(response);\n }\n\n if (withCallback) options.onResult!(result);\n return { result, startedAt, endedAt: new Date().toUTCString() };\n } catch (error) {\n checkModule(settings, 'cancelation', abort.drop);\n\n if (withCallback) options.onResult!(error);\n\n if (error instanceof Error && error.name === 'AbortError') {\n return rejectWithValue({ message: 'Request was cancelled', cancelled: true });\n }\n\n return rejectWithValue({ message: error instanceof Error ? error.message : 'Unknown error occurred' });\n }\n };\n\n if (settings.modules.includes('queryQueue')) {\n return queryQueue.enqueue(executeRequest);\n }\n\n return executeRequest();\n },\n);\n\n","import { type CdeebeeListStrategy, type CdeebeeState } from './types';\nimport { isRecord, mergeDeepRight, omit } from './helpers';\n\ntype ResponseValue = Record<string, unknown>;\n\ntype IResponse = Record<string, ResponseValue>;\n\ntype StorageData = Record<string, unknown>;\n\nfunction isDataWithPrimaryKey(value: unknown): value is { data: unknown[]; primaryKey: string } {\n return (\n isRecord(value) &&\n Array.isArray(value.data) &&\n typeof value.primaryKey === 'string'\n );\n}\nfunction normalizeDataWithPrimaryKey(data: unknown[], primaryKey: string): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n \n for (const item of data) {\n if (isRecord(item) && primaryKey in item) {\n const key = String(item[primaryKey]);\n result[key] = item;\n }\n }\n \n return result;\n}\n\nfunction applyStrategy(\n existingValue: StorageData,\n newValue: StorageData | ResponseValue,\n strategy: string,\n key: string\n): ResponseValue {\n if (strategy === 'replace') {\n return newValue as ResponseValue;\n } else if (strategy === 'merge') {\n return mergeDeepRight(existingValue, newValue as StorageData) as ResponseValue;\n } else if (strategy === 'skip') {\n return existingValue as ResponseValue;\n } else {\n console.warn(`Cdeebee: Unknown strategy \"${strategy}\" for key \"${key}\". Skipping normalization.`);\n return mergeDeepRight(existingValue, newValue as StorageData) as ResponseValue;\n }\n}\n\nexport function defaultNormalize<T>(\n cdeebee: CdeebeeState<T>,\n response: IResponse,\n strategyList: CdeebeeListStrategy<T> \n): Record<string, ResponseValue> {\n const keyList = Object.keys(response);\n const currentStorage = isRecord(cdeebee.storage) ? (cdeebee.storage as Record<string, unknown>) : {};\n \n const result = { ...currentStorage } as Record<string, ResponseValue>;\n const keyListToOmit = new Set<string>();\n\n for (const key of keyList) {\n const responseValue = response[key];\n\n if (responseValue === null || responseValue === undefined || typeof responseValue === 'string') {\n keyListToOmit.add(key);\n continue;\n }\n\n const strategy = strategyList[key as keyof T] ?? 'merge';\n \n // For 'skip' strategy, if key doesn't exist in storage, skip it entirely\n if (strategy === 'skip' && !(key in currentStorage)) {\n continue;\n }\n \n const existingValue = key in currentStorage ? (currentStorage[key] as StorageData) : {};\n\n if (isDataWithPrimaryKey(responseValue)) {\n const normalizedValue = normalizeDataWithPrimaryKey(responseValue.data, responseValue.primaryKey);\n result[key] = applyStrategy(existingValue, normalizedValue, strategy, key);\n continue;\n }\n\n if (isRecord(responseValue)) {\n result[key] = applyStrategy(existingValue, responseValue as StorageData, strategy, key);\n } else {\n result[key] = responseValue;\n }\n }\n\n return keyListToOmit.size > 0 ? omit(Array.from(keyListToOmit), result) : result;\n}\n","import { createSlice, current, type PayloadAction } from '@reduxjs/toolkit';\n\nimport { type CdeebeeSettings, type CdeebeeState, type CdeebeeValueList, type CdeebeeListStrategy } from './types';\nimport { checkModule, mergeDeepRight, batchingUpdate, extractResultIdList } from './helpers';\nimport { abortQuery } from './abortController';\nimport { request } from './request';\nimport { defaultNormalize } from './storage';\n\nconst initialState: CdeebeeState<unknown> = {\n settings: {\n modules: ['history', 'listener', 'storage', 'cancelation'],\n fileKey: 'file',\n bodyKey: 'value',\n listStrategy: {},\n mergeWithData: {},\n mergeWithHeaders: {},\n },\n storage: {},\n request: {\n active: [],\n errors: {},\n done: {},\n lastResultIdList: {},\n },\n};\n\nexport const factory = <T>(settings: CdeebeeSettings<T>, storage?: T) => {\n const slice = createSlice({\n name: 'cdeebee',\n initialState: mergeDeepRight(initialState, { settings, storage: storage ?? {} }) as CdeebeeState<T>,\n reducers: {\n set(state, action: { payload: CdeebeeValueList<T> }) {\n // Directly mutate state.storage using Immer Draft\n // This is more performant than creating a new object\n // Immer will track changes and create minimal updates\n batchingUpdate(state.storage as Record<string, unknown>, action.payload);\n },\n historyClear(state, action: PayloadAction<string | undefined>) {\n const api = action.payload;\n\n if (api) {\n delete state.request.done[api];\n delete state.request.errors[api];\n } else {\n state.request.done = {};\n state.request.errors = {};\n }\n }\n },\n extraReducers: builder => {\n builder\n .addCase(request.pending, (state, action) => {\n const api = action.meta.arg.api;\n const requestId = action.meta.requestId;\n\n if (action.meta.arg.historyClear) {\n checkModule(state.settings, 'history', () => {\n delete state.request.done[api];\n delete state.request.errors[api];\n });\n }\n\n checkModule(state.settings, 'cancelation', () => {\n abortQuery(api, requestId);\n });\n checkModule(state.settings, 'listener', () => {\n state.request.active.push({ api, requestId });\n });\n })\n .addCase(request.fulfilled, (state, action) => {\n const requestId = action.meta.requestId;\n const api = action.meta.arg.api;\n\n checkModule(state.settings, 'listener', () => {\n state.request.active = state.request.active.filter(q => !(q.api === api && q.requestId === requestId));\n });\n checkModule(state.settings, 'history', () => {\n if (!state.request.done[api]) state.request.done[api] = [];\n state.request.done[api].push({ api, request: action.payload, requestId });\n });\n checkModule(state.settings, 'storage', () => {\n if (action.meta.arg.ignore) {\n return;\n }\n\n const strategyList = (action.meta.arg.listStrategy ?? state.settings.listStrategy ?? {}) as CdeebeeListStrategy<T>;\n const normalize = action.meta.arg.normalize ?? state.settings.normalize ?? defaultNormalize;\n\n const currentState = current(state) as CdeebeeState<T>;\n // Type assertion is safe here because we've already checked isRecord\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const normalizedData = normalize(currentState, action.payload.result as any, strategyList);\n\n // Normalize already handles merge/replace/skip and preserves keys not in response\n // Simply apply the result\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (state.storage as any) = normalizedData;\n\n // Extract and store result IDs for filtering\n state.request.lastResultIdList[api] = extractResultIdList(action.payload.result);\n });\n })\n .addCase(request.rejected, (state, action) => {\n const requestId = action.meta.requestId;\n const api = action.meta.arg.api;\n\n checkModule(state.settings, 'listener', () => {\n state.request.active = state.request.active.filter(q => !(q.api === api && q.requestId === requestId));\n });\n checkModule(state.settings, 'history', () => {\n if (!state.request.errors[api]) state.request.errors[api] = [];\n state.request.errors[api].push({ requestId: requestId, api, request: action.error });\n });\n });\n },\n });\n\n return slice;\n};\n","import { useSelector } from 'react-redux';\nimport { type CdeebeeState } from '../reducer/types';\n\n/**\n * Generic hook factory that creates a selector hook for cdeebee state.\n * This allows the hooks to work with any Redux root state structure.\n *\n * @template RootState - The shape of the Redux root state\n * @template Storage - The shape of the cdeebee storage\n * @param selectCdeebee - Function to select the cdeebee slice from root state\n * @returns An object containing all cdeebee hooks\n */\nexport function createCdeebeeHooks<RootState, Storage>(\n selectCdeebee: (state: RootState) => CdeebeeState<Storage>\n) {\n /**\n * Check if any of the specified APIs are currently loading.\n *\n * @param apiList - Array of API endpoints to check\n * @returns true if any of the APIs are currently active/loading\n *\n * @example\n * const isLoading = useLoading(['/api/forums', '/api/threads']);\n * if (isLoading) return <Spinner />;\n */\n function useLoading(apiList: string[]): boolean {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.active.some(q => apiList.includes(q.api));\n });\n }\n\n /**\n * Get the successful request history for a specific API endpoint.\n *\n * @param api - The API endpoint\n * @returns Array of successful request history entries\n *\n * @example\n * const history = useRequestHistory('/api/forums');\n * console.log(`Made ${history.length} successful requests`);\n */\n function useRequestHistory(api: string) {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.done[api] ?? [];\n });\n }\n\n /**\n * Get the error history for a specific API endpoint.\n *\n * @param api - The API endpoint\n * @returns Array of error history entries\n *\n * @example\n * const errors = useRequestErrors('/api/forums');\n * if (errors.length > 0) {\n * console.error('Last error:', errors[errors.length - 1]);\n * }\n */\n function useRequestErrors(api: string) {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.errors[api] ?? [];\n });\n }\n\n /**\n * Get a specific list from storage with full type safety.\n *\n * @param listName - The name of the list in storage\n * @returns The list data\n *\n * @example\n * const forums = useStorageList('forumList');\n * const forumArray = Object.values(forums);\n */\n function useStorageList<K extends keyof Storage>(listName: K): Storage[K] {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.storage[listName];\n });\n }\n\n /**\n * Get the entire cdeebee storage.\n *\n * @returns The complete storage object\n *\n * @example\n * const storage = useStorage();\n * console.log(Object.keys(storage)); // ['forumList', 'threadList', ...]\n */\n function useStorage(): Storage {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.storage;\n });\n }\n\n /**\n * Check if any request is currently loading (across all APIs).\n *\n * @returns true if any request is active\n *\n * @example\n * const isAnythingLoading = useIsLoading();\n * if (isAnythingLoading) return <GlobalSpinner />;\n */\n function useIsLoading(): boolean {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.active.length > 0;\n });\n }\n\n /**\n * Get the list of IDs returned by the last successful request to an API.\n * Useful for filtering storage data to show only results from a specific request.\n *\n * @param api - The API endpoint\n * @returns Array of primary key IDs from the last response\n *\n * @example\n * const productList = useStorageList('productList');\n * const lastIds = useLastResultIdList('/api/search');\n * const displayResults = lastIds.map(id => productList[id]).filter(Boolean);\n */\n function useLastResultIdList(api: string): string[] {\n return useSelector((state: RootState) => {\n const cdeebee = selectCdeebee(state);\n return cdeebee.request.lastResultIdList[api] ?? [];\n });\n }\n\n return {\n useLoading,\n useRequestHistory,\n useRequestErrors,\n useStorageList,\n useStorage,\n useIsLoading,\n useLastResultIdList,\n };\n}\n","import { useSelector } from 'react-redux';\nimport { type CdeebeeState } from '../reducer/types';\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param apiList - Array of API endpoints to check\n * @returns true if any of the APIs are currently active/loading\n *\n * @example\n * const isLoading = useLoading(['/api/forums', '/api/threads']);\n */\nexport function useLoading<Storage = unknown>(apiList: string[]): boolean {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.active.some(q => apiList.includes(q.api));\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param api - The API endpoint\n * @returns Array of successful request history entries\n */\nexport function useRequestHistory<Storage = unknown>(api: string) {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.done[api] ?? [];\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param api - The API endpoint\n * @returns Array of error history entries\n */\nexport function useRequestErrors<Storage = unknown>(api: string) {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.errors[api] ?? [];\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @param listName - The name of the list in storage\n * @returns The list data\n */\nexport function useStorageList<Storage, K extends keyof Storage>(listName: K): Storage[K] {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.storage[listName];\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @returns The complete storage object\n */\nexport function useStorage<Storage>(): Storage {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.storage;\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * @returns true if any request is active\n */\nexport function useIsLoading<Storage = unknown>(): boolean {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.active.length > 0;\n });\n}\n\n/**\n * Standalone hook that can be used without createCdeebeeHooks.\n * Assumes the cdeebee slice is at state.cdeebee.\n *\n * Get the list of IDs returned by the last successful request to an API.\n * Useful for filtering storage data to show only results from a specific request.\n *\n * @param api - The API endpoint\n * @returns Array of primary key IDs from the last response\n *\n * @example\n * const productList = useStorageList('productList');\n * const lastIds = useLastResultIdList('/api/search');\n * const displayResults = lastIds.map(id => productList[id]).filter(Boolean);\n */\nexport function useLastResultIdList<Storage = unknown>(api: string): string[] {\n return useSelector((state: { cdeebee: CdeebeeState<Storage> }) => {\n return state.cdeebee.request.lastResultIdList[api] ?? [];\n });\n}\n"],"names":["checkModule","settings","module","result","isRecord","value","mergeDeepRight","left","right","rightRecord","key","leftValue","rightValue","omit","keys","obj","extractResultIdList","response","ids","primaryKey","item","batchingUpdate","state","valueList","i","path","current","j","pathKey","index","nextIsNumeric","next","AbortControllerStore","api","requestId","controller","apiSet","excludeRequestId","requestIds","abortStore","abortQuery","currentRequestId","abortManager","signal","cleanup","QueryQueue","task","previousPromise","queryQueue","request","createAsyncThunk","options","rejectWithValue","getState","startedAt","abort","withCallback","executeRequest","method","body","headers","extraHeaders","b","requestData","formData","fileKey","bodyKey","responseType","error","isDataWithPrimaryKey","normalizeDataWithPrimaryKey","data","applyStrategy","existingValue","newValue","strategy","defaultNormalize","cdeebee","strategyList","keyList","currentStorage","keyListToOmit","responseValue","normalizedValue","initialState","factory","storage","createSlice","action","builder","q","normalize","currentState","normalizedData","createCdeebeeHooks","selectCdeebee","useLoading","apiList","useSelector","useRequestHistory","useRequestErrors","useStorageList","listName","useStorage","useIsLoading","useLastResultIdList"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@recats/cdeebee",
3
- "version": "3.0.0-beta.12",
3
+ "version": "3.0.0-beta.13",
4
4
  "description": "React Redux data-logic library",
5
5
  "repository": "git@github.com:recats/cdeebee.git",
6
6
  "author": "recats",