{"version":3,"file":"useDisposableState.mjs","names":["state: T | undefined"],"sources":["../src/useDisposableState.ts"],"sourcesContent":["import type { ItemCleanupPair } from '@isograph/disposable-types';\nimport { useEffect, useRef } from 'react';\nimport type { ParentCache } from './ParentCache';\nimport { useCachedResponsivePrecommitValue } from './useCachedResponsivePrecommitValue';\nimport {\n  UNASSIGNED_STATE,\n  type UnassignedState,\n  useUpdatableDisposableState,\n} from './useUpdatableDisposableState';\n\ntype UseUpdatableDisposableStateReturnValue<T> = {\n  state: T;\n  setState: (pair: ItemCleanupPair<Exclude<T, UnassignedState>>) => void;\n};\n\nexport function useDisposableState<T = never>(\n  parentCache: ParentCache<T>,\n): UseUpdatableDisposableStateReturnValue<T> {\n  const itemCleanupPairRef = useRef<ItemCleanupPair<T> | null>(null);\n\n  const preCommitItem = useCachedResponsivePrecommitValue(\n    parentCache,\n    (pair) => {\n      itemCleanupPairRef.current?.[1]();\n      itemCleanupPairRef.current = pair;\n    },\n  );\n\n  const { state: stateFromDisposableStateHook, setState } =\n    useUpdatableDisposableState<T>();\n\n  useEffect(\n    function cleanupItemCleanupPairRefAfterSetState() {\n      if (stateFromDisposableStateHook !== UNASSIGNED_STATE) {\n        if (itemCleanupPairRef.current != null) {\n          itemCleanupPairRef.current[1]();\n          itemCleanupPairRef.current = null;\n        } else {\n          throw new Error(\n            'itemCleanupPairRef.current is unexpectedly null. ' +\n              'This indicates a bug in react-disposable-state.',\n          );\n        }\n      }\n    },\n    [stateFromDisposableStateHook],\n  );\n\n  useEffect(function cleanupItemCleanupPairRefIfSetStateNotCalled() {\n    return () => {\n      if (itemCleanupPairRef.current != null) {\n        itemCleanupPairRef.current[1]();\n        itemCleanupPairRef.current = null;\n      }\n    };\n  }, []);\n  const state: T | undefined =\n    (stateFromDisposableStateHook !== UNASSIGNED_STATE\n      ? stateFromDisposableStateHook\n      : null) ??\n    preCommitItem?.state ??\n    itemCleanupPairRef.current?.[0];\n\n  if (state != null) {\n    return {\n      state: state,\n      setState,\n    };\n  }\n\n  // Safety: we can be in one of three states. Pre-commit, in which case\n  // preCommitItem is assigned, post-commit but before setState has been\n  // called, in which case itemCleanupPairRef.current is assigned, or\n  // after setState has been called, in which case\n  // stateFromDisposableStateHook is assigned.\n  //\n  // Therefore, the type of state is T, not T | undefined. But the fact\n  // that we are in one of the three states is not reflected in the types.\n  // So we have to cast to T.\n  //\n  // Note that in the post-commit post-setState state, itemCleanupPairRef\n  // can still be assigned, during the render before the\n  // cleanupItemCleanupPairRefAfterSetState effect is called.\n  throw new Error(\n    'state was unexpectedly null. This indicates a bug in react-disposable-state.',\n  );\n}\n\n// @ts-ignore\nfunction tsTests() {\n  let x: any;\n  const a = useDisposableState(x);\n  // This should be a compiler error, because the generic is inferred to be of\n  // type never. TODO determine why this doesn't break the build!\n  // @ts-expect-error\n  a.setState(['asdf', () => {}]);\n  // @ts-expect-error\n  a.setState([UNASSIGNED_STATE, () => {}]);\n  const b = useDisposableState<string | UnassignedState>(x);\n  // @ts-expect-error\n  b.setState([UNASSIGNED_STATE, () => {}]);\n  b.setState(['asdf', () => {}]);\n}\n"],"mappings":";;;;;AAeA,SAAgB,mBACd,aAC2C;CAC3C,MAAM,qBAAqB,OAAkC,KAAK;CAElE,MAAM,gBAAgB,kCACpB,cACC,SAAS;AACR,qBAAmB,UAAU,IAAI;AACjC,qBAAmB,UAAU;GAEhC;CAED,MAAM,EAAE,OAAO,8BAA8B,aAC3C,6BAAgC;AAElC,WACE,SAAS,yCAAyC;AAChD,MAAI,iCAAiC,iBACnC,KAAI,mBAAmB,WAAW,MAAM;AACtC,sBAAmB,QAAQ,IAAI;AAC/B,sBAAmB,UAAU;QAE7B,OAAM,IAAI,MACR,mGAED;IAIP,CAAC,6BAA6B,CAC/B;AAED,WAAU,SAAS,+CAA+C;AAChE,eAAa;AACX,OAAI,mBAAmB,WAAW,MAAM;AACtC,uBAAmB,QAAQ,IAAI;AAC/B,uBAAmB,UAAU;;;IAGhC,EAAE,CAAC;CACN,MAAMA,SACH,iCAAiC,mBAC9B,+BACA,SACJ,eAAe,SACf,mBAAmB,UAAU;AAE/B,KAAI,SAAS,KACX,QAAO;EACE;EACP;EACD;AAgBH,OAAM,IAAI,MACR,+EACD"}