@@ -35,8 +35,13 @@ export type TConnect<Config extends Configuration> = {
3535
3636let nextComponentId = 0
3737
38- export const createHook = < A extends Overmind < Configuration > > ( overmind : A ) => {
39- let componentInstanceId = 0
38+ export const createHook = < A extends Overmind < Configuration > > (
39+ overmind : A
40+ ) : ( ( ) => {
41+ state : A [ 'state' ]
42+ actions : A [ 'actions' ]
43+ } ) => {
44+ let currentComponentInstanceId = 0
4045 const {
4146 ReactCurrentOwner,
4247 } = __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
@@ -55,230 +60,148 @@ export const createHook = <A extends Overmind<Configuration>>(overmind: A) => {
5560 typeof component . __componentId === 'undefined'
5661 ? nextComponentId ++
5762 : component . __componentId
58- const [ overmindState , setOvermindState ] = useState < any > ( { } )
63+ const [ tree , updateComponent ] = useState < any > ( ( ) =>
64+ ( overmind as any ) . proxyStateTree . getTrackStateTree ( )
65+ )
66+ const [ debugging ] = useState < any > ( ( ) => ( {
67+ isFirstRender : true ,
68+ currentFlushId : 0 ,
69+ currentComponentsInstaceId : currentComponentInstanceId ++ ,
70+ } ) )
71+
72+ tree . track ( ( mutations , paths , flushId ) => {
73+ debugging . currentFlushId = flushId
74+ updateComponent ( ( state ) => state )
75+ } )
5976
60- const trackId = overmind . trackState ( )
6177 useLayoutEffect ( ( ) => {
62- const paths = overmind . clearTrackState ( trackId )
63-
64- if ( overmindState . listener ) {
65- overmind . eventHub . emitAsync ( EventType . COMPONENT_UPDATE , {
78+ if ( debugging . isFirstRender ) {
79+ overmind . eventHub . emitAsync ( EventType . COMPONENT_ADD , {
6680 componentId : component . __componentId ,
67- componentInstanceId : overmindState . componentInstanceId ,
81+ componentInstanceId : debugging . componentInstanceId ,
6882 name,
69- paths : Array . from ( paths ) ,
83+ paths : Array . from ( tree . pathDependencies ) as any ,
7084 } )
71- overmindState . listener . update ( paths )
85+ debugging . isFirstRender = false
7286 } else {
73- overmindState . componentInstanceId = componentInstanceId ++
74- overmindState . listener = overmind . addFlushListener ( paths , ( flushId ) => {
75- overmind . eventHub . emitAsync ( EventType . COMPONENT_UPDATE , {
76- componentId : component . __componentId ,
77- componentInstanceId : overmindState . componentInstanceId ,
78- name,
79- flushId,
80- paths : Array . from ( paths ) ,
81- } )
82- setOvermindState ( ( state ) => state )
83- } )
84- overmind . eventHub . emitAsync ( EventType . COMPONENT_ADD , {
87+ overmind . eventHub . emitAsync ( EventType . COMPONENT_UPDATE , {
8588 componentId : component . __componentId ,
86- componentInstanceId : overmindState . componentInstanceId ,
89+ componentInstanceId : debugging . componentInstanceId ,
8790 name,
88- paths : Array . from ( paths ) ,
91+ flushId : debugging . currentFlushId ,
92+ paths : Array . from ( tree . pathDependencies as Set < string > ) ,
8993 } )
9094 }
9195 } )
92- useEffect ( ( ) => {
93- return ( ) => {
94- if ( ! overmindState . listener ) {
95- return
96- }
9796
97+ useEffect (
98+ ( ) => ( ) => {
99+ ; ( overmind as any ) . proxyStateTree . disposeTree ( tree )
98100 overmind . eventHub . emitAsync ( EventType . COMPONENT_REMOVE , {
99101 componentId : component . __componentId ,
100- componentInstanceId : overmindState . componentInstanceId ,
102+ componentInstanceId : debugging . componentInstanceId ,
101103 name,
102104 } )
103- overmindState . listener . dispose ( )
104- }
105- } , [ ] )
106- return overmind
105+ } ,
106+ [ ]
107+ )
108+
109+ return {
110+ state : tree . state ,
111+ actions : overmind . actions ,
112+ }
107113 }
108114}
109115
110116export const createConnect = < A extends Overmind < Configuration > > (
111117 overmind : A
112118) => {
113119 return < Props > (
114- Component : IReactComponent < Props & TConnect < A > >
120+ component : IReactComponent <
121+ Props & { overmind : { state : A [ 'state' ] ; actions : A [ 'actions' ] } }
122+ >
115123 ) : IReactComponent < Omit < Props & TConnect < A > , keyof TConnect < A > > > => {
116124 let componentInstanceId = 0
125+ const name = component . name
126+ const populatedComponent = component as any
127+ populatedComponent . __componentId =
128+ typeof populatedComponent . __componentId === 'undefined'
129+ ? nextComponentId ++
130+ : populatedComponent . __componentId
117131 const isClassComponent =
118- Component . prototype && typeof Component . prototype . render === 'function'
132+ component . prototype && typeof component . prototype . render === 'function'
119133
120134 if ( isClassComponent ) {
121- const originalRender = Component . prototype . render
122- const originalWillUnmount = Component . prototype . componentWillUnmount
123-
124- Component . prototype . componentWillUnmount = function ( ) {
125- if ( ! this . props . overmind ) {
126- return originalWillUnmount && originalWillUnmount . call ( this )
127- }
128-
129- this . __isUnmounting = true
130- if ( this . __mutationListener ) {
131- overmind . eventHub . emitAsync ( EventType . COMPONENT_REMOVE , {
132- componentId : this . __componentId ,
133- componentInstanceId : this . props . overmind . __componentInstanceId ,
134- name : Component . name || '' ,
135- } )
136-
137- this . __mutationListener . dispose ( )
138- }
139- originalWillUnmount && originalWillUnmount . call ( this )
140- }
141- Component . prototype . render = function ( ) {
142- if ( ! this . props . overmind ) {
143- return originalRender . call ( this )
144- }
145-
146- if ( typeof this . __componentId === 'undefined' ) {
147- this . __componentId = nextComponentId ++
148- }
149- const trackId = overmind . trackState ( )
150- const value = originalRender . call ( this )
151- const paths = overmind . clearTrackState ( trackId )
152-
153- if ( this . __mutationListener ) {
154- this . __mutationListener . update ( paths )
155- overmind . eventHub . emitAsync ( EventType . COMPONENT_UPDATE , {
156- componentId : this . __componentId ,
157- componentInstanceId : this . props . overmind . __componentInstanceId ,
158- name : Component . name || '' ,
159- paths : Array . from ( paths ) ,
160- } )
161- } else {
162- overmind . eventHub . emitAsync ( EventType . COMPONENT_ADD , {
163- componentId : this . __componentId ,
164- componentInstanceId : this . props . overmind . __componentInstanceId ,
165- name : Component . name || '' ,
166- paths : Array . from ( paths ) ,
167- } )
168- this . __mutationListener = overmind . addFlushListener (
169- paths ,
170- ( flushId ) => {
171- if ( this . __isUnmounting ) {
172- return
173- }
174- overmind . eventHub . emitAsync ( EventType . COMPONENT_UPDATE , {
175- componentId : this . __componentId ,
176- componentInstanceId : this . props . overmind . __componentInstanceId ,
177- name : Component . name || '' ,
178- paths : Array . from ( paths ) ,
179- flushId,
180- } )
181- this . forceUpdate ( )
182- }
183- )
184- }
185-
186- return value
135+ const originalRender = component . prototype . render
136+ component . prototype . render = function ( ) {
137+ this . props . overmind &&
138+ this . props . overmind . tree . track ( this . props . overmind . onUpdate )
139+ return originalRender . call ( this )
187140 }
188141 }
189142
190- const klass = class extends PureComponent <
191- Omit < Props & TConnect < A > , keyof TConnect < A > >
192- > {
193- __mutationListener : any
194- __isUnmounting : boolean
195- __componentId : number
196- __componentInstanceId = componentInstanceId ++
143+ class HOC extends PureComponent {
144+ tree = ( overmind as any ) . proxyStateTree . getTrackStateTree ( )
145+ componentInstanceId = componentInstanceId ++
146+ currentFlushId = 0
147+ componentDidMount ( ) {
148+ overmind . eventHub . emitAsync ( EventType . COMPONENT_ADD , {
149+ componentId : populatedComponent . __componentId ,
150+ componentInstanceId : this . componentInstanceId ,
151+ name,
152+ paths : Array . from ( this . tree . pathDependencies ) as any ,
153+ } )
154+ }
155+ componentDidUpdate ( ) {
156+ overmind . eventHub . emitAsync ( EventType . COMPONENT_UPDATE , {
157+ componentId : populatedComponent . __componentId ,
158+ componentInstanceId : this . componentInstanceId ,
159+ name,
160+ flushId : this . currentFlushId ,
161+ paths : Array . from ( this . tree . pathDependencies as Set < string > ) ,
162+ } )
163+ }
197164 componentWillUnmount ( ) {
198- this . __isUnmounting = true
199- if ( this . __mutationListener ) {
200- overmind . eventHub . emitAsync ( EventType . COMPONENT_REMOVE , {
201- componentId : this . __componentId ,
202- componentInstanceId : this . __componentInstanceId ,
203- name : Component . name || '' ,
204- } )
205- this . __mutationListener . dispose ( )
206- }
165+ ; ( overmind as any ) . proxyStateTree . disposeTree ( this . tree )
166+ overmind . eventHub . emitAsync ( EventType . COMPONENT_REMOVE , {
167+ componentId : populatedComponent . __componentId ,
168+ componentInstanceId : this . componentInstanceId ,
169+ name,
170+ } )
171+ }
172+ onUpdate = ( mutatons , paths , flushId ) => {
173+ this . currentFlushId = flushId
174+ this . forceUpdate ( )
207175 }
208- renderStatelessComponent ( ) {
209- const trackId = overmind . trackState ( )
210- const value = ( Component as any ) (
211- Object . assign ( { } , this . props , {
176+ render ( ) {
177+ if ( isClassComponent ) {
178+ return createElement ( component , {
179+ ... this . props ,
212180 overmind : {
213- state : overmind . state ,
181+ state : this . tree . state ,
214182 actions : overmind . actions ,
215- __componentInstanceId : this . __componentInstanceId ,
183+ onUpdate : this . onUpdate ,
184+ tree : this . tree ,
216185 } ,
217- } ) ,
218- this . context
219- )
220- const paths = overmind . clearTrackState ( trackId )
221-
222- if ( this . __mutationListener ) {
223- this . __mutationListener . update ( paths )
224- overmind . eventHub . emitAsync ( EventType . COMPONENT_UPDATE , {
225- componentId : this . __componentId ,
226- componentInstanceId : this . __componentInstanceId ,
227- name : Component . name || '' ,
228- paths : Array . from ( paths ) ,
229- } )
230- } else {
231- overmind . eventHub . emitAsync ( EventType . COMPONENT_ADD , {
232- componentId : this . __componentId ,
233- componentInstanceId : this . __componentInstanceId ,
234- name : Component . name || '' ,
235- paths : Array . from ( paths ) ,
236- } )
237- this . __mutationListener = overmind . addFlushListener (
238- paths ,
239- ( flushId ) => {
240- if ( this . __isUnmounting ) {
241- return
242- }
243- overmind . eventHub . emitAsync ( EventType . COMPONENT_UPDATE , {
244- componentId : this . __componentId ,
245- componentInstanceId : this . __componentInstanceId ,
246- name : Component . name || '' ,
247- paths : Array . from ( paths ) ,
248- flushId,
249- } )
250- this . forceUpdate ( )
251- }
252- )
186+ } as any )
253187 }
254188
255- return value
256- }
257- renderClassComponent ( ) {
258- return createElement ( Component , Object . assign ( { } , this . props , {
189+ this . tree . track ( this . onUpdate )
190+
191+ return createElement ( component , {
192+ ... this . props ,
259193 overmind : {
260- state : overmind . state ,
194+ state : this . tree . state ,
261195 actions : overmind . actions ,
262- __componentInstanceId : this . __componentInstanceId ,
263196 } ,
264- } ) as any )
265- }
266- render ( ) {
267- if ( isClassComponent ) {
268- return this . renderClassComponent ( )
269- }
270-
271- if ( typeof this . __componentId === 'undefined' ) {
272- this . __componentId = nextComponentId ++
273- }
274-
275- return this . renderStatelessComponent ( )
197+ } as any )
276198 }
277199 }
278200
279- Object . defineProperties ( klass , {
280- name : { value : Component . displayName || Component . name || '' } ,
201+ Object . defineProperties ( HOC , {
202+ name : { value : component . displayName || component . name || '' } ,
281203 } )
282- return klass
204+
205+ return HOC as any
283206 }
284207}
0 commit comments