dev-react-microstore 4.0.1 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,9 +1,34 @@
1
1
  type StoreListener = () => void;
2
+ type MiddlewareFunction<T extends object> = (currentState: T, update: Partial<T>, next: (modifiedUpdate?: Partial<T>) => void) => void;
3
+ /**
4
+ * Creates a new reactive store with fine-grained subscriptions and middleware support.
5
+ *
6
+ * @param initialState - The initial state object for the store
7
+ * @returns Store object with methods: get, set, subscribe, select, addMiddleware, onChange
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const store = createStoreState({ count: 0, name: 'John' });
12
+ * store.set({ count: 1 }); // Update state
13
+ * const { count } = useStoreSelector(store, ['count']); // Subscribe in React
14
+ * ```
15
+ */
2
16
  declare function createStoreState<T extends object>(initialState: T): {
3
17
  get: () => T;
4
- set: (next: Partial<T>, debounceDelay?: number | boolean) => void;
18
+ getKey: <K extends keyof T>(key: K) => T[K];
19
+ set: (update: Partial<T>) => void;
20
+ setKey: <K extends keyof T>(key: K, value: T[K]) => void;
21
+ merge: <K extends keyof T>(key: K, value: T[K] extends object ? Partial<T[K]> : never) => T[K];
22
+ mergeSet: <K extends keyof T>(key: K, value: T[K] extends object ? Partial<T[K]> : never) => void;
23
+ reset: (keys?: (keyof T)[]) => void;
24
+ batch: (fn: () => void) => void;
5
25
  subscribe: (keys: (keyof T)[], listener: StoreListener) => (() => void);
6
26
  select: <K extends keyof T>(keys: K[]) => Pick<T, K>;
27
+ addMiddleware: (callbackOrTuple: MiddlewareFunction<T> | [MiddlewareFunction<T>, (keyof T)[]], affectedKeys?: (keyof T)[] | null) => () => void;
28
+ onChange: <K extends keyof T>(keys: K[], callback: (values: Pick<T, K>, prev: Pick<T, K>) => void) => (() => void);
29
+ skipSetWhen: <K extends keyof T>(key: K, fn: (prev: T[K], next: T[K]) => boolean) => void;
30
+ removeSkipSetWhen: (key: keyof T) => void;
31
+ _eqReg: Record<string, ((prev: any, next: any) => boolean) | undefined>;
7
32
  };
8
33
  type StoreType<T extends object> = ReturnType<typeof createStoreState<T>>;
9
34
  type PrimitiveKey<T extends object> = keyof T;
@@ -17,6 +42,108 @@ type ExtractSelectorKeys<T extends object, S extends SelectorInput<T>> = {
17
42
  [K in S[number] extends infer Item ? Item extends keyof T ? Item : keyof Item : never]: T[K];
18
43
  };
19
44
  type Picked<T extends object, S extends SelectorInput<T>> = ExtractSelectorKeys<T, S>;
45
+ /**
46
+ * React hook that subscribes to specific keys in a store with fine-grained re-renders.
47
+ * Only re-renders when the selected keys actually change (using Object.is comparison).
48
+ *
49
+ * @param store - The store created with createStoreState
50
+ * @param selector - Array of keys to subscribe to, or objects with custom compare functions
51
+ * @returns Selected state values from the store
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * // Subscribe to specific keys
56
+ * const { count, name } = useStoreSelector(store, ['count', 'name']);
57
+ *
58
+ * // Custom comparison for complex objects
59
+ * const { tasks } = useStoreSelector(store, [
60
+ * { tasks: (prev, next) => prev.length === next.length }
61
+ * ]);
62
+ * ```
63
+ */
20
64
  declare function useStoreSelector<T extends object, S extends SelectorInput<T>>(store: StoreType<T>, selector: S): Picked<T, S>;
