{"version":3,"sources":["../../../../src/next-devtools/userspace/app/segment-explorer-node.tsx"],"sourcesContent":["'use client'\n\nimport type { ReactNode } from 'react'\nimport {\n  useState,\n  createContext,\n  useContext,\n  use,\n  useMemo,\n  useCallback,\n} from 'react'\nimport { useLayoutEffect } from 'react'\nimport { dispatcher } from 'next/dist/compiled/next-devtools'\nimport { GlobalLayoutRouterContext } from '../../../shared/lib/app-router-context.shared-runtime'\nimport { notFound } from '../../../client/components/not-found'\n\nexport type SegmentBoundaryType =\n  | 'not-found'\n  | 'error'\n  | 'loading'\n  | 'global-error'\n\nexport const SEGMENT_EXPLORER_SIMULATED_ERROR_MESSAGE =\n  'NEXT_DEVTOOLS_SIMULATED_ERROR'\n\nexport type SegmentNodeState = {\n  type: string\n  pagePath: string\n  boundaryType: string | null\n  setBoundaryType: (type: SegmentBoundaryType | null) => void\n}\n\nfunction SegmentTrieNode({\n  type,\n  pagePath,\n}: {\n  type: string\n  pagePath: string\n}): React.ReactNode {\n  const { boundaryType, setBoundaryType } = useSegmentState()\n  const nodeState: SegmentNodeState = useMemo(() => {\n    return {\n      type,\n      pagePath,\n      boundaryType,\n      setBoundaryType,\n    }\n  }, [type, pagePath, boundaryType, setBoundaryType])\n\n  // Use `useLayoutEffect` to ensure the state is updated during suspense.\n  // `useEffect` won't work as the state is preserved during suspense.\n  useLayoutEffect(() => {\n    dispatcher.segmentExplorerNodeAdd(nodeState)\n    return () => {\n      dispatcher.segmentExplorerNodeRemove(nodeState)\n    }\n  }, [nodeState])\n\n  return null\n}\n\nfunction NotFoundSegmentNode(): React.ReactNode {\n  notFound()\n}\n\nfunction ErrorSegmentNode(): React.ReactNode {\n  throw new Error(SEGMENT_EXPLORER_SIMULATED_ERROR_MESSAGE)\n}\n\nconst forever = new Promise(() => {})\nfunction LoadingSegmentNode(): React.ReactNode {\n  use(forever)\n  return null\n}\n\nexport function SegmentViewStateNode({ page }: { page: string }) {\n  const { tree } = useContext(GlobalLayoutRouterContext)\n  useLayoutEffect(() => {\n    dispatcher.segmentExplorerUpdateRouteState(page, tree)\n    return () => {\n      dispatcher.segmentExplorerUpdateRouteState('', null)\n    }\n  }, [page, tree])\n  return null\n}\n\nexport function SegmentBoundaryTriggerNode() {\n  const { boundaryType } = useSegmentState()\n  let segmentNode: React.ReactNode = null\n  if (boundaryType === 'loading') {\n    segmentNode = <LoadingSegmentNode />\n  } else if (boundaryType === 'not-found') {\n    segmentNode = <NotFoundSegmentNode />\n  } else if (boundaryType === 'error') {\n    segmentNode = <ErrorSegmentNode />\n  }\n  return segmentNode\n}\n\nexport function SegmentViewNode({\n  type,\n  pagePath,\n  children,\n}: {\n  type: string\n  pagePath: string\n  children?: ReactNode\n}): React.ReactNode {\n  const segmentNode = (\n    <SegmentTrieNode key={type} type={type} pagePath={pagePath} />\n  )\n\n  return (\n    <>\n      {segmentNode}\n      {children}\n    </>\n  )\n}\n\nconst SegmentStateContext = createContext<{\n  boundaryType: SegmentBoundaryType | null\n  setBoundaryType: (type: SegmentBoundaryType | null) => void\n}>({\n  boundaryType: null,\n  setBoundaryType: () => {},\n})\n\nexport function SegmentStateProvider({ children }: { children: ReactNode }) {\n  const [boundaryType, setBoundaryType] = useState<SegmentBoundaryType | null>(\n    null\n  )\n\n  const [errorBoundaryKey, setErrorBoundaryKey] = useState(0)\n  const reloadBoundary = useCallback(\n    () => setErrorBoundaryKey((prev) => prev + 1),\n    []\n  )\n\n  const setBoundaryTypeAndReload = useCallback(\n    (type: SegmentBoundaryType | null) => {\n      if (type === null) {\n        reloadBoundary()\n      }\n      setBoundaryType(type)\n    },\n    [reloadBoundary]\n  )\n\n  return (\n    <SegmentStateContext.Provider\n      key={errorBoundaryKey}\n      value={{\n        boundaryType,\n        setBoundaryType: setBoundaryTypeAndReload,\n      }}\n    >\n      {children}\n    </SegmentStateContext.Provider>\n  )\n}\n\nexport function useSegmentState() {\n  return useContext(SegmentStateContext)\n}\n"],"names":["SEGMENT_EXPLORER_SIMULATED_ERROR_MESSAGE","SegmentBoundaryTriggerNode","SegmentStateProvider","SegmentViewNode","SegmentViewStateNode","useSegmentState","SegmentTrieNode","type","pagePath","boundaryType","setBoundaryType","nodeState","useMemo","useLayoutEffect","dispatcher","segmentExplorerNodeAdd","segmentExplorerNodeRemove","NotFoundSegmentNode","notFound","ErrorSegmentNode","Error","forever","Promise","LoadingSegmentNode","use","page","tree","useContext","GlobalLayoutRouterContext","segmentExplorerUpdateRouteState","segmentNode","children","SegmentStateContext","createContext","useState","errorBoundaryKey","setErrorBoundaryKey","reloadBoundary","useCallback","prev","setBoundaryTypeAndReload","Provider","value"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;IAsBaA,wCAAwC;eAAxCA;;IAgEGC,0BAA0B;eAA1BA;;IA0CAC,oBAAoB;eAApBA;;IA7BAC,eAAe;eAAfA;;IAxBAC,oBAAoB;eAApBA;;IAuFAC,eAAe;eAAfA;;;;uBAxJT;8BAEoB;+CACe;0BACjB;AAQlB,MAAML,2CACX;AASF,SAASM,gBAAgB,EACvBC,IAAI,EACJC,QAAQ,EAIT;IACC,MAAM,EAAEC,YAAY,EAAEC,eAAe,EAAE,GAAGL;IAC1C,MAAMM,YAA8BC,IAAAA,cAAO,EAAC;QAC1C,OAAO;YACLL;YACAC;YACAC;YACAC;QACF;IACF,GAAG;QAACH;QAAMC;QAAUC;QAAcC;KAAgB;IAElD,wEAAwE;IACxE,oEAAoE;IACpEG,IAAAA,sBAAe,EAAC;QACdC,wBAAU,CAACC,sBAAsB,CAACJ;QAClC,OAAO;YACLG,wBAAU,CAACE,yBAAyB,CAACL;QACvC;IACF,GAAG;QAACA;KAAU;IAEd,OAAO;AACT;AAEA,SAASM;IACPC,IAAAA,kBAAQ;AACV;AAEA,SAASC;IACP,MAAM,qBAAmD,CAAnD,IAAIC,MAAMpB,2CAAV,qBAAA;eAAA;oBAAA;sBAAA;IAAkD;AAC1D;AAEA,MAAMqB,UAAU,IAAIC,QAAQ,KAAO;AACnC,SAASC;IACPC,IAAAA,UAAG,EAACH;IACJ,OAAO;AACT;AAEO,SAASjB,qBAAqB,EAAEqB,IAAI,EAAoB;IAC7D,MAAM,EAAEC,IAAI,EAAE,GAAGC,IAAAA,iBAAU,EAACC,wDAAyB;IACrDf,IAAAA,sBAAe,EAAC;QACdC,wBAAU,CAACe,+BAA+B,CAACJ,MAAMC;QACjD,OAAO;YACLZ,wBAAU,CAACe,+BAA+B,CAAC,IAAI;QACjD;IACF,GAAG;QAACJ;QAAMC;KAAK;IACf,OAAO;AACT;AAEO,SAASzB;IACd,MAAM,EAAEQ,YAAY,EAAE,GAAGJ;IACzB,IAAIyB,cAA+B;IACnC,IAAIrB,iBAAiB,WAAW;QAC9BqB,4BAAc,qBAACP;IACjB,OAAO,IAAId,iBAAiB,aAAa;QACvCqB,4BAAc,qBAACb;IACjB,OAAO,IAAIR,iBAAiB,SAAS;QACnCqB,4BAAc,qBAACX;IACjB;IACA,OAAOW;AACT;AAEO,SAAS3B,gBAAgB,EAC9BI,IAAI,EACJC,QAAQ,EACRuB,QAAQ,EAKT;IACC,MAAMD,4BACJ,qBAACxB;QAA2BC,MAAMA;QAAMC,UAAUA;OAA5BD;IAGxB,qBACE;;YACGuB;YACAC;;;AAGP;AAEA,MAAMC,oCAAsBC,IAAAA,oBAAa,EAGtC;IACDxB,cAAc;IACdC,iBAAiB,KAAO;AAC1B;AAEO,SAASR,qBAAqB,EAAE6B,QAAQ,EAA2B;IACxE,MAAM,CAACtB,cAAcC,gBAAgB,GAAGwB,IAAAA,eAAQ,EAC9C;IAGF,MAAM,CAACC,kBAAkBC,oBAAoB,GAAGF,IAAAA,eAAQ,EAAC;IACzD,MAAMG,iBAAiBC,IAAAA,kBAAW,EAChC,IAAMF,oBAAoB,CAACG,OAASA,OAAO,IAC3C,EAAE;IAGJ,MAAMC,2BAA2BF,IAAAA,kBAAW,EAC1C,CAAC/B;QACC,IAAIA,SAAS,MAAM;YACjB8B;QACF;QACA3B,gBAAgBH;IAClB,GACA;QAAC8B;KAAe;IAGlB,qBACE,qBAACL,oBAAoBS,QAAQ;QAE3BC,OAAO;YACLjC;YACAC,iBAAiB8B;QACnB;kBAECT;OANII;AASX;AAEO,SAAS9B;IACd,OAAOsB,IAAAA,iBAAU,EAACK;AACpB","ignoreList":[0]}