fsm.js 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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 { createMachine, interpret, InterpreterStatus } from '@xstate/fsm';
  18. import { useCallback, useEffect, useRef, useState } from 'react';
  19. import useIsomorphicLayoutEffect from 'use-isomorphic-layout-effect';
  20. import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector';
  21. import useConstant from './useConstant';
  22. function identity(a) {
  23. return a;
  24. }
  25. var getServiceState = function (service) {
  26. var currentValue;
  27. service
  28. .subscribe(function (state) {
  29. currentValue = state;
  30. })
  31. .unsubscribe();
  32. return currentValue;
  33. };
  34. export function useMachine(stateMachine, options) {
  35. var persistedStateRef = useRef();
  36. if (process.env.NODE_ENV !== 'production') {
  37. var _a = __read(useState(stateMachine), 1), initialMachine = _a[0];
  38. if (stateMachine !== initialMachine) {
  39. console.warn('Machine given to `useMachine` has changed between renders. This is not supported and might lead to unexpected results.\n' +
  40. 'Please make sure that you pass the same Machine as argument each time.');
  41. }
  42. }
  43. var _b = __read(useConstant(function () {
  44. var queue = [];
  45. var service = interpret(createMachine(stateMachine.config, options ? options : stateMachine._options));
  46. var send = service.send;
  47. service.send = function (event) {
  48. if (service.status === InterpreterStatus.NotStarted) {
  49. queue.push(event);
  50. return;
  51. }
  52. send(event);
  53. persistedStateRef.current = service.state;
  54. };
  55. return [service, queue];
  56. }), 2), service = _b[0], queue = _b[1];
  57. useIsomorphicLayoutEffect(function () {
  58. if (options) {
  59. service._machine._options = options;
  60. }
  61. });
  62. var useServiceResult = useService(service);
  63. useEffect(function () {
  64. service.start(persistedStateRef.current);
  65. queue.forEach(service.send);
  66. persistedStateRef.current = service.state;
  67. return function () {
  68. service.stop();
  69. };
  70. }, []);
  71. return useServiceResult;
  72. }
  73. var isEqual = function (_prevState, nextState) { return nextState.changed === false; };
  74. export function useService(service) {
  75. var getSnapshot = useCallback(function () { return getServiceState(service); }, [service]);
  76. var subscribe = useCallback(function (handleStoreChange) {
  77. var unsubscribe = service.subscribe(handleStoreChange).unsubscribe;
  78. return unsubscribe;
  79. }, [service]);
  80. var storeSnapshot = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity, isEqual);
  81. return [storeSnapshot, service.send, service];
  82. }