stunk 2.8.1 → 3.0.0-beta.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/README.md CHANGED
@@ -1,22 +1,21 @@
1
1
  # Stunk
2
2
 
3
- Stunk is a lightweight, framework-agnostic state management library built on atomic state principles. It simplifies state management by breaking state into manageable "chunks", ensuring efficient updates and reactivity.
3
+ Stunk is a lightweight, framework-agnostic state management library built on atomic state principles. Break state into independent **chunks** each one reactive, composable, and self-contained.
4
4
 
5
- - **Pronunciation**: _Stunk_ (A playful blend of "state" and "chunk")
6
-
7
- **Stunk** is like dividing your jar into many smaller containers, each holding a single piece of state. These smaller containers are called **chunks**. Each **chunk** can be updated and accessed easily, and any part of your app can subscribe to changes in a chunk so it gets updated automatically.
5
+ - **Pronunciation**: _Stunk_ (a playful blend of "state" and "chunk")
8
6
 
9
7
  ## Features
10
8
 
11
- - 🚀 **Lightweight and Fast**: No dependencies, minimal overhead
12
- - 🔄 **Reactive**: Automatic updates when state changes
13
- - 📦 **Batch Updates**: Group multiple state updates together
14
- - 🎯 **Atomic State Management**: Break down state into manageable chunks
15
- - 🎭 **State Selection**: Select and derive specific parts of the state
16
- - 🔄 **Async Support**: Handle async state with built-in loading and error states
17
- - 🔌 **Middleware Support**: Extend functionality with custom middleware
18
- - ⏱️ **Time Travel**: Undo/redo state changes
19
- - 🔍 **Type-Safe**: Written in TypeScript with full type inference
9
+ - 🚀 **Lightweight** 3.32kB gzipped, zero dependencies
10
+ - ⚛️ **Atomic** break state into independent chunks
11
+ - 🔄 **Reactive** fine-grained updates, only affected components re-render
12
+ - 🧮 **Auto-tracking computed** no dependency arrays, just call `.get()`
13
+ - 🌐 **Async & Query layer** loading, error, caching, deduplication, pagination built in
14
+ - 🔁 **Mutations** reactive POST/PUT/DELETE with automatic cache invalidation
15
+ - 📦 **Batch updates** group multiple updates into one render
16
+ - 🔌 **Middleware** logging, persistence, validation — plug anything in
17
+ - ⏱️ **Time travel** undo/redo state changes
18
+ - 🔍 **TypeScript first** — full type inference, no annotations needed
20
19
 
21
20
  ## Installation
22
21
 
@@ -25,18 +24,23 @@ npm install stunk
25
24
  # or
26
25
  yarn add stunk
27
26
  # or
28
- pnpm install stunk
27
+ pnpm add stunk
29
28
  ```
30
29
 
31
- Read Docs:
30
+ 📖 [Read the docs](https://stunk.dev)
32
31
 
32
+ <<<<<<< HEAD
33
33
  [Stunk](https://stunk.dev/)
34
+ =======
35
+ ---
36
+ >>>>>>> v3
34
37
 
35
- ## Creating a Chunk
38
+ ## Core State
36
39
 
37
- ```typescript
40
+ ```ts
38
41
  import { chunk } from "stunk";
39
42
 
43
+ <<<<<<< HEAD
40
44
  // Create a chunk holding a number
41
45
  const count = chunk<number>(0);
42
46
 
@@ -91,15 +95,124 @@ const Counter = () => {
91
95
  ```
92
96
 
