@shopify/hydrogen-react
Version:
React components, hooks, and utilities for creating custom Shopify storefronts
69 lines (68 loc) • 1.98 kB
JavaScript
;
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