dev-react-microstore 1.1.1 → 1.1.2

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.js CHANGED
@@ -1 +1 @@
1
- "use strict";var S=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames,j=Object.getOwnPropertySymbols;var g=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable;var K=(r,e,t)=>e in r?S(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,k=(r,e)=>{for(var t in e||(e={}))g.call(e,t)&&K(r,t,e[t]);if(j)for(var t of j(e))v.call(e,t)&&K(r,t,e[t]);return r};var I=(r,e)=>{for(var t in e)S(r,t,{get:e[t],enumerable:!0})},C=(r,e,t,y)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of h(e))!g.call(r,a)&&a!==t&&S(r,a,{get:()=>e[a],enumerable:!(y=P(e,a))||y.enumerable});return r};var O=r=>C(S({},"__esModule",{value:!0}),r);var R={};I(R,{createStoreState:()=>V,useStoreSelector:()=>F});module.exports=O(R);var p=require("react");function V(r){let e=r,t=new Map;return{get:()=>e,set:s=>{var c;if(s==null||typeof s!="object"||Array.isArray(s)){console.error(`set() called with invalid value: ${s===null?"null":s===void 0?"undefined":typeof s}`);return}let o=!1,n=[];for(let d in s)if(Object.prototype.hasOwnProperty.call(s,d)){let i=d;i in e&&!Object.is(e[i],s[i])&&(o=!0,n.push(i))}if(o){e=k(k({},e),s);for(let d of n)(c=t.get(d))==null||c.forEach(i=>i())}},subscribe:(s,o)=>{for(let n of s)t.has(n)||t.set(n,new Set),t.get(n).add(o);return()=>{var n;for(let c of s)(n=t.get(c))==null||n.delete(o)}},select:s=>{let o={},n=e;for(let c of s)o[c]=n[c];return o}}}function F(r,e){let t=(0,p.useRef)(r.get()),y=(0,p.useRef)({}),a=e.flatMap(o=>typeof o=="string"?[{key:o}]:Object.entries(o).map(([n,c])=>({key:n,compare:c}))),b=()=>{let o=r.get(),n=t.current;if(!(!y.current||Object.keys(y.current).length===0||a.some(({key:u,compare:f})=>{let T=n[u],l=o[u];return f?f(T,l):!Object.is(T,l)})))return y.current;t.current=o;let i={};for(let{key:u,compare:f}of a){let T=y.current[u],l=o[u],x=f?f(T,l):!Object.is(T,l);i[u]=x?l:T}return y.current=i,i},m=(()=>{let o=r.get();return a.reduce((n,{key:c})=>(n[c]=o[c],n),{})})();return(0,p.useSyncExternalStore)(o=>r.subscribe(a.map(n=>n.key),o),b,()=>m)}0&&(module.exports={createStoreState,useStoreSelector});
1
+ "use strict";var h=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames,P=Object.getOwnPropertySymbols;var I=Object.prototype.hasOwnProperty,V=Object.prototype.propertyIsEnumerable;var v=(r,e,t)=>e in r?h(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,j=(r,e)=>{for(var t in e||(e={}))I.call(e,t)&&v(r,t,e[t]);if(P)for(var t of P(e))V.call(e,t)&&v(r,t,e[t]);return r};var C=(r,e)=>{for(var t in e)h(r,t,{get:e[t],enumerable:!0})},F=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of z(e))!I.call(r,o)&&o!==t&&h(r,o,{get:()=>e[o],enumerable:!(s=R(e,o))||s.enumerable});return r};var O=r=>F(h({},"__esModule",{value:!0}),r);var A={};C(A,{createStoreState:()=>w,useStoreSelector:()=>N});module.exports=O(A);var y=require("react");function w(r){let e=r,t=new Map;return{get:()=>e,set:n=>{var i;if(n==null||typeof n!="object"||Array.isArray(n)){console.error(`set() called with invalid value: ${n===null?"null":n===void 0?"undefined":typeof n}`);return}let u=!1,c=[];for(let S in n)if(Object.prototype.hasOwnProperty.call(n,S)){let d=S;d in e&&!Object.is(e[d],n[d])&&(u=!0,c.push(d))}if(u){e=j(j({},e),n);for(let S of c)(i=t.get(S))==null||i.forEach(d=>d())}},subscribe:(n,u)=>{for(let c of n)t.has(c)||t.set(c,new Set),t.get(c).add(u);return()=>{var c;for(let i of n)(c=t.get(i))==null||c.delete(u)}},select:n=>{let u={},c=e;for(let i of n)u[i]=c[i];return u}}}function E(r,e){return r.length===e.length&&r.every((t,s)=>t===e[s])}function L(r,e,t){let s={};for(let{key:o,compare:p}of t){let T=e[o],n=r[o],u=T===void 0?!0:p?p(T,n):!Object.is(T,n);s[o]=u?n:T}return s}function N(r,e){let t=(0,y.useRef)(r.get()),s=(0,y.useRef)({}),o=(0,y.useRef)(null),p=(0,y.useRef)(null),T=(0,y.useRef)(null),n=(0,y.useRef)(!0);if(!o.current||!E(o.current,e)){let l=[],f=[];for(let a of e)if(typeof a=="string"){let b=a;l.push({key:b}),f.push(b)}else for(let[b,m]of Object.entries(a)){let k=b;l.push({key:k,compare:m}),f.push(k)}p.current=l,T.current=f,o.current=e}let u=p.current,c=T.current,i=()=>{let l=r.get(),f=t.current,a=n.current;return(a||u.some(({key:m,compare:k})=>{var x;let K=f[m],g=l[m];return(x=k==null?void 0:k(K,g))!=null?x:!Object.is(K,g)}))&&(a&&(n.current=!1),t.current=l,s.current=L(l,s.current,u)),s.current},S=(()=>{let l=r.get();return c.reduce((f,a)=>(f[a]=l[a],f),{})})();return(0,y.useSyncExternalStore)(l=>r.subscribe(c,l),i,()=>S)}0&&(module.exports={createStoreState,useStoreSelector});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var g=Object.defineProperty;var b=Object.getOwnPropertySymbols;var x=Object.prototype.hasOwnProperty,P=Object.prototype.propertyIsEnumerable;var m=(s,r,o)=>r in s?g(s,r,{enumerable:!0,configurable:!0,writable:!0,value:o}):s[r]=o,p=(s,r)=>{for(var o in r||(r={}))x.call(r,o)&&m(s,o,r[o]);if(b)for(var o of b(r))P.call(r,o)&&m(s,o,r[o]);return s};import{useRef as j,useSyncExternalStore as h}from"react";function C(s){let r=s,o=new Map;return{get:()=>r,set:n=>{var c;if(n==null||typeof n!="object"||Array.isArray(n)){console.error(`set() called with invalid value: ${n===null?"null":n===void 0?"undefined":typeof n}`);return}let e=!1,t=[];for(let d in n)if(Object.prototype.hasOwnProperty.call(n,d)){let a=d;a in r&&!Object.is(r[a],n[a])&&(e=!0,t.push(a))}if(e){r=p(p({},r),n);for(let d of t)(c=o.get(d))==null||c.forEach(a=>a())}},subscribe:(n,e)=>{for(let t of n)o.has(t)||o.set(t,new Set),o.get(t).add(e);return()=>{var t;for(let c of n)(t=o.get(c))==null||t.delete(e)}},select:n=>{let e={},t=r;for(let c of n)e[c]=t[c];return e}}}function O(s,r){let o=j(s.get()),i=j({}),l=r.flatMap(e=>typeof e=="string"?[{key:e}]:Object.entries(e).map(([t,c])=>({key:t,compare:c}))),S=()=>{let e=s.get(),t=o.current;if(!(!i.current||Object.keys(i.current).length===0||l.some(({key:y,compare:f})=>{let u=t[y],T=e[y];return f?f(u,T):!Object.is(u,T)})))return i.current;o.current=e;let a={};for(let{key:y,compare:f}of l){let u=i.current[y],T=e[y],K=f?f(u,T):!Object.is(u,T);a[y]=K?T:u}return i.current=a,a},k=(()=>{let e=s.get();return l.reduce((t,{key:c})=>(t[c]=e[c],t),{})})();return h(e=>s.subscribe(l.map(t=>t.key),e),S,()=>k)}export{C as createStoreState,O as useStoreSelector};
1
+ var v=Object.defineProperty;var x=Object.getOwnPropertySymbols;var I=Object.prototype.hasOwnProperty,R=Object.prototype.propertyIsEnumerable;var P=(n,e,t)=>e in n?v(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,h=(n,e)=>{for(var t in e||(e={}))I.call(e,t)&&P(n,t,e[t]);if(x)for(var t of x(e))R.call(e,t)&&P(n,t,e[t]);return n};import{useRef as k,useSyncExternalStore as z}from"react";function w(n){let e=n,t=new Map;return{get:()=>e,set:r=>{var l;if(r==null||typeof r!="object"||Array.isArray(r)){console.error(`set() called with invalid value: ${r===null?"null":r===void 0?"undefined":typeof r}`);return}let c=!1,o=[];for(let p in r)if(Object.prototype.hasOwnProperty.call(r,p)){let f=p;f in e&&!Object.is(e[f],r[f])&&(c=!0,o.push(f))}if(c){e=h(h({},e),r);for(let p of o)(l=t.get(p))==null||l.forEach(f=>f())}},subscribe:(r,c)=>{for(let o of r)t.has(o)||t.set(o,new Set),t.get(o).add(c);return()=>{var o;for(let l of r)(o=t.get(l))==null||o.delete(c)}},select:r=>{let c={},o=e;for(let l of r)c[l]=o[l];return c}}}function V(n,e){return n.length===e.length&&n.every((t,u)=>t===e[u])}function C(n,e,t){let u={};for(let{key:a,compare:d}of t){let y=e[a],r=n[a],c=y===void 0?!0:d?d(y,r):!Object.is(y,r);u[a]=c?r:y}return u}function E(n,e){let t=k(n.get()),u=k({}),a=k(null),d=k(null),y=k(null),r=k(!0);if(!a.current||!V(a.current,e)){let s=[],T=[];for(let i of e)if(typeof i=="string"){let b=i;s.push({key:b}),T.push(b)}else for(let[b,m]of Object.entries(i)){let S=b;s.push({key:S,compare:m}),T.push(S)}d.current=s,y.current=T,a.current=e}let c=d.current,o=y.current,l=()=>{let s=n.get(),T=t.current,i=r.current;return(i||c.some(({key:m,compare:S})=>{var g;let j=T[m],K=s[m];return(g=S==null?void 0:S(j,K))!=null?g:!Object.is(j,K)}))&&(i&&(r.current=!1),t.current=s,u.current=C(s,u.current,c)),u.current},p=(()=>{let s=n.get();return o.reduce((T,i)=>(T[i]=s[i],T),{})})();return z(s=>n.subscribe(o,s),l,()=>p)}export{w as createStoreState,E as useStoreSelector};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dev-react-microstore",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "A minimal global state manager for React with fine-grained subscriptions.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/index.ts CHANGED
@@ -89,67 +89,101 @@ type NormalizedSelector<T extends object> = {
89
89
  compare?: CompareFn<T[keyof T]>;
90
90
  };
91
91
 
92
+ // Helper functions for useStoreSelector
93
+ function shallowEqualSelector<T extends object>(
94
+ a: SelectorInput<T>,
95
+ b: SelectorInput<T>
96
+ ): boolean {
97
+ return a.length === b.length && a.every((item, i) => item === b[i]);
98
+ }
99
+
100
+ function pickKeys<T extends object>(
101
+ base: T,
102
+ prev: Partial<T>,
103
+ selectors: NormalizedSelector<T>[]
104
+ ): Partial<T> {
105
+ const out: Partial<T> = {};
106
+ for (const { key, compare } of selectors) {
107
+ const prevVal = prev[key];
108
+ const nextVal = base[key];
109
+ const changed = prevVal === undefined ? true : (compare ? compare(prevVal, nextVal) : !Object.is(prevVal, nextVal));
110
+ out[key] = changed ? nextVal : prevVal;
111
+ }
112
+ return out;
113
+ }
114
+
92
115
  export function useStoreSelector<T extends object, S extends SelectorInput<T>>(
93
116
  store: StoreType<T>,
94
117
  selector: S
95
118
  ): Picked<T, S> {
96
119
  const lastState = useRef(store.get());
97
120
  const lastSelected = useRef<Partial<T>>({});
98
-
99
- const normalized = selector.flatMap((item): NormalizedSelector<T>[] => {
100
- if (typeof item === 'string') {
101
- return [{ key: item as keyof T }];
121
+ const prevSelector = useRef<SelectorInput<T> | null>(null);
122
+ const normalizedRef = useRef<NormalizedSelector<T>[] | null>(null);
123
+ const keysRef = useRef<(keyof T)[] | null>(null);
124
+ const isFirstRunRef = useRef(true);
125
+
126
+ if (!prevSelector.current || !shallowEqualSelector(prevSelector.current, selector)) {
127
+ const normalized: NormalizedSelector<T>[] = [];
128
+ const keys: (keyof T)[] = [];
129
+
130
+ for (const item of selector) {
131
+ if (typeof item === 'string') {
132
+ const key = item as keyof T;
133
+ normalized.push({ key });
134
+ keys.push(key);
135
+ } else {
136
+ for (const [key, compare] of Object.entries(item)) {
137
+ const typedKey = key as keyof T;
138
+ normalized.push({ key: typedKey, compare: compare as CompareFn<T[keyof T]> });
139
+ keys.push(typedKey);
140
+ }
141
+ }
102
142
  }
103
- return Object.entries(item).map(([key, compare]) => ({
104
- key: key as keyof T,
105
- compare: compare as CompareFn<T[keyof T]>,
106
- }));
107
- });
143
+
144
+ normalizedRef.current = normalized;
145
+ keysRef.current = keys;
146
+ prevSelector.current = selector;
147
+ }
148
+
149
+ const normalized = normalizedRef.current!;
150
+ const keys = keysRef.current!;
108
151
 
109
152
  const getSnapshot = () => {
110
153
  const current = store.get();
111
154
  const prev = lastState.current;
112
155
 
113
- const isFirstRun = !lastSelected.current || Object.keys(lastSelected.current).length === 0;
156
+ const isFirstRun = isFirstRunRef.current;
114
157
 
115
158
  const changed = isFirstRun || normalized.some(({ key, compare }) => {
116
159
  const prevVal = prev[key];
117
160
  const nextVal = current[key];
118
- return compare ? compare(prevVal, nextVal) : !Object.is(prevVal, nextVal);
161
+ return compare?.(prevVal, nextVal) ?? !Object.is(prevVal, nextVal);
119
162
  });
120
163
 
121
164
  if (!changed) {
122
165
  return lastSelected.current as Picked<T, S>;
123
166
  }
124
-
125
- lastState.current = current;
126
-
127
- const nextSelected: Partial<T> = {};
128
-
129
- for (const { key, compare } of normalized) {
130
- const prevVal = lastSelected.current[key];
131
- const nextVal = current[key];
132
- const hasChanged = compare
133
- ? compare(prevVal as T[keyof T], nextVal as T[keyof T])
134
- : !Object.is(prevVal, nextVal);
135
-
136
- nextSelected[key] = hasChanged ? nextVal : prevVal;
167
+
168
+ if (isFirstRun) {
169
+ isFirstRunRef.current = false;
137
170
  }
138
171
 
139
- lastSelected.current = nextSelected;
140
-
141
- return nextSelected as Picked<T, S>;
172
+ lastState.current = current;
173
+ lastSelected.current = pickKeys(current, lastSelected.current, normalized);
174
+ return lastSelected.current as Picked<T, S>;
142
175
  };
143
176
 
144
177
  const staticSnapshot = (() => {
145
178
  const current = store.get();
146
- return normalized.reduce((acc, { key }) => {
179
+ return keys.reduce((acc, key) => {
147
180
  acc[key] = current[key];
148
181
  return acc;
149
182
  }, {} as Partial<T>) as Picked<T, S>;
150
183
  })();
151
-
184
+
152
185
  const subscribe = (onStoreChange: () => void) =>
153
- store.subscribe(normalized.map(sel => sel.key), onStoreChange);
186
+ store.subscribe(keys, onStoreChange);
187
+
154
188
  return useSyncExternalStore(subscribe, getSnapshot, () => staticSnapshot);
155
189
  }