Skip to content

Commit f7e37b2

Browse files
Merge pull request cerebral#167 from cerebral/scopedTracking
Scoped tracking
2 parents eceffcc + 60dc73d commit f7e37b2

File tree

21 files changed

+1213
-1188
lines changed

21 files changed

+1213
-1188
lines changed

packages/node_modules/overmind-angular/src/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export type TConnect<Config extends Configuration> = {
1111
}
1212

1313
let nextComponentId = 0
14-
14+
/*
1515
export const createConnect = <A extends Overmind<any>>(overmind: A) => () => {
1616
const componentId = nextComponentId++
1717
let componentInstanceId = 0
@@ -29,7 +29,7 @@ export const createConnect = <A extends Overmind<any>>(overmind: A) => () => {
2929
actions: overmind.actions,
3030
}
3131
this.__componentInstanceId = componentInstanceId++
32-
this.__shouldUpdatePaths = false
32+
this.__tree = false
3333
this.__currentTrackId = null
3434
this.__listener = null
3535
@@ -129,3 +129,4 @@ export const createConnect = <A extends Overmind<any>>(overmind: A) => () => {
129129
return target
130130
}
131131
}
132+
*/

packages/node_modules/overmind-devtools/src/components/ActionsList/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ const ActionsList: SFC = () => {
4242
<div key={item.id}>
4343
<div
4444
className={styles.actionItem}
45-
key={item.id}
4645
onClick={() => actions.selectAction(item.id)}
4746
>
4847
<span

packages/node_modules/overmind-react/src/index.test.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Overmind, TAction } from 'overmind'
22
import * as React from 'react'
33
import * as renderer from 'react-test-renderer'
4-
54
import { TConnect, createConnect } from './'
65

76
describe('React', () => {

packages/node_modules/overmind-react/src/index.ts

Lines changed: 105 additions & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,13 @@ export type TConnect<Config extends Configuration> = {
3535

3636
let 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

110116
export 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

Comments
 (0)