Skip to content

Commit 0c25108

Browse files
authored
Merge pull request cerebral#1 from cerebral/next
new goodies
2 parents d84ceb1 + 233e3d0 commit 0c25108

File tree

16 files changed

+234
-104
lines changed

16 files changed

+234
-104
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
"prettier": "1.13.7",
6161
"react": "16.4.1",
6262
"react-test-renderer": "16.4.1",
63-
"repo-cooker": "^6.2.2",
63+
"repo-cooker": "^6.2.4",
6464
"rimraf": "2.6.2",
6565
"ts-jest": "23.0.0",
6666
"ts-loader": "4.4.2",

packages/node_modules/action-chain/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
"typecheck": "tsc --noEmit",
1717
"test": "jest",
1818
"test:watch": "jest --watch --updateSnapshot --coverage false",
19-
"prepare": "npm run build",
2019
"prebuild": "npm run clean",
2120
"postbuild": "rimraf {lib,es}/**/__tests__",
2221
"posttest": "npm run typecheck"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { derived } from 'overmind'
2+
import { State, Component } from './state'
3+
4+
export const currentApp = derived(
5+
(state: State) => state.apps[state.currentPort]
6+
)
7+
8+
export const componentsMounted = derived((state: State) =>
9+
Object.keys(state.currentApp.components).reduce(
10+
(aggr, key) => {
11+
if (state.currentApp.components[key].isMounted) {
12+
return aggr.concat(state.currentApp.components[key])
13+
}
14+
15+
return aggr
16+
},
17+
[] as Component[]
18+
)
19+
)
20+
21+
export const componentsUpdateCount = derived((state: State) =>
22+
state.componentsMounted.reduce(
23+
(aggr, component) => aggr + component.updateCount,
24+
0
25+
)
26+
)
27+
28+
export const componentsStatePathCount = derived((state: State) =>
29+
state.componentsMounted.reduce(
30+
(aggr, component) => aggr + component.paths.length,
31+
0
32+
)
33+
)

