Skip to content

Commit

Permalink
Set deepest nested service to current (#231)
Browse files Browse the repository at this point in the history
* Set deepest nested service to current

This makes it so that we always use the deepest nested service as the `current`.

This is not a breaking change as this is current expected behavior. We were passing `service.child` to be the new current, but not accounting for the possibility of deeply nested machines.

Fixes #195

* Add changeset

* update test expectations

* Update packages/robot-hooks/test/test.js
  • Loading branch information
matthewp authored Dec 27, 2024
1 parent 91ea22f commit 9fbdbcb
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 12 deletions.
6 changes: 6 additions & 0 deletions .changeset/hungry-planes-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"robot-hooks": patch
"robot3": patch
---

Set the most deeply nested current service to current
3 changes: 2 additions & 1 deletion packages/core/machine.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,9 @@ function transitionTo(service, machine, fromEvent, candidates) {
if (d._onEnter) d._onEnter(machine, to, service.context, context, fromEvent);
let state = newMachine.state.value;
service.machine = newMachine;
let ret = state.enter(newMachine, service, fromEvent);
service.onChange(service);
return state.enter(newMachine, service, fromEvent);
return ret;
}
}
}
Expand Down
4 changes: 1 addition & 3 deletions packages/core/test/test-invoke.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ QUnit.module('Invoke', hooks => {

QUnit.test('Invoking a machine that immediately finishes', async assert => {
assert.expect(3);
const expectations = [ 'two', 'nestedTwo', 'three' ];
const expectations = [ 'nestedTwo', 'three', 'three' ];

const child = createMachine({
nestedOne: state(
Expand All @@ -379,8 +379,6 @@ QUnit.module('Invoke', hooks => {
});

let service = interpret(parent, s => {
// TODO not totally sure if this is correct, but I think it should
// hit this only once and be equal to three
assert.equal(s.machine.current, expectations.shift());
});

Expand Down
6 changes: 5 additions & 1 deletion packages/robot-hooks/machine.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ export function createUseMachine(useEffect, useState) {
if (!mounted) {
return;
}
setCurrent(createCurrent(service.child || service));
let currentService = service;
while(currentService.child) {
currentService = currentService.child;
}
setCurrent(createCurrent(currentService));
}, data || initialContext);
}

Expand Down
22 changes: 15 additions & 7 deletions packages/robot-hooks/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,19 @@ QUnit.module('useMachine', hooks => {
el.remove();
});

QUnit.skip('Invoking machines the "current" is the child machine', async assert => {
QUnit.test('Invoking machines the "current" is the child machine', async assert => {
const deep = createMachine({
deepOne: state(
transition('next', 'deepTwo')
),
deepTwo: state(),
});
const nested = createMachine({
nestedOne: state(
transition('next', 'nestedTwo')
),
nestedTwo: state()
nestedTwo: invoke(deep, transition('done', 'nestedThree')),
nestedThree: state()
});
const machine = createMachine({
one: state(
Expand All @@ -150,11 +157,9 @@ QUnit.module('useMachine', hooks => {
three: state()
});

let current, send, service;
let service;
function App() {
const [currentState, sendEvent, thisService] = useMachine(machine);
current = currentState;
send = sendEvent;
const [current, _send, thisService] = useMachine(machine);
service = thisService;

return html`
Expand All @@ -167,10 +172,13 @@ QUnit.module('useMachine', hooks => {
let text = () => el.textContent.trim();

assert.equal(text(), 'State: one');
yield send('next');
yield service.send('next');

assert.equal(text(), 'State: nestedOne');
yield service.child.send('next');

assert.equal(text(), 'State: deepOne');
yield service.child.child.send('next');

assert.equal(text(), 'State: three');
});
Expand Down

0 comments on commit 9fbdbcb

Please sign in to comment.