-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add changeset entry for interpreterOption changes
- Loading branch information
1 parent
9990bd7
commit 9ee0ef3
Showing
1 changed file
with
98 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
--- | ||
'ember-statecharts': minor | ||
--- | ||
|
||
## 🥁 Features | ||
|
||
### InterpreterOptions | ||
Bring back ability to customize [InterpreterOptions](https://xstate.js.org/docs/guides/interpretation.html#options) that are used when a machine passed to `useMachine` gets interpreted. This is probably most useful for people that want to have xState delays etc. be scheduled via a custom clock service that uses [Ember's runloop](https://guides.emberjs.com/release/applications/run-loop/), but can be used to pass other [interpreterOptions](https://xstate.js.org/docs/guides/interpretation.html#options) as well. | ||
|
||
To customize `interpreterOptions`, when you would like to provide the same options every time you use `useMachine`, you can create a wrapper-function for `useMachine`: | ||
|
||
Example: | ||
|
||
```js | ||
const wrappedUseMachine = (context, options) => { | ||
return useMachine(context, () => { | ||
return { | ||
interpreterOptions: { | ||
clock: { | ||
setTimeout(fn, timeout) { | ||
later.call(null, fn, timeout); | ||
}, | ||
clearTimeout(id) { | ||
cancel.call(null, id); | ||
}, | ||
}, | ||
}, | ||
...options(), | ||
}; | ||
}); | ||
}; | ||
|
||
statechart = wrappedUseMachine(this, () => { | ||
// ... | ||
}); | ||
``` | ||
|
||
### `runloopClockService`-configuration option | ||
For the use-case of having xState timeouts etc. be schedule via the runloop, `ember-statecharts` now provides a configuration option. You can turn it on to have xState use a custom [clock](https://xstate.js.org/docs/guides/delays.html#interpretation) and schedule, and cancel timeouts via the ember-runloop. This makes testing via `@ember/test-helpers` arguably more ergonomic, as you won't need to explicitly await ui changes that are triggered by schedule statechart changes explicitly anymore. | ||
|
||
Example - based on the test that tests this behavior: | ||
|
||
```js | ||
import { module, test } from 'qunit'; | ||
import { setupRenderingTest } from 'test-app/tests/helpers'; | ||
import { click, render, waitUntil } from '@ember/test-helpers'; | ||
import { hbs } from 'ember-cli-htmlbars'; | ||
|
||
module('Integration | Component | use-machine', function (hooks) { | ||
setupRenderingTest(hooks); | ||
|
||
test('awaiting needs to be explicit with no `runloopClockService`-option set', async function (assert) { | ||
const config = this.owner.resolveRegistration('config:environment'); | ||
|
||
config['ember-statecharts'] = { | ||
runloopClockService: false, | ||
}; | ||
|
||
await render(hbs`<DelayedToggle data-test-toggle />`); | ||
|
||
assert.dom('[data-test-off]').exists('initially toggle is off'); | ||
|
||
await click('[data-test-toggle]'); | ||
|
||
// oh noes, we need to wait explicitly as xState uses `window.setTimeout` by default 😢 | ||
await waitUntil(() => { | ||
return document.querySelector('[data-test-off]'); | ||
}); | ||
|
||
assert.dom('[data-test-off]').exists('initially toggle is off'); | ||
}); | ||
|
||
test('awaiting happens automatically when `runloopClockService`-option is set', async function (assert) { | ||
const config = this.owner.resolveRegistration('config:environment'); | ||
|
||
config['ember-statecharts'] = { | ||
runloopClockService: true, | ||
}; | ||
|
||
await render(hbs`<DelayedToggle data-test-toggle />`); | ||
|
||
assert.dom('[data-test-off]').exists('initially toggle is off'); | ||
|
||
// just awaiting the click is enough now, because we schedule delays on the runloop 🥳 | ||
await click('[data-test-toggle]'); | ||
|
||
assert.dom('[data-test-off]').exists('initially toggle is off'); | ||
}); | ||
}); | ||
``` | ||
|
||
To turn on this behavior, you can set the `runloopClockService`-configuration in `config/environment.js`: | ||
|
||
```js | ||
ENV['ember-statecharts'] = { | ||
runloopClockService: true | ||
} | ||
``` |