stunk 2.6.0 → 2.7.1
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/dist/index.cjs +1 -1
- package/dist/index.d.cts +32 -1
- package/dist/index.d.ts +32 -1
- package/dist/index.js +1 -1
- package/dist/use-react/index.d.ts +17 -1
- package/dist/use-react/index.js +1 -1
- package/package.json +8 -4
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var Y=Object.defineProperty;var Z=(e,a)=>{for(var r in a)Y(e,r,{get:a[r],enumerable:true});};function _(e){return e!==null}function ee(e){if(!e||typeof e!="object")return false;let a=e;return ["get","set","subscribe","derive","reset","destroy"].every(t=>typeof a[t]=="function")}function te(e){let a=false,r;return ()=>(a||(r=e(),a=true),r)}function re(e){let a=Object.keys(e).reduce((n,u)=>(n[u]=null,n),{}),r={loading:Object.keys(e).length>0,error:null,errors:{},data:a},t=k(r);return Object.entries(e).forEach(([n,u])=>{u.subscribe(o=>{let c=t.get(),l=false,s=null,d={};Object.entries(e).forEach(([h,x])=>{let p=x.get();p.loading&&(l=true),p.error&&(s||(s=p.error),d[h]=p.error);}),t.set({loading:l,error:s,errors:d,data:{...c.data,[n]:o.data}});});}),t}function N(e,a){if(e===null)throw new Error("Value cannot be null.");let r=e,t=0;for(;t<a.length;){let n=a[t],u=typeof n=="function"?n:n.fn,o=typeof n=="function"?`index ${t}`:n.name||`index ${t}`,c=false,l=null;try{u(r,s=>{c=!0,l=s;});}catch(s){let d=s instanceof Error?s.message:String(s);throw new Error(`Middleware "${o}" threw an error: ${d}`)}if(!c)break;if(l===null)throw new Error(`Middleware at index ${t} returned null value.`);r=l,t++;}return r}function M(e,a){if(e===a)return true;if(!e||!a||typeof e!=typeof a)return false;if(Array.isArray(e)&&Array.isArray(a)){if(e.length!==a.length)return false;for(let r=0;r<e.length;r++)if(e[r]!==a[r])return false;return true}if(typeof e=="object"&&typeof a=="object"){let r=Object.keys(e),t=Object.keys(a);if(r.length!==t.length)return false;for(let n of r)if(!Object.prototype.hasOwnProperty.call(a,n)||e[n]!==a[n])return false;return true}return false}function D(e,a,r=""){if(typeof e=="object"&&e!==null&&typeof a=="object"&&a!==null){if(Array.isArray(e)&&Array.isArray(a)){if(e.length>0&&typeof e[0]=="object")for(let t=0;t<a.length;t++)D(e[0],a[t],`${r}[${t}]`);}else if(!Array.isArray(e)&&!Array.isArray(a)){let t=Object.keys(e),n=Object.keys(a),u=n.filter(o=>!t.includes(o));u.length>0&&(console.error(`\u{1F6A8} Stunk: Unknown properties detected at '${r||"root"}': ${u.join(", ")}. This might cause bugs.`),console.error("Expected keys:",t),console.error("Received keys:",n));for(let o of t)D(e[o],a[o],r?`${r}.${o}`:o);}}}var V=false,R=new Set,O=new Map,ne=0;function ae(e){let a=V;V=true;try{e();}finally{if(!a){V=false;let r=Array.from(R);R.clear(),r.forEach(t=>{let n=O.get(t);n&&n.notify();});}}}function k(e,a=[]){if(e===null)throw new Error("Initial value cannot be null.");let r=e,t=new Set,n=ne++,u=()=>{t.forEach(p=>p(r));};O.set(n,{notify:u});let o=()=>{t.size!==0&&(V?R.add(n):u());},c=()=>r,l=p=>{let y;typeof p=="function"?y=p(r):y=p,D(r,y);let b=N(y,a);b!==r&&(r=b,o());},s=p=>{if(typeof p!="function")throw new Error("Callback must be a function.");return t.add(p),p(r),()=>t.delete(p)};return {get:c,set:l,subscribe:s,derive:p=>{if(typeof p!="function")throw new Error("Derive function must be a function.");let y=p(r),b=k(y),f=s(()=>{let E=p(r);b.set(E);}),g=b.destroy;return b.destroy=()=>{f(),g();},b},reset:()=>{r=e,o();},destroy:()=>{t.clear(),r=e,R.delete(n),O.delete(n);}}}function z(e,a={}){let{initialData:r=null,onError:t,retryCount:n=0,retryDelay:u=1e3,refresh:o={},pagination:c,enabled:l=true}=a,{staleTime:s=0,cacheTime:d=300*1e3,refetchInterval:h}=o,x=!!c,p=c?.mode||"replace",y=e.length>0,b={loading:l&&!y,error:null,data:r,lastFetched:void 0,pagination:x?{page:c.initialPage||1,pageSize:c.pageSize||10}:void 0},f=k(b),g={},E=null,v=null,L=()=>{let i=f.get();return !i.lastFetched||s===0?true:Date.now()-i.lastFetched>s},G=()=>{f.set({...f.get(),data:r,lastFetched:void 0});},Q=()=>{v&&clearTimeout(v),d>0&&(v=setTimeout(G,d));},m=async(i,T=n,A=false)=>{if(!l||(i!==void 0&&(g={...g,...i}),!A&&!L()&&f.get().data!==null))return;let C=f.get();f.set({...C,loading:true,error:null});try{let S={...g};x&&C.pagination&&(S.page=C.pagination.page,S.pageSize=C.pagination.pageSize);let P=y?await e(S):await e(),w,H,$;if(P&&typeof P=="object"&&"data"in P){let j=P;w=j.data,H=j.total,$=j.hasMore;}else w=P;x&&p==="accumulate"&&C.data&&Array.isArray(C.data)&&Array.isArray(w)&&(w=[...C.data,...w]);let X=Date.now();f.set({loading:!1,error:null,data:w,lastFetched:X,pagination:x?{...C.pagination,total:H,hasMore:$}:void 0}),Q();}catch(S){if(T>0)return await new Promise(w=>setTimeout(w,u)),m(i,T-1,A);let P=f.get();f.set({loading:false,error:S,data:P.data,lastFetched:P.lastFetched,pagination:P.pagination}),t&&t(S);}};h&&h>0&&l&&(E=setInterval(()=>{l&&m(void 0,0,false);},h)),l&&!y&&m();let F=()=>{E&&(clearInterval(E),E=null),v&&(clearTimeout(v),v=null);},I={...f,reload:async i=>{await m(i,n,true);},refresh:async i=>{await m(i,n,false);},mutate:i=>{let T=f.get(),A=i(T.data);f.set({...T,data:A});},reset:()=>{F(),g={},f.set({...b,loading:l&&!y}),l&&!y&&(m(),h&&h>0&&(E=setInterval(()=>{l&&m(void 0,0,false);},h)));},cleanup:F,setParams:i=>{g={...g,...i},l&&m(i,n,true);}};return x?{...I,nextPage:async()=>{let i=f.get();i.pagination&&i.pagination.hasMore!==false&&(f.set({...i,pagination:{...i.pagination,page:i.pagination.page+1}}),await m(g,n,true));},prevPage:async()=>{let i=f.get();!i.pagination||i.pagination.page<=1||(f.set({...i,pagination:{...i.pagination,page:i.pagination.page-1}}),await m(g,n,true));},goToPage:async i=>{let T=f.get();!T.pagination||i<1||(f.set({...T,pagination:{...T.pagination,page:i}}),await m(g,n,true));},resetPagination:async()=>{let i=f.get();if(!i.pagination)return;let T=c?.initialPage||1;f.set({...i,data:p==="accumulate"?r:i.data,pagination:{...i.pagination,page:T}}),await m(g,n,true);}}:I}function oe(e,a={}){let{pageSize:r=10,staleTime:t,cacheTime:n,retryCount:u,retryDelay:o,onError:c}=a;return z(e,{pagination:{pageSize:r,mode:"accumulate",initialPage:1},refresh:{staleTime:t,cacheTime:n},retryCount:u,retryDelay:o,onError:c})}function se(e,a){let r=e.map(s=>s.get()),t=a(...r),n=k(t),u=n.set,o=false,c=()=>{let s=false;for(let d=0;d<e.length;d++){let h=e[d].get();h!==r[d]&&(r[d]=h,s=true);}if(s){let d=a(...r);d!==t&&(typeof d!="object"||typeof t!="object"||!M(d,t))&&(t=d,u(d)),o=false;}},l=e.map(s=>s.subscribe(()=>{o=true,c();}));return {...n,get:()=>(o&&c(),t),recompute:c,isDirty:()=>o,set:()=>{throw new Error("Cannot set values directly on computed. Modify the source chunk instead.")},reset:()=>(e.forEach(s=>{typeof s.reset=="function"&&s.reset();}),o=true,c(),t),destroy:()=>{l.forEach(s=>s()),n.destroy?.();}}}function q(e,a,r={}){let{useShallowEqual:t=false}=r,n=e.get(),u=a(n),o=k(u),c=()=>{let s=e.get(),d=a(s);n=s,(t?!M(d,u):d!==u)&&(u=d,o.set(d));},l=e.subscribe(c);return {get:()=>o.get(),set:()=>{throw new Error("Cannot set values directly on a selector. Modify the source chunk instead.")},subscribe:o.subscribe,derive:s=>q(o,s,r),reset:()=>{throw new Error("Cannot reset a selector chunk. Reset the source chunk instead.")},destroy:()=>{l(),o.destroy();}}}var U={};Z(U,{logger:()=>K,nonNegativeValidator:()=>W,withHistory:()=>B,withPersistence:()=>J});var K=(e,a)=>{console.log("Setting value:",e),a(e);};var W=(e,a)=>{if(e<0)throw new Error("Value must be non-negative!");a(e);};function B(e,a={}){let{maxHistory:r=100}=a,t=[e.get()],n=0,u=false,o={...e,set:c=>{if(u){e.set(c);return}let l;if(typeof c=="function"){let s=e.get();l=c(s);}else l=c;if(t.splice(n+1),t.push(l),t.length>r){console.warn("History limit reached. Removing oldest entries.");let s=t.length-r;t.splice(0,s),n=Math.max(0,n-s);}n=t.length-1,e.set(l);},undo:()=>{o.canUndo()&&(u=true,n--,o.set(t[n]),u=false);},redo:()=>{o.canRedo()&&(u=true,n++,o.set(t[n]),u=false);},canUndo:()=>n>0,canRedo:()=>n<t.length-1,getHistory:()=>[...t],clearHistory:()=>{let c=e.get();t.length=0,t.push(c),n=0;},destroy:()=>{t.length=0,e.destroy();}};return o}function J(e,a){let{key:r,storage:t=localStorage,serialize:n=JSON.stringify,deserialize:u=JSON.parse}=a;try{let o=t.getItem(r);if(o){let c=u(o);e.set(c);}}catch(o){console.error("Failed to load persisted state:",o);}return e.subscribe(o=>{try{let c=n(o);t.setItem(r,c);}catch(c){console.log("Failed to persist chunk",c);}}),e}exports.asyncChunk=z;exports.batch=ae;exports.chunk=k;exports.combineAsyncChunks=re;exports.computed=se;exports.infiniteAsyncChunk=oe;exports.isChunk=ee;exports.isValidChunkValue=_;exports.middleware=U;exports.once=te;exports.select=q;
|
package/dist/index.d.cts
CHANGED
|
@@ -118,6 +118,37 @@ declare function asyncChunk<T, E extends Error = Error, P extends Record<string,
|
|
|
118
118
|
refresh: (params?: Partial<P>) => Promise<void>;
|
|
119
119
|
};
|
|
120
120
|
|
|
121
|
+
interface InfiniteAsyncChunkOptions<T, E extends Error> {
|
|
122
|
+
/** Initial page size (default: 10) */
|
|
123
|
+
pageSize?: number;
|
|
124
|
+
/** Time in ms after which data becomes stale */
|
|
125
|
+
staleTime?: number;
|
|
126
|
+
/** Time in ms to cache data */
|
|
127
|
+
cacheTime?: number;
|
|
128
|
+
/** Retry count on error */
|
|
129
|
+
retryCount?: number;
|
|
130
|
+
/** Delay between retries in ms */
|
|
131
|
+
retryDelay?: number;
|
|
132
|
+
/** Error callback */
|
|
133
|
+
onError?: (error: E) => void;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Create an infinite scroll async chunk with accumulate mode.
|
|
137
|
+
* Automatically handles pagination in accumulate mode for infinite scrolling.
|
|
138
|
+
*/
|
|
139
|
+
declare function infiniteAsyncChunk<T, E extends Error = Error, P extends Record<string, any> = {}>(fetcher: (params: P & {
|
|
140
|
+
page: number;
|
|
141
|
+
pageSize: number;
|
|
142
|
+
}) => Promise<{
|
|
143
|
+
data: T[];
|
|
144
|
+
hasMore?: boolean;
|
|
145
|
+
total?: number;
|
|
146
|
+
}>, options?: InfiniteAsyncChunkOptions<T, E>): PaginatedAsyncChunk<T[], E> & {
|
|
147
|
+
setParams: (params: Partial<P>) => void;
|
|
148
|
+
reload: (params?: Partial<P>) => Promise<void>;
|
|
149
|
+
refresh: (params?: Partial<P>) => Promise<void>;
|
|
150
|
+
};
|
|
151
|
+
|
|
121
152
|
type ChunkValue<T> = T extends Chunk<infer U> ? U : never;
|
|
122
153
|
type DependencyValues<T extends Chunk<any>[]> = {
|
|
123
154
|
[K in keyof T]: T[K] extends Chunk<any> ? ChunkValue<T[K]> : never;
|
|
@@ -209,4 +240,4 @@ declare namespace index {
|
|
|
209
240
|
export { index_logger as logger, index_nonNegativeValidator as nonNegativeValidator, index_withHistory as withHistory, index_withPersistence as withPersistence };
|
|
210
241
|
}
|
|
211
242
|
|
|
212
|
-
export { type Chunk, type Middleware, asyncChunk, batch, chunk, combineAsyncChunks, computed, isChunk, isValidChunkValue, index as middleware, once, select };
|
|
243
|
+
export { type AsyncChunk, type AsyncState, type AsyncStateWithPagination, type Chunk, type Middleware, type PaginatedAsyncChunk, asyncChunk, batch, chunk, combineAsyncChunks, computed, infiniteAsyncChunk, isChunk, isValidChunkValue, index as middleware, once, select };
|
package/dist/index.d.ts
CHANGED
|
@@ -118,6 +118,37 @@ declare function asyncChunk<T, E extends Error = Error, P extends Record<string,
|
|
|
118
118
|
refresh: (params?: Partial<P>) => Promise<void>;
|
|
119
119
|
};
|
|
120
120
|
|
|
121
|
+
interface InfiniteAsyncChunkOptions<T, E extends Error> {
|
|
122
|
+
/** Initial page size (default: 10) */
|
|
123
|
+
pageSize?: number;
|
|
124
|
+
/** Time in ms after which data becomes stale */
|
|
125
|
+
staleTime?: number;
|
|
126
|
+
/** Time in ms to cache data */
|
|
127
|
+
cacheTime?: number;
|
|
128
|
+
/** Retry count on error */
|
|
129
|
+
retryCount?: number;
|
|
130
|
+
/** Delay between retries in ms */
|
|
131
|
+
retryDelay?: number;
|
|
132
|
+
/** Error callback */
|
|
133
|
+
onError?: (error: E) => void;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Create an infinite scroll async chunk with accumulate mode.
|
|
137
|
+
* Automatically handles pagination in accumulate mode for infinite scrolling.
|
|
138
|
+
*/
|
|
139
|
+
declare function infiniteAsyncChunk<T, E extends Error = Error, P extends Record<string, any> = {}>(fetcher: (params: P & {
|
|
140
|
+
page: number;
|
|
141
|
+
pageSize: number;
|
|
142
|
+
}) => Promise<{
|
|
143
|
+
data: T[];
|
|
144
|
+
hasMore?: boolean;
|
|
145
|
+
total?: number;
|
|
146
|
+
}>, options?: InfiniteAsyncChunkOptions<T, E>): PaginatedAsyncChunk<T[], E> & {
|
|
147
|
+
setParams: (params: Partial<P>) => void;
|
|
148
|
+
reload: (params?: Partial<P>) => Promise<void>;
|
|
149
|
+
refresh: (params?: Partial<P>) => Promise<void>;
|
|
150
|
+
};
|
|
151
|
+
|
|
121
152
|
type ChunkValue<T> = T extends Chunk<infer U> ? U : never;
|
|
122
153
|
type DependencyValues<T extends Chunk<any>[]> = {
|
|
123
154
|
[K in keyof T]: T[K] extends Chunk<any> ? ChunkValue<T[K]> : never;
|
|
@@ -209,4 +240,4 @@ declare namespace index {
|
|
|
209
240
|
export { index_logger as logger, index_nonNegativeValidator as nonNegativeValidator, index_withHistory as withHistory, index_withPersistence as withPersistence };
|
|
210
241
|
}
|
|
211
242
|
|
|
212
|
-
export { type Chunk, type Middleware, asyncChunk, batch, chunk, combineAsyncChunks, computed, isChunk, isValidChunkValue, index as middleware, once, select };
|
|
243
|
+
export { type AsyncChunk, type AsyncState, type AsyncStateWithPagination, type Chunk, type Middleware, type PaginatedAsyncChunk, asyncChunk, batch, chunk, combineAsyncChunks, computed, infiniteAsyncChunk, isChunk, isValidChunkValue, index as middleware, once, select };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var Y=Object.defineProperty;var Z=(e,a)=>{for(var r in a)Y(e,r,{get:a[r],enumerable:true});};function _(e){return e!==null}function ee(e){if(!e||typeof e!="object")return false;let a=e;return ["get","set","subscribe","derive","reset","destroy"].every(t=>typeof a[t]=="function")}function te(e){let a=false,r;return ()=>(a||(r=e(),a=true),r)}function re(e){let a=Object.keys(e).reduce((n,u)=>(n[u]=null,n),{}),r={loading:Object.keys(e).length>0,error:null,errors:{},data:a},t=k(r);return Object.entries(e).forEach(([n,u])=>{u.subscribe(o=>{let c=t.get(),l=false,s=null,d={};Object.entries(e).forEach(([h,x])=>{let p=x.get();p.loading&&(l=true),p.error&&(s||(s=p.error),d[h]=p.error);}),t.set({loading:l,error:s,errors:d,data:{...c.data,[n]:o.data}});});}),t}function N(e,a){if(e===null)throw new Error("Value cannot be null.");let r=e,t=0;for(;t<a.length;){let n=a[t],u=typeof n=="function"?n:n.fn,o=typeof n=="function"?`index ${t}`:n.name||`index ${t}`,c=false,l=null;try{u(r,s=>{c=!0,l=s;});}catch(s){let d=s instanceof Error?s.message:String(s);throw new Error(`Middleware "${o}" threw an error: ${d}`)}if(!c)break;if(l===null)throw new Error(`Middleware at index ${t} returned null value.`);r=l,t++;}return r}function M(e,a){if(e===a)return true;if(!e||!a||typeof e!=typeof a)return false;if(Array.isArray(e)&&Array.isArray(a)){if(e.length!==a.length)return false;for(let r=0;r<e.length;r++)if(e[r]!==a[r])return false;return true}if(typeof e=="object"&&typeof a=="object"){let r=Object.keys(e),t=Object.keys(a);if(r.length!==t.length)return false;for(let n of r)if(!Object.prototype.hasOwnProperty.call(a,n)||e[n]!==a[n])return false;return true}return false}function D(e,a,r=""){if(typeof e=="object"&&e!==null&&typeof a=="object"&&a!==null){if(Array.isArray(e)&&Array.isArray(a)){if(e.length>0&&typeof e[0]=="object")for(let t=0;t<a.length;t++)D(e[0],a[t],`${r}[${t}]`);}else if(!Array.isArray(e)&&!Array.isArray(a)){let t=Object.keys(e),n=Object.keys(a),u=n.filter(o=>!t.includes(o));u.length>0&&(console.error(`\u{1F6A8} Stunk: Unknown properties detected at '${r||"root"}': ${u.join(", ")}. This might cause bugs.`),console.error("Expected keys:",t),console.error("Received keys:",n));for(let o of t)D(e[o],a[o],r?`${r}.${o}`:o);}}}var V=false,R=new Set,O=new Map,ne=0;function ae(e){let a=V;V=true;try{e();}finally{if(!a){V=false;let r=Array.from(R);R.clear(),r.forEach(t=>{let n=O.get(t);n&&n.notify();});}}}function k(e,a=[]){if(e===null)throw new Error("Initial value cannot be null.");let r=e,t=new Set,n=ne++,u=()=>{t.forEach(p=>p(r));};O.set(n,{notify:u});let o=()=>{t.size!==0&&(V?R.add(n):u());},c=()=>r,l=p=>{let y;typeof p=="function"?y=p(r):y=p,D(r,y);let b=N(y,a);b!==r&&(r=b,o());},s=p=>{if(typeof p!="function")throw new Error("Callback must be a function.");return t.add(p),p(r),()=>t.delete(p)};return {get:c,set:l,subscribe:s,derive:p=>{if(typeof p!="function")throw new Error("Derive function must be a function.");let y=p(r),b=k(y),f=s(()=>{let E=p(r);b.set(E);}),g=b.destroy;return b.destroy=()=>{f(),g();},b},reset:()=>{r=e,o();},destroy:()=>{t.clear(),r=e,R.delete(n),O.delete(n);}}}function z(e,a={}){let{initialData:r=null,onError:t,retryCount:n=0,retryDelay:u=1e3,refresh:o={},pagination:c,enabled:l=true}=a,{staleTime:s=0,cacheTime:d=300*1e3,refetchInterval:h}=o,x=!!c,p=c?.mode||"replace",y=e.length>0,b={loading:l&&!y,error:null,data:r,lastFetched:void 0,pagination:x?{page:c.initialPage||1,pageSize:c.pageSize||10}:void 0},f=k(b),g={},E=null,v=null,L=()=>{let i=f.get();return !i.lastFetched||s===0?true:Date.now()-i.lastFetched>s},G=()=>{f.set({...f.get(),data:r,lastFetched:void 0});},Q=()=>{v&&clearTimeout(v),d>0&&(v=setTimeout(G,d));},m=async(i,T=n,A=false)=>{if(!l||(i!==void 0&&(g={...g,...i}),!A&&!L()&&f.get().data!==null))return;let C=f.get();f.set({...C,loading:true,error:null});try{let S={...g};x&&C.pagination&&(S.page=C.pagination.page,S.pageSize=C.pagination.pageSize);let P=y?await e(S):await e(),w,H,$;if(P&&typeof P=="object"&&"data"in P){let j=P;w=j.data,H=j.total,$=j.hasMore;}else w=P;x&&p==="accumulate"&&C.data&&Array.isArray(C.data)&&Array.isArray(w)&&(w=[...C.data,...w]);let X=Date.now();f.set({loading:!1,error:null,data:w,lastFetched:X,pagination:x?{...C.pagination,total:H,hasMore:$}:void 0}),Q();}catch(S){if(T>0)return await new Promise(w=>setTimeout(w,u)),m(i,T-1,A);let P=f.get();f.set({loading:false,error:S,data:P.data,lastFetched:P.lastFetched,pagination:P.pagination}),t&&t(S);}};h&&h>0&&l&&(E=setInterval(()=>{l&&m(void 0,0,false);},h)),l&&!y&&m();let F=()=>{E&&(clearInterval(E),E=null),v&&(clearTimeout(v),v=null);},I={...f,reload:async i=>{await m(i,n,true);},refresh:async i=>{await m(i,n,false);},mutate:i=>{let T=f.get(),A=i(T.data);f.set({...T,data:A});},reset:()=>{F(),g={},f.set({...b,loading:l&&!y}),l&&!y&&(m(),h&&h>0&&(E=setInterval(()=>{l&&m(void 0,0,false);},h)));},cleanup:F,setParams:i=>{g={...g,...i},l&&m(i,n,true);}};return x?{...I,nextPage:async()=>{let i=f.get();i.pagination&&i.pagination.hasMore!==false&&(f.set({...i,pagination:{...i.pagination,page:i.pagination.page+1}}),await m(g,n,true));},prevPage:async()=>{let i=f.get();!i.pagination||i.pagination.page<=1||(f.set({...i,pagination:{...i.pagination,page:i.pagination.page-1}}),await m(g,n,true));},goToPage:async i=>{let T=f.get();!T.pagination||i<1||(f.set({...T,pagination:{...T.pagination,page:i}}),await m(g,n,true));},resetPagination:async()=>{let i=f.get();if(!i.pagination)return;let T=c?.initialPage||1;f.set({...i,data:p==="accumulate"?r:i.data,pagination:{...i.pagination,page:T}}),await m(g,n,true);}}:I}function oe(e,a={}){let{pageSize:r=10,staleTime:t,cacheTime:n,retryCount:u,retryDelay:o,onError:c}=a;return z(e,{pagination:{pageSize:r,mode:"accumulate",initialPage:1},refresh:{staleTime:t,cacheTime:n},retryCount:u,retryDelay:o,onError:c})}function se(e,a){let r=e.map(s=>s.get()),t=a(...r),n=k(t),u=n.set,o=false,c=()=>{let s=false;for(let d=0;d<e.length;d++){let h=e[d].get();h!==r[d]&&(r[d]=h,s=true);}if(s){let d=a(...r);d!==t&&(typeof d!="object"||typeof t!="object"||!M(d,t))&&(t=d,u(d)),o=false;}},l=e.map(s=>s.subscribe(()=>{o=true,c();}));return {...n,get:()=>(o&&c(),t),recompute:c,isDirty:()=>o,set:()=>{throw new Error("Cannot set values directly on computed. Modify the source chunk instead.")},reset:()=>(e.forEach(s=>{typeof s.reset=="function"&&s.reset();}),o=true,c(),t),destroy:()=>{l.forEach(s=>s()),n.destroy?.();}}}function q(e,a,r={}){let{useShallowEqual:t=false}=r,n=e.get(),u=a(n),o=k(u),c=()=>{let s=e.get(),d=a(s);n=s,(t?!M(d,u):d!==u)&&(u=d,o.set(d));},l=e.subscribe(c);return {get:()=>o.get(),set:()=>{throw new Error("Cannot set values directly on a selector. Modify the source chunk instead.")},subscribe:o.subscribe,derive:s=>q(o,s,r),reset:()=>{throw new Error("Cannot reset a selector chunk. Reset the source chunk instead.")},destroy:()=>{l(),o.destroy();}}}var U={};Z(U,{logger:()=>K,nonNegativeValidator:()=>W,withHistory:()=>B,withPersistence:()=>J});var K=(e,a)=>{console.log("Setting value:",e),a(e);};var W=(e,a)=>{if(e<0)throw new Error("Value must be non-negative!");a(e);};function B(e,a={}){let{maxHistory:r=100}=a,t=[e.get()],n=0,u=false,o={...e,set:c=>{if(u){e.set(c);return}let l;if(typeof c=="function"){let s=e.get();l=c(s);}else l=c;if(t.splice(n+1),t.push(l),t.length>r){console.warn("History limit reached. Removing oldest entries.");let s=t.length-r;t.splice(0,s),n=Math.max(0,n-s);}n=t.length-1,e.set(l);},undo:()=>{o.canUndo()&&(u=true,n--,o.set(t[n]),u=false);},redo:()=>{o.canRedo()&&(u=true,n++,o.set(t[n]),u=false);},canUndo:()=>n>0,canRedo:()=>n<t.length-1,getHistory:()=>[...t],clearHistory:()=>{let c=e.get();t.length=0,t.push(c),n=0;},destroy:()=>{t.length=0,e.destroy();}};return o}function J(e,a){let{key:r,storage:t=localStorage,serialize:n=JSON.stringify,deserialize:u=JSON.parse}=a;try{let o=t.getItem(r);if(o){let c=u(o);e.set(c);}}catch(o){console.error("Failed to load persisted state:",o);}return e.subscribe(o=>{try{let c=n(o);t.setItem(r,c);}catch(c){console.log("Failed to persist chunk",c);}}),e}export{z as asyncChunk,ae as batch,k as chunk,re as combineAsyncChunks,se as computed,oe as infiniteAsyncChunk,ee as isChunk,_ as isValidChunkValue,U as middleware,te as once,q as select};
|
|
@@ -122,4 +122,20 @@ declare function useAsyncChunk<T, E extends Error = Error, P extends Record<stri
|
|
|
122
122
|
}, options?: UseAsyncChunkOptions<P> | Partial<P>): UseAsyncChunkResultWithParams<T, E, P>;
|
|
123
123
|
declare function useAsyncChunk<T, E extends Error = Error, P extends Record<string, any> = {}>(asyncChunk: AsyncChunk<T, E>, options?: UseAsyncChunkOptions<P> | Partial<P>): UseAsyncChunkResult<T, E, P>;
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
interface UseInfiniteAsyncChunkOptions<P extends Record<string, any>> extends Omit<UseAsyncChunkOptions<P>, 'initialParams'> {
|
|
126
|
+
/** Initial parameters (page and pageSize added automatically) */
|
|
127
|
+
initialParams?: Omit<Partial<P>, 'page' | 'pageSize'>;
|
|
128
|
+
/** Enable auto-loading on scroll (default: true) */
|
|
129
|
+
autoLoad?: boolean;
|
|
130
|
+
/** Intersection observer threshold (default: 1.0) */
|
|
131
|
+
threshold?: number;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Hook for infinite scroll functionality.
|
|
135
|
+
* Automatically loads more data when scrolling to the bottom.
|
|
136
|
+
*/
|
|
137
|
+
declare function useInfiniteAsyncChunk<T, E extends Error = Error, P extends Record<string, any> = {}>(asyncChunk: PaginatedAsyncChunk<T[], E> & {
|
|
138
|
+
setParams: (params: Partial<P>) => void;
|
|
139
|
+
}, options?: UseInfiniteAsyncChunkOptions<P>): any;
|
|
140
|
+
|
|
141
|
+
export { useAsyncChunk, useChunk, useChunkProperty, useChunkValue, useChunkValues, useComputed, useDerive, useInfiniteAsyncChunk };
|
package/dist/use-react/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {useState,useEffect,useCallback,useRef,useMemo}from'react';var
|
|
1
|
+
import {useState,useEffect,useCallback,useRef,useMemo}from'react';var S=new Set,D=new Map,j=0;function P(e,r=[]){if(e===null)throw new Error("Initial value cannot be null.");let t=e,n=new Set,s=j++,i=()=>{n.forEach(f=>f(t));};D.set(s,{notify:i});let o=()=>{n.size!==0&&(i());},l=()=>t,c=f=>{let h;typeof f=="function"?h=f(t):h=f,b(t,h);let p=M(h,r);p!==t&&(t=p,o());},a=f=>{if(typeof f!="function")throw new Error("Callback must be a function.");return n.add(f),f(t),()=>n.delete(f)};return {get:l,set:c,subscribe:a,derive:f=>{if(typeof f!="function")throw new Error("Derive function must be a function.");let h=f(t),p=P(h),m=a(()=>{let k=f(t);p.set(k);}),d=p.destroy;return p.destroy=()=>{m(),d();},p},reset:()=>{t=e,o();},destroy:()=>{n.clear(),t=e,S.delete(s),D.delete(s);}}}function M(e,r){if(e===null)throw new Error("Value cannot be null.");let t=e,n=0;for(;n<r.length;){let s=r[n],i=typeof s=="function"?s:s.fn,o=typeof s=="function"?`index ${n}`:s.name||`index ${n}`,l=false,c=null;try{i(t,a=>{l=!0,c=a;});}catch(a){let u=a instanceof Error?a.message:String(a);throw new Error(`Middleware "${o}" threw an error: ${u}`)}if(!l)break;if(c===null)throw new Error(`Middleware at index ${n} returned null value.`);t=c,n++;}return t}function x(e,r){if(e===r)return true;if(!e||!r||typeof e!=typeof r)return false;if(Array.isArray(e)&&Array.isArray(r)){if(e.length!==r.length)return false;for(let t=0;t<e.length;t++)if(e[t]!==r[t])return false;return true}if(typeof e=="object"&&typeof r=="object"){let t=Object.keys(e),n=Object.keys(r);if(t.length!==n.length)return false;for(let s of t)if(!Object.prototype.hasOwnProperty.call(r,s)||e[s]!==r[s])return false;return true}return false}function b(e,r,t=""){if(typeof e=="object"&&e!==null&&typeof r=="object"&&r!==null){if(Array.isArray(e)&&Array.isArray(r)){if(e.length>0&&typeof e[0]=="object")for(let n=0;n<r.length;n++)b(e[0],r[n],`${t}[${n}]`);}else if(!Array.isArray(e)&&!Array.isArray(r)){let n=Object.keys(e),s=Object.keys(r),i=s.filter(o=>!n.includes(o));i.length>0&&(console.error(`\u{1F6A8} Stunk: Unknown properties detected at '${t||"root"}': ${i.join(", ")}. This might cause bugs.`),console.error("Expected keys:",n),console.error("Received keys:",s));for(let o of n)b(e[o],r[o],t?`${t}.${o}`:o);}}}function E(e,r,t={}){let{useShallowEqual:n=false}=t,s=e.get(),i=r(s),o=P(i),l=()=>{let a=e.get(),u=r(a);s=a,(n?!x(u,i):u!==i)&&(i=u,o.set(u));},c=e.subscribe(l);return {get:()=>o.get(),set:()=>{throw new Error("Cannot set values directly on a selector. Modify the source chunk instead.")},subscribe:o.subscribe,derive:a=>E(o,a,t),reset:()=>{throw new Error("Cannot reset a selector chunk. Reset the source chunk instead.")},destroy:()=>{c(),o.destroy();}}}function C(e,r){let t=r?E(e,r):e,[n,s]=useState(()=>t.get());useEffect(()=>{let c=t.subscribe(a=>{s(()=>a);});return ()=>c()},[t]);let i=useCallback(c=>{e.set(c);},[e]),o=useCallback(()=>{e.reset();},[e]),l=useCallback(()=>{e.destroy();},[e]);return [n,i,o,l]}function F(e,r){let t=useRef(r);useEffect(()=>{t.current=r;},[r]);let n=useMemo(()=>e.derive(i=>t.current(i)),[e]),[s]=C(n);return s}function V(e,r){let t=e.map(a=>a.get()),n=r(...t),s=P(n),i=s.set,o=false,l=()=>{let a=false;for(let u=0;u<e.length;u++){let T=e[u].get();T!==t[u]&&(t[u]=T,a=true);}if(a){let u=r(...t);u!==n&&(typeof u!="object"||typeof n!="object"||!x(u,n))&&(n=u,i(u)),o=false;}},c=e.map(a=>a.subscribe(()=>{o=true,l();}));return {...s,get:()=>(o&&l(),n),recompute:l,isDirty:()=>o,set:()=>{throw new Error("Cannot set values directly on computed. Modify the source chunk instead.")},reset:()=>(e.forEach(a=>{typeof a.reset=="function"&&a.reset();}),o=true,l(),n),destroy:()=>{c.forEach(a=>a()),s.destroy?.();}}}function L(e,r){let t=useMemo(()=>V(e,r),[...e]),[n,s]=useState(()=>t.get());return useEffect(()=>{let i=t.subscribe(o=>{s(o);});return ()=>{i();}},[t]),n}function v(e,r){let[t]=C(e,r);return t}function G(e,r){let t=useMemo(()=>n=>n[r],[r]);return v(e,t)}function X(e){let[r,t]=useState(()=>e.map(n=>n.get()));return useEffect(()=>{let n=e.map((s,i)=>s.subscribe(o=>{t(l=>{let c=[...l];return c[i]=o,c});}));return ()=>{n.forEach(s=>s());}},[e]),r}function Z(e){return "nextPage"in e}function O(e){return "setParams"in e}function R(e,r){let{initialParams:t,fetchOnMount:n}=typeof r=="object"&&("initialParams"in r||"fetchOnMount"in r)?r:{initialParams:r,fetchOnMount:false},[s,i]=useState(()=>e.get());useEffect(()=>e.subscribe(k=>{i(k);}),[e]),useEffect(()=>{t&&O(e)?e.setParams(t):n&&!t&&e.reload();},[e]),useEffect(()=>()=>{e.cleanup();},[e]);let o=useCallback(d=>e.reload(d),[e]),l=useCallback(d=>e.refresh(d),[e]),c=useCallback(d=>e.mutate(d),[e]),a=useCallback(()=>e.reset(),[e]),u=useCallback(d=>{"setParams"in e&&e.setParams(d);},[e]),{data:T,loading:g,error:f,lastFetched:h,pagination:p}=s,m={data:T,loading:g,error:f,lastFetched:h,reload:o,refresh:l,mutate:c,reset:a};if(O(e)&&(m.setParams=u),Z(e)){let d=m;d.pagination=p,d.nextPage=useCallback(()=>e.nextPage(),[e]),d.prevPage=useCallback(()=>e.prevPage(),[e]),d.goToPage=useCallback(k=>e.goToPage(k),[e]),d.resetPagination=useCallback(()=>e.resetPagination(),[e]);}return m}function re(e,r={}){let{initialParams:t,autoLoad:n=true,threshold:s=1,...i}=r,o=useRef(null),l=R(e,{initialParams:{...t,page:1,pageSize:e.get().pagination?.pageSize||10},...i}),{loading:c,pagination:a,nextPage:u}=l;useEffect(()=>{if(!n)return;let g=new IntersectionObserver(h=>{h[0].isIntersecting&&!c&&a?.hasMore&&u();},{threshold:s}),f=o.current;return f&&g.observe(f),()=>{f&&g.unobserve(f);}},[c,a?.hasMore,u,n,s]);let T=useCallback(()=>{!c&&a?.hasMore&&u();},[c,a?.hasMore,u]);return {...l,loadMore:T,observerTarget:o,hasMore:a?.hasMore??false,isFetchingMore:c&&(l.data?.length??0)>0}}export{R as useAsyncChunk,C as useChunk,G as useChunkProperty,v as useChunkValue,X as useChunkValues,L as useComputed,F as useDerive,re as useInfiniteAsyncChunk};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stunk",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Stunk is a lightweight, framework-agnostic state management library for JavaScript and TypeScript. It uses chunk-based state units for efficient updates, reactivity, and performance optimization in React, Vue, Svelte, and Vanilla JS/TS applications.",
|
|
3
|
+
"version": "2.7.1",
|
|
4
|
+
"description": "Stunk is a lightweight, framework-agnostic state management library for JavaScript and TypeScript. It uses chunk-based state units for efficient updates, reactivity, and performance optimization in React, Vue(WIP), Svelte(Coming soon), and Vanilla JS/TS applications.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -67,8 +67,12 @@
|
|
|
67
67
|
"url": "https://github.com/I-am-abdulazeez"
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
|
-
"name": "
|
|
71
|
-
"url": "https://github.com/
|
|
70
|
+
"name": "Chiboy",
|
|
71
|
+
"url": "https://github.com/chibx"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"name": "Idris",
|
|
75
|
+
"url": "https://github.com/Dreezy305"
|
|
72
76
|
}
|
|
73
77
|
],
|
|
74
78
|
"license": "MIT",
|