useMachine.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. var __read = (this && this.__read) || function (o, n) {
  2. var m = typeof Symbol === "function" && o[Symbol.iterator];
  3. if (!m) return o;
  4. var i = m.call(o), r, ar = [], e;
  5. try {
  6. while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
  7. }
  8. catch (error) { e = { error: error }; }
  9. finally {
  10. try {
  11. if (r && !r.done && (m = i["return"])) m.call(i);
  12. }
  13. finally { if (e) throw e.error; }
  14. }
  15. return ar;
  16. };
  17. import { useCallback, useEffect } from 'react';
  18. import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector';
  19. import { InterpreterStatus, State } from 'xstate';
  20. import { useIdleInterpreter } from './useInterpret';
  21. import { isInterpreterStateEqual } from './utils';
  22. function identity(a) {
  23. return a;
  24. }
  25. export function useMachine(getMachine) {
  26. var _a = [];
  27. for (var _i = 1; _i < arguments.length; _i++) {
  28. _a[_i - 1] = arguments[_i];
  29. }
  30. var _b = __read(_a, 1), _c = _b[0], options = _c === void 0 ? {} : _c;
  31. // using `useIdleInterpreter` allows us to subscribe to the service *before* we start it
  32. // so we don't miss any notifications
  33. var service = useIdleInterpreter(getMachine, options);
  34. var getSnapshot = useCallback(function () {
  35. if (service.status === InterpreterStatus.NotStarted) {
  36. return (options.state
  37. ? State.create(options.state)
  38. : service.machine.initialState);
  39. }
  40. return service.getSnapshot();
  41. }, [service]);
  42. var isEqual = useCallback(function (prevState, nextState) {
  43. return isInterpreterStateEqual(service, prevState, nextState);
  44. }, [service]);
  45. var subscribe = useCallback(function (handleStoreChange) {
  46. var unsubscribe = service.subscribe(handleStoreChange).unsubscribe;
  47. return unsubscribe;
  48. }, [service]);
  49. var storeSnapshot = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity, isEqual);
  50. useEffect(function () {
  51. var rehydratedState = options.state;
  52. service.start(rehydratedState ? State.create(rehydratedState) : undefined);
  53. return function () {
  54. service.stop();
  55. service.status = InterpreterStatus.NotStarted;
  56. };
  57. }, []);
  58. return [storeSnapshot, service.send, service];
  59. }