93
97
  👉 [See full explanation in docs](https://stunk.dev/useChunk.html)
98
+ =======
99
+ const count = chunk(0);
100
+
101
+ count.get(); // 0
102
+ count.set(10); // set directly
103
+ count.set((prev) => prev + 1); // updater function
104
+ count.peek(); // read without tracking dependencies
105
+ count.reset(); // back to 0
106
+ count.destroy(); // clear all subscribers
107
+ ```
94
108
 
95
- ## React via useDerive
109
+ ---
110
+ >>>>>>> v3
96
111
 
97
- Hook that lets you create a read-only derived state from a Chunk. It keeps the derived value reactive, automatically updating whenever the source Chunk changes.
112
+ ## Computed auto dependency tracking
98
113
 
99
- ```typescript
114
+ No dependency arrays. Any chunk whose `.get()` is called inside the function is tracked automatically:
115
+
116
+ ```ts
117
+ import { chunk, computed } from "stunk";
118
+
119
+ const price = chunk(100);
120
+ const quantity = chunk(3);
121
+
122
+ const total = computed(() => price.get() * quantity.get());
123
+
124
+ total.get(); // 300
125
+
126
+ price.set(200);
127
+ total.get(); // 600 — recomputed automatically
128
+ ```
129
+
130
+ Use `.peek()` to read without tracking:
131
+
132
+ ```ts
133
+ const taxRate = chunk(0.1);
134
+ const subtotal = computed(() => price.get() * (1 + taxRate.peek()));
135
+ // only recomputes when price changes
136
+ ```
137
+
138
+ ---
139
+
140
+ ## Async & Query
141
+
142
+ ```ts
143
+ import { asyncChunk } from "stunk/query";
144
+
145
+ const userChunk = asyncChunk(
146
+ async ({ id }: { id: number }) => fetchUser(id),
147
+ {
148
+ key: "user", // deduplicates concurrent requests
149
+ keepPreviousData: true, // no UI flicker on param changes
150
+ staleTime: 30_000,
151
+ onError: (err) => toast.error(err.message),
152
+ }
153
+ );
154
+
155
+ userChunk.setParams({ id: 1 });
156
+ // { loading: true, data: null, error: null }
157
+ // { loading: false, data: { id: 1, name: "..." }, error: null }
158
+ ```
159
+
160
+ ---
161
+
162
+ ## Mutations
163
+
164
+ Reactive POST/PUT/DELETE — one function, always safe to await or fire and forget:
165
+
166
+ ```ts
167
+ import { mutation } from "stunk/query";
168
+
169
+ const createPost = mutation(
170
+ async (data: NewPost) => fetchAPI("/posts", { method: "POST", body: data }),
171
+ {
172
+ invalidates: [postsChunk], // auto-reloads on success
173
+ onSuccess: () => toast.success("Created!"),
174
+ onError: (err) => toast.error(err.message),
175
+ }
176
+ );
177
+
178
+ // Fire and forget — safe
179
+ createPost.mutate({ title: "Hello" });
180
+
181
+ // Await for local control — no try/catch needed
182
+ const { data, error } = await createPost.mutate({ title: "Hello" });
183
+ if (!error) router.push("/posts");
184
+ ```
185
+
186
+ ---
187
+
188
+ ## Global Query Config
189
+
190
+ Set defaults once for all async chunks and mutations:
191
+
192
+ ```ts
193
+ import { configureQuery } from "stunk/query";
194
+
195
+ configureQuery({
196
+ query: {
197
+ staleTime: 30_000,
198
+ retryCount: 3,
199
+ onError: (err) => toast.error(err.message),
200
+ },
201
+ mutation: {
202
+ onError: (err) => toast.error(err.message),
203
+ },
204
+ });
205
+ ```
206
+
207
+ ---
208
+
209
+ ## Middleware
210
+
211
+ ```ts
100
212
  import { chunk } from "stunk";
101
- import { useDerive } from "stunk/react";
213
+ import { logger, nonNegativeValidator } from "stunk/middleware";
102
214
 
215
+ <<<<<<< HEAD
103
216
  const count = chunk<number>(0);
104
217
 
105
218
  const DoubledCount = () => {
@@ -150,30 +263,112 @@ interface User {
150
263
  const fetchUser = asyncChunk<User>(async () => {
151
264
  const res = await fetch("https://jsonplaceholder.typicode.com/users/1");
152
265
  return res.json();
266
+ =======
267
+ const score = chunk(0, {
268
+ middleware: [logger(), nonNegativeValidator]
269
+ >>>>>>> v3
153
270
  });
154
271
 
155
- const UserProfile = () => {
156
- const { data, loading, error, reload } = useAsyncChunk(fetchUser);
272
+ score.set(10); // logs: "Setting value: 10"
273
+ score.set(-1); // throws: "Value must be non-negative!"
274
+ ```
157
275
 
158
- if (loading) return <p>Loading...</p>;
159
- if (error) return <p>Error: {error.message}</p>;
276
+ ---
277
+
278
+ ## History (undo/redo)
279
+
280
+ ```ts
281
+ import { chunk } from "stunk";
282
+ import { history } from "stunk/middleware";
283
+
284
+ const count = chunk(0);
285
+ const tracked = history(count);
286
+
287
+ tracked.set(1);
288
+ tracked.set(2);
289
+ tracked.undo(); // 1
290
+ tracked.redo(); // 2
291
+ tracked.reset(); // 0 — clears history too
292
+ ```
293
+
294
+ ---
295
+
296
+ ## Persist
297
+
298
+ ```ts
299
+ import { chunk } from "stunk";
300
+ import { persist } from "stunk/middleware";
301
+
302
+ const theme = chunk<"light" | "dark">("light");
303
+ const saved = persist(theme, { key: "theme" });
304
+
305
+ saved.set("dark"); // saved to localStorage
306
+ saved.clearStorage(); // remove from localStorage
307
+ ```
308
+
309
+ ---
310
+
311
+ ## React
312
+
313
+ ```tsx
314
+ import { chunk, computed } from "stunk";
315
+ import { useChunk, useChunkValue, useAsyncChunk, useMutation } from "stunk/react";
316
+
317
+ const counter = chunk(0);
318
+ const double = computed(() => counter.get() * 2);
319
+
320
+ function Counter() {
321
+ const [count, setCount] = useChunk(counter);
322
+ const doubled = useChunkValue(double);
160
323
 
161
324
  return (
162
325
  <div>
326
+ <<<<<<< HEAD
163
327
  <h2>{data?.name}</h2>
164
328
  <p>{data?.email}</p>
165
329
  <button onClick={reload}>Reload</button>
330
+ =======
331
+ <p>Count: {count} — Doubled: {doubled}</p>
332
+ <button onClick={() => setCount((n) => n + 1)}>+</button>
333
+ >>>>>>> v3
166
334
  </div>
167
335
  );
168
- };
336
+ }
337
+
338
+ // Async
339
+ function PostList() {
340
+ const { data, loading, error } = useAsyncChunk(postsChunk);
341
+ if (loading) return <p>Loading...</p>;
342
+ return <ul>{data?.map(p => <li key={p.id}>{p.title}</li>)}</ul>;
343
+ }
344
+
345
+ // Mutation
346
+ function CreatePostForm() {
347
+ const { mutate, loading, error } = useMutation(createPost);
348
+
349
+ const handleSubmit = async (data: NewPost) => {
350
+ const { error } = await mutate(data);
351
+ if (!error) router.push("/posts");
352
+ };
353
+ }
169
354
  ```
170
355
 
356
+ <<<<<<< HEAD
171
357
  👉 [See full explanation in docs](https://stunk.dev/useAysncChunk.html)
358
+ =======
359
+ ---
360
+ >>>>>>> v3
172
361
 
173
- ## React via useChunkValue
362
+ ## Package exports
174
363
 
175
- Hook that subscribes to a Chunk and returns its current value. It is useful for read-only components that don’t need to modify the state.
364
+ | Import | Contents |
365
+ | ------------------ | --------------------------------------------------------------- |
366
+ | `stunk` | `chunk`, `computed`, `select`, `batch`, `isChunk`, and more |
367
+ | `stunk/react` | `useChunk`, `useChunkValue`, `useAsyncChunk`, `useInfiniteAsyncChunk`, `useMutation` |
368
+ | `stunk/query` | `asyncChunk`, `infiniteAsyncChunk`, `combineAsyncChunks`, `mutation`, `configureQuery` |
369
+ | `stunk/middleware` | `history`, `persist`, `logger`, `nonNegativeValidator` |
176
370
 
371
+ <<<<<<< HEAD
177
372
  ```typescript
178
373
  import { chunk } from "stunk";
179
374
  import { useChunkValue } from "stunk/react";
@@ -200,13 +395,14 @@ Coding Examples:
200
395
  Further Examples:
201
396
 
202
397
  👉 [Visit](https://github.com/I-am-abdulazeez/stunk-examples/)
398
+ =======
399
+ ---
400
+ >>>>>>> v3
203
401
 
204
402
  ## Contributing
205
403
 
206
- Contributions are welcome! Please feel free to submit a Pull Request.
207
-
208
- [Pull Request](https://github.com/I-am-abdulazeez/stunk/pulls)
404
+ Contributions are welcome open a [pull request](https://github.com/I-am-abdulazeez/stunk/pulls) or [issue](https://github.com/I-am-abdulazeez/stunk/issues).
209
405
 
210
406
  ## License
211
407
 
212
- This is licence under MIT
408
+ MIT
@@ -0,0 +1 @@
1
+ function h(e,r){if(e===void 0)throw new Error("Value cannot be undefined.");if(r.length===0)return e;let t=e;for(let o=0;o<r.length;o++){let s=r[o],y=typeof s=="function"?s:s.fn,u=typeof s=="function"?`index ${o}`:s.name||`index ${o}`;try{let f=y(t);if(f===void 0)break;if(f===null)throw new Error(`Middleware "${u}" returned null value.`);t=f;}catch(f){let l=f instanceof Error?f.message:String(f);throw new Error(`Middleware "${u}" threw an error: ${l}`)}}return t}function k(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),o=Object.keys(r);if(t.length!==o.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 a(e,r,t="",o={}){let{checkMissing:s=true,checkTypes:y=true}=o;if(e===null||r===null||e===void 0||r===void 0)return;if(typeof e!=typeof r){console.error(`\u{1F6A8} Stunk: Type mismatch at '${t||"root"}'. Expected ${typeof e}, got ${typeof r}.`);return}if(typeof e!="object"||typeof r!="object")return;if(Array.isArray(e)!==Array.isArray(r)){console.error(`\u{1F6A8} Stunk: Type mismatch at '${t||"root"}'. Expected ${Array.isArray(e)?"array":"object"}, got ${Array.isArray(r)?"array":"object"}.`);return}if(Array.isArray(e)&&Array.isArray(r)){if(e.length>0&&typeof e[0]=="object")for(let n=0;n<r.length;n++)a(e[0],r[n],`${t}[${n}]`,o);return}let u=Object.keys(e),f=Object.keys(r),l=f.filter(n=>!u.includes(n));if(l.length>0&&(console.error(`\u{1F6A8} Stunk: Unknown properties at '${t||"root"}': ${l.join(", ")}`),console.error("Expected keys:",u),console.error("Received keys:",f)),s){let n=u.filter(c=>!f.includes(c));n.length>0&&console.error(`\u{1F6A8} Stunk: Missing properties at '${t||"root"}': ${n.join(", ")}`);}for(let n of u){let c=e[n],i=r[n];c===void 0||i===void 0||i===null||(y&&typeof c!="object"&&typeof c!=typeof i&&console.error(`\u{1F6A8} Stunk: Type mismatch at '${t?t+".":""}${n}'. Expected ${typeof c}, got ${typeof i}.`),a(c,i,t?`${t}.${n}`:n,o));}}export{h as a,k as b,a as c};
@@ -0,0 +1 @@
1
+ import {c,a}from'./chunk-3DOB632D.js';var v=new Set,l=new Map,j=0;function A(t,a$1={}){let s=j++,d=a$1.name||`chunk_${s}`,m=a$1.middleware||[],C=a$1.strict??false;if(t===void 0)throw new Error(`[${d}] Initial value cannot be undefined.`);let f=t!==null&&typeof t=="object"&&!Array.isArray(t)?new Set(Object.keys(t)):null,n=t,u=new Set,y=()=>{u.forEach(e=>e(n));};l.set(s,{notify:y});let h=()=>{if(u.size===0){l.delete(s);return}y();},D=()=>(n),_=()=>n,S=e=>{let r;if(typeof e=="function"?r=e(n):r=e,c(n,r),f&&r!==null&&typeof r=="object"&&!Array.isArray(r)){let i=Object.keys(r).filter(c=>!f.has(c));if(i.length>0){let c=`[${d}] Unexpected keys in set(): ${i.join(", ")}. These keys were not present in the initial shape.`;if(C)throw new Error(`\u{1F6A8} Stunk: ${c}`);console.error(`\u{1F6A8} Stunk: ${c}`);}}let o=a(r,m);o!==n&&(n=o,h());},T=e=>{if(typeof e!="function")throw new Error("Callback must be a function.");return u.add(e),()=>u.delete(e)},k={get:D,peek:_,set:S,subscribe:T,derive:e=>{if(typeof e!="function")throw new Error("Derive function must be a function.");let r=e(n),o=A(r),i=T(()=>{let g=e(n);o.set(g);}),c=o.destroy;return o.destroy=()=>{i(),c();},o},reset:()=>{n=t,h();},destroy:()=>{u.clear(),n=t,v.delete(s),l.delete(s);},[Symbol.for("stunk.meta")]:{name:d,id:s}};return k}export{A as a};
@@ -3,16 +3,21 @@ type Middleware<T> = (value: T) => T | undefined;
3
3
  interface Chunk<T> {
4
4
  /** Get the current value of the chunk. */
5
5
  get: () => T;
6
+ /** Peek at the current value without tracking dependencies. */
7
+ peek: () => T;
6
8
  /** Set a new value for the chunk & Update existing value efficiently. */
7
9
  set: (newValueOrUpdater: T | ((currentValue: T) => T)) => void;
8
10
  /** Subscribe to changes in the chunk. Returns an unsubscribe function. */
9
11
  subscribe: (callback: Subscriber<T>) => () => void;
10
12
  /** Create a derived chunk based on this chunk's value. */
11
- derive: <D>(fn: (value: T) => D) => Chunk<D>;
13
+ derive: <D>(fn: (value: T) => D) => ReadOnlyChunk<D>;
12
14
  /** Reset the chunk to its initial value. */
13
15
  reset: () => void;
14
16
  /** Destroy the chunk and all its subscribers. */
15
17
  destroy: () => void;
16
18
  }
19
+ interface ReadOnlyChunk<T> extends Omit<Chunk<T>, 'set' | 'reset'> {
20
+ derive: <D>(fn: (value: T) => D) => ReadOnlyChunk<D>;
21
+ }
17
22
 
18
23
  export type { Chunk as C, Middleware as M };
@@ -3,16 +3,21 @@ type Middleware<T> = (value: T) => T | undefined;
3
3
  interface Chunk<T> {
4
4
  /** Get the current value of the chunk. */
5
5
  get: () => T;
6
+ /** Peek at the current value without tracking dependencies. */
7
+ peek: () => T;
6
8
  /** Set a new value for the chunk & Update existing value efficiently. */
7
9
  set: (newValueOrUpdater: T | ((currentValue: T) => T)) => void;
8
10
  /** Subscribe to changes in the chunk. Returns an unsubscribe function. */
9
11
  subscribe: (callback: Subscriber<T>) => () => void;
10
12
  /** Create a derived chunk based on this chunk's value. */
11
- derive: <D>(fn: (value: T) => D) => Chunk<D>;
13
+ derive: <D>(fn: (value: T) => D) => ReadOnlyChunk<D>;
12
14
  /** Reset the chunk to its initial value. */
13
15
  reset: () => void;
14
16
  /** Destroy the chunk and all its subscribers. */
15
17
  destroy: () => void;
16
18
  }
19
+ interface ReadOnlyChunk<T> extends Omit<Chunk<T>, 'set' | 'reset'> {
20
+ derive: <D>(fn: (value: T) => D) => ReadOnlyChunk<D>;
21
+ }
17
22
 
18
23
  export type { Chunk as C, Middleware as M };
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- 'use strict';var Y=Object.defineProperty;var Z=(e,o)=>{for(var r in o)Y(e,r,{get:o[r],enumerable:true});};function _(e){return e!==null}function ee(e){if(!e||typeof e!="object")return false;let o=e;return ["get","set","subscribe","derive","reset","destroy"].every(t=>typeof o[t]=="function")}function te(e){let o=false,r;return ()=>(o||(r=e(),o=true),r)}function re(e){let o=Object.keys(e).reduce((n,u)=>(n[u]=null,n),{}),r={loading:Object.keys(e).length>0,error:null,errors:{},data:o},t=k(r);return Object.entries(e).forEach(([n,u])=>{u.subscribe(a=>{let s=t.get(),l=false,c=null,f={};Object.entries(e).forEach(([h,x])=>{let p=x.get();p.loading&&(l=true),p.error&&(c||(c=p.error),f[h]=p.error);}),t.set({loading:l,error:c,errors:f,data:{...s.data,[n]:a.data}});});}),t}function N(e,o){if(e===null)throw new Error("Value cannot be null.");let r=e;for(let t=0;t<o.length;t++){let n=o[t],u=typeof n=="function"?n:n.fn,a=typeof n=="function"?`index ${t}`:n.name||`index ${t}`;try{let s=u(r);if(s===void 0)break;if(s===null)throw new Error(`Middleware "${a}" returned null value.`);r=s;}catch(s){let l=s instanceof Error?s.message:String(s);throw new Error(`Middleware "${a}" threw an error: ${l}`)}}return r}function M(e,o){if(e===o)return true;if(!e||!o||typeof e!=typeof o)return false;if(Array.isArray(e)&&Array.isArray(o)){if(e.length!==o.length)return false;for(let r=0;r<e.length;r++)if(e[r]!==o[r])return false;return true}if(typeof e=="object"&&typeof o=="object"){let r=Object.keys(e),t=Object.keys(o);if(r.length!==t.length)return false;for(let n of r)if(!Object.prototype.hasOwnProperty.call(o,n)||e[n]!==o[n])return false;return true}return false}function D(e,o,r=""){if(typeof e=="object"&&e!==null&&typeof o=="object"&&o!==null){if(Array.isArray(e)&&Array.isArray(o)){if(e.length>0&&typeof e[0]=="object")for(let t=0;t<o.length;t++)D(e[0],o[t],`${r}[${t}]`);}else if(!Array.isArray(e)&&!Array.isArray(o)){let t=Object.keys(e),n=Object.keys(o),u=n.filter(a=>!t.includes(a));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 a of t)D(e[a],o[a],r?`${r}.${a}`:a);}}}var V=false,R=new Set,O=new Map,ne=0;function oe(e){let o=V;V=true;try{e();}finally{if(!o){V=false;let r=Array.from(R);R.clear(),r.forEach(t=>{let n=O.get(t);n&&n.notify();});}}}function k(e,o=[]){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 a=()=>{t.size!==0&&(V?R.add(n):u());},s=()=>r,l=p=>{let y;typeof p=="function"?y=p(r):y=p,D(r,y);let b=N(y,o);b!==r&&(r=b,a());},c=p=>{if(typeof p!="function")throw new Error("Callback must be a function.");return t.add(p),p(r),()=>t.delete(p)};return {get:s,set:l,subscribe:c,derive:p=>{if(typeof p!="function")throw new Error("Derive function must be a function.");let y=p(r),b=k(y),d=c(()=>{let w=p(r);b.set(w);}),g=b.destroy;return b.destroy=()=>{d(),g();},b},reset:()=>{r=e,a();},destroy:()=>{t.clear(),r=e,R.delete(n),O.delete(n);}}}function z(e,o={}){let{initialData:r=null,onError:t,retryCount:n=0,retryDelay:u=1e3,refresh:a={},pagination:s,enabled:l=true}=o,{staleTime:c=0,cacheTime:f=5*60*1e3,refetchInterval:h}=a,x=!!s,p=s?.mode||"replace",y=e.length>0,b={loading:l&&!y,error:null,data:r,lastFetched:void 0,pagination:x?{page:s.initialPage||1,pageSize:s.pageSize||10}:void 0},d=k(b),g={},w=null,v=null,L=()=>{let i=d.get();return !i.lastFetched||c===0?true:Date.now()-i.lastFetched>c},G=()=>{d.set({...d.get(),data:r,lastFetched:void 0});},Q=()=>{v&&clearTimeout(v),f>0&&(v=setTimeout(G,f));},m=async(i,T=n,A=false)=>{if(!l||(i!==void 0&&(g={...g,...i}),!A&&!L()&&d.get().data!==null))return;let C=d.get();d.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(),E,H,$;if(P&&typeof P=="object"&&"data"in P){let j=P;E=j.data,H=j.total,$=j.hasMore;}else E=P;x&&p==="accumulate"&&C.data&&Array.isArray(C.data)&&Array.isArray(E)&&(E=[...C.data,...E]);let X=Date.now();d.set({loading:!1,error:null,data:E,lastFetched:X,pagination:x?{...C.pagination,total:H,hasMore:$}:void 0}),Q();}catch(S){if(T>0)return await new Promise(E=>setTimeout(E,u)),m(i,T-1,A);let P=d.get();d.set({loading:false,error:S,data:P.data,lastFetched:P.lastFetched,pagination:P.pagination}),t&&t(S);}};h&&h>0&&l&&(w=setInterval(()=>{l&&m(void 0,0,false);},h)),l&&!y&&m();let F=()=>{w&&(clearInterval(w),w=null),v&&(clearTimeout(v),v=null);},I={...d,reload:async i=>{await m(i,n,true);},refresh:async i=>{await m(i,n,false);},mutate:i=>{let T=d.get(),A=i(T.data);d.set({...T,data:A});},reset:()=>{F(),g={},d.set({...b,loading:l&&!y}),l&&!y&&(m(),h&&h>0&&(w=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=d.get();i.pagination&&i.pagination.hasMore!==false&&(d.set({...i,pagination:{...i.pagination,page:i.pagination.page+1}}),await m(g,n,true));},prevPage:async()=>{let i=d.get();!i.pagination||i.pagination.page<=1||(d.set({...i,pagination:{...i.pagination,page:i.pagination.page-1}}),await m(g,n,true));},goToPage:async i=>{let T=d.get();!T.pagination||i<1||(d.set({...T,pagination:{...T.pagination,page:i}}),await m(g,n,true));},resetPagination:async()=>{let i=d.get();if(!i.pagination)return;let T=s?.initialPage||1;d.set({...i,data:p==="accumulate"?r:i.data,pagination:{...i.pagination,page:T}}),await m(g,n,true);}}:I}function ae(e,o={}){let{pageSize:r=10,staleTime:t,cacheTime:n,retryCount:u,retryDelay:a,onError:s}=o;return z(e,{pagination:{pageSize:r,mode:"accumulate",initialPage:1},refresh:{staleTime:t,cacheTime:n},retryCount:u,retryDelay:a,onError:s})}function se(e,o){let r=e.map(c=>c.get()),t=o(...r),n=k(t),u=n.set,a=false,s=()=>{let c=false;for(let f=0;f<e.length;f++){let h=e[f].get();h!==r[f]&&(r[f]=h,c=true);}if(c){let f=o(...r);f!==t&&(typeof f!="object"||typeof t!="object"||!M(f,t))&&(t=f,u(f)),a=false;}},l=e.map(c=>c.subscribe(()=>{a=true,s();}));return {...n,get:()=>(a&&s(),t),recompute:s,isDirty:()=>a,set:()=>{throw new Error("Cannot set values directly on computed. Modify the source chunk instead.")},reset:()=>(e.forEach(c=>{typeof c.reset=="function"&&c.reset();}),a=true,s(),t),destroy:()=>{l.forEach(c=>c()),n.destroy?.();}}}function q(e,o,r={}){let{useShallowEqual:t=false}=r,n=e.get(),u=o(n),a=k(u),s=()=>{let c=e.get(),f=o(c);n=c,(t?!M(f,u):f!==u)&&(u=f,a.set(f));},l=e.subscribe(s);return {get:()=>a.get(),set:()=>{throw new Error("Cannot set values directly on a selector. Modify the source chunk instead.")},subscribe:a.subscribe,derive:c=>q(a,c,r),reset:()=>{throw new Error("Cannot reset a selector chunk. Reset the source chunk instead.")},destroy:()=>{l(),a.destroy();}}}var U={};Z(U,{logger:()=>K,nonNegativeValidator:()=>W,withHistory:()=>B,withPersistence:()=>J});var K=e=>(console.log("Setting value:",e),e);var W=e=>{if(e<0)throw new Error("Value must be non-negative!");return e};function B(e,o={}){let{maxHistory:r=100}=o,t=[e.get()],n=0,u=false,a={...e,set:s=>{if(u){e.set(s);return}let l;if(typeof s=="function"){let c=e.get();l=s(c);}else l=s;if(t.splice(n+1),t.push(l),t.length>r){console.warn("History limit reached. Removing oldest entries.");let c=t.length-r;t.splice(0,c),n=Math.max(0,n-c);}n=t.length-1,e.set(l);},undo:()=>{a.canUndo()&&(u=true,n--,a.set(t[n]),u=false);},redo:()=>{a.canRedo()&&(u=true,n++,a.set(t[n]),u=false);},canUndo:()=>n>0,canRedo:()=>n<t.length-1,getHistory:()=>[...t],clearHistory:()=>{let s=e.get();t.length=0,t.push(s),n=0;},destroy:()=>{t.length=0,e.destroy();}};return a}function J(e,o){let{key:r,storage:t=localStorage,serialize:n=JSON.stringify,deserialize:u=JSON.parse}=o;try{let a=t.getItem(r);if(a){let s=u(a);e.set(s);}}catch(a){console.error("Failed to load persisted state:",a);}return e.subscribe(a=>{try{let s=n(a);t.setItem(r,s);}catch(s){console.log("Failed to persist chunk",s);}}),e}exports.asyncChunk=z;exports.batch=oe;exports.chunk=k;exports.combineAsyncChunks=re;exports.computed=se;exports.infiniteAsyncChunk=ae;exports.isChunk=ee;exports.isValidChunkValue=_;exports.middleware=U;exports.once=te;exports.select=q;
1
+ 'use strict';var be=Object.defineProperty;var re=(e,a)=>{for(var t in a)be(e,t,{get:a[t],enumerable:true});};function ne(e,a){if(e===void 0)throw new Error("Value cannot be undefined.");if(a.length===0)return e;let t=e;for(let c=0;c<a.length;c++){let i=a[c],s=typeof i=="function"?i:i.fn,f=typeof i=="function"?`index ${c}`:i.name||`index ${c}`;try{let n=s(t);if(n===void 0)break;if(n===null)throw new Error(`Middleware "${f}" returned null value.`);t=n;}catch(n){let r=n instanceof Error?n.message:String(n);throw new Error(`Middleware "${f}" threw an error: ${r}`)}}return t}function O(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 t=0;t<e.length;t++)if(e[t]!==a[t])return false;return true}if(typeof e=="object"&&typeof a=="object"){let t=Object.keys(e),c=Object.keys(a);if(t.length!==c.length)return false;for(let i of t)if(!Object.prototype.hasOwnProperty.call(a,i)||e[i]!==a[i])return false;return true}return false}function ke(e){return e[Symbol.for("stunk.meta")]}var _=null;function U(e){let a=new Set,t=_;_=a;try{return [e(),Array.from(a)]}finally{_=t;}}function Ee(e){_&&_.add(e);}var Q=false,G=new Set,W=new Map,ve=0;function xe(e){let a=Q;Q=true;try{e();}finally{if(!a){Q=false;let t=Array.from(G);G.clear(),t.forEach(c=>{let i=W.get(c);i&&i.notify();});}}}function v(e,a={}){let t=ve++,c=`chunk_${t}`,i=a.middleware||[];a.strict??false;if(e===void 0)throw new Error(`[${c}] Initial value cannot be undefined.`);let n=e,r=new Set,p=()=>{r.forEach(h=>h(n));};W.set(t,{notify:p});let u=()=>{if(r.size===0){W.delete(t);return}Q?G.add(t):p();},o=()=>(Ee(D),n),d=()=>n,m=h=>{let x;typeof h=="function"?x=h(n):x=h;let P=ne(x,i);P!==n&&(n=P,u());},T=h=>{if(typeof h!="function")throw new Error("Callback must be a function.");return r.add(h),()=>r.delete(h)},D={get:o,peek:d,set:m,subscribe:T,derive:h=>{if(typeof h!="function")throw new Error("Derive function must be a function.");let x=h(n),P=v(x),y=T(()=>{let $=h(n);P.set($);}),g=P.destroy;return P.destroy=()=>{y(),g();},P},reset:()=>{n=e,u();},destroy:()=>{r.clear(),n=e,G.delete(t),W.delete(t);}};return D}function oe(e){let[a,t]=U(e),c=a,i=t,s=false,f=[],n=0,r=v(c),p=()=>{if(!s)return;s=false;let[o,d]=U(e);O(d,i)||(f.forEach(T=>T()),f=d.map(T=>T.subscribe(()=>{s=true,n>0&&p();})),i=d),(typeof o=="object"&&typeof c=="object"?!O(o,c):o!==c)&&(c=o,r.set(o));};f=i.map(o=>o.subscribe(()=>{s=true,n>0&&p();}));let u;return u={get:()=>(s&&p(),r.get()),peek:()=>c,subscribe:o=>{let d=r.subscribe(o);return n++,()=>{n=Math.max(0,n-1),d();}},derive:o=>(n++,oe(()=>o(u.get()))),recompute:()=>{s=true,p();},isDirty:()=>s,destroy:()=>{f.forEach(o=>o()),r.destroy(),n=0;}},u}function ae(e,a,t={}){let{useShallowEqual:c=false}=t,i=e.get(),s=a(i),f=v(s),n=()=>{let d=e.get(),m=a(d);(c?!O(m,s):m!==s)&&(s=m,f.set(m));},r=e.subscribe(n),{set:p,reset:u,...o}=f;return {...o,derive:d=>ae(f,d,t),destroy:()=>{r(),f.destroy();}}}var ce={};re(ce,{history:()=>ue,logger:()=>ie,nonNegativeValidator:()=>se,persist:()=>le});function ie(){return e=>(console.log("Setting value:",e),e)}var se=e=>{if(e<0)throw new Error("Value must be non-negative!");return e};function ue(e,a={}){let{maxHistory:t=100,skipDuplicates:c=false}=a,i=[e.get()],s=0;return {...e,get:()=>e.get(),peek:()=>e.peek(),set:n=>{let r;if(typeof n=="function"?r=n(e.get()):r=n,c){let p=i[s];if(r===p||c==="shallow"&&typeof r=="object"&&typeof p=="object"&&r!==null&&p!==null&&O(r,p))return}if(i.splice(s+1),i.push(r),i.length>t){let p=i.length-t;i.splice(0,p);}s=i.length-1,e.set(r);},undo:()=>{s<=0||(s--,e.set(i[s]));},redo:()=>{s>=i.length-1||(s++,e.set(i[s]));},canUndo:()=>s>0,canRedo:()=>s<i.length-1,getHistory:()=>[...i],clearHistory:()=>{let n=e.get();i.length=0,i.push(n),s=0;},reset:()=>{e.reset(),i.length=0,i.push(e.get()),s=0;},destroy:()=>{i.length=0,e.destroy();},subscribe:n=>e.subscribe(n)}}function le(e,a){let{key:t,serialize:c=JSON.stringify,deserialize:i=JSON.parse,onError:s}=a,f="storage"in a?a.storage:typeof window<"u"?localStorage:void 0;if(!f)return console.warn(`persist: Storage not available for key "${t}". Persistence disabled.`),{...e,clearStorage:()=>{}};let n=e.get();try{let u=f.getItem(t);if(u!==null){let o=i(u);if(o!==null&&n!==null&&(typeof o!=typeof n||Array.isArray(o)!==Array.isArray(n))){let T=`persist: Type mismatch for "${t}". Expected ${Array.isArray(n)?"array":typeof n}, got ${Array.isArray(o)?"array":typeof o}. Using initial value.`;console.warn(T),s?.(new Error(T),"load");}else e.set(o);}}catch(u){let o=u instanceof Error?u:new Error(String(u));console.error(`persist: Failed to load state for "${t}":`,o),s?.(o,"load");}let r=e.subscribe(u=>{try{f.setItem(t,c(u));}catch(o){let d=o instanceof Error?o:new Error(String(o));console.error(`persist: Failed to save state for "${t}":`,d),s?.(d,"save");}});return {...e,get:()=>e.get(),peek:()=>e.peek(),set:u=>e.set(u),subscribe:u=>e.subscribe(u),derive:u=>e.derive(u),reset:()=>e.reset(),destroy:()=>{r(),e.destroy();},clearStorage:()=>{try{f.removeItem(t);}catch(u){let o=u instanceof Error?u:new Error(String(u));console.error(`persist: Failed to clear storage for "${t}":`,o),s?.(o,"save");}}}}var he={};re(he,{asyncChunk:()=>K,combineAsyncChunks:()=>pe,configureQuery:()=>de,getGlobalQueryConfig:()=>F,infiniteAsyncChunk:()=>ye,mutation:()=>me,resetQueryConfig:()=>fe});var q={};function de(e){q={...e.query!==void 0&&{query:{...q.query,...e.query}},...e.mutation!==void 0&&{mutation:{...q.mutation,...e.mutation}}};}function F(){return q}function fe(){q={};}var N=new Map,Pe=0;function K(e,a={}){let t=F().query??{},{key:c,initialData:i=null,enabled:s=true,onSuccess:f=t.onSuccess,onError:n=t.onError,retryCount:r=t.retryCount??0,retryDelay:p=t.retryDelay??1e3,keepPreviousData:u=false,staleTime:o=t.staleTime??0,cacheTime:d=t.cacheTime??5*60*1e3,refetchInterval:m=t.refetchInterval,refetchOnWindowFocus:T=t.refetchOnWindowFocus??false,pagination:A}=a,E=c??`async_chunk_${Pe++}`,C=()=>typeof s=="function"?s():s,D=!!A,h=A?.mode||"replace",x=e.length>0,P={loading:C()&&!x,error:null,data:i,lastFetched:void 0,isPlaceholderData:false,pagination:D?{page:A.initialPage||1,pageSize:A.pageSize||10,total:void 0,hasMore:void 0}:void 0},y=v(P),g={},$=null,R=null,I=null,H=0,J=()=>{let l=y.get();return !l.lastFetched||o===0?true:Date.now()-l.lastFetched>o},ge=()=>{y.set({...y.get(),data:i,lastFetched:void 0});},Te=()=>{R&&clearTimeout(R),d>0&&(R=setTimeout(ge,d));},B=()=>{$&&(clearInterval($),$=null),R&&(clearTimeout(R),R=null),I&&typeof window<"u"&&(window.removeEventListener("focus",I),I=null);},X=()=>{C()&&(typeof window>"u"||(m&&m>0&&($=setInterval(()=>{k(void 0,0,false);},m)),T&&(I=()=>{J()&&k(void 0,0,false);},window.addEventListener("focus",I))));},k=async(l,b=r,M=false)=>{if(!C()||(l!==void 0&&(g={...g,...l}),!M&&!J()&&y.get().data!==null))return;if(N.has(E))return N.get(E);let L=y.get();y.set({...L,loading:true,error:null,data:L.data,isPlaceholderData:u&&L.data!==null});let Z=(async()=>{try{let j={...g};if(D){let V=y.get().pagination;V&&(j.page=V.page,j.pageSize=V.pageSize);}let w=x?await e(j):await e(),S,ee,te;if(w&&typeof w=="object"&&"data"in w){let V=w;S=V.data,ee=V.total,te=V.hasMore;}else S=w;let z=y.get();D&&h==="accumulate"&&z.data&&Array.isArray(z.data)&&Array.isArray(S)&&(S=[...z.data,...S]),y.set({loading:!1,error:null,data:S,lastFetched:Date.now(),isPlaceholderData:!1,pagination:D?{...z.pagination,total:ee,hasMore:te}:void 0}),Te(),f&&f(S);}catch(j){if(b>0)return await new Promise(S=>setTimeout(S,p)),N.delete(E),k(l,b-1,M);let w=y.get();y.set({loading:false,error:j,data:w.data,lastFetched:w.lastFetched,isPlaceholderData:false,pagination:w.pagination}),n&&n(j);}finally{N.delete(E);}})();return N.set(E,Z),Z};X(),C()&&!x&&k();let Y={...y,subscribe:l=>{H++;let b=y.subscribe(l);return ()=>{b(),H--;}},reload:async l=>{await k(l,r,true);},refresh:async l=>{await k(l,r,false);},mutate:l=>{let b=y.get();y.set({...b,data:l(b.data)});},reset:()=>{B(),g={},y.set({...P,loading:C()&&!x}),X(),C()&&!x&&k();},cleanup:()=>{H<=0&&B();},forceCleanup:()=>{B();},setParams:l=>{let b={...g};for(let M in l)l[M]===null?delete b[M]:b[M]=l[M];g=b,C()&&k(g,r,true);},clearParams:()=>{g={},C()&&k(void 0,r,true);}};return D?{...Y,nextPage:async()=>{let l=y.get();!l.pagination||l.pagination.hasMore===false||(y.set({...l,pagination:{...l.pagination,page:l.pagination.page+1}}),await k(g,r,true));},prevPage:async()=>{let l=y.get();!l.pagination||l.pagination.page<=1||(y.set({...l,pagination:{...l.pagination,page:l.pagination.page-1}}),await k(g,r,true));},goToPage:async l=>{let b=y.get();!b.pagination||l<1||(y.set({...b,pagination:{...b.pagination,page:l}}),await k(g,r,true));},resetPagination:async()=>{let l=y.get();l.pagination&&(y.set({...l,data:h==="accumulate"?i:l.data,pagination:{...l.pagination,page:A?.initialPage||1}}),await k(g,r,true));}}:Y}function ye(e,a={}){let{pageSize:t=10,...c}=a;return K(e,{...c,pagination:{pageSize:t,mode:"accumulate",initialPage:1}})}function pe(e){let a=Object.entries(e),t=a.reduce((r,[p,u])=>(r[p]=u.get().data,r),{}),c=a.reduce((r,[p,u])=>{let o=u.get().error;return o&&(r[p]=o),r},{}),i=a.some(([,r])=>r.get().loading),s=a.find(([,r])=>r.get().error)?.[1].get().error??null,n=v({loading:i,error:s,errors:c,data:t});return a.forEach(([r,p])=>{p.subscribe(()=>{let u=false,o=null,d={},m={...n.get().data};a.forEach(([T,A])=>{let E=A.get();E.loading&&(u=true),E.error&&(o||(o=E.error),d[T]=E.error),m[T]=E.data;}),n.set({loading:u,error:o,errors:d,data:m});});}),n}function me(e,a={}){let t=F().mutation??{},{invalidates:c=[],onSuccess:i=t.onSuccess,onError:s=t.onError,onSettled:f}=a,n={loading:false,data:null,error:null,isSuccess:false},r=v(n);return {mutate:async(...u)=>{let o=u[0];r.set({loading:true,data:null,error:null,isSuccess:false});try{let d=await e(o);return r.set({loading:!1,data:d,error:null,isSuccess:!0}),c.length>0&&await Promise.all(c.map(m=>m.reload())),i&&i(d,o),f&&f(d,null,o),{data:d,error:null}}catch(d){let m=d;return r.set({loading:false,data:null,error:m,isSuccess:false}),s&&s(m,o),f&&f(null,m,o),{data:null,error:m}}},get:()=>r.get(),subscribe:u=>r.subscribe(u),reset:()=>r.set(n)}}exports.batch=xe;exports.chunk=v;exports.computed=oe;exports.getChunkMeta=ke;exports.middleware=ce;exports.query=he;exports.select=ae;