Skip to content

Commit

Permalink
Add changeset + clean up invoke.test.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
davidkpiano committed May 21, 2020
1 parent 5569d75 commit 390eaaa
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 28 deletions.
105 changes: 105 additions & 0 deletions .changeset/rotten-rivers-wonder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
'xstate': major
---

**Breaking:** Activities are no longer a separate concept. Instead, activities are invoked. Internally, this is how activities worked. The API is consolidated so that `activities` are no longer a property of the state node or machine options:

```diff
import { createMachine } from 'xstate';
+import { invokeActivity } from 'xstate/invoke';

const machine = createMachine(
{
// ...
- activities: 'someActivity',
+ invoke: {
+ src: 'someActivity'
+ }
},
{
- activities: {
+ behaviors: {
- someActivity: ((context, event) => {
+ someActivity: invokeActivity((context, event) => {
// ... some continuous activity

return () => {
// dispose activity
}
})
}
}
);
```

**Breaking:** The `services` option passed as the second argument to `createMachine(config, options)` is renamed to `behaviors`. Each value in `behaviors`should be a function that takes in `context` and `event` and returns a [behavior](TODO: link). The provided invoke creators are:

- `invokeActivity`
- `invokePromise`
- `invokeCallback`
- `invokeObservable`
- `invokeMachine`

```diff
import { createMachine } from 'xstate';
+import { invokePromise } from 'xstate/invoke';

const machine = createMachine(
{
// ...
invoke: {
src: 'fetchFromAPI'
}
},
{
- services: {
+ behaviors: {
- fetchFromAPI: ((context, event) => {
+ fetchFromAPI: invokePromise((context, event) => {
// ... (return a promise)
})
}
}
);
```

**Breaking:** The `state.children` property is now a mapping of invoked actor IDs to their `ActorRef` instances.

**Breaking:** The way that you interface with invoked/spawned actors is now through `ActorRef` instances. An `ActorRef` is an opaque reference to an `Actor`, which should be never referenced directly.

**Breaking:** The `spawn` function is no longer imported globally. Spawning actors is now done inside of `assign(...)`, as seen below:

```diff
-import { createMachine, spawn } from 'xstate';
+import { createMachine } from 'xstate';

const machine = createMachine({
// ...
entry: assign({
- someRef: (context, event) => {
+ someRef: (context, event, { spawn }) => {
- return spawn(somePromise);
+ return spawn.from(somePromise);
}
})
});

```

**Breaking:** The `src` of an `invoke` config is now either a string that references the machine's `options.behaviors`, or a `BehaviorCreator`, which is a function that takes in `context` and `event` and returns a `Behavior`:

```diff
import { createMachine } from 'xstate';
+import { invokePromise } from 'xstate/invoke';

const machine = createMachine({
// ...
invoke: {
- src: (context, event) => somePromise
+ src: invokePromise((context, event) => somePromise)
}
// ...
});
```

**Breaking:** The `origin` of an `SCXML.Event` is no longer a string, but an `ActorRef` instance, which can be serialized into a string.

This comment has been minimized.

Copy link
@Andarist

Andarist May 21, 2020

Member

how to serialize it into a string? can the serialized string be used anyhow?

10 changes: 7 additions & 3 deletions docs/packages/xstate-react/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,16 @@ const Fetcher = ({ onFetch = () => new Promise(res => res('some data')) }) => {
};
```

## Configuring Machines <Badge text="0.7+"/>
## Configuring Machines

Existing machines can be configured by passing the machine options as the 2nd argument of `useMachine(machine, options)`.

Example: the `'fetchData'` service and `'notifySuccess'` action are both configurable:

```js
import { createMachine } from 'xstate';
import { invokePromise } from 'xstate/invoke';

const fetchMachine = Machine({
id: 'fetch',
initial: 'idle',
Expand Down Expand Up @@ -201,8 +204,9 @@ const Fetcher = ({ onResolve }) => {
notifySuccess: (ctx) => onResolve(ctx.data)
},
behaviors: {
fetchData: (_, e) =>
fetch(`some/api/${e.query}`).then((res) => res.json())
fetchData: invokePromise((_, event) =>
fetch(`some/api/${event.query}`).then((res) => res.json())
)
}
});

Expand Down
45 changes: 20 additions & 25 deletions packages/core/test/invoke.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
} from '../src/invoke';
import { interval } from 'rxjs';
import { map, take } from 'rxjs/operators';
import { createMachineBehavior } from '../src/behavior';

const user = { name: 'David' };

Expand Down Expand Up @@ -503,19 +502,17 @@ describe('invoke', () => {
initial: 'pending',
states: {
pending: {
invoke: (_, __, { parent }) =>
createMachineBehavior(
Machine({
id: 'child',
initial: 'sending',
states: {
sending: {
entry: sendParent({ type: 'SUCCESS', data: 42 })
}
invoke: invokeMachine(
Machine({
id: 'child',
initial: 'sending',
states: {
sending: {
entry: sendParent({ type: 'SUCCESS', data: 42 })
}
}),
parent
),
}
})
),
on: {
SUCCESS: {
target: 'success',
Expand Down Expand Up @@ -548,19 +545,17 @@ describe('invoke', () => {
initial: 'b',
states: {
b: {
invoke: (_, __, { parent }) =>
createMachineBehavior(
Machine({
id: 'child',
initial: 'sending',
states: {
sending: {
entry: sendParent({ type: 'SUCCESS', data: 42 })
}
invoke: invokeMachine(
Machine({
id: 'child',
initial: 'sending',
states: {
sending: {
entry: sendParent({ type: 'SUCCESS', data: 42 })
}
}),
parent
)
}
})
)
}
}
},
Expand Down

0 comments on commit 390eaaa

Please sign in to comment.