forked from mul-ink/mulink
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuseInterpret.js
76 lines (68 loc) · 1.89 KB
/
useInterpret.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { useLayoutEffect, interpret, State } from './deps.js';
import useConstant from './useConstant.js';
function toObserver(nextHandler, errorHandler, completionHandler) {
if (typeof nextHandler === 'object') {
return nextHandler;
}
const noop = () => void 0;
return {
next: nextHandler,
error: errorHandler || noop,
complete: completionHandler || noop
};
}
export function useInterpret(getMachine, options = {}, observerOrListener) {
const machine = useConstant(() => {
return typeof getMachine === 'function' ? getMachine() : getMachine;
});
const {
context,
guards,
actions,
activities,
services,
delays,
state: rehydratedState,
...interpreterOptions
} = options;
const service = useConstant(() => {
const machineConfig = {
context,
guards,
actions,
activities,
services,
delays
};
const machineWithConfig = machine.withConfig(machineConfig, () => ({ ...machine.context,
...context
}));
return interpret(machineWithConfig, {
deferEvents: true,
...interpreterOptions
});
});
useLayoutEffect(() => {
let sub;
if (observerOrListener) {
sub = service.subscribe(toObserver(observerOrListener));
}
return () => {
sub?.unsubscribe();
};
}, [observerOrListener]);
useLayoutEffect(() => {
service.start(rehydratedState ? State.create(rehydratedState) : undefined);
return () => {
service.stop();
};
}, []);
useLayoutEffect(() => {
Object.assign(service.machine.options.actions, actions);
Object.assign(service.machine.options.guards, guards);
Object.assign(service.machine.options.activities, activities);
Object.assign(service.machine.options.services, services);
Object.assign(service.machine.options.delays, delays);
}, [actions, guards, activities, services, delays]);
return service;
}