({
enableCacheIndicator,
getOwnerStack,
getSquashedHydrationErrorDetails,
isRecoverableError,
routerType,
shadowRoot,
}: {
enableCacheIndicator: boolean
getOwnerStack: (error: Error) => string | null | undefined
getSquashedHydrationErrorDetails: (error: Error) => HydrationErrorState | null
isRecoverableError: (error: Error) => boolean
routerType: 'app' | 'pages'
shadowRoot: ShadowRoot
})
| 247 | } |
| 248 | |
| 249 | function DevOverlayRoot({ |
| 250 | enableCacheIndicator, |
| 251 | getOwnerStack, |
| 252 | getSquashedHydrationErrorDetails, |
| 253 | isRecoverableError, |
| 254 | routerType, |
| 255 | shadowRoot, |
| 256 | }: { |
| 257 | enableCacheIndicator: boolean |
| 258 | getOwnerStack: (error: Error) => string | null | undefined |
| 259 | getSquashedHydrationErrorDetails: (error: Error) => HydrationErrorState | null |
| 260 | isRecoverableError: (error: Error) => boolean |
| 261 | routerType: 'app' | 'pages' |
| 262 | shadowRoot: ShadowRoot |
| 263 | }) { |
| 264 | const [state, dispatch] = useErrorOverlayReducer( |
| 265 | routerType, |
| 266 | getOwnerStack, |
| 267 | isRecoverableError, |
| 268 | enableCacheIndicator |
| 269 | ) |
| 270 | |
| 271 | useEffect(() => { |
| 272 | currentOverlayState = { ...state, routerType } |
| 273 | }, [state, routerType]) |
| 274 | |
| 275 | useLayoutEffect(() => { |
| 276 | const portalNode = shadowRoot.host |
| 277 | if (state.theme === 'dark') { |
| 278 | portalNode.classList.add('dark') |
| 279 | portalNode.classList.remove('light') |
| 280 | } else if (state.theme === 'light') { |
| 281 | portalNode.classList.add('light') |
| 282 | portalNode.classList.remove('dark') |
| 283 | } else { |
| 284 | portalNode.classList.remove('dark') |
| 285 | portalNode.classList.remove('light') |
| 286 | } |
| 287 | }, [shadowRoot, state.theme]) |
| 288 | |
| 289 | useInsertionEffect(() => { |
| 290 | maybeDispatch = dispatch |
| 291 | |
| 292 | // Can't schedule updates from useInsertionEffect, so we need to defer. |
| 293 | // Could move this into a passive Effect but we don't want replaying when |
| 294 | // we reconnect. |
| 295 | const replayTimeout = setTimeout(() => { |
| 296 | replayQueuedEvents(dispatch) |
| 297 | }) |
| 298 | |
| 299 | return () => { |
| 300 | maybeDispatch = null |
| 301 | clearTimeout(replayTimeout) |
| 302 | } |
| 303 | }, []) |
| 304 | |
| 305 | return ( |
| 306 | <> |
nothing calls this directly
no test coverage detected