Skip to content

Commit cc500c8

Browse files
fix(overmind): general fixes on parallel statecharts
1 parent 6604879 commit cc500c8

File tree

2 files changed

+34
-19
lines changed

2 files changed

+34
-19
lines changed

packages/node_modules/overmind/src/config/statechart.test.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { IAction, createOvermind } from '../'
22
import { Statechart, statechart } from './'
33

44
describe('Statecharts', () => {
5-
test.only('should wrap configs', () => {
5+
test('should wrap configs', () => {
66
const config = {}
77

88
const chart: Statechart<typeof config, 'foo'> = {
@@ -369,7 +369,7 @@ describe('Statecharts', () => {
369369
statechart(config, [parallelChartA, parallelChartB])
370370
)
371371

372-
expect(instance.state.states).toEqual([['bar'], ['foo']])
372+
expect(instance.state.states).toEqual([[0, 'bar'], [1, 'foo']])
373373
expect(instance.state.actions).toEqual({
374374
increaseCount: true,
375375
changeToBar: true,
@@ -386,10 +386,10 @@ describe('Statecharts', () => {
386386

387387
instance.actions.changeToBar()
388388

389-
expect(instance.state.states).toEqual([['foo'], ['bar']])
389+
expect(instance.state.states).toEqual([[0, 'foo'], [1, 'bar']])
390390
expect(instance.state.actions).toEqual({
391-
increaseCount: true,
392-
changeToBar: true,
391+
increaseCount: false,
392+
changeToBar: false,
393393
})
394394
expect(instance.state.matches('foo')).toEqual(true)
395395
expect(instance.state.matches('bar')).toEqual(true)
@@ -455,7 +455,7 @@ describe('Statecharts', () => {
455455
statechart(config, [parallelChartA, parallelChartB])
456456
)
457457

458-
expect(instance.state.states).toEqual([['bar'], ['foo', 'foo']])
458+
expect(instance.state.states).toEqual([[0, 'bar'], [1, 'foo', 'foo']])
459459
expect(instance.state.actions).toEqual({
460460
increaseCount: true,
461461
changeToBar: true,
@@ -472,10 +472,10 @@ describe('Statecharts', () => {
472472

473473
instance.actions.changeToBar()
474474

475-
expect(instance.state.states).toEqual([['foo'], ['bar']])
475+
expect(instance.state.states).toEqual([[0, 'foo'], [1, 'bar']])
476476
expect(instance.state.actions).toEqual({
477-
increaseCount: true,
478-
changeToBar: true,
477+
increaseCount: false,
478+
changeToBar: false,
479479
})
480480
expect(instance.state.matches('foo')).toEqual(true)
481481
expect(instance.state.matches('bar', 'foo')).toEqual(false)
@@ -533,13 +533,13 @@ describe('Statecharts', () => {
533533

534534
const instance = createOvermind(statechart(config, mainChart))
535535

536-
expect(instance.state.states).toEqual([['foo', 'baz'], ['foo', 'baz']])
537-
expect(instance.state.actions).toEqual({ increaseCount: true })
536+
expect(instance.state.states).toEqual([['foo', 0, 'baz'], ['foo', 1, 'baz']])
537+
expect(instance.state.actions).toEqual({ increaseCount: true, changeToBar: true })
538538
expect(instance.state.matches('foo', 'baz')).toEqual(true)
539539
expect(instance.state.count).toBe(2)
540540
instance.actions.changeToBar()
541541
expect(instance.state.states).toEqual([['bar']])
542-
expect(instance.state.actions).toEqual({ increaseCount: false })
542+
expect(instance.state.actions).toEqual({ increaseCount: false, changeToBar: false })
543543
expect(instance.state.matches('foo', 'baz')).toEqual(false)
544544
expect(instance.state.count).toBe(3)
545545
})

packages/node_modules/overmind/src/config/statechart.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ function getActionTransitions(
5454
return
5555
}
5656
if (target.on && typeof target.on[key] === 'string') {
57+
// If we have already transition to this path it means
58+
// we are moving away from multiple paths (parallel)
59+
if (transitions.includes(target.on[key])) {
60+
return
61+
}
5762
transitions.push(target.on[key])
5863
return
5964
}
@@ -99,9 +104,6 @@ function getInitialStates(chart, paths: Array<(string | number)[]> = [[]]) {
99104
if (chart.states[chart.initial].chart) {
100105
getInitialStates(chart.states[chart.initial].chart, paths)
101106
}
102-
if (Array.isArray(chart.states[chart.initial])) {
103-
getInitialStates(chart.states[chart.initial], paths)
104-
}
105107
}
106108

107109
return paths
@@ -198,6 +200,10 @@ export function statechart<C extends IConfiguration>(
198200

199201
return {
200202
onInitialize: ((context, instance) => {
203+
if (config.onInitialize) {
204+
config.onInitialize(context, instance)
205+
}
206+
201207
currentInstance = instance
202208
const stateTarget = getTarget(
203209
context.state,
@@ -242,8 +248,10 @@ export function statechart<C extends IConfiguration>(
242248
matches: (state) => (...args) => {
243249
return state.states.reduce((aggr, path) => {
244250
if (aggr) return aggr
251+
252+
const cleanPath = path.filter((pathKey) => typeof pathKey !== 'number')
245253
for (let x = 0; x < args.length; x++) {
246-
if (args[x] !== path[x]) {
254+
if (args[x] !== cleanPath[x]) {
247255
return false
248256
}
249257
}
@@ -276,12 +284,18 @@ export function statechart<C extends IConfiguration>(
276284
)
277285
const newStates: Array<(string | number)[]> = []
278286

287+
if (transitions.includes('entry') || transitions.includes('exit')) {
288+
actions[key](context, payload)
289+
}
290+
279291
transitions.forEach((transition, index) => {
292+
const oldStatePath = stateTarget.states[index].slice()
293+
280294
if (transition === 'entry' || transition === 'exit') {
281-
return actions[key](context, payload)
295+
newStates.push(oldStatePath)
296+
return
282297
}
283-
284-
const oldStatePath = stateTarget.states[index].slice()
298+
285299
const currentStatePath = stateTarget.states[index].slice()
286300
const stateTransitions = currentStatePath.map(() => null)
287301

@@ -342,6 +356,7 @@ export function statechart<C extends IConfiguration>(
342356
return actions[key](context, payload)
343357
})
344358

359+
// Actually change what has changed
345360
stateTarget.states = newStates
346361

347362
if (process.env.NODE_ENV === 'development' && currentInstance.devtools) {

0 commit comments

Comments
 (0)