UNPKG

@shopify/hydrogen-react

Version:

React components, hooks, and utilities for creating custom Shopify storefronts

69 lines (68 loc) 1.98 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const fsm = require("@xstate/fsm"); const React = require("react"); const useIsomorphicLayoutEffect = typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect; function useConstant(fn) { const ref = React.useRef(); if (!ref.current) { ref.current = { v: fn() }; } return ref.current.v; } function getServiceState(service) { let currentValue; service.subscribe((state) => currentValue = state).unsubscribe(); return currentValue; } function useMachine(stateMachine, options) { const persistedStateRef = React.useRef(); const [service, queue] = useConstant(() => { const eventQueue = []; const svc = fsm.interpret( fsm.createMachine( stateMachine.config, options ? options : stateMachine._options ) ); const originalSend = svc.send; svc.send = (event) => { if (svc.status === fsm.InterpreterStatus.NotStarted) { eventQueue.push(event); return; } originalSend(event); persistedStateRef.current = svc.state; }; return [svc, eventQueue]; }); useIsomorphicLayoutEffect(() => { if (options) { service._machine._options = options; } }); const getSnapshot = React.useCallback(() => getServiceState(service), [service]); const subscribe = React.useCallback( (handleStoreChange) => { const { unsubscribe } = service.subscribe(handleStoreChange); return unsubscribe; }, [service] ); const storeSnapshot = React.useSyncExternalStore( subscribe, getSnapshot, getSnapshot ); React.useEffect(() => { service.start(persistedStateRef.current); queue.forEach(service.send); persistedStateRef.current = service.state; return () => { service.stop(); }; }, []); return [storeSnapshot, service.send, service]; } exports.useMachine = useMachine; //# sourceMappingURL=useMachine.js.map