11import { createTrackedSelector } from 'react-tracked' ;
2- import { subscribeWithSelector } from 'zustand/middleware' ;
32import { createWithEqualityFn as createStoreZustand } from 'zustand/traditional' ;
43
5- import {
6- devToolsMiddleware ,
7- immerMiddleware ,
8- persistMiddleware ,
9- } from './middlewares' ;
10- import { mutativeMiddleware } from './middlewares/mutative' ;
4+ import { buildStateCreator } from './internal/buildStateCreator' ;
5+ import { createBaseApi } from './internal/createBaseApi' ;
116import { DefaultMutators , TBaseStoreOptions , TState } from './types' ;
12- import { TMiddleware } from './types/middleware' ;
13- import { getOptions } from './utils/helpers' ;
147import { storeFactory } from './utils/storeFactory' ;
158
169import type { TStateApiForBuilder } from './types' ;
@@ -34,139 +27,19 @@ export const createStore = <
3427options :CreateStoreOptions
3528) => {
3629type Mutators = [ ...DefaultMutators < StateType , CreateStoreOptions > , ...Mcs ] ;
37- const {
38- name,
39- devtools :devtoolsOptions ,
40- immer :immerOptions ,
41- mutative :mutativeOptions ,
42- persist :persistOptions ,
43- isMutativeState,
44- } = options ;
45-
46- //current middlewares order devTools(persist(immer(initiator)))
47- const middlewares :TMiddleware [ ] = [ ] ;
48-
49- //enable devtools
50- const _devtoolsOptionsInternal = getOptions ( devtoolsOptions ) ;
51- if ( _devtoolsOptionsInternal . enabled ) {
52- middlewares . push ( ( config ) =>
53- devToolsMiddleware ( config , {
54- ..._devtoolsOptionsInternal ,
55- name :_devtoolsOptionsInternal ?. name ?? name ,
56- } )
57- ) ;
58- }
59-
60- //enable persist
61- const _persistOptionsInternal = getOptions ( persistOptions ) ;
62- if ( _persistOptionsInternal . enabled ) {
63- middlewares . push ( ( config ) =>
64- persistMiddleware ( config , {
65- ..._persistOptionsInternal ,
66- name :_persistOptionsInternal . name ?? name ,
67- } )
68- ) ;
69- }
70-
71- //enable immer
72- const _immerOptionsInternal = getOptions ( immerOptions ) ;
73- if ( _immerOptionsInternal . enabled ) {
74- middlewares . push ( ( config ) =>
75- immerMiddleware ( config , _immerOptionsInternal )
76- ) ;
77- }
78-
79- //enable mutative
80- const _mutativeOptionsInternal = getOptions ( mutativeOptions ) ;
81- if ( _mutativeOptionsInternal . enabled ) {
82- middlewares . push ( ( config ) =>
83- mutativeMiddleware ( config , _mutativeOptionsInternal )
84- ) ;
85- }
86-
87- const stateMutators = middlewares
88- . reverse ( )
89- . reduce (
90- ( y , fn ) => fn ( y ) ,
91- ( typeof initializer === 'function'
92- ?initializer
93- :( ) => initializer ) as StateCreator < StateType >
94- ) as StateCreator < StateType , [ ] , Mutators > ;
95-
96- const store = createStoreZustand ( subscribeWithSelector ( stateMutators ) ) ;
30+ const builder = buildStateCreator ( initializer , options ) ;
31+ const store = createStoreZustand ( builder . stateCreator ) ;
9732
9833const useTrackedStore = createTrackedSelector ( store ) ;
9934
10035const useTracked = ( key :string ) => {
10136return useTrackedStore ( ) [ key as keyof StateType ] ;
10237} ;
10338
104- const getFn = ( key :string ) => {
105- if ( key === 'state' ) {
106- return store . getState ( ) ;
107- }
108-
109- return store . getState ( ) [ key as keyof StateType ] ;
110- } ;
111-
112- const subscribeFn = (
113- key :string ,
114- selector :any ,
115- listener :any ,
116- subscribeOptions :any
117- ) => {
118- if ( key === 'state' ) {
119- //@ts -expect-error -- typescript is unable to infer the 3 args version
120- return store . subscribe ( selector , listener , subscribeOptions ) ;
121- }
122-
123- let wrappedSelector :any ;
124-
125- if ( listener ) {
126- // subscribe(selector, listener, subscribeOptions) variant
127- wrappedSelector = ( state :StateType ) =>
128- selector ( state [ key as keyof StateType ] ) ;
129- } else {
130- // subscribe(listener) variant
131- listener = selector ;
132- wrappedSelector = ( state :StateType ) => state [ key as keyof StateType ] ;
133- }
134-
135- //@ts -expect-error -- typescript is unable to infer the 3 args version
136- return store . subscribe ( wrappedSelector , listener , subscribeOptions ) ;
137- } ;
138-
139- const isMutative =
140- isMutativeState ||
141- _immerOptionsInternal . enabled ||
142- _mutativeOptionsInternal . enabled ;
143-
144- const setFn = ( key :string , value :any ) => {
145- if ( key === 'state' ) {
146- return ( store . setState as any ) ( value ) ;
147- }
148-
149- const typedKey = key as keyof StateType ;
150- const prevValue = store . getState ( ) [ typedKey ] ;
151-
152- if ( typeof value === 'function' ) {
153- value = value ( prevValue ) ;
154- }
155- if ( prevValue === value ) return ;
156-
157- const actionKey = key . replace ( / ^ \S / , ( s ) => s . toUpperCase ( ) ) ;
158- const debugLog = name ?`@@${ name } /set${ actionKey } ` :undefined ;
159-
160- ( store . setState as any ) ?.(
161- isMutative
162- ?( draft :StateType ) => {
163- draft [ typedKey ] = value ;
164- }
165- :{ [ typedKey ] :value } ,
166- undefined ,
167- debugLog
168- ) ;
169- } ;
39+ const baseApi = createBaseApi < StateType , Mutators , { } , { } > ( store , {
40+ name :builder . name ,
41+ isMutative :builder . isMutative ,
42+ } ) ;
17043
17144const useValue = (
17245key :string ,
@@ -181,22 +54,17 @@ export const createStore = <
18154) => {
18255const value = useValue ( key , equalityFn ) ;
18356
184- return [ value , ( val :any ) => setFn ( key , val ) ] ;
57+ return [ value , ( val :any ) => baseApi . set ( key as keyof StateType , val ) ] ;
18558} ;
18659
18760const apiInternal = {
188- get :getFn ,
189- name,
190- set :setFn ,
191- subscribe :subscribeFn ,
61+ ...baseApi ,
19262 store,
19363useStore :store ,
19464 useValue,
19565 useState,
19666 useTracked,
19767 useTrackedStore,
198- actions :{ } ,
199- selectors :{ } ,
20068} as any as TStateApiForBuilder < StateType , Mutators > ;
20169
20270return storeFactory ( apiInternal ) ;