packages/node_modules/overmind-devtools/src/client/app/state.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import * as derived from './derived'
2+
13
export type Mutation = {
24
args: any[]
35
method: string
@@ -59,6 +61,10 @@ export type State = {
5961
newPortValue: string
6062
currentTab: Tab
6163
expandedStatePaths: string[]
64+
currentApp: App
65+
componentsMounted: Component[]
66+
componentsUpdateCount: number
67+
componentsStatePathCount: number
6268
}
6369

6470
const state: State = {
@@ -70,6 +76,10 @@ const state: State = {
7076
newPortValue: '',
7177
currentTab: Tab.State,
7278
expandedStatePaths: [''],
79+
currentApp: derived.currentApp,
80+
componentsMounted: derived.componentsMounted,
81+
componentsUpdateCount: derived.componentsUpdateCount,
82+
componentsStatePathCount: derived.componentsStatePathCount,
7383
}
7484

7585
export default state

packages/node_modules/overmind-devtools/src/client/components/Components/index.tsx

Lines changed: 47 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,66 +5,52 @@ import Table, { Row, Cell } from '../common/Table'
55
import Pill from '../common/Pill'
66
import { Wrapper, Panels, Panel } from './elements'
77

8-
const Components: React.SFC<Connect> = ({ appState }) => {
9-
const components = appState.apps[appState.currentPort].components
10-
const keys = Object.keys(components)
11-
const mountedKeys = keys.filter((key) => components[key].isMounted)
12-
const updatesCount = keys.reduce(
13-
(aggr, key) => aggr + components[key].updateCount,
14-
0
15-
)
16-
const statePathsCount = keys.reduce(
17-
(aggr, key) => aggr + components[key].paths.length,
18-
0
19-
)
20-
return (
21-
<Wrapper>
22-
<Panels>
23-
<Panel>
24-
<Text variant="label" dense>
25-
connected
26-
</Text>
27-
<Text variant="header" dense>
28-
{mountedKeys.length}
29-
</Text>
30-
</Panel>
31-
<Panel>
32-
<Text variant="label" dense>
33-
updates
34-
</Text>
35-
<Text variant="header" dense>
36-
{updatesCount}
37-
</Text>
38-
</Panel>
39-
<Panel>
40-
<Text variant="label" dense>
41-
values watched
42-
</Text>
43-
<Text variant="header" dense>
44-
{statePathsCount}
45-
</Text>
46-
</Panel>
47-
</Panels>
48-
<Table headers={['name', 'updates', 'values']}>
49-
{mountedKeys.map((key) => {
50-
const component = components[key]
51-
return (
52-
<Row key={component.id}>
53-
<Cell>{component.name}</Cell>
54-
<Cell>
55-
<Text variant="title" dense>
56-
{component.updateCount}
57-
</Text>
58-
</Cell>
59-
<Cell>
60-
{component.paths.map((path) => <Pill key={path}>{path}</Pill>)}
61-
</Cell>
62-
</Row>
63-
)
64-
})}
65-
</Table>
66-
</Wrapper>
67-
)
68-
}
8+
const Components: React.SFC<Connect> = ({ appState }) => (
9+
<Wrapper>
10+
<Panels>
11+
<Panel>
12+
<Text variant="label" dense>
13+
connected
14+
</Text>
15+
<Text variant="header" dense>
16+
{appState.componentsMounted.length}
17+
</Text>
18+
</Panel>
19+
<Panel>
20+
<Text variant="label" dense>
21+
updates
22+
</Text>
23+
<Text variant="header" dense>
24+
{appState.componentsUpdateCount}
25+
</Text>
26+
</Panel>
27+
<Panel>
28+
<Text variant="label" dense>
29+
values watched
30+
</Text>
31+
<Text variant="header" dense>
32+
{appState.componentsStatePathCount}
33+
</Text>
34+
</Panel>
35+
</Panels>
36+
<Table headers={['name', 'updates', 'values']}>
37+
{appState.componentsMounted.map((component) => {
38+
return (
39+
<Row key={component.id}>
40+
<Cell>{component.name}</Cell>
41+
<Cell>
42+
<Text variant="title" dense>
43+
{component.updateCount}
44+
</Text>
45+
</Cell>
46+
<Cell>
47+
{component.paths.map((path) => <Pill key={path}>{path}</Pill>)}
48+
</Cell>
49+
</Row>
50+
)
51+
})}
52+
</Table>
53+
</Wrapper>
54+
)
6955

7056
export default connect(Components)

packages/node_modules/overmind-devtools/src/client/components/Console/index.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ import { Wrapper } from './elements'
66
class Console extends React.Component<Connect> {
77
render() {
88
const { appState } = this.props
9-
const messagesReversed = appState.apps[appState.currentPort].messages
10-
.slice()
11-
.reverse()
9+
const messagesReversed = appState.currentApp.messages.slice().reverse()
1210

1311
return (
1412
<Wrapper>

packages/node_modules/overmind/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"repository": "git+https://github.com/cerebral/overmind.git",
88
"main": "lib/index.js",
99
"module": "es/index.js",
10-
"types": "lib/bundle.d.ts",
10+
"types": "lib/index.d.ts",
1111
"scripts": {
1212
"build": "npm run build:lib & npm run build:es",
1313
"build:lib": "tsc --outDir lib --module commonjs",
@@ -16,7 +16,6 @@
1616
"typecheck": "tsc --noEmit",
1717
"test": "jest",
1818
"test:watch": "jest --watch --updateSnapshot --coverage false",
19-
"prepare": "npm run build",
2019
"prebuild": "npm run clean",
2120
"postbuild": "rimraf {lib,es}/**/__tests__",
2221
"posttest": "npm run typecheck"
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import App, { derived } from './'
2+
3+
type State = {
4+
foo: string
5+
upperFoo: string
6+
}
7+
8+
describe('Derived', () => {
9+
test('should instantiate app with derived state', () => {
10+
const app = new App({
11+
state: {
12+
foo: 'bar',
13+
upperFoo: derived((state: State) => state.foo.toUpperCase()),
14+
},
15+
})
16+
expect(app.state.upperFoo).toEqual('BAR')
17+
})
18+
test('should track derived state', () => {
19+
let renderCount = 0
20+
const app = new App({
21+
state: {
22+
foo: 'bar',
23+
upperFoo: derived((state: State) => state.foo.toUpperCase()),
24+
},
25+
actions: (action) => ({
26+
changeFoo: action().mutation((_, state) => (state.foo = 'bar2')),
27+
}),
28+
})
29+
function render() {
30+
const trackId = app.trackState()
31+
app.state.upperFoo
32+
return app.clearTrackState(trackId)
33+
}
34+
app.addMutationListener(render(), () => {
35+
renderCount++
36+
})
37+
app.actions.changeFoo()
38+
expect(app.state.upperFoo).toBe('BAR2')
39+
expect(renderCount).toBe(1)
40+
})
41+
})
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import ProxyStateTree from 'proxy-state-tree'
2+
3+
class Derived {
4+
isDirty: boolean
5+
proxyStateTreeListener: any
6+
value: any
7+
cb: (state: object) => void
8+
paths: Set<string>
9+
constructor(cb) {
10+
this.isDirty = true
11+
this.proxyStateTreeListener = null
12+
this.value = null
13+
this.cb = cb
14+
return this.evaluate.bind(this)
15+
}
16+
evaluate(proxyStateTree: ProxyStateTree) {
17+
if (this.isDirty) {
18+
const trackId = proxyStateTree.startPathsTracking()
19+
this.value = this.cb(proxyStateTree.get())
20+
this.isDirty = false
21+
this.paths = proxyStateTree.clearPathsTracking(trackId)
22+
if (this.proxyStateTreeListener) {
23+
this.proxyStateTreeListener.update(this.paths)
24+
} else {
25+
this.proxyStateTreeListener = proxyStateTree.addMutationListener(
26+
this.paths,
27+
() => {
28+
this.isDirty = true
29+
}
30+
)
31+
}
32+
}
33+
34+
// Tracks the paths for the consumer of this derived value
35+
for (let path of this.paths) {
36+
proxyStateTree.addTrackingPath(path)
37+
}
38+
39+
return this.value
40+
}
41+
}
42+
43+
export default function derived<NewValue>(
44+
cb: (state: object) => NewValue
45+
): NewValue {
46+
return (new Derived(cb) as any) as NewValue
47+
}

packages/node_modules/overmind/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import createActionFactory, {
66
NoValueAction,
77
} from './createActionFactory'
88
export { default as compose } from './compose'
9+
export { default as derived } from './derived'
910

1011
type Configuration<State, Providers, Actions> = {
1112
state?: State
@@ -178,7 +179,7 @@ export default class App<
178179
clearTrackState(id: number) {
179180
return this.proxyStateTree.clearPathsTracking(id)
180181
}
181-
addMutationListener(name, paths, cb) {
182+
addMutationListener(paths, cb) {
182183
return this.proxyStateTree.addMutationListener(paths, cb)
183184
}
184185
}

0 commit comments

Comments
 (0)