dev-react-microstore 1.0.3 → 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.d.mts CHANGED
@@ -1,21 +1,22 @@
1
1
  type StoreListener = () => void;
2
- declare function createStoreState<T>(initialState: T): {
2
+ declare function createStoreState<T extends object>(initialState: T): {
3
3
  get: () => T;
4
4
  set: (next: Partial<T>) => void;
5
5
  subscribe: (keys: (keyof T)[], listener: StoreListener) => (() => void);
6
+ select: <K extends keyof T>(keys: K[]) => Pick<T, K>;
6
7
  };
7
- type StoreType<T> = ReturnType<typeof createStoreState<T>>;
8
- type PrimitiveKey<T> = keyof T;
8
+ type StoreType<T extends object> = ReturnType<typeof createStoreState<T>>;
9
+ type PrimitiveKey<T extends object> = keyof T;
9
10
  type CompareFn<V> = (prev: V, next: V) => boolean;
10
- type KeySelector<T> = PrimitiveKey<T>;
11
- type CustomSelector<T> = {
11
+ type KeySelector<T extends object> = PrimitiveKey<T>;
12
+ type CustomSelector<T extends object> = {
12
13
  [K in keyof T]?: CompareFn<T[K]>;
13
14
  };
14
- type SelectorInput<T> = ReadonlyArray<KeySelector<T> | CustomSelector<T>>;
15
- type ExtractSelectorKeys<T, S extends SelectorInput<T>> = {
15
+ type SelectorInput<T extends object> = ReadonlyArray<KeySelector<T> | CustomSelector<T>>;
16
+ type ExtractSelectorKeys<T extends object, S extends SelectorInput<T>> = {
16
17
  [K in S[number] extends infer Item ? Item extends keyof T ? Item : keyof Item : never]: T[K];
17
18
  };
18
- type Picked<T, S extends SelectorInput<T>> = ExtractSelectorKeys<T, S>;
19
- declare function useStoreSelector<T, S extends SelectorInput<T>>(store: StoreType<T>, selector: S): Picked<T, S>;
19
+ type Picked<T extends object, S extends SelectorInput<T>> = ExtractSelectorKeys<T, S>;
20
+ declare function useStoreSelector<T extends object, S extends SelectorInput<T>>(store: StoreType<T>, selector: S): Picked<T, S>;
20
21
 
21
22
  export { createStoreState, useStoreSelector };
package/dist/index.d.ts CHANGED
@@ -1,21 +1,22 @@
1
1
  type StoreListener = () => void;
2
- declare function createStoreState<T>(initialState: T): {
2
+ declare function createStoreState<T extends object>(initialState: T): {
3
3
  get: () => T;
4
4
  set: (next: Partial<T>) => void;
5
5
  subscribe: (keys: (keyof T)[], listener: StoreListener) => (() => void);
6
+ select: <K extends keyof T>(keys: K[]) => Pick<T, K>;
6
7
  };
7
- type StoreType<T> = ReturnType<typeof createStoreState<T>>;
8
- type PrimitiveKey<T> = keyof T;
8
+ type StoreType<T extends object> = ReturnType<typeof createStoreState<T>>;
9
+ type PrimitiveKey<T extends object> = keyof T;
9
10
  type CompareFn<V> = (prev: V, next: V) => boolean;
10
- type KeySelector<T> = PrimitiveKey<T>;
11
- type CustomSelector<T> = {
11
+ type KeySelector<T extends object> = PrimitiveKey<T>;
12
+ type CustomSelector<T extends object> = {
12
13
  [K in keyof T]?: CompareFn<T[K]>;
13
14
  };
14
- type SelectorInput<T> = ReadonlyArray<KeySelector<T> | CustomSelector<T>>;
15
- type ExtractSelectorKeys<T, S extends SelectorInput<T>> = {
15
+ type SelectorInput<T extends object> = ReadonlyArray<KeySelector<T> | CustomSelector<T>>;
16
+ type ExtractSelectorKeys<T extends object, S extends SelectorInput<T>> = {
16
17
  [K in S[number] extends infer Item ? Item extends keyof T ? Item : keyof Item : never]: T[K];
17
18
  };
18
- type Picked<T, S extends SelectorInput<T>> = ExtractSelectorKeys<T, S>;
19
- declare function useStoreSelector<T, S extends SelectorInput<T>>(store: StoreType<T>, selector: S): Picked<T, S>;
19
+ type Picked<T extends object, S extends SelectorInput<T>> = ExtractSelectorKeys<T, S>;
20
+ declare function useStoreSelector<T extends object, S extends SelectorInput<T>>(store: StoreType<T>, selector: S): Picked<T, S>;
20
21
 
21
22
  export { createStoreState, useStoreSelector };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var l=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames,g=Object.getOwnPropertySymbols;var h=Object.prototype.hasOwnProperty,I=Object.prototype.propertyIsEnumerable;var x=(r,e,t)=>e in r?l(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,k=(r,e)=>{for(var t in e||(e={}))h.call(e,t)&&x(r,t,e[t]);if(g)for(var t of g(e))I.call(e,t)&&x(r,t,e[t]);return r};var C=(r,e)=>{for(var t in e)l(r,t,{get:e[t],enumerable:!0})},V=(r,e,t,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of v(e))!h.call(r,s)&&s!==t&&l(r,s,{get:()=>e[s],enumerable:!(a=P(e,s))||a.enumerable});return r};var F=r=>V(l({},"__esModule",{value:!0}),r);var R={};C(R,{createStoreState:()=>j,useStoreSelector:()=>O});module.exports=F(R);var f=require("react");function j(r){let e=r,t=new Map;return{get:()=>e,set:T=>{var n;let i=!1,o=[];for(let c in T)Object.is(e[c],T[c])||(i=!0,o.push(c));if(i){e=k(k({},e),T);for(let c of o)(n=t.get(c))==null||n.forEach(b=>b())}},subscribe:(T,i)=>{for(let o of T)t.has(o)||t.set(o,new Set),t.get(o).add(i);return()=>{var o;for(let n of T)(o=t.get(n))==null||o.delete(i)}}}}function O(r,e){let t=(0,f.useRef)(r.get()),a=(0,f.useRef)({}),s=e.flatMap(o=>typeof o=="string"?[{key:o}]:Object.entries(o).map(([n,c])=>({key:n,compare:c}))),m=()=>{let o=r.get(),n=t.current;if(!(!a.current||Object.keys(a.current).length===0||s.some(({key:y,compare:p})=>{let u=n[y],S=o[y];return p?p(u,S):!Object.is(u,S)})))return a.current;t.current=o;let d={};for(let{key:y,compare:p}of s){let u=a.current[y],S=o[y],K=p?p(u,S):!Object.is(u,S);d[y]=K?S:u}return a.current=d,d},T=(()=>{let o=r.get();return s.reduce((n,{key:c})=>(n[c]=o[c],n),{})})();return(0,f.useSyncExternalStore)(o=>r.subscribe(s.map(n=>n.key),o),m,()=>T)}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 h=Object.defineProperty;var m=Object.getOwnPropertySymbols;var K=Object.prototype.hasOwnProperty,P=Object.prototype.propertyIsEnumerable;var b=(o,r,t)=>r in o?h(o,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[r]=t,l=(o,r)=>{for(var t in r||(r={}))K.call(r,t)&&b(o,t,r[t]);if(m)for(var t of m(r))P.call(r,t)&&b(o,t,r[t]);return o};import{useRef as g,useSyncExternalStore as v}from"react";function V(o){let r=o,t=new Map;return{get:()=>r,set:c=>{var n;let T=!1,e=[];for(let s in c)Object.is(r[s],c[s])||(T=!0,e.push(s));if(T){r=l(l({},r),c);for(let s of e)(n=t.get(s))==null||n.forEach(k=>k())}},subscribe:(c,T)=>{for(let e of c)t.has(e)||t.set(e,new Set),t.get(e).add(T);return()=>{var e;for(let n of c)(e=t.get(n))==null||e.delete(T)}}}}function F(o,r){let t=g(o.get()),a=g({}),S=r.flatMap(e=>typeof e=="string"?[{key:e}]:Object.entries(e).map(([n,s])=>({key:n,compare:s}))),d=()=>{let e=o.get(),n=t.current;if(!(!a.current||Object.keys(a.current).length===0||S.some(({key:i,compare:p})=>{let y=n[i],u=e[i];return p?p(y,u):!Object.is(y,u)})))return a.current;t.current=e;let f={};for(let{key:i,compare:p}of S){let y=a.current[i],u=e[i],x=p?p(y,u):!Object.is(y,u);f[i]=x?u:y}return a.current=f,f},c=(()=>{let e=o.get();return S.reduce((n,{key:s})=>(n[s]=e[s],n),{})})();return v(e=>o.subscribe(S.map(n=>n.key),e),d,()=>c)}export{V as createStoreState,F 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.0.3",
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
@@ -1,7 +1,9 @@
1
1
  import { useRef, useSyncExternalStore } from 'react';
2
2
  type StoreListener = () => void;
3
3
 
4
- export function createStoreState<T>(initialState: T) {
4
+
5
+
6
+ export function createStoreState<T extends object>(initialState: T) {
5
7
  let state = initialState;
6
8
 
7
9
  // Map from key to set of subscribers interested in that key
@@ -10,13 +12,21 @@ export function createStoreState<T>(initialState: T) {
10
12
  const get = () => state;
11
13
 
12
14
  const set = (next: Partial<T>) => {
15
+ if (next === null || next === undefined || typeof next !== 'object' || Array.isArray(next)) {
16
+ console.error(`set() called with invalid value: ${next === null ? 'null' : next === undefined ? 'undefined' : typeof next}`);
17
+ return;
18
+ }
19
+
13
20
  let changed = false;
14
21
  const updatedKeys: (keyof T)[] = [];
15
22
 
16
23
  for (const key in next) {
17
- if (!Object.is(state[key], next[key])) {
18
- changed = true;
19
- updatedKeys.push(key);
24
+ if (Object.prototype.hasOwnProperty.call(next, key)) {
25
+ const typedKey = key as keyof T;
26
+ if (typedKey in state && !Object.is(state[typedKey], next[typedKey])) {
27
+ changed = true;
28
+ updatedKeys.push(typedKey);
29
+ }
20
30
  }
21
31
  }
22
32
 
@@ -28,7 +38,7 @@ export function createStoreState<T>(initialState: T) {
28
38
  keyListeners.get(key)?.forEach(listener => listener());
29
39
  }
30
40
  };
31
-
41
+
32
42
  const subscribe = (keys: (keyof T)[], listener: StoreListener): (() => void) => {
33
43
  for (const key of keys) {
34
44
  if (!keyListeners.has(key)) {
@@ -44,18 +54,27 @@ export function createStoreState<T>(initialState: T) {
44
54
  };
45
55
  };
46
56
 
47
- return { get, set, subscribe };
57
+ const select = <K extends keyof T>(keys: K[]): Pick<T, K> => {
58
+ const result = {} as Pick<T, K>;
59
+ const currentState = state;
60
+ for (const key of keys) {
61
+ result[key] = currentState[key];
62
+ }
63
+ return result;
64
+ };
65
+
66
+ return { get, set, subscribe, select };
48
67
  }
49
68
 
50
- type StoreType<T> = ReturnType<typeof createStoreState<T>>;
51
- type PrimitiveKey<T> = keyof T;
69
+ type StoreType<T extends object> = ReturnType<typeof createStoreState<T>>;
70
+ type PrimitiveKey<T extends object> = keyof T;
52
71
  type CompareFn<V> = (prev: V, next: V) => boolean;
53
72
 
54
- type KeySelector<T> = PrimitiveKey<T>;
55
- type CustomSelector<T> = { [K in keyof T]?: CompareFn<T[K]> };
56
- type SelectorInput<T> = ReadonlyArray<KeySelector<T> | CustomSelector<T>>;
73
+ type KeySelector<T extends object> = PrimitiveKey<T>;
74
+ type CustomSelector<T extends object> = { [K in keyof T]?: CompareFn<T[K]> };
75
+ type SelectorInput<T extends object> = ReadonlyArray<KeySelector<T> | CustomSelector<T>>;
57
76
 
58
- type ExtractSelectorKeys<T, S extends SelectorInput<T>> = {
77
+ type ExtractSelectorKeys<T extends object, S extends SelectorInput<T>> = {
59
78
  [K in S[number] extends infer Item
60
79
  ? Item extends keyof T
61
80
  ? Item
@@ -63,74 +82,108 @@ type ExtractSelectorKeys<T, S extends SelectorInput<T>> = {
63
82
  : never]: T[K];
64
83
  };
65
84
 
66
- type Picked<T, S extends SelectorInput<T>> = ExtractSelectorKeys<T, S>;
85
+ type Picked<T extends object, S extends SelectorInput<T>> = ExtractSelectorKeys<T, S>;
67
86
 
68
- type NormalizedSelector<T> = {
87
+ type NormalizedSelector<T extends object> = {
69
88
  key: keyof T;
70
89
  compare?: CompareFn<T[keyof T]>;
71
90
  };
72
91
 
73
- export function useStoreSelector<T, S extends SelectorInput<T>>(
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
+
115
+ export function useStoreSelector<T extends object, S extends SelectorInput<T>>(
74
116
  store: StoreType<T>,
75
117
  selector: S
76
118
  ): Picked<T, S> {
77
119
  const lastState = useRef(store.get());
78
120
  const lastSelected = useRef<Partial<T>>({});
79
-
80
- const normalized = selector.flatMap((item): NormalizedSelector<T>[] => {
81
- if (typeof item === 'string') {
82
- 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
+ }
83
142
  }
84
- return Object.entries(item).map(([key, compare]) => ({
85
- key: key as keyof T,
86
- compare: compare as CompareFn<T[keyof T]>,
87
- }));
88
- });
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!;
89
151
 
90
152
  const getSnapshot = () => {
91
153
  const current = store.get();
92
154
  const prev = lastState.current;
93
155
 
94
- const isFirstRun = !lastSelected.current || Object.keys(lastSelected.current).length === 0;
156
+ const isFirstRun = isFirstRunRef.current;
95
157
 
96
158
  const changed = isFirstRun || normalized.some(({ key, compare }) => {
97
159
  const prevVal = prev[key];
98
160
  const nextVal = current[key];
99
- return compare ? compare(prevVal, nextVal) : !Object.is(prevVal, nextVal);
161
+ return compare?.(prevVal, nextVal) ?? !Object.is(prevVal, nextVal);
100
162
  });
101
163
 
102
164
  if (!changed) {
103
165
  return lastSelected.current as Picked<T, S>;
104
166
  }
105
-
106
- lastState.current = current;
107
-
108
- const nextSelected: Partial<T> = {};
109
-
110
- for (const { key, compare } of normalized) {
111
- const prevVal = lastSelected.current[key];
112
- const nextVal = current[key];
113
- const hasChanged = compare
114
- ? compare(prevVal as T[keyof T], nextVal as T[keyof T])
115
- : !Object.is(prevVal, nextVal);
116
-
117
- nextSelected[key] = hasChanged ? nextVal : prevVal;
167
+
168
+ if (isFirstRun) {
169
+ isFirstRunRef.current = false;
118
170
  }
119
171
 
120
- lastSelected.current = nextSelected;
121
-
122
- 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>;
123
175
  };
124
176
 
125
177
  const staticSnapshot = (() => {
126
178
  const current = store.get();
127
- return normalized.reduce((acc, { key }) => {
179
+ return keys.reduce((acc, key) => {
128
180
  acc[key] = current[key];
129
181
  return acc;
130
182
  }, {} as Partial<T>) as Picked<T, S>;
131
183
  })();
132
-
184
+
133
185
  const subscribe = (onStoreChange: () => void) =>
134
- store.subscribe(normalized.map(sel => sel.key), onStoreChange);
186
+ store.subscribe(keys, onStoreChange);
187
+
135
188
  return useSyncExternalStore(subscribe, getSnapshot, () => staticSnapshot);
136
189
  }