Skip to content

Commit c28b02d

Browse files
Merge pull request cerebral#36 from cerebral/devtoolsImprovements
fix(overmind-devtools): fix provider tracking and some styling
2 parents 5c165ea + 7437dab commit c28b02d

File tree

16 files changed

+187
-98
lines changed

16 files changed

+187
-98
lines changed

packages/demos/todomvc/src/app/actions.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@ import { Todo } from './state'
44
import * as helpers from './helpers'
55
import * as mutations from './mutations'
66

7-
function hasLength(_, value: string) {
8-
return Boolean(value.length)
9-
}
10-
11-
function noop() {}
12-
137
export default (action: Action) => ({
148
changeNewTodoTitle: action<React.ChangeEvent<HTMLInputElement>>()
159
.map(helpers.getEventValue)
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
1-
export const foo = {}
1+
export const say = {
2+
hello: (name: string) => ({ hello: `Hello ${name}` }),
3+
}
4+
5+
export const api = {
6+
getPosts: () =>
7+
fetch('https://jsonplaceholder.typicode.com/posts').then((response) =>
8+
response.json()
9+
),
10+
}

packages/node_modules/action-chain/src/ActionChain.ts

Lines changed: 53 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export interface ActionChainEvents {
4040
name: string
4141
method: string | number | symbol
4242
result: any
43+
args: any[]
4344
}
4445
'action:start': ActionExecution
4546
'action:end': ActionExecution
@@ -56,6 +57,10 @@ export interface ActionChainEvents {
5657
}
5758
}
5859

60+
function isObject(value) {
61+
return typeof value === 'object' && !Array.isArray(value) && value !== null
62+
}
63+
5964
export class ActionChain<Context> extends EventEmitter<ActionChainEvents> {
6065
constructor(
6166
private context: Context,
@@ -64,53 +69,64 @@ export class ActionChain<Context> extends EventEmitter<ActionChainEvents> {
6469
super()
6570
this.options.providerExceptions = options.providerExceptions || []
6671
}
72+
private createGetHandler(execution, path) {
73+
const instance = this
74+
return (target, prop) => {
75+
if (typeof target[prop] === 'function') {
76+
return (...args) => {
77+
const result = target[prop](...args)
78+
if (result instanceof Promise) {
79+
result.then((promisedResult) => {
80+
instance.emit('provider', {
81+
...execution,
82+
name: path,
83+
method: prop,
84+
args,
85+
result: promisedResult,
86+
})
87+
})
88+
} else {
89+
instance.emit('provider', {
90+
...execution,
91+
name: path,
92+
method: prop,
93+
args,
94+
result,
95+
})
96+
}
97+
98+
return result
99+
}
100+
} else if (isObject(target[prop])) {
101+
return new Proxy(target[prop], {
102+
get: instance.createGetHandler(execution, path + '.' + prop),
103+
})
104+
}
105+
106+
return target[prop]
107+
}
108+
}
67109

68110
getContext(thisExecution: Execution, executionContext: ExecutionContext) {
69-
const instance = this
70-
const providers = Object.keys(this.context).reduce(
71-
(currentContext, key) => {
111+
let context = this.context
112+
113+
if (IS_DEVELOPMENT) {
114+
context = Object.keys(this.context).reduce((currentContext, key) => {
72115
if (
73-
IS_DEVELOPMENT &&
74-
this.options.providerExceptions.indexOf(key) === -1
116+
this.options.providerExceptions.indexOf(key) === -1 &&
117+
isObject(this.context[key])
75118
) {
76119
currentContext[key] = new Proxy(this.context[key], {
77-
get(target, prop) {
78-
if (typeof target[prop] === 'function') {
79-
return (...args) => {
80-
const result = target[prop](...args)
81-
if (result instanceof Promise) {
82-
result.then((promisedResult) => {
83-
instance.emit('provider', {
84-
...thisExecution,
85-
name: key,
86-
method: prop,
87-
result: promisedResult,
88-
})
89-
})
90-
} else {
91-
instance.emit('provider', {
92-
...thisExecution,
93-
name: key,
94-
method: prop,
95-
result,
96-
})
97-
}
98-
99-
return result
100-
}
101-
}
102-
103-
return target[prop]
104-
},
120+
get: this.createGetHandler(thisExecution, key),
105121
})
106122
} else {
107123
currentContext[key] = this.context[key]
108124
}
109125

110126
return currentContext
111-
},
112-
{}
113-
)
114-
return { ...providers, ...executionContext }
127+
}, {}) as Context
128+
}
129+
130+
return Object.assign({}, context, executionContext)
115131
}
116132
}

packages/node_modules/action-chain/src/index.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ const context = {
6262
bar() {
6363
return 'baz'
6464
},
65+
nestedProvider: {
66+
bar() {
67+
return 'baz'
68+
},
69+
},
6570
},
6671
test: new TestProvider(),
6772
}
@@ -135,6 +140,26 @@ describe('PROVIDER', () => {
135140
executionId: 0,
136141
method: 'bar',
137142
name: 'foo',
143+
args: [],
144+
result: 'baz',
145+
})
146+
})
147+
fn()
148+
})
149+
test('should track execution of namespaced providers', () => {
150+
expect.assertions(2)
151+
const fn = action().test(({ foo }) => {
152+
expect(foo.nestedProvider.bar()).toBe('baz')
153+
})
154+
155+
actionChain.once('provider', (task) => {
156+
expect(task).toEqual({
157+
operatorId: 0,
158+
actionId: 0,
159+
executionId: 0,
160+
method: 'bar',
161+
name: 'foo.nestedProvider',
162+
args: [],
138163
result: 'baz',
139164
})
140165
})
@@ -152,6 +177,7 @@ describe('PROVIDER', () => {
152177
actionId: 0,
153178
executionId: 0,
154179
method: 'foo',
180+
args: [],
155181
name: 'test',
156182
result: 'bar',
157183
})

packages/node_modules/overmind-devtools/src/app/actions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export default (action: Action) => {
1010

1111
const loadDevtools = action()
1212
// .do(({ storage }) => storage.clear())
13+
// Do a check if the current app matches the keys of the ???
1314
.map(helpers.getAppsFromStorage)
1415
.mutation(mutations.setApps)
1516
.map(helpers.getCurrentPortFromStorage)

packages/node_modules/overmind-devtools/src/app/derived.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ export const flushes = derived((state: State) =>
3636
Object.keys(state.currentApp.flushes)
3737
.sort(
3838
(idA, idB) =>
39-
state.currentApp.flushes[idA].flushId -
40-
state.currentApp.flushes[idB].flushId
39+
state.currentApp.flushes[idB].flushId -
40+
state.currentApp.flushes[idA].flushId
4141
)
4242
.map((id) => state.currentApp.flushes[id])
4343
)

packages/node_modules/overmind-devtools/src/app/mutations.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,12 +276,12 @@ export function performMutationsByMessageType(state: State, message: Message) {
276276
break
277277
}
278278
case 'provider': {
279-
const providers = clientMessage.data
280-
const id = `${providers.actionId}_${providers.executionId}`
279+
const provider = clientMessage.data
280+
const id = getActionId(provider)
281281
const operator =
282-
state.apps[message.port].actions[id].operators[providers.operatorId]
282+
state.apps[message.port].actions[id].operators[provider.operatorId]
283283

284-
operator.providers = providers.providers
284+
operator.providers.push(provider)
285285
break
286286
}
287287
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ export type Mutation = {
99
export type Provider = {
1010
args: any[]
1111
method: string
12-
path: string
13-
returnValue: any
12+
name: string
13+
result: any
1414
}
1515

1616
export enum ActionsListItemType {
@@ -190,7 +190,7 @@ const state: State = {
190190
currentPort: null,
191191
apps: {},
192192
newPortValue: '',
193-
currentTab: Tab.Actions,
193+
currentTab: Tab.State,
194194
expandedStatePaths: [''],
195195
currentApp: derived.currentApp,
196196
componentsMounted: derived.componentsMounted,

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,10 @@ import Flush from '../ActionFlush'
66
import { getActionId, getOperatorId } from '../../app/utils'
77

88
const Action: React.SFC<Connect> = ({ app }) => {
9-
if (!app.state.currentAction) {
10-
return null
11-
}
12-
139
const flushReference =
1410
app.state.currentApp.flushByActionId[getActionId(app.state.currentAction)]
15-
const flush = app.state.currentApp.flushes[flushReference.flushId]
11+
const flush =
12+
flushReference && app.state.currentApp.flushes[flushReference.flushId]
1613

1714
return (
1815
<Wrapper>

packages/node_modules/overmind-devtools/src/components/ActionOperator/elements.tsx

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ import { Colors } from '../../theme'
44
export const Operator = styled<
55
{
66
borderColor: keyof Colors
7+
onClick: any
78
},
89
'div'
910
>('div')`
1011
flex: 1;
1112
display: flex;
1213
flex-direction: column;
1314
padding: ${({ theme }) => `0 ${theme.padding.smaller}`};
14-
cursor: pointer;
15+
cursor: ${({ onClick }) => (onClick ? 'pointer' : 'default')};
1516
border: 1px solid ${({ theme, borderColor }) => theme.color[borderColor]};
1617
background-color: #fff;
1718
border-radius: ${({ theme }) => theme.borderRadius.normal};
@@ -23,20 +24,17 @@ export const OperatorHeader = styled.div`
2324
> *:first-child {
2425
margin-right: 10px;
2526
}
26-
> *:last-child {
27+
> *:nth-child(3) {
2728
margin-left: auto;
2829
color: ${({ theme }) => theme.color.fade(theme.color.black, 0.75)};
2930
}
3031
`
3132

32-
export const Mutation = styled.div`
33+
export const OperatorItem = styled.div`
3334
display: flex;
3435
align-items: center;
35-
> *:first-child {
36-
flex: 0 0 50px;
37-
}
38-
> *:last-child {
39-
flex: 0 0 200px;
40-
margin-left: auto;
36+
margin-bottom: ${({ theme }) => theme.padding.smaller};
37+
> * {
38+
margin-right: 10px;
4139
}
4240
`

0 commit comments

Comments
 (0)