Skip to content

Commit 4722872

Browse files
feat(overmind): parallel and onInitialize
1 parent e6f6678 commit 4722872

File tree

14 files changed

+278
-70
lines changed

14 files changed

+278
-70
lines changed

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

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -222,14 +222,14 @@ export const performMutationsByMessageType: Mutate<Message> = (
222222
case 'action:start': {
223223
const app = state.apps[message.port]
224224
const action = clientMessage.data
225-
const id = getActionId(action)
225+
const actionId = getActionId(action)
226226
const isSelectingFirstAction =
227227
!app.currentActionId || app.currentActionId === app.actionsList[0].id
228228

229-
app.actions[id] = {
229+
app.actions[actionId] = {
230230
...action,
231231
isRunning: true,
232-
operators: {},
232+
operators: [],
233233
}
234234

235235
if (
@@ -238,7 +238,7 @@ export const performMutationsByMessageType: Mutate<Message> = (
238238
) {
239239
app.actionsList.unshift({
240240
type: ActionsListItemType.ACTION,
241-
id,
241+
id: actionId,
242242
actionId: action.actionId,
243243
})
244244
} else if (app.actionsList[0].type === ActionsListItemType.ACTION) {
@@ -248,40 +248,65 @@ export const performMutationsByMessageType: Mutate<Message> = (
248248
id: getActionId(action),
249249
actionId: action.actionId,
250250
isCollapsed: true,
251-
actionIds: [id, existingId],
251+
actionIds: [actionId, existingId],
252252
}
253253
} else if (app.actionsList[0].type === ActionsListItemType.GROUP) {
254-
;(app.actionsList[0] as ActionGroupItem).actionIds.unshift(id)
255-
;(app.actionsList[0] as ActionGroupItem).id = id
254+
;(app.actionsList[0] as ActionGroupItem).actionIds.unshift(actionId)
255+
;(app.actionsList[0] as ActionGroupItem).id = actionId
256256
}
257257

258258
if (isSelectingFirstAction) {
259-
app.currentActionId = id
259+
app.currentActionId = actionId
260260
}
261261
break
262262
}
263263
case 'operator:start': {
264-
const operator = clientMessage.data
265-
const id = `${operator.actionId}_${operator.executionId}`
266-
const action = state.apps[message.port].actions[id]
267-
268-
action.operators[operator.operatorId] = {
269-
...operator,
264+
const operatorData = clientMessage.data
265+
const actionId = getActionId(operatorData)
266+
const action = state.apps[message.port].actions[actionId]
267+
const operator = {
268+
...operatorData,
270269
isRunning: true,
271270
isCollapsed: true,
272271
mutations: [],
273272
effects: [],
274273
}
274+
275+
action.operators.push(operator)
276+
277+
/*
278+
This ensures the order of operators, as actions composed with
279+
"parallel" operator can trigger operators sync/async, adding
280+
them in wrong order
281+
*/
282+
const paths = new Map()
283+
action.operators.forEach((operator, index) => {
284+
const path = operator.path.length
285+
? operator.path.join('.')
286+
: '__' + index
287+
if (paths.has(path)) {
288+
paths.get(path).push(operator)
289+
} else {
290+
paths.set(path, [operator])
291+
}
292+
})
293+
action.operators = Array.from(paths).reduce(
294+
(aggr, arr) => aggr.concat(arr[1]),
295+
[]
296+
)
275297
break
276298
}
277299
case 'operator:end': {
278-
const operator = clientMessage.data
279-
const id = `${operator.actionId}_${operator.executionId}`
280-
const action = state.apps[message.port].actions[id]
300+
const operatorData = clientMessage.data
301+
const actionId = getActionId(operatorData)
302+
const action = state.apps[message.port].actions[actionId]
303+
const operator = action.operators.find(
304+
(operator) => getOperatorId(operatorData) === getOperatorId(operator)
305+
)
281306

282-
action.operators[operator.operatorId].isAsync = operator.isAsync
283-
action.operators[operator.operatorId].isRunning = false
284-
action.operators[operator.operatorId].result = operator.result
307+
operator.isAsync = operatorData.isAsync
308+
operator.isRunning = false
309+
operator.result = operatorData.result
285310
break
286311
}
287312
case 'action:end': {

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,12 @@ export type Operator = {
5050
result: any
5151
}
5252

53-
export type Operators = {
54-
[id: string]: Operator
55-
}
56-
5753
export type Action = {
5854
actionName: string
5955
actionId: number
6056
executionId: number
6157
isRunning: boolean
62-
operators: Operators
58+
operators: Operator[]
6359
value: any
6460
}
6561

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

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Operator from '../ActionOperator'
55
import Flush from '../ActionFlush'
66
import { getActionId, getOperatorId } from '../../app/utils'
77

8-
const ignoreOperatorValues = ['when', 'try', 'fork', 'compose']
8+
const ignoreOperatorValues = ['when', 'try', 'fork', 'compose', 'parallel']
99

1010
const Action: React.SFC<Connect> = ({ app }) => {
1111
const flushReference =
@@ -16,35 +16,42 @@ const Action: React.SFC<Connect> = ({ app }) => {
1616
return (
1717
<Wrapper>
1818
<Container>
19-
{Object.keys(app.state.currentAction.operators).map(
20-
(key, index, array) => {
21-
const operator = app.state.currentAction.operators[key]
22-
const prevOperator =
23-
app.state.currentAction.operators[array[index - 1]]
24-
const value =
25-
index === 0
26-
? app.state.currentAction.value
27-
: ignoreOperatorValues.includes(prevOperator.type)
28-
? undefined
29-
: prevOperator.result
30-
const flushReference =
31-
app.state.currentApp.flushByOperatorId[getOperatorId(operator)]
32-
const flush =
33-
flushReference &&
34-
app.state.currentApp.flushes[flushReference.flushId]
19+
{app.state.currentAction.operators.map((operator, index) => {
20+
const prevOperator = app.state.currentAction.operators[index - 1]
21+
const value =
22+
index === 0
23+
? app.state.currentAction.value
24+
: ignoreOperatorValues.includes(prevOperator.type)
25+
? undefined
26+
: prevOperator.result
27+
const flushReference =
28+
app.state.currentApp.flushByOperatorId[getOperatorId(operator)]
29+
const flush =
30+
flushReference &&
31+
app.state.currentApp.flushes[flushReference.flushId]
3532

36-
if (flush) {
37-
return (
38-
<React.Fragment key={key}>
39-
<Flush flush={flush} flushReference={flushReference} />
40-
<Operator key={key} operator={operator} value={value} />
41-
</React.Fragment>
42-
)
43-
}
44-
45-
return <Operator key={key} operator={operator} value={value} />
33+
if (flush) {
34+
return (
35+
<React.Fragment key={operator.operatorId}>
36+
<Flush flush={flush} flushReference={flushReference} />
37+
<Operator
38+
prevOperator={prevOperator}
39+
operator={operator}
40+
value={value}
41+
/>
42+
</React.Fragment>
43+
)
4644
}
47-
)}
45+
46+
return (
47+
<Operator
48+
key={operator.operatorId}
49+
prevOperator={prevOperator}
50+
operator={operator}
51+
value={value}
52+
/>
53+
)
54+
})}
4855
{!app.state.currentAction.isRunning && flush ? (
4956
<Flush flush={flush} flushReference={flushReference} />
5057
) : null}

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,17 @@ import { Pipe } from '../Action/elements'
99
import { Operator, OperatorHeader, OperatorItem } from './elements'
1010

1111
type Props = {
12+
prevOperator: OperatorType
1213
operator: OperatorType
1314
value: any
1415
} & Connect
1516

16-
const ActionOperator: React.SFC<Props> = ({ operator, value, app }) => (
17+
const ActionOperator: React.SFC<Props> = ({
18+
prevOperator,
19+
operator,
20+
value,
21+
app,
22+
}) => (
1723
<React.Fragment key={operator.operatorId}>
1824
{value === undefined ? null : (
1925
<Pipe>
@@ -22,7 +28,13 @@ const ActionOperator: React.SFC<Props> = ({ operator, value, app }) => (
2228
</Pipe>
2329
)}
2430
<Pipe>
25-
<Path borderColor={operator.type === 'mutation' ? 'red' : 'primary'}>
31+
<Path
32+
visible={
33+
prevOperator &&
34+
prevOperator.path.join('.') !== operator.path.join('.')
35+
}
36+
borderColor={operator.type === 'mutation' ? 'red' : 'primary'}
37+
>
2638
{operator.path.length ? (
2739
<Text variant="hint">
2840
<b>{operator.path.join('.')}</b>

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
import styled from '../../styled-components'
22
import { Colors } from 'overmind-themes'
33

4-
export const Path = styled.div`
4+
export const Path = styled<
5+
{
6+
visible?: boolean
7+
},
8+
'div'
9+
>('div')`
510
position: relative;
611
min-width: 25px;
12+
visibility: ${({ visible }) => (visible === false ? 'hidden' : 'visible')};
713
`
814

915
export const PathLine = styled<

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import { Colors } from 'overmind-themes'
44

55
type Props = {
66
borderColor?: keyof Colors
7+
visible?: boolean
78
}
89

9-
const ActionPath: React.SFC<Props> = ({ borderColor, children }) => (
10-
<Path>
10+
const ActionPath: React.SFC<Props> = ({ visible, borderColor, children }) => (
11+
<Path visible={visible}>
1112
<PathLine borderColor={borderColor} />
1213
{children ? (
1314
<PathText borderColor={borderColor}>{children}</PathText>

packages/node_modules/overmind/src/Action.ts

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export default class ActionClass<
8383
}
8484
const [chain, initialActionId, runOperators] = this.createOperatorResult(
8585
'fork',
86-
cb.name,
86+
(cb as any).displayName || cb.name,
8787
operator
8888
)
8989

@@ -113,7 +113,7 @@ export default class ActionClass<
113113

114114
const [chain, initialActionId, runOperators] = this.createOperatorResult(
115115
'mutate',
116-
cb.name,
116+
(cb as any).displayName || cb.name,
117117
operator
118118
)
119119

@@ -136,7 +136,7 @@ export default class ActionClass<
136136

137137
const [chain, initialActionId, runOperators] = this.createOperatorResult(
138138
'do',
139-
cb.name,
139+
(cb as any).displayName || cb.name,
140140
operator
141141
)
142142

@@ -154,7 +154,7 @@ export default class ActionClass<
154154
: IValueAction<State, Effects, InitialValue, NewValue> = (cb) => {
155155
const [chain, initialActionId, runOperators] = this.createOperatorResult(
156156
'map',
157-
cb.name,
157+
(cb as any).displayName || cb.name,
158158
cb
159159
)
160160

@@ -207,7 +207,7 @@ export default class ActionClass<
207207
}
208208
const [chain, initialActionId, runOperators] = this.createOperatorResult(
209209
'try',
210-
cb.name,
210+
(cb as any).displayName || cb.name,
211211
operator
212212
)
213213

@@ -243,7 +243,7 @@ export default class ActionClass<
243243
}
244244
const [chain, initialActionId, runOperators] = this.createOperatorResult(
245245
'when',
246-
cb.name,
246+
(cb as any).displayName || cb.name,
247247
operator
248248
)
249249

@@ -267,7 +267,41 @@ export default class ActionClass<
267267
}
268268
const [chain, initialActionId, runOperators] = this.createOperatorResult(
269269
'compose',
270-
action.name,
270+
(action as any).dispayName || action.name,
271+
operator
272+
)
273+
274+
return new ActionClass(
275+
this.proxyStateTree,
276+
chain,
277+
initialActionId,
278+
runOperators
279+
) as any
280+
}
281+
parallel: (
282+
actions: Compose<State, Effects, Value, any>[]
283+
) => [InitialValue] extends [void]
284+
? INoValueAction<State, Effects, InitialValue, Value>
285+
: IValueAction<State, Effects, InitialValue, Value> = (actions) => {
286+
const composedActions = actions.map((action) =>
287+
(action as any)(
288+
() => new ActionClass(this.proxyStateTree, this.getActionChain())
289+
)
290+
)
291+
const operator = (effects, value) => {
292+
return Promise.all(
293+
composedActions.map((composedAction, index) =>
294+
composedAction(
295+
value,
296+
effects,
297+
(actions[index] as any).displayName || actions[index].name
298+
)
299+
)
300+
).then(() => value)
301+
}
302+
const [chain, initialActionId, runOperators] = this.createOperatorResult(
303+
'parallel',
304+
'',
271305
operator
272306
)
273307

@@ -294,7 +328,7 @@ export default class ActionClass<
294328
}
295329
const [chain, initialActionId, runOperators] = this.createOperatorResult(
296330
'filter',
297-
cb.name,
331+
(cb as any).displayName || cb.name,
298332
operator
299333
)
300334

0 commit comments

Comments
 (0)