65
+ /**
66
+ * Creates a pre-bound selector hook for a specific store instance.
67
+ * Infers the state type from the store — no manual generics needed.
68
+ *
69
+ * @param store - The store created with createStoreState
70
+ * @returns A React hook with the same API as useStoreSelector, but with the store already bound
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * const useMyStore = createSelectorHook(myStore);
75
+ *
76
+ * // In a component:
77
+ * const { count, name } = useMyStore(['count', 'name']);
78
+ * ```
79
+ */
80
+ declare function createSelectorHook<T extends object>(store: StoreType<T>): <S extends SelectorInput<T>>(selector: S) => Picked<T, S>;
81
+ /**
82
+ * Interface for synchronous storage (localStorage, sessionStorage, etc.).
83
+ */
84
+ interface StorageSupportingInterface {
85
+ getItem(key: string): string | null;
86
+ setItem(key: string, value: string): void;
87
+ }
88
+ /**
89
+ * Interface for asynchronous storage (React Native AsyncStorage, etc.).
90
+ */
91
+ interface AsyncStorageSupportingInterface {
92
+ getItem(key: string): Promise<string | null>;
93
+ setItem(key: string, value: string): Promise<void>;
94
+ }
95
+ type AnyStorage = Storage | StorageSupportingInterface | AsyncStorageSupportingInterface;
96
+ /**
97
+ * Creates a persistence middleware that saves individual keys to storage.
98
+ * Only writes when the specified keys actually change, using per-key storage.
99
+ * Storage format: `${persistKey}:${keyName}` for each persisted key.
100
+ *
101
+ * Works with both synchronous storage (localStorage) and asynchronous storage
102
+ * (React Native AsyncStorage). Async writes are fire-and-forget — the state
103
+ * update is never blocked by a slow write.
104
+ *
105
+ * @param storage - Storage interface (localStorage, sessionStorage, AsyncStorage, etc.)
106
+ * @param persistKey - Base key prefix for storage (e.g., 'myapp' creates 'myapp:theme')
107
+ * @param keys - Array of state keys to persist
108
+ * @returns Tuple of [middleware function, affected keys] for use with addMiddleware
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * // Sync — localStorage
113
+ * store.addMiddleware(
114
+ * createPersistenceMiddleware(localStorage, 'myapp', ['theme', 'isLoggedIn'])
115
+ * );
116
+ *
117
+ * // Async — React Native AsyncStorage
118
+ * store.addMiddleware(
119
+ * createPersistenceMiddleware(AsyncStorage, 'myapp', ['theme', 'isLoggedIn'])
120
+ * );
121
+ * ```
122
+ */
123
+ declare function createPersistenceMiddleware<T extends object>(storage: AnyStorage, persistKey: string, keys: (keyof T)[]): [MiddlewareFunction<T>, (keyof T)[]];
124
+ /**
125
+ * Loads persisted state from individual key storage during store initialization.
126
+ * Reads keys saved by createPersistenceMiddleware and returns them as partial state.
127
+ *
128
+ * Returns synchronously for sync storage and a Promise for async storage.
129
+ *
130
+ * @param storage - Storage interface to read from (same as used in middleware)
131
+ * @param persistKey - Base key prefix used for storage (same as used in middleware)
132
+ * @param keys - Array of keys to restore (should match middleware keys)
133
+ * @returns Partial state object (sync) or Promise of partial state (async)
134
+ *
135
+ * @example
136
+ * ```ts
137
+ * // Sync — localStorage
138
+ * const persisted = loadPersistedState(localStorage, 'myapp', ['theme']);
139
+ * const store = createStoreState({ theme: 'light', ...persisted });
140
+ *
141
+ * // Async — React Native AsyncStorage
142
+ * const persisted = await loadPersistedState(AsyncStorage, 'myapp', ['theme']);
143
+ * const store = createStoreState({ theme: 'light', ...persisted });
144
+ * ```
145
+ */
146
+ declare function loadPersistedState<T extends object>(storage: Storage | StorageSupportingInterface, persistKey: string, keys: (keyof T)[]): Partial<T>;
147
+ declare function loadPersistedState<T extends object>(storage: AsyncStorageSupportingInterface, persistKey: string, keys: (keyof T)[]): Promise<Partial<T>>;
21
148
 
22
- export { createStoreState, useStoreSelector };
149
+ export { type AsyncStorageSupportingInterface, type StorageSupportingInterface, createPersistenceMiddleware, createSelectorHook, createStoreState, loadPersistedState, useStoreSelector };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var K=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var j=Object.prototype.hasOwnProperty;var I=(o,e)=>{for(var n in e)K(o,n,{get:e[n],enumerable:!0})},R=(o,e,n,c)=>{if(e&&typeof e=="object"||typeof e=="function")for(let p of v(e))!j.call(o,p)&&p!==n&&K(o,p,{get:()=>e[p],enumerable:!(c=P(e,p))||c.enumerable});return o};var C=o=>R(K({},"__esModule",{value:!0}),o);var w={};I(w,{createStoreState:()=>F,useStoreSelector:()=>E});module.exports=C(w);var f=require("react");function V(o,e){let n;return(...c)=>{clearTimeout(n),n=setTimeout(()=>o(...c),e)}}function F(o){let e=o,n=new Map,c=new Map;return{get:()=>e,set:(i,a=!1)=>{var S;if(!i)return;let r=[];for(let k in i){let t=k,l=e[t],T=i[t];l!==T&&(Object.is(l,T)||(e[t]=T,r.push(t)))}if(r.length!==0)for(let k of r)a!==!1?(c.has(k)||c.set(k,V(()=>{var t;(t=n.get(k))==null||t.forEach(l=>l())},typeof a=="number"?a:0)),c.get(k)()):(S=n.get(k))==null||S.forEach(t=>t())},subscribe:(i,a)=>{for(let r of i)n.has(r)||n.set(r,new Set),n.get(r).add(a);return()=>{var r;for(let S of i)(r=n.get(S))==null||r.delete(a)}},select:i=>{let a={},r=e;for(let S of i)a[S]=r[S];return a}}}function z(o,e){return o.length===e.length&&o.every((n,c)=>n===e[c])}function E(o,e){let n=(0,f.useRef)({}),c=(0,f.useRef)(null),p=(0,f.useRef)(null),x=(0,f.useRef)(null),h=(0,f.useRef)(!0),b=(0,f.useRef)({}),i=(0,f.useRef)(null);if(!c.current||!z(c.current,e)){let t=[],l=[];for(let T of e)if(typeof T=="string"){let d=T;t.push({key:d}),l.push(d)}else{let d=T;for(let s in d){let y=d[s],u=s;t.push({key:u,compare:y}),l.push(u)}}p.current=t,x.current=l,c.current=e,i.current=null}let a=p.current,r=x.current,S=()=>{let t=o.get();if(h.current){h.current=!1;let s={};for(let{key:y}of a){let u=t[y];b.current[y]=u,s[y]=u}return n.current=s,s}if(!(()=>{var s;for(let{key:y,compare:u}of a){let m=b.current[y],g=t[y];if(m===void 0||((s=u==null?void 0:u(m,g))!=null?s:!Object.is(m,g)))return!0}return!1})())return n.current;let d={};for(let{key:s,compare:y}of a){let u=b.current[s],m=t[s];u===void 0||(y?!y(u,m):!Object.is(u,m))?(b.current[s]=m,d[s]=m):d[s]=u}return n.current=d,d},k=(0,f.useMemo)(()=>{let t=o.get(),l={};for(let T of r)l[T]=t[T];return l},[r]);return i.current||(i.current=t=>o.subscribe(r,t)),(0,f.useSyncExternalStore)(i.current,S,()=>k)}0&&(module.exports={createStoreState,useStoreSelector});
1
+ "use strict";var F=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var q=Object.getOwnPropertyNames,R=Object.getOwnPropertySymbols;var A=Object.prototype.hasOwnProperty,L=Object.prototype.propertyIsEnumerable;var V=(o,i,r)=>i in o?F(o,i,{enumerable:!0,configurable:!0,writable:!0,value:r}):o[i]=r,h=(o,i)=>{for(var r in i||(i={}))A.call(i,r)&&V(o,r,i[r]);if(R)for(var r of R(i))L.call(i,r)&&V(o,r,i[r]);return o};var N=(o,i)=>{for(var r in i)F(o,r,{get:i[r],enumerable:!0})},W=(o,i,r,t)=>{if(i&&typeof i=="object"||typeof i=="function")for(let l of q(i))!A.call(o,l)&&l!==r&&F(o,l,{get:()=>i[l],enumerable:!(t=$(i,l))||t.enumerable});return o};var _=o=>W(F({},"__esModule",{value:!0}),o);var Q={};N(Q,{createPersistenceMiddleware:()=>D,createSelectorHook:()=>B,createStoreState:()=>J,loadPersistedState:()=>G,useStoreSelector:()=>z});module.exports=_(Q);var I=require("react");function J(o){let i=h({},o),r=o,t=Object.create(null),l=[],f=Object.create(null),S=null,m=()=>r,k=e=>r[e],p=e=>{var n;if(S){S.add(e);return}(n=t[e])==null||n.forEach(s=>s())},u=(e,n)=>{if(Object.is(r[e],n))return;let s=f[e];s&&s(r[e],n)||(r[e]=n,p(e))},d=(e,n)=>{if(l.length===0){u(e,n);return}let s={};s[e]=n,b(s)},y=(e,n)=>h(h({},r[e]),n),K=(e,n)=>{if(l.length===0){u(e,h(h({},r[e]),n));return}let s={};s[e]=h(h({},r[e]),n),b(s)},P=e=>{if(!e)b(h({},i));else{let n={};for(let s of e)n[s]=i[s];b(n)}},x=e=>{var n;if(S){e();return}S=new Set;try{e()}finally{let s=S;S=null;let c=new Set;for(let T of s)(n=t[T])==null||n.forEach(a=>{c.has(a)||(c.add(a),a())})}},b=e=>{if(!e)return;if(l.length===0){v(e);return}let n=e,s=0,c=!1,T=a=>{if(a!==void 0&&(n=a),s>=l.length){c||v(n);return}let g=l[s++];if(!g.keys||g.keys.some(w=>w in n)){let w=!1,j=M=>{w||(w=!0,T(M))};try{g.callback(r,n,j)}catch(M){c=!0,console.error("Middleware error:",M);return}if(!w){c=!0;return}}else T()};T()},v=e=>{var s,c;let n=[];for(let T in e){let a=T;if(Object.is(r[a],e[a]))continue;let g=f[T];g&&g(r[a],e[a])||(r[a]=e[a],n.push(T))}if(n.length!==0){if(S){for(let T of n)S.add(T);return}if(n.length===1)(s=t[n[0]])==null||s.forEach(T=>T());else{let T=new Set;for(let a of n)(c=t[a])==null||c.forEach(g=>{T.has(g)||(T.add(g),g())})}}},O=(e,n=null)=>{let s,c;Array.isArray(e)?[s,c]=e:(s=e,c=n);let T={callback:s,keys:c};return l.push(T),()=>{let a=l.indexOf(T);a>-1&&l.splice(a,1)}},C=(e,n)=>{for(let s of e){let c=s;t[c]||(t[c]=new Set),t[c].add(n)}return()=>{var s;for(let c of e)(s=t[c])==null||s.delete(n)}};return{get:m,getKey:k,set:b,setKey:d,merge:y,mergeSet:K,reset:P,batch:x,subscribe:C,select:e=>{let n={},s=r;for(let c of e)n[c]=s[c];return n},addMiddleware:O,onChange:(e,n)=>{let s={};for(let a of e)s[a]=r[a];let c=!1;return C(e,()=>{c||(c=!0,queueMicrotask(()=>{c=!1;let a=!1;for(let j of e)if(!Object.is(r[j],s[j])){a=!0;break}if(!a)return;let g={};for(let j of e)g[j]=r[j];let w=s;s=g,n(g,w)}))})},skipSetWhen:(e,n)=>{f[e]=n},removeSkipSetWhen:e=>{delete f[e]},_eqReg:f}}function H(o,i){return o.length===i.length&&o.every((r,t)=>r===i[t])}function z(o,i){let t=(0,I.useRef)({lastSelected:{},prevSelector:null,normalized:null,keys:null,isFirstRun:!0,lastValues:{},subscribe:null,store:o}).current,l=t.store!==o;if(l&&(t.store=o,t.lastSelected={},t.prevSelector=null,t.normalized=null,t.keys=null,t.isFirstRun=!0,t.lastValues={},t.subscribe=null),!t.prevSelector||!H(t.prevSelector,i)){let p=[],u=[];for(let d of i)if(typeof d=="string"){let y=d;p.push({key:y}),u.push(y)}else{let y=d;for(let K in y){let P=y[K],x=K;p.push({key:x,compare:P}),u.push(x)}}t.normalized=p,t.keys=u,t.prevSelector=i,t.subscribe=null}let f=t.normalized,S=t.keys,m=()=>{let p=o.get();if(t.isFirstRun){t.isFirstRun=!1;let d={};for(let{key:y}of f){let K=p[y];t.lastValues[y]=K,d[y]=K}return t.lastSelected=d,d}let u=null;for(let d=0;d<f.length;d++){let{key:y,compare:K}=f[d],P=t.lastValues[y],x=p[y];if(!Object.is(P,x)){let b=K||o._eqReg[y];if(!b||!b(P,x)){if(!u){u={};for(let v=0;v<d;v++)u[f[v].key]=t.lastValues[f[v].key]}t.lastValues[y]=x,u[y]=x;continue}}u&&(u[y]=P)}return u?(t.lastSelected=u,u):t.lastSelected},k=(0,I.useMemo)(()=>{let p=o.get(),u={};for(let d of S)u[d]=p[d];return u},[S]);return(!t.subscribe||l)&&(t.subscribe=p=>o.subscribe(S,p)),(0,I.useSyncExternalStore)(t.subscribe,m,()=>k)}function B(o){return function(i){return z(o,i)}}function E(o){return o!=null&&typeof o.then=="function"}function D(o,i,r){return[(l,f,S)=>{let m=r.filter(k=>k in f);if(m.length===0)return S();for(let k of m)try{let p=f[k],u=`${i}:${String(k)}`,d=o.setItem(u,JSON.stringify(p));E(d)&&d.catch(y=>{console.warn(`Failed to persist key ${String(k)}:`,y)})}catch(p){console.warn(`Failed to persist key ${String(k)}:`,p)}S()},r]}function G(o,i,r){let t={},l=[];for(let f of r){let S=`${i}:${String(f)}`;try{let m=o.getItem(S);E(m)?l.push(m.then(k=>{k!==null&&(t[f]=JSON.parse(k))}).catch(k=>{console.warn(`Failed to load persisted key ${String(f)}:`,k)})):m!==null&&(t[f]=JSON.parse(m))}catch(m){console.warn(`Failed to load persisted key ${String(f)}:`,m)}}return l.length>0?Promise.all(l).then(()=>t):t}0&&(module.exports={createPersistenceMiddleware,createSelectorHook,createStoreState,loadPersistedState,useStoreSelector});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{useMemo as K,useRef as k,useSyncExternalStore as P}from"react";function v(T,s){let n;return(...a)=>{clearTimeout(n),n=setTimeout(()=>T(...a),s)}}function C(T){let s=T,n=new Map,a=new Map;return{get:()=>s,set:(c,u=!1)=>{var d;if(!c)return;let t=[];for(let p in c){let e=p,i=s[e],l=c[e];i!==l&&(Object.is(i,l)||(s[e]=l,t.push(e)))}if(t.length!==0)for(let p of t)u!==!1?(a.has(p)||a.set(p,v(()=>{var e;(e=n.get(p))==null||e.forEach(i=>i())},typeof u=="number"?u:0)),a.get(p)()):(d=n.get(p))==null||d.forEach(e=>e())},subscribe:(c,u)=>{for(let t of c)n.has(t)||n.set(t,new Set),n.get(t).add(u);return()=>{var t;for(let d of c)(t=n.get(d))==null||t.delete(u)}},select:c=>{let u={},t=s;for(let d of c)u[d]=t[d];return u}}}function j(T,s){return T.length===s.length&&T.every((n,a)=>n===s[a])}function V(T,s){let n=k({}),a=k(null),b=k(null),x=k(null),h=k(!0),m=k({}),c=k(null);if(!a.current||!j(a.current,s)){let e=[],i=[];for(let l of s)if(typeof l=="string"){let y=l;e.push({key:y}),i.push(y)}else{let y=l;for(let o in y){let f=y[o],r=o;e.push({key:r,compare:f}),i.push(r)}}b.current=e,x.current=i,a.current=s,c.current=null}let u=b.current,t=x.current,d=()=>{let e=T.get();if(h.current){h.current=!1;let o={};for(let{key:f}of u){let r=e[f];m.current[f]=r,o[f]=r}return n.current=o,o}if(!(()=>{var o;for(let{key:f,compare:r}of u){let S=m.current[f],g=e[f];if(S===void 0||((o=r==null?void 0:r(S,g))!=null?o:!Object.is(S,g)))return!0}return!1})())return n.current;let y={};for(let{key:o,compare:f}of u){let r=m.current[o],S=e[o];r===void 0||(f?!f(r,S):!Object.is(r,S))?(m.current[o]=S,y[o]=S):y[o]=r}return n.current=y,y},p=K(()=>{let e=T.get(),i={};for(let l of t)i[l]=e[l];return i},[t]);return c.current||(c.current=e=>T.subscribe(t,e)),P(c.current,d,()=>p)}export{C as createStoreState,V as useStoreSelector};
1
+ var A=Object.defineProperty;var M=Object.getOwnPropertySymbols;var z=Object.prototype.hasOwnProperty,E=Object.prototype.propertyIsEnumerable;var C=(s,i,o)=>i in s?A(s,i,{enumerable:!0,configurable:!0,writable:!0,value:o}):s[i]=o,h=(s,i)=>{for(var o in i||(i={}))z.call(i,o)&&C(s,o,i[o]);if(M)for(var o of M(i))E.call(i,o)&&C(s,o,i[o]);return s};import{useMemo as O,useRef as $,useSyncExternalStore as q}from"react";function G(s){let i=h({},s),o=s,t=Object.create(null),S=[],u=Object.create(null),T=null,m=()=>o,k=e=>o[e],p=e=>{var n;if(T){T.add(e);return}(n=t[e])==null||n.forEach(r=>r())},l=(e,n)=>{if(Object.is(o[e],n))return;let r=u[e];r&&r(o[e],n)||(o[e]=n,p(e))},f=(e,n)=>{if(S.length===0){l(e,n);return}let r={};r[e]=n,b(r)},d=(e,n)=>h(h({},o[e]),n),K=(e,n)=>{if(S.length===0){l(e,h(h({},o[e]),n));return}let r={};r[e]=h(h({},o[e]),n),b(r)},P=e=>{if(!e)b(h({},i));else{let n={};for(let r of e)n[r]=i[r];b(n)}},x=e=>{var n;if(T){e();return}T=new Set;try{e()}finally{let r=T;T=null;let c=new Set;for(let y of r)(n=t[y])==null||n.forEach(a=>{c.has(a)||(c.add(a),a())})}},b=e=>{if(!e)return;if(S.length===0){v(e);return}let n=e,r=0,c=!1,y=a=>{if(a!==void 0&&(n=a),r>=S.length){c||v(n);return}let g=S[r++];if(!g.keys||g.keys.some(w=>w in n)){let w=!1,j=I=>{w||(w=!0,y(I))};try{g.callback(o,n,j)}catch(I){c=!0,console.error("Middleware error:",I);return}if(!w){c=!0;return}}else y()};y()},v=e=>{var r,c;let n=[];for(let y in e){let a=y;if(Object.is(o[a],e[a]))continue;let g=u[y];g&&g(o[a],e[a])||(o[a]=e[a],n.push(y))}if(n.length!==0){if(T){for(let y of n)T.add(y);return}if(n.length===1)(r=t[n[0]])==null||r.forEach(y=>y());else{let y=new Set;for(let a of n)(c=t[a])==null||c.forEach(g=>{y.has(g)||(y.add(g),g())})}}},V=(e,n=null)=>{let r,c;Array.isArray(e)?[r,c]=e:(r=e,c=n);let y={callback:r,keys:c};return S.push(y),()=>{let a=S.indexOf(y);a>-1&&S.splice(a,1)}},F=(e,n)=>{for(let r of e){let c=r;t[c]||(t[c]=new Set),t[c].add(n)}return()=>{var r;for(let c of e)(r=t[c])==null||r.delete(n)}};return{get:m,getKey:k,set:b,setKey:f,merge:d,mergeSet:K,reset:P,batch:x,subscribe:F,select:e=>{let n={},r=o;for(let c of e)n[c]=r[c];return n},addMiddleware:V,onChange:(e,n)=>{let r={};for(let a of e)r[a]=o[a];let c=!1;return F(e,()=>{c||(c=!0,queueMicrotask(()=>{c=!1;let a=!1;for(let j of e)if(!Object.is(o[j],r[j])){a=!0;break}if(!a)return;let g={};for(let j of e)g[j]=o[j];let w=r;r=g,n(g,w)}))})},skipSetWhen:(e,n)=>{u[e]=n},removeSkipSetWhen:e=>{delete u[e]},_eqReg:u}}function L(s,i){return s.length===i.length&&s.every((o,t)=>o===i[t])}function N(s,i){let t=$({lastSelected:{},prevSelector:null,normalized:null,keys:null,isFirstRun:!0,lastValues:{},subscribe:null,store:s}).current,S=t.store!==s;if(S&&(t.store=s,t.lastSelected={},t.prevSelector=null,t.normalized=null,t.keys=null,t.isFirstRun=!0,t.lastValues={},t.subscribe=null),!t.prevSelector||!L(t.prevSelector,i)){let p=[],l=[];for(let f of i)if(typeof f=="string"){let d=f;p.push({key:d}),l.push(d)}else{let d=f;for(let K in d){let P=d[K],x=K;p.push({key:x,compare:P}),l.push(x)}}t.normalized=p,t.keys=l,t.prevSelector=i,t.subscribe=null}let u=t.normalized,T=t.keys,m=()=>{let p=s.get();if(t.isFirstRun){t.isFirstRun=!1;let f={};for(let{key:d}of u){let K=p[d];t.lastValues[d]=K,f[d]=K}return t.lastSelected=f,f}let l=null;for(let f=0;f<u.length;f++){let{key:d,compare:K}=u[f],P=t.lastValues[d],x=p[d];if(!Object.is(P,x)){let b=K||s._eqReg[d];if(!b||!b(P,x)){if(!l){l={};for(let v=0;v<f;v++)l[u[v].key]=t.lastValues[u[v].key]}t.lastValues[d]=x,l[d]=x;continue}}l&&(l[d]=P)}return l?(t.lastSelected=l,l):t.lastSelected},k=O(()=>{let p=s.get(),l={};for(let f of T)l[f]=p[f];return l},[T]);return(!t.subscribe||S)&&(t.subscribe=p=>s.subscribe(T,p)),q(t.subscribe,m,()=>k)}function Q(s){return function(i){return N(s,i)}}function R(s){return s!=null&&typeof s.then=="function"}function X(s,i,o){return[(S,u,T)=>{let m=o.filter(k=>k in u);if(m.length===0)return T();for(let k of m)try{let p=u[k],l=`${i}:${String(k)}`,f=s.setItem(l,JSON.stringify(p));R(f)&&f.catch(d=>{console.warn(`Failed to persist key ${String(k)}:`,d)})}catch(p){console.warn(`Failed to persist key ${String(k)}:`,p)}T()},o]}function Y(s,i,o){let t={},S=[];for(let u of o){let T=`${i}:${String(u)}`;try{let m=s.getItem(T);R(m)?S.push(m.then(k=>{k!==null&&(t[u]=JSON.parse(k))}).catch(k=>{console.warn(`Failed to load persisted key ${String(u)}:`,k)})):m!==null&&(t[u]=JSON.parse(m))}catch(m){console.warn(`Failed to load persisted key ${String(u)}:`,m)}}return S.length>0?Promise.all(S).then(()=>t):t}export{X as createPersistenceMiddleware,Q as createSelectorHook,G as createStoreState,Y as loadPersistedState,N as useStoreSelector};
@@ -0,0 +1,54 @@
1
+ # React + TypeScript + Vite
2
+
3
+ This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4
+
5
+ Currently, two official plugins are available:
6
+
7
+ - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
8
+ - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9
+
10
+ ## Expanding the ESLint configuration
11
+
12
+ If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
13
+
14
+ ```js
15
+ export default tseslint.config({
16
+ extends: [
17
+ // Remove ...tseslint.configs.recommended and replace with this
18
+ ...tseslint.configs.recommendedTypeChecked,
19
+ // Alternatively, use this for stricter rules
20
+ ...tseslint.configs.strictTypeChecked,
21
+ // Optionally, add this for stylistic rules
22
+ ...tseslint.configs.stylisticTypeChecked,
23
+ ],
24
+ languageOptions: {
25
+ // other options...
26
+ parserOptions: {
27
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
28
+ tsconfigRootDir: import.meta.dirname,
29
+ },
30
+ },
31
+ })
32
+ ```
33
+
34
+ You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
35
+
36
+ ```js
37
+ // eslint.config.js
38
+ import reactX from 'eslint-plugin-react-x'
39
+ import reactDom from 'eslint-plugin-react-dom'
40
+
41
+ export default tseslint.config({
42
+ plugins: {
43
+ // Add the react-x and react-dom plugins
44
+ 'react-x': reactX,
45
+ 'react-dom': reactDom,
46
+ },
47
+ rules: {
48
+ // other rules...
49
+ // Enable its recommended typescript rules
50
+ ...reactX.configs['recommended-typescript'].rules,
51
+ ...reactDom.configs.recommended.rules,
52
+ },
53
+ })
54
+ ```
@@ -0,0 +1,28 @@
1
+ import js from '@eslint/js'
2
+ import globals from 'globals'
3
+ import reactHooks from 'eslint-plugin-react-hooks'
4
+ import reactRefresh from 'eslint-plugin-react-refresh'
5
+ import tseslint from 'typescript-eslint'
6
+
7
+ export default tseslint.config(
8
+ { ignores: ['dist'] },
9
+ {
10
+ extends: [js.configs.recommended, ...tseslint.configs.recommended],
11
+ files: ['**/*.{ts,tsx}'],
12
+ languageOptions: {
13
+ ecmaVersion: 2020,
14
+ globals: globals.browser,
15
+ },
16
+ plugins: {
17
+ 'react-hooks': reactHooks,
18
+ 'react-refresh': reactRefresh,
19
+ },
20
+ rules: {
21
+ ...reactHooks.configs.recommended.rules,
22
+ 'react-refresh/only-export-components': [
23
+ 'warn',
24
+ { allowConstantExport: true },
25
+ ],
26
+ },
27
+ },
28
+ )
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Vite + React + TS</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.tsx"></script>
12
+ </body>
13
+ </html>