1
1
import { useSyncExternalStore } from "react" ;
2
2
3
- export type Selector = string | number | Symbol ;
4
3
type Listener = ( ) => void ;
5
- type ListenerWithSelectors = { l : Listener ; s : Selector [ ] } ;
4
+ type ListenerWithSelectors = {
5
+ l : Listener ;
6
+ s : [ includeRegExp ?: RegExp | null , excludeRegExp ?: RegExp ] ;
7
+ } ;
6
8
7
9
export type SetterArgType < T > = T | ( ( prevState : T ) => T ) ;
8
10
export type SetStateAction < T > = ( value : SetterArgType < T > ) => void ;
@@ -29,21 +31,35 @@ export const globalRGS = globalThisForBetterMinification.rgs;
29
31
30
32
/** trigger all listeners */
31
33
export const triggerListeners = < T > ( rgs : RGS , oldV : T , newV : T ) => {
32
- const updatedFiels : Selector [ ] = [ ] ;
34
+ const updatedFiels : string [ ] = [ ] ;
33
35
// no need to test this --- it will automatically fail
34
36
// if (typeof oldV === "object" && typeof rgs.v === "object")
35
37
for ( const key in oldV ) if ( oldV [ key ] !== newV [ key ] ) updatedFiels . push ( key ) ;
36
- rgs . l . forEach ( ( { l, s } ) => ( ! s . length || s . some ( filed => updatedFiels . includes ( filed ) ) ) && l ( ) ) ;
38
+ // const testStr = updatedFiels.join("; ");
39
+ rgs . l . forEach (
40
+ ( { l, s : [ includeRegExp , excludeRegExp ] } ) =>
41
+ updatedFiels . filter (
42
+ s =>
43
+ ( ! includeRegExp || includeRegExp . test ( s ) ) && ( ! excludeRegExp || ! excludeRegExp . test ( s ) ) ,
44
+ ) . length && l ( ) ,
45
+ ) ;
37
46
} ;
38
47
39
48
/** Extract coomon create hook logic to utils */
40
- export const createHook = < T > ( key : string , fields : ( keyof T ) [ ] ) : [ T , SetStateAction < T > ] => {
49
+ export const createHook = < T > (
50
+ key : string ,
51
+ includeRegExp ?: RegExp | null ,
52
+ excludeRegExp ?: RegExp ,
53
+ ) : [ T , SetStateAction < T > ] => {
41
54
const rgs = globalRGS [ key ] as RGS ;
42
55
/** This function is called by react to get the current stored value. */
43
56
const getSnapshot = ( ) => rgs . v as T ;
44
57
const val = useSyncExternalStore < T > (
45
58
listener => {
46
- const listenerWithSelectors = { l : listener , s : fields } ;
59
+ const listenerWithSelectors = {
60
+ l : listener ,
61
+ s : [ includeRegExp , excludeRegExp ] ,
62
+ } as ListenerWithSelectors ;
47
63
rgs . l . push ( listenerWithSelectors ) ;
48
64
return ( ) => {
49
65
rgs . l = rgs . l . filter ( l => l !== listenerWithSelectors ) ;
@@ -133,8 +149,9 @@ export const useRGSWithPlugins = <T>(
133
149
value ?: ValueType < T > ,
134
150
plugins ?: Plugin < T > [ ] ,
135
151
doNotInit = false ,
136
- ...fields : ( keyof T ) [ ]
152
+ includeRegExp ?: RegExp | null ,
153
+ excludeRegExp ?: RegExp ,
137
154
) : [ T , SetStateAction < T > ] => {
138
155
if ( ! globalRGS [ key ] ?. s ) initWithPlugins ( key , value , plugins , doNotInit ) ;
139
- return createHook < T > ( key , fields ) ;
156
+ return createHook < T > ( key , includeRegExp , excludeRegExp ) ;
140
157
} ;
0 commit comments