@xstate/react 4.0.0-beta.3 → 4.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/declarations/src/createActorContext.d.ts +6 -6
- package/dist/declarations/src/index.d.ts +6 -7
- package/dist/declarations/src/useActor.d.ts +6 -3
- package/dist/declarations/src/useActorRef.d.ts +14 -0
- package/dist/declarations/src/useMachine.d.ts +9 -9
- package/dist/useConstant-2ee82f84.cjs.js +35 -0
- package/dist/useConstant-ae6dceac.development.cjs.js +35 -0
- package/dist/{useConstant-c09b427a.cjs.prod.js → useConstant-bac83df4.development.esm.js} +3 -5
- package/dist/useConstant-c7ec0fdd.esm.js +13 -0
- package/dist/xstate-react.cjs.d.mts +2 -0
- package/dist/xstate-react.cjs.d.mts.map +1 -0
- package/dist/xstate-react.cjs.d.ts +1 -0
- package/dist/xstate-react.cjs.d.ts.map +1 -0
- package/dist/xstate-react.cjs.js +178 -4
- package/dist/xstate-react.cjs.mjs +8 -0
- package/dist/xstate-react.development.cjs.js +190 -0
- package/dist/xstate-react.development.esm.js +159 -0
- package/dist/xstate-react.esm.js +74 -245
- package/fsm/dist/xstate-react-fsm.cjs.d.mts +2 -0
- package/fsm/dist/xstate-react-fsm.cjs.d.mts.map +1 -0
- package/fsm/dist/xstate-react-fsm.cjs.d.ts +1 -0
- package/fsm/dist/xstate-react-fsm.cjs.d.ts.map +1 -0
- package/fsm/dist/xstate-react-fsm.cjs.js +65 -4
- package/fsm/dist/xstate-react-fsm.cjs.mjs +4 -0
- package/fsm/dist/xstate-react-fsm.development.cjs.js +74 -0
- package/fsm/dist/xstate-react-fsm.development.esm.js +65 -0
- package/fsm/dist/xstate-react-fsm.esm.js +30 -42
- package/package.json +30 -4
- package/dist/declarations/src/types.d.ts +0 -15
- package/dist/declarations/src/useConstant.d.ts +0 -1
- package/dist/declarations/src/useInterpret.d.ts +0 -12
- package/dist/declarations/src/useSpawn.d.ts +0 -9
- package/dist/useConstant-0013a606.esm.js +0 -68
- package/dist/useConstant-ff65b597.cjs.dev.js +0 -71
- package/dist/xstate-react.cjs.dev.js +0 -335
- package/dist/xstate-react.cjs.prod.js +0 -327
- package/fsm/dist/xstate-react-fsm.cjs.dev.js +0 -80
- package/fsm/dist/xstate-react-fsm.cjs.prod.js +0 -127
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useEffect, useState, useCallback } from 'react';
|
|
3
|
+
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector';
|
|
4
|
+
import { toObserver, InterpreterStatus, interpret } from 'xstate';
|
|
5
|
+
import { u as useConstant } from './useConstant-bac83df4.development.esm.js';
|
|
6
|
+
import useIsomorphicLayoutEffect from 'use-isomorphic-layout-effect';
|
|
7
|
+
import { isActorRef } from 'xstate/actors';
|
|
8
|
+
|
|
9
|
+
function useIdleInterpreter(machine, options) {
|
|
10
|
+
{
|
|
11
|
+
const [initialMachine] = useState(machine);
|
|
12
|
+
if (machine.config !== initialMachine.config) {
|
|
13
|
+
console.warn(`Actor logic has changed between renders. This is not supported and may lead to invalid snapshots.`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const actorRef = useConstant(() => {
|
|
17
|
+
return interpret(machine, options);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// TODO: consider using `useAsapEffect` that would do this in `useInsertionEffect` is that's available
|
|
21
|
+
useIsomorphicLayoutEffect(() => {
|
|
22
|
+
actorRef.behavior.options = machine.options;
|
|
23
|
+
});
|
|
24
|
+
return actorRef;
|
|
25
|
+
}
|
|
26
|
+
function useActorRef(machine, ...[options = {}, observerOrListener]) {
|
|
27
|
+
const service = useIdleInterpreter(machine, options);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (!observerOrListener) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
let sub = service.subscribe(toObserver(observerOrListener));
|
|
33
|
+
return () => {
|
|
34
|
+
sub.unsubscribe();
|
|
35
|
+
};
|
|
36
|
+
}, [observerOrListener]);
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
service.start();
|
|
39
|
+
return () => {
|
|
40
|
+
service.stop();
|
|
41
|
+
service.status = InterpreterStatus.NotStarted;
|
|
42
|
+
service._initState();
|
|
43
|
+
};
|
|
44
|
+
}, []);
|
|
45
|
+
return service;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function identity(a) {
|
|
49
|
+
return a;
|
|
50
|
+
}
|
|
51
|
+
const isEqual = (prevState, nextState) => {
|
|
52
|
+
return prevState === nextState || nextState.changed === false;
|
|
53
|
+
};
|
|
54
|
+
function useActor(behavior, options = {}) {
|
|
55
|
+
if (isActorRef(behavior)) {
|
|
56
|
+
throw new Error(`useActor() expects actor logic (e.g. a machine), but received an ActorRef. Use the useSelector(actorRef, ...) hook instead to read the ActorRef's snapshot.`);
|
|
57
|
+
}
|
|
58
|
+
const actorRef = useIdleInterpreter(behavior, options);
|
|
59
|
+
const getSnapshot = useCallback(() => {
|
|
60
|
+
return actorRef.getSnapshot();
|
|
61
|
+
}, [actorRef]);
|
|
62
|
+
const subscribe = useCallback(handleStoreChange => {
|
|
63
|
+
const {
|
|
64
|
+
unsubscribe
|
|
65
|
+
} = actorRef.subscribe(handleStoreChange);
|
|
66
|
+
return unsubscribe;
|
|
67
|
+
}, [actorRef]);
|
|
68
|
+
const actorSnapshot = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity, isEqual);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
actorRef.start();
|
|
71
|
+
return () => {
|
|
72
|
+
actorRef.stop();
|
|
73
|
+
actorRef.status = InterpreterStatus.NotStarted;
|
|
74
|
+
actorRef._initState();
|
|
75
|
+
};
|
|
76
|
+
}, [actorRef]);
|
|
77
|
+
return [actorSnapshot, actorRef.send, actorRef];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function defaultCompare(a, b) {
|
|
81
|
+
return a === b;
|
|
82
|
+
}
|
|
83
|
+
function useSelector(actor, selector, compare = defaultCompare) {
|
|
84
|
+
const subscribe = useCallback(handleStoreChange => {
|
|
85
|
+
const {
|
|
86
|
+
unsubscribe
|
|
87
|
+
} = actor.subscribe(handleStoreChange);
|
|
88
|
+
return unsubscribe;
|
|
89
|
+
}, [actor]);
|
|
90
|
+
const boundGetSnapshot = useCallback(() => actor.getSnapshot(), [actor]);
|
|
91
|
+
const selectedSnapshot = useSyncExternalStoreWithSelector(subscribe, boundGetSnapshot, boundGetSnapshot, selector, compare);
|
|
92
|
+
return selectedSnapshot;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// From https://github.com/reduxjs/react-redux/blob/720f0ba79236cdc3e1115f4ef9a7760a21784b48/src/utils/shallowEqual.ts
|
|
96
|
+
function is(x, y) {
|
|
97
|
+
if (x === y) {
|
|
98
|
+
return x !== 0 || y !== 0 || 1 / x === 1 / y;
|
|
99
|
+
} else {
|
|
100
|
+
return x !== x && y !== y;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function shallowEqual(objA, objB) {
|
|
104
|
+
if (is(objA, objB)) return true;
|
|
105
|
+
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
const keysA = Object.keys(objA);
|
|
109
|
+
const keysB = Object.keys(objB);
|
|
110
|
+
if (keysA.length !== keysB.length) return false;
|
|
111
|
+
for (let i = 0; i < keysA.length; i++) {
|
|
112
|
+
if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function createActorContext(machine, interpreterOptions, observerOrListener) {
|
|
120
|
+
const ReactContext = /*#__PURE__*/React.createContext(null);
|
|
121
|
+
const OriginalProvider = ReactContext.Provider;
|
|
122
|
+
function Provider({
|
|
123
|
+
children,
|
|
124
|
+
machine: providedMachine = machine
|
|
125
|
+
}) {
|
|
126
|
+
const actor = useActorRef(providedMachine, interpreterOptions, observerOrListener);
|
|
127
|
+
return /*#__PURE__*/React.createElement(OriginalProvider, {
|
|
128
|
+
value: actor,
|
|
129
|
+
children
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
Provider.displayName = `ActorProvider(${machine.id})`;
|
|
133
|
+
function useContext() {
|
|
134
|
+
const actor = React.useContext(ReactContext);
|
|
135
|
+
if (!actor) {
|
|
136
|
+
throw new Error(`You used a hook from "${Provider.displayName}" but it's not inside a <${Provider.displayName}> component.`);
|
|
137
|
+
}
|
|
138
|
+
return actor;
|
|
139
|
+
}
|
|
140
|
+
function useSelector$1(selector, compare) {
|
|
141
|
+
const actor = useContext();
|
|
142
|
+
return useSelector(actor, selector, compare);
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
Provider: Provider,
|
|
146
|
+
useActorRef: useContext,
|
|
147
|
+
useSelector: useSelector$1
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
*
|
|
153
|
+
* @deprecated Use `useActor(...)` instead.
|
|
154
|
+
*/
|
|
155
|
+
function useMachine(machine, options = {}) {
|
|
156
|
+
return useActor(machine, options);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export { createActorContext, shallowEqual, useActor, useActorRef, useMachine, useSelector };
|
package/dist/xstate-react.esm.js
CHANGED
|
@@ -1,99 +1,36 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { useEffect,
|
|
3
|
-
import useIsomorphicLayoutEffect from 'use-isomorphic-layout-effect';
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useEffect, useCallback } from 'react';
|
|
4
3
|
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector';
|
|
5
4
|
import { toObserver, InterpreterStatus, interpret } from 'xstate';
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (source == null) return {};
|
|
10
|
-
var target = {};
|
|
11
|
-
var sourceKeys = Object.keys(source);
|
|
12
|
-
var key, i;
|
|
13
|
-
for (i = 0; i < sourceKeys.length; i++) {
|
|
14
|
-
key = sourceKeys[i];
|
|
15
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
16
|
-
target[key] = source[key];
|
|
17
|
-
}
|
|
18
|
-
return target;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function _objectWithoutProperties(source, excluded) {
|
|
22
|
-
if (source == null) return {};
|
|
23
|
-
var target = _objectWithoutPropertiesLoose(source, excluded);
|
|
24
|
-
var key, i;
|
|
25
|
-
if (Object.getOwnPropertySymbols) {
|
|
26
|
-
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
|
|
27
|
-
for (i = 0; i < sourceSymbolKeys.length; i++) {
|
|
28
|
-
key = sourceSymbolKeys[i];
|
|
29
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
30
|
-
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|
31
|
-
target[key] = source[key];
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return target;
|
|
35
|
-
}
|
|
5
|
+
import { u as useConstant } from './useConstant-c7ec0fdd.esm.js';
|
|
6
|
+
import useIsomorphicLayoutEffect from 'use-isomorphic-layout-effect';
|
|
7
|
+
import 'xstate/actors';
|
|
36
8
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return typeof getMachine === 'function' ? getMachine() : getMachine;
|
|
41
|
-
});
|
|
42
|
-
if (process.env.NODE_ENV !== 'production' && typeof getMachine !== 'function') {
|
|
43
|
-
var _useState = useState(machine),
|
|
44
|
-
_useState2 = _slicedToArray(_useState, 1),
|
|
45
|
-
initialMachine = _useState2[0];
|
|
46
|
-
if (getMachine !== initialMachine) {
|
|
47
|
-
console.warn('Machine given to `useMachine` has changed between renders. This is not supported and might lead to unexpected results.\n' + 'Please make sure that you pass the same Machine as argument each time.');
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
var actors = options.actors,
|
|
51
|
-
guards = options.guards,
|
|
52
|
-
actions = options.actions,
|
|
53
|
-
delays = options.delays,
|
|
54
|
-
interpreterOptions = _objectWithoutProperties(options, _excluded);
|
|
55
|
-
var service = useConstant(function () {
|
|
56
|
-
var machineConfig = {
|
|
57
|
-
guards: guards,
|
|
58
|
-
actions: actions,
|
|
59
|
-
actors: actors,
|
|
60
|
-
delays: delays
|
|
61
|
-
};
|
|
62
|
-
var machineWithConfig = machine.provide(machineConfig);
|
|
63
|
-
return interpret(machineWithConfig, interpreterOptions);
|
|
9
|
+
function useIdleInterpreter(machine, options) {
|
|
10
|
+
const actorRef = useConstant(() => {
|
|
11
|
+
return interpret(machine, options);
|
|
64
12
|
});
|
|
65
13
|
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
Object.assign(service.behavior.options.guards, guards);
|
|
72
|
-
Object.assign(service.behavior.options.actors, actors);
|
|
73
|
-
Object.assign(service.behavior.options.delays, delays);
|
|
74
|
-
}, [actions, guards, actors, delays]);
|
|
75
|
-
return service;
|
|
14
|
+
// TODO: consider using `useAsapEffect` that would do this in `useInsertionEffect` is that's available
|
|
15
|
+
useIsomorphicLayoutEffect(() => {
|
|
16
|
+
actorRef.behavior.options = machine.options;
|
|
17
|
+
});
|
|
18
|
+
return actorRef;
|
|
76
19
|
}
|
|
77
|
-
function
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
var _ref$ = _ref[0],
|
|
82
|
-
options = _ref$ === void 0 ? {} : _ref$,
|
|
83
|
-
observerOrListener = _ref[1];
|
|
84
|
-
var service = useIdleInterpreter(getMachine, options);
|
|
85
|
-
useEffect(function () {
|
|
20
|
+
function useActorRef(machine, ...[options = {}, observerOrListener]) {
|
|
21
|
+
const service = useIdleInterpreter(machine, options);
|
|
22
|
+
useEffect(() => {
|
|
86
23
|
if (!observerOrListener) {
|
|
87
24
|
return;
|
|
88
25
|
}
|
|
89
|
-
|
|
90
|
-
return
|
|
26
|
+
let sub = service.subscribe(toObserver(observerOrListener));
|
|
27
|
+
return () => {
|
|
91
28
|
sub.unsubscribe();
|
|
92
29
|
};
|
|
93
30
|
}, [observerOrListener]);
|
|
94
|
-
useEffect(
|
|
31
|
+
useEffect(() => {
|
|
95
32
|
service.start();
|
|
96
|
-
return
|
|
33
|
+
return () => {
|
|
97
34
|
service.stop();
|
|
98
35
|
service.status = InterpreterStatus.NotStarted;
|
|
99
36
|
service._initState();
|
|
@@ -105,104 +42,47 @@ function useInterpret(getMachine) {
|
|
|
105
42
|
function identity(a) {
|
|
106
43
|
return a;
|
|
107
44
|
}
|
|
108
|
-
|
|
45
|
+
const isEqual = (prevState, nextState) => {
|
|
109
46
|
return prevState === nextState || nextState.changed === false;
|
|
110
47
|
};
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
var _ref$ = _ref[0],
|
|
116
|
-
options = _ref$ === void 0 ? {} : _ref$;
|
|
117
|
-
// using `useIdleInterpreter` allows us to subscribe to the service *before* we start it
|
|
118
|
-
// so we don't miss any notifications
|
|
119
|
-
var service = useIdleInterpreter(getMachine, options);
|
|
120
|
-
var getSnapshot = useCallback(function () {
|
|
121
|
-
return service.getSnapshot();
|
|
122
|
-
}, [service]);
|
|
123
|
-
var subscribe = useCallback(function (handleStoreChange) {
|
|
124
|
-
var _service$subscribe = service.subscribe(handleStoreChange),
|
|
125
|
-
unsubscribe = _service$subscribe.unsubscribe;
|
|
126
|
-
return unsubscribe;
|
|
127
|
-
}, [service]);
|
|
128
|
-
var storeSnapshot = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity, isEqual);
|
|
129
|
-
useEffect(function () {
|
|
130
|
-
service.start();
|
|
131
|
-
return function () {
|
|
132
|
-
service.stop();
|
|
133
|
-
service.status = InterpreterStatus.NotStarted;
|
|
134
|
-
service._initState();
|
|
135
|
-
};
|
|
136
|
-
}, []);
|
|
137
|
-
return [storeSnapshot, service.send, service];
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
function useActor(actorRef) {
|
|
141
|
-
var subscribe = useCallback(function (handleStoreChange) {
|
|
142
|
-
var _actorRef$subscribe = actorRef.subscribe(handleStoreChange),
|
|
143
|
-
unsubscribe = _actorRef$subscribe.unsubscribe;
|
|
144
|
-
return unsubscribe;
|
|
145
|
-
}, [actorRef]);
|
|
146
|
-
var boundGetSnapshot = useCallback(function () {
|
|
48
|
+
function useActor(behavior, options = {}) {
|
|
49
|
+
const actorRef = useIdleInterpreter(behavior, options);
|
|
50
|
+
const getSnapshot = useCallback(() => {
|
|
147
51
|
return actorRef.getSnapshot();
|
|
148
52
|
}, [actorRef]);
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
53
|
+
const subscribe = useCallback(handleStoreChange => {
|
|
54
|
+
const {
|
|
55
|
+
unsubscribe
|
|
56
|
+
} = actorRef.subscribe(handleStoreChange);
|
|
57
|
+
return unsubscribe;
|
|
58
|
+
}, [actorRef]);
|
|
59
|
+
const actorSnapshot = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity, isEqual);
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
actorRef.start();
|
|
62
|
+
return () => {
|
|
63
|
+
actorRef.stop();
|
|
64
|
+
actorRef.status = InterpreterStatus.NotStarted;
|
|
65
|
+
actorRef._initState();
|
|
66
|
+
};
|
|
152
67
|
}, [actorRef]);
|
|
153
|
-
return [
|
|
68
|
+
return [actorSnapshot, actorRef.send, actorRef];
|
|
154
69
|
}
|
|
155
70
|
|
|
156
71
|
function defaultCompare(a, b) {
|
|
157
72
|
return a === b;
|
|
158
73
|
}
|
|
159
|
-
function useSelector(actor, selector) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
74
|
+
function useSelector(actor, selector, compare = defaultCompare) {
|
|
75
|
+
const subscribe = useCallback(handleStoreChange => {
|
|
76
|
+
const {
|
|
77
|
+
unsubscribe
|
|
78
|
+
} = actor.subscribe(handleStoreChange);
|
|
164
79
|
return unsubscribe;
|
|
165
80
|
}, [actor]);
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}, [actor]);
|
|
169
|
-
var selectedSnapshot = useSyncExternalStoreWithSelector(subscribe, boundGetSnapshot, boundGetSnapshot, selector, compare);
|
|
81
|
+
const boundGetSnapshot = useCallback(() => actor.getSnapshot(), [actor]);
|
|
82
|
+
const selectedSnapshot = useSyncExternalStoreWithSelector(subscribe, boundGetSnapshot, boundGetSnapshot, selector, compare);
|
|
170
83
|
return selectedSnapshot;
|
|
171
84
|
}
|
|
172
85
|
|
|
173
|
-
/**
|
|
174
|
-
* React hook that spawns an `ActorRef` with the specified `behavior`.
|
|
175
|
-
* The returned `ActorRef` can be used with the `useActor(actorRef)` hook.
|
|
176
|
-
*
|
|
177
|
-
* @param behavior The actor behavior to spawn
|
|
178
|
-
* @returns An ActorRef with the specified `behavior`
|
|
179
|
-
*/
|
|
180
|
-
function useSpawn(behavior) {
|
|
181
|
-
var actorRef = useConstant(function () {
|
|
182
|
-
// TODO: figure out what to do about the name argument
|
|
183
|
-
return interpret(behavior);
|
|
184
|
-
});
|
|
185
|
-
useEffect(function () {
|
|
186
|
-
var _actorRef$start;
|
|
187
|
-
(_actorRef$start = actorRef.start) === null || _actorRef$start === void 0 ? void 0 : _actorRef$start.call(actorRef);
|
|
188
|
-
return function () {
|
|
189
|
-
var _stop, _ref;
|
|
190
|
-
(_stop = (_ref = actorRef).stop) === null || _stop === void 0 ? void 0 : _stop.call(_ref);
|
|
191
|
-
};
|
|
192
|
-
}, []);
|
|
193
|
-
return actorRef;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
function _typeof(obj) {
|
|
197
|
-
"@babel/helpers - typeof";
|
|
198
|
-
|
|
199
|
-
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
|
|
200
|
-
return typeof obj;
|
|
201
|
-
} : function (obj) {
|
|
202
|
-
return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|
203
|
-
}, _typeof(obj);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
86
|
// From https://github.com/reduxjs/react-redux/blob/720f0ba79236cdc3e1115f4ef9a7760a21784b48/src/utils/shallowEqual.ts
|
|
207
87
|
function is(x, y) {
|
|
208
88
|
if (x === y) {
|
|
@@ -213,13 +93,13 @@ function is(x, y) {
|
|
|
213
93
|
}
|
|
214
94
|
function shallowEqual(objA, objB) {
|
|
215
95
|
if (is(objA, objB)) return true;
|
|
216
|
-
if (
|
|
96
|
+
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
|
|
217
97
|
return false;
|
|
218
98
|
}
|
|
219
|
-
|
|
220
|
-
|
|
99
|
+
const keysA = Object.keys(objA);
|
|
100
|
+
const keysB = Object.keys(objB);
|
|
221
101
|
if (keysA.length !== keysB.length) return false;
|
|
222
|
-
for (
|
|
102
|
+
for (let i = 0; i < keysA.length; i++) {
|
|
223
103
|
if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
|
|
224
104
|
return false;
|
|
225
105
|
}
|
|
@@ -227,95 +107,44 @@ function shallowEqual(objA, objB) {
|
|
|
227
107
|
return true;
|
|
228
108
|
}
|
|
229
109
|
|
|
230
|
-
function _toPrimitive(input, hint) {
|
|
231
|
-
if (typeof input !== "object" || input === null) return input;
|
|
232
|
-
var prim = input[Symbol.toPrimitive];
|
|
233
|
-
if (prim !== undefined) {
|
|
234
|
-
var res = prim.call(input, hint || "default");
|
|
235
|
-
if (typeof res !== "object") return res;
|
|
236
|
-
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
237
|
-
}
|
|
238
|
-
return (hint === "string" ? String : Number)(input);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
function _toPropertyKey(arg) {
|
|
242
|
-
var key = _toPrimitive(arg, "string");
|
|
243
|
-
return typeof key === "symbol" ? key : String(key);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
function _defineProperty(obj, key, value) {
|
|
247
|
-
key = _toPropertyKey(key);
|
|
248
|
-
if (key in obj) {
|
|
249
|
-
Object.defineProperty(obj, key, {
|
|
250
|
-
value: value,
|
|
251
|
-
enumerable: true,
|
|
252
|
-
configurable: true,
|
|
253
|
-
writable: true
|
|
254
|
-
});
|
|
255
|
-
} else {
|
|
256
|
-
obj[key] = value;
|
|
257
|
-
}
|
|
258
|
-
return obj;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
function ownKeys(object, enumerableOnly) {
|
|
262
|
-
var keys = Object.keys(object);
|
|
263
|
-
if (Object.getOwnPropertySymbols) {
|
|
264
|
-
var symbols = Object.getOwnPropertySymbols(object);
|
|
265
|
-
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
|
266
|
-
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
267
|
-
})), keys.push.apply(keys, symbols);
|
|
268
|
-
}
|
|
269
|
-
return keys;
|
|
270
|
-
}
|
|
271
|
-
function _objectSpread2(target) {
|
|
272
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
273
|
-
var source = null != arguments[i] ? arguments[i] : {};
|
|
274
|
-
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
|
|
275
|
-
_defineProperty(target, key, source[key]);
|
|
276
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
|
|
277
|
-
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
return target;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
110
|
function createActorContext(machine, interpreterOptions, observerOrListener) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
function Provider(
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
return /*#__PURE__*/createElement(OriginalProvider, {
|
|
111
|
+
const ReactContext = /*#__PURE__*/React.createContext(null);
|
|
112
|
+
const OriginalProvider = ReactContext.Provider;
|
|
113
|
+
function Provider({
|
|
114
|
+
children,
|
|
115
|
+
machine: providedMachine = machine
|
|
116
|
+
}) {
|
|
117
|
+
const actor = useActorRef(providedMachine, interpreterOptions, observerOrListener);
|
|
118
|
+
return /*#__PURE__*/React.createElement(OriginalProvider, {
|
|
293
119
|
value: actor,
|
|
294
|
-
children
|
|
120
|
+
children
|
|
295
121
|
});
|
|
296
122
|
}
|
|
297
|
-
Provider.displayName =
|
|
298
|
-
function useContext
|
|
299
|
-
|
|
123
|
+
Provider.displayName = `ActorProvider(${machine.id})`;
|
|
124
|
+
function useContext() {
|
|
125
|
+
const actor = React.useContext(ReactContext);
|
|
300
126
|
if (!actor) {
|
|
301
|
-
throw new Error(
|
|
127
|
+
throw new Error(`You used a hook from "${Provider.displayName}" but it's not inside a <${Provider.displayName}> component.`);
|
|
302
128
|
}
|
|
303
129
|
return actor;
|
|
304
130
|
}
|
|
305
|
-
function useActor$1() {
|
|
306
|
-
var actor = useContext$1();
|
|
307
|
-
return useActor(actor);
|
|
308
|
-
}
|
|
309
131
|
function useSelector$1(selector, compare) {
|
|
310
|
-
|
|
132
|
+
const actor = useContext();
|
|
311
133
|
return useSelector(actor, selector, compare);
|
|
312
134
|
}
|
|
313
135
|
return {
|
|
314
136
|
Provider: Provider,
|
|
315
|
-
useActorRef: useContext
|
|
316
|
-
useActor: useActor$1,
|
|
137
|
+
useActorRef: useContext,
|
|
317
138
|
useSelector: useSelector$1
|
|
318
139
|
};
|
|
319
140
|
}
|
|
320
141
|
|
|
321
|
-
|
|
142
|
+
/**
|
|
143
|
+
*
|
|
144
|
+
* @deprecated Use `useActor(...)` instead.
|
|
145
|
+
*/
|
|
146
|
+
function useMachine(machine, options = {}) {
|
|
147
|
+
return useActor(machine, options);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export { createActorContext, shallowEqual, useActor, useActorRef, useMachine, useSelector };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xstate-react-fsm.cjs.d.mts","sourceRoot":"","sources":["../../dist/declarations/src/fsm.d.ts"],"names":[],"mappings":"AAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xstate-react-fsm.cjs.d.ts","sourceRoot":"","sources":["../../dist/declarations/src/fsm.d.ts"],"names":[],"mappings":"AAAA"}
|
|
@@ -1,7 +1,68 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var fsm = require('@xstate/fsm');
|
|
6
|
+
var React = require('react');
|
|
7
|
+
var useIsomorphicLayoutEffect = require('use-isomorphic-layout-effect');
|
|
8
|
+
var withSelector = require('use-sync-external-store/shim/with-selector');
|
|
9
|
+
var useConstant = require('../../dist/useConstant-2ee82f84.cjs.js');
|
|
10
|
+
|
|
11
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
12
|
+
|
|
13
|
+
var useIsomorphicLayoutEffect__default = /*#__PURE__*/_interopDefault(useIsomorphicLayoutEffect);
|
|
14
|
+
|
|
15
|
+
function identity(a) {
|
|
16
|
+
return a;
|
|
7
17
|
}
|
|
18
|
+
function useMachine(stateMachine, options) {
|
|
19
|
+
const persistedStateRef = React.useRef();
|
|
20
|
+
const [service, queue] = useConstant.useConstant(() => {
|
|
21
|
+
const queue = [];
|
|
22
|
+
const service = fsm.interpret(fsm.createMachine(stateMachine.config, options ? options : stateMachine._options));
|
|
23
|
+
const {
|
|
24
|
+
send
|
|
25
|
+
} = service;
|
|
26
|
+
service.send = event => {
|
|
27
|
+
if (service.status === fsm.InterpreterStatus.NotStarted) {
|
|
28
|
+
queue.push(event);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
send(event);
|
|
32
|
+
persistedStateRef.current = service.state;
|
|
33
|
+
};
|
|
34
|
+
return [service, queue];
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// TODO: consider using `useInsertionEffect` if available
|
|
38
|
+
useIsomorphicLayoutEffect__default["default"](() => {
|
|
39
|
+
if (options) {
|
|
40
|
+
service._machine._options = options;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
const useServiceResult = useService(service);
|
|
44
|
+
React.useEffect(() => {
|
|
45
|
+
service.start(persistedStateRef.current);
|
|
46
|
+
queue.forEach(service.send);
|
|
47
|
+
persistedStateRef.current = service.state;
|
|
48
|
+
return () => {
|
|
49
|
+
service.stop();
|
|
50
|
+
};
|
|
51
|
+
}, []);
|
|
52
|
+
return useServiceResult;
|
|
53
|
+
}
|
|
54
|
+
const isEqual = (_prevState, nextState) => nextState.changed === false;
|
|
55
|
+
function useService(service) {
|
|
56
|
+
const getSnapshot = React.useCallback(() => service.state, [service]);
|
|
57
|
+
const subscribe = React.useCallback(handleStoreChange => {
|
|
58
|
+
const {
|
|
59
|
+
unsubscribe
|
|
60
|
+
} = service.subscribe(handleStoreChange);
|
|
61
|
+
return unsubscribe;
|
|
62
|
+
}, [service]);
|
|
63
|
+
const storeSnapshot = withSelector.useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity, isEqual);
|
|
64
|
+
return [storeSnapshot, service.send, service];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
exports.useMachine = useMachine;
|
|
68
|
+
exports.useService = useService;
|