{"version":3,"file":"useMachine.mjs","sources":["../../src/useMachine.ts"],"sourcesContent":["// Inlined React binding for xstate/fsm's state machine interpreter.\n//\n// This replaces the xstate/react/fsm entrypoint, which had no official version\n// supporting both React 19 and xstate/fsm. By owning this hook, we eliminate\n// the xstate/react dependency (and its React version peer dep constraint)\n// while keeping xstate/fsm and the cart state machine definition unchanged.\n//\n// Adapted from xstate/react v3.2.1/fsm (MIT license, Stately/xstate).\n// Copyright (c) 2015 David Khourshid\nimport {\n  createMachine,\n  interpret,\n  InterpreterStatus,\n  StateMachine,\n  EventObject,\n} from '@xstate/fsm';\nimport {\n  useCallback,\n  useEffect,\n  useLayoutEffect,\n  useRef,\n  useSyncExternalStore,\n} from 'react';\n\n// useLayoutEffect in the browser (sync after DOM mutations, before paint),\n// useEffect on the server (where useLayoutEffect warns). The check runs once\n// at module evaluation time (not per-render). This matches the original\n// xstate/react behavior via use-isomorphic-layout-effect.\nconst useIsomorphicLayoutEffect =\n  typeof window !== 'undefined' ? useLayoutEffect : useEffect;\n\nfunction useConstant<T>(fn: () => T): T {\n  const ref = useRef<{v: T}>();\n  if (!ref.current) {\n    ref.current = {v: fn()};\n  }\n  return ref.current.v;\n}\n\nfunction getServiceState<\n  TC extends object,\n  TE extends EventObject,\n  TS extends {value: any; context: TC},\n>(service: StateMachine.Service<TC, TE, TS>): StateMachine.State<TC, TE, TS> {\n  let currentValue!: StateMachine.State<TC, TE, TS>;\n  service.subscribe((state) => (currentValue = state)).unsubscribe();\n  return currentValue;\n}\n\nexport function useMachine<\n  TC extends object,\n  TE extends EventObject,\n  TS extends {value: any; context: TC},\n>(\n  stateMachine: StateMachine.Machine<TC, TE, TS>,\n  options?: {actions?: StateMachine.ActionMap<TC, TE>},\n): readonly [\n  StateMachine.State<TC, TE, TS>,\n  StateMachine.Service<TC, TE, TS>['send'],\n  StateMachine.Service<TC, TE, TS>,\n] {\n  const persistedStateRef = useRef<StateMachine.State<TC, TE, TS>>();\n\n  const [service, queue] = useConstant(() => {\n    const eventQueue: Array<TE | TE['type']> = [];\n    const svc = interpret(\n      createMachine(\n        stateMachine.config,\n        options ? options : (stateMachine as any)._options,\n      ),\n    );\n    const originalSend = svc.send;\n    svc.send = (event: TE | TE['type']) => {\n      if (svc.status === InterpreterStatus.NotStarted) {\n        eventQueue.push(event);\n        return;\n      }\n      originalSend(event);\n      persistedStateRef.current = svc.state;\n    };\n    return [svc, eventQueue] as const;\n  });\n\n  // Keep action implementations in sync without re-creating the service.\n  // useIsomorphicLayoutEffect ensures this runs before child effects and paint,\n  // preventing a window where stale action handlers could be invoked.\n  useIsomorphicLayoutEffect(() => {\n    if (options) {\n      (service as any)._machine._options = options;\n    }\n  });\n\n  const getSnapshot = useCallback(() => getServiceState(service), [service]);\n\n  const subscribe = useCallback(\n    (handleStoreChange: () => void) => {\n      const {unsubscribe} = service.subscribe(handleStoreChange);\n      return unsubscribe;\n    },\n    [service],\n  );\n\n  const storeSnapshot = useSyncExternalStore(\n    subscribe,\n    getSnapshot,\n    getSnapshot,\n  );\n\n  useEffect(() => {\n    service.start(persistedStateRef.current as any);\n    queue.forEach(service.send);\n    persistedStateRef.current = service.state;\n    return () => {\n      service.stop();\n    };\n    // service and queue are stable refs from useConstant\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []);\n\n  return [storeSnapshot, service.send, service] as const;\n}\n"],"names":[],"mappings":";;AA4BA,MAAM,4BACJ,OAAO,WAAW,cAAc,kBAAkB;AAEpD,SAAS,YAAe,IAAgB;AACtC,QAAM,MAAM,OAAA;AACZ,MAAI,CAAC,IAAI,SAAS;AAChB,QAAI,UAAU,EAAC,GAAG,GAAA,EAAG;AAAA,EACvB;AACA,SAAO,IAAI,QAAQ;AACrB;AAEA,SAAS,gBAIP,SAA2E;AAC3E,MAAI;AACJ,UAAQ,UAAU,CAAC,UAAW,eAAe,KAAM,EAAE,YAAA;AACrD,SAAO;AACT;AAEO,SAAS,WAKd,cACA,SAKA;AACA,QAAM,oBAAoB,OAAA;AAE1B,QAAM,CAAC,SAAS,KAAK,IAAI,YAAY,MAAM;AACzC,UAAM,aAAqC,CAAA;AAC3C,UAAM,MAAM;AAAA,MACV;AAAA,QACE,aAAa;AAAA,QACb,UAAU,UAAW,aAAqB;AAAA,MAAA;AAAA,IAC5C;AAEF,UAAM,eAAe,IAAI;AACzB,QAAI,OAAO,CAAC,UAA2B;AACrC,UAAI,IAAI,WAAW,kBAAkB,YAAY;AAC/C,mBAAW,KAAK,KAAK;AACrB;AAAA,MACF;AACA,mBAAa,KAAK;AAClB,wBAAkB,UAAU,IAAI;AAAA,IAClC;AACA,WAAO,CAAC,KAAK,UAAU;AAAA,EACzB,CAAC;AAKD,4BAA0B,MAAM;AAC9B,QAAI,SAAS;AACV,cAAgB,SAAS,WAAW;AAAA,IACvC;AAAA,EACF,CAAC;AAED,QAAM,cAAc,YAAY,MAAM,gBAAgB,OAAO,GAAG,CAAC,OAAO,CAAC;AAEzE,QAAM,YAAY;AAAA,IAChB,CAAC,sBAAkC;AACjC,YAAM,EAAC,YAAA,IAAe,QAAQ,UAAU,iBAAiB;AACzD,aAAO;AAAA,IACT;AAAA,IACA,CAAC,OAAO;AAAA,EAAA;AAGV,QAAM,gBAAgB;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,YAAU,MAAM;AACd,YAAQ,MAAM,kBAAkB,OAAc;AAC9C,UAAM,QAAQ,QAAQ,IAAI;AAC1B,sBAAkB,UAAU,QAAQ;AACpC,WAAO,MAAM;AACX,cAAQ,KAAA;AAAA,IACV;AAAA,EAGF,GAAG,CAAA,CAAE;AAEL,SAAO,CAAC,eAAe,QAAQ,MAAM,OAAO;AAC9C;"}