@@ -176,10 +176,6 @@ instance MonadJSM m => MonadJSM (HydrationDomBuilderT t m) where
177data HydrationDomSpace
177data HydrationDomSpace
179−data HydrationEventSpec (er :: EventTag -> *) = HydrationEventSpec deriving (Generic)
181−instance Default (HydrationEventSpec er)
183instance DomSpace HydrationDomSpace where
179instance DomSpace HydrationDomSpace where
184 type EventSpec HydrationDomSpace = GhcjsEventSpec
180 type EventSpec HydrationDomSpace = GhcjsEventSpec
185 type RawDocument HydrationDomSpace = DOM.Document
181 type RawDocument HydrationDomSpace = DOM.Document
@@ -203,13 +199,6 @@ instance DomSpace HydrationDomSpace where
203 return (newFlags, return mEventResult)
199 return (newFlags, return mEventResult)
204 in DMap.alter f' en $ _ghcjsEventSpec_filters es
200 in DMap.alter f' en $ _ghcjsEventSpec_filters es
206−-- addEventSpecFlags _ _ _ _ = HydrationEventSpec
209− - Fence off `prerender` and totally replace immediately
210− - Fence off `runWithReplace` and hydrate at postBuild
211− - Otherwise hydrate at build time, skipping elements without SSR attribute, stripping the attrs as we go
214data HydrationDomBuilderEnv t m
203data HydrationDomBuilderEnv t m
215 = HydrationDomBuilderEnv { _hydrationDomBuilderEnv_document :: {-# UNPACK #-} !Document
204 = HydrationDomBuilderEnv { _hydrationDomBuilderEnv_document :: {-# UNPACK #-} !Document
@@ -293,6 +282,7 @@ askParent = HydrationDomBuilderT $ asks _hydrationDomBuilderEnv_parent
293askEvents :: Monad m => HydrationDomBuilderT t m (Chan [DSum (EventTriggerRef t) TriggerInvocation])
282askEvents :: Monad m => HydrationDomBuilderT t m (Chan [DSum (EventTriggerRef t) TriggerInvocation])
294askEvents = HydrationDomBuilderT . lift . lift . lift $ TriggerEventT.askEvents
283askEvents = HydrationDomBuilderT . lift . lift . lift $ TriggerEventT.askEvents
285+{-# INLINABLE localEnv #-}
296localEnv :: Monad m => (HydrationState t m -> HydrationState t m) -> (HydrationDomBuilderEnv t m -> HydrationDomBuilderEnv t m) -> HydrationDomBuilderT t m a -> HydrationDomBuilderT t m a
286localEnv :: Monad m => (HydrationState t m -> HydrationState t m) -> (HydrationDomBuilderEnv t m -> HydrationDomBuilderEnv t m) -> HydrationDomBuilderT t m a -> HydrationDomBuilderT t m a
297localEnv f g (HydrationDomBuilderT m) = HydrationDomBuilderT $ do
287localEnv f g (HydrationDomBuilderT m) = HydrationDomBuilderT $ do
298 env <- ask
288 env <- ask
@@ -311,7 +301,7 @@ setPreviousNode n = HydrationDomBuilderT $ modify $ \hs -> hs { _hydrationState_
311append :: MonadJSM m => DOM.Node -> HydrationDomBuilderT t m ()
301append :: MonadJSM m => DOM.Node -> HydrationDomBuilderT t m ()
312append n = do
302append n = do
313 p <- askParent
303 p <- askParent
314− liftJSM $ appendChild_ p n
304+ appendChild_ p n
315 return ()
305 return ()
317data HydrationMode
307data HydrationMode
@@ -319,20 +309,22 @@ data HydrationMode
319 | HydrationMode_Immediate
309 | HydrationMode_Immediate
320 deriving (Eq, Ord, Show)
310 deriving (Eq, Ord, Show)
312+{-# INLINABLE getHydrationMode #-}
322getHydrationMode :: MonadIO m => HydrationDomBuilderT t m HydrationMode
313getHydrationMode :: MonadIO m => HydrationDomBuilderT t m HydrationMode
323−getHydrationMode = do
324− ref <- HydrationDomBuilderT $ asks _hydrationDomBuilderEnv_hydrationMode
314+getHydrationMode = liftIO . readIORef =<< HydrationDomBuilderT (asks _hydrationDomBuilderEnv_hydrationMode)
325− liftIO $ readIORef ref
327{-# INLINABLE textNodeInternal #-}
316{-# INLINABLE textNodeInternal #-}
328textNodeInternal :: (MonadJSM m, ToDOMString contents) => contents -> HydrationDomBuilderT t m DOM.Text
317textNodeInternal :: (MonadJSM m, ToDOMString contents) => contents -> HydrationDomBuilderT t m DOM.Text
329−textNodeInternal !t = makeNodeInternal (const $ pure True) (askDocument >>= \doc -> liftJSM $ createTextNode doc t) DOM.Text
318+textNodeInternal !t = makeNodeInternal (const $ pure True) (askDocument >>= \doc -> createTextNode doc t) DOM.Text
331{-# INLINABLE commentNodeInternal #-}
320{-# INLINABLE commentNodeInternal #-}
332commentNodeInternal :: (MonadJSM m, ToDOMString contents) => contents -> HydrationDomBuilderT t m DOM.Comment
321commentNodeInternal :: (MonadJSM m, ToDOMString contents) => contents -> HydrationDomBuilderT t m DOM.Comment
333−commentNodeInternal !t = makeNodeInternal (const $ pure True) (askDocument >>= \doc -> liftJSM $ createComment doc t) DOM.Comment
322+commentNodeInternal !t = makeNodeInternal (const $ pure True) (askDocument >>= \doc -> createComment doc t) DOM.Comment
335{-# INLINABLE makeNodeInternal #-}
324{-# INLINABLE makeNodeInternal #-}
325+-- | This function, in hydration mode, expects the existing DOM at the current
326+-- hydration node to be correct. It skips any nodes that are the wrong type, or
327+-- that fail the @check@. The previous node reference is also updated.
336makeNodeInternal :: (MonadJSM m, IsNode node, Typeable node) => (node -> HydrationDomBuilderT t m Bool) -> HydrationDomBuilderT t m node -> (DOM.JSVal -> node) -> HydrationDomBuilderT t m node
328makeNodeInternal :: (MonadJSM m, IsNode node, Typeable node) => (node -> HydrationDomBuilderT t m Bool) -> HydrationDomBuilderT t m node -> (DOM.JSVal -> node) -> HydrationDomBuilderT t m node
337makeNodeInternal check mkNode constructor = do
329makeNodeInternal check mkNode constructor = do
338 doc <- askDocument
330 doc <- askDocument
@@ -363,14 +355,10 @@ makeNodeInternal check mkNode constructor = do
363 setPreviousNode $ Just $ toNode n
355 setPreviousNode $ Just $ toNode n
366−-- skipToCommentId "prerender-start" (liftJSM $ createComment doc "rerender-start") $ \new -> \case
367−-- Nothing -> void $ append $ toNode new
368−-- Just node -> void $ liftJSM $ Node.replaceChild parent new node
370-- | s and e must both be children of the same node and s must precede e;
358-- | s and e must both be children of the same node and s must precede e;
371-- all nodes between s and e will be removed, but s and e will not be removed
359-- all nodes between s and e will be removed, but s and e will not be removed
372deleteBetweenExclusive :: (MonadJSM m, IsNode start, IsNode end) => start -> end -> m ()
360deleteBetweenExclusive :: (MonadJSM m, IsNode start, IsNode end) => start -> end -> m ()
373−deleteBetweenExclusive s e = liftJSM $ do
361+deleteBetweenExclusive s e = do
374 df <- createDocumentFragment =<< getOwnerDocumentUnchecked s
362 df <- createDocumentFragment =<< getOwnerDocumentUnchecked s
375 extractBetweenExclusive df s e -- In many places in HydrationDomBuilderT, we assume that things always have a parent; by adding them to this DocumentFragment, we maintain that invariant
363 extractBetweenExclusive df s e -- In many places in HydrationDomBuilderT, we assume that things always have a parent; by adding them to this DocumentFragment, we maintain that invariant
@@ -672,35 +660,47 @@ instance SupportsHydrationDomBuilder t m => MountableDomBuilder t (HydrationDomB
672 liftIO $ writeIORef (_hydrationDomFragment_state childFragment) $ FragmentState_Mounted (before, after)
660 liftIO $ writeIORef (_hydrationDomFragment_state childFragment) $ FragmentState_Mounted (before, after)
673 liftIO $ writeIORef (_hydrationDomFragment_state fragment) $ FragmentState_Mounted (before, after)
661 liftIO $ writeIORef (_hydrationDomFragment_state fragment) $ FragmentState_Mounted (before, after)
663+-- | We leave markers in the static builder as comments, and rip these comments
664+-- out at hydration time, replacing them with empty text nodes.
675−skipToCommentId :: MonadJSM m => Text -> HydrationDomBuilderT t m (DOM.Node, Text)
665+skipToAndReplaceComment :: MonadJSM m => Text -> HydrationDomBuilderT t m (DOM.Text, Text)
676−skipToCommentId prefix = do
666+skipToAndReplaceComment prefix = getHydrationMode >>= \case
667+ HydrationMode_Immediate -> do
668+ -- If we're in immediate mode, we don't try to replace an existing comment,
669+ -- and just return a dummy key
670+ t <- textNodeInternal ("" :: Text)
672+ HydrationMode_Hydrating -> do
677− doc <- askDocument
673+ doc <- askDocument
678− parent <- askParent
674+ parent <- askParent
679− lastHydrationNode <- getPreviousNode
675+ lastHydrationNode <- getPreviousNode
680− let go mLastNode = do
676+ let go mLastNode = do
681− node <- maybe (Node.getFirstChildUnchecked parent) Node.getNextSiblingUnchecked mLastNode
677+ node <- maybe (Node.getFirstChildUnchecked parent) Node.getNextSiblingUnchecked mLastNode
682− DOM.castTo DOM.Comment node >>= \case
678+ DOM.castTo DOM.Comment node >>= \case
683− Just comment -> do
679+ Just comment -> do
684− commentText <- Node.getTextContentUnchecked comment
680+ commentText <- Node.getTextContentUnchecked comment
685− case T.stripPrefix prefix commentText of
681+ case T.stripPrefix prefix commentText of
686− Just key -> pure (comment, key)
682+ Just key -> do
683+ -- Replace the comment with an (invisible) text node
684+ textNode <- createTextNode doc ("" :: Text)
685+ Node.replaceChild_ parent textNode comment
686+ pure (textNode, key)
687− Nothing -> do
687+ Nothing -> do
688− liftIO $ putStrLn $ "Bad key in comment, skipping"
688+ liftIO $ putStrLn $ "Bad key in comment, skipping"
689− go (Just node)
689+ go (Just node)
690− Nothing -> do
690+ Nothing -> do
691− commentText <- Node.getTextContentUnchecked node
691+ commentText <- Node.getTextContentUnchecked node
692− liftIO $ putStrLn $ "Not a comment, skipping"
692+ liftIO $ putStrLn $ "Not a comment, skipping"
693− liftIO $ putStrLn commentText
693+ liftIO $ putStrLn commentText
694− go (Just node)
694+ go (Just node)
695− (a, key) <- go lastHydrationNode
695+ (a, key) <- go lastHydrationNode
696− setPreviousNode $ Just $ toNode a
696+ setPreviousNode $ Just $ toNode a
697− pure (toNode a, key)
697+ pure (a, key)
699−skipToReplaceStart :: MonadJSM m => HydrationDomBuilderT t m (DOM.Node, Text)
699+skipToReplaceStart :: MonadJSM m => HydrationDomBuilderT t m (DOM.Text, Text)
700−skipToReplaceStart = skipToCommentId "replace-start"
700+skipToReplaceStart = skipToAndReplaceComment "replace-start"
702−skipToReplaceEnd :: MonadJSM m => Text -> HydrationDomBuilderT t m DOM.Node
702+skipToReplaceEnd :: MonadJSM m => Text -> HydrationDomBuilderT t m DOM.Text
703−skipToReplaceEnd key = fmap fst $ skipToCommentId $ "replace-end" <> key
703+skipToReplaceEnd key = fmap fst $ skipToAndReplaceComment $ "replace-end" <> key
705instance (Reflex t, Adjustable t m, MonadJSM m, MonadHold t m, MonadFix m, PrimMonad m, Ref m ~ IORef, PerformEvent t m, MonadReflexCreateTrigger t m, MonadJSM (Performable m), MonadRef m) => Adjustable t (HydrationDomBuilderT t m) where
705instance (Reflex t, Adjustable t m, MonadJSM m, MonadHold t m, MonadFix m, PrimMonad m, Ref m ~ IORef, PerformEvent t m, MonadReflexCreateTrigger t m, MonadJSM (Performable m), MonadRef m) => Adjustable t (HydrationDomBuilderT t m) where
706 {-# INLINABLE runWithReplace #-}
706 {-# INLINABLE runWithReplace #-}
@@ -714,7 +714,7 @@ instance (Reflex t, Adjustable t m, MonadJSM m, MonadHold t m, MonadFix m, PrimM
714 HydrationMode_Immediate -> do
714 HydrationMode_Immediate -> do
715 t <- textNodeInternal ("" :: Text)
715 t <- textNodeInternal ("" :: Text)
716 append $ toNode t
716 append $ toNode t
717− pure (toNode t, "")
717+ pure (t, "")
718 let parentUnreadyChildren = _hydrationDomBuilderEnv_unreadyChildren initialEnv
718 let parentUnreadyChildren = _hydrationDomBuilderEnv_unreadyChildren initialEnv
719 haveEverBeenReady <- liftIO $ newIORef False
719 haveEverBeenReady <- liftIO $ newIORef False
720 currentCohort <- liftIO $ newIORef (-1 :: Int) -- Equal to the cohort currently in the DOM
720 currentCohort <- liftIO $ newIORef (-1 :: Int) -- Equal to the cohort currently in the DOM
@@ -735,7 +735,7 @@ instance (Reflex t, Adjustable t m, MonadJSM m, MonadHold t m, MonadFix m, PrimM
735 HydrationMode_Immediate -> do
735 HydrationMode_Immediate -> do
736 t <- textNodeInternal ("" :: Text)
736 t <- textNodeInternal ("" :: Text)
737 append $ toNode t
737 append $ toNode t
738− pure (toNode t)
738+ pure t
739 let drawInitialChild = do
739 let drawInitialChild = do
740 liftIO $ putStrLn "drawInitialChild"
740 liftIO $ putStrLn "drawInitialChild"
741 p <- liftIO (readIORef hydrating) >>= \case
741 p <- liftIO (readIORef hydrating) >>= \case
@@ -843,7 +843,12 @@ instance (Reflex t, Adjustable t m, MonadJSM m, MonadHold t m, MonadFix m, PrimM
843 liftIO $ writeIORef placeholders $! phsAfter
843 liftIO $ writeIORef placeholders $! phsAfter
845{-# INLINABLE traverseDMapWithKeyWithAdjust' #-}
845{-# INLINABLE traverseDMapWithKeyWithAdjust' #-}
846+traverseDMapWithKeyWithAdjust'
846−traverseDMapWithKeyWithAdjust' :: forall t m (k :: * -> *) v v'. (Adjustable t m, MonadHold t m, MonadFix m, MonadIO m, MonadJSM m, PrimMonad m, DMap.GCompare k) => (forall a. k a -> v a -> HydrationDomBuilderT t m (v' a)) -> DMap k v -> Event t (PatchDMap k v) -> HydrationDomBuilderT t m (DMap k v', Event t (PatchDMap k v'))
847+ :: forall t m (k :: * -> *) v v'. (Adjustable t m, MonadHold t m, MonadFix m, MonadIO m, MonadJSM m, PrimMonad m, DMap.GCompare k)
848+ => (forall a. k a -> v a -> HydrationDomBuilderT t m (v' a))
850+ -> Event t (PatchDMap k v)
851+ -> HydrationDomBuilderT t m (DMap k v', Event t (PatchDMap k v'))
847traverseDMapWithKeyWithAdjust' = do
852traverseDMapWithKeyWithAdjust' = do
848 let updateChildUnreadiness (p :: PatchDMap k (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v')) old = do
853 let updateChildUnreadiness (p :: PatchDMap k (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v')) old = do
849 let new :: forall a. k a -> ComposeMaybe (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v') a -> IO (ComposeMaybe (Constant (IORef (ChildReadyState k))) a)
854 let new :: forall a. k a -> ComposeMaybe (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v') a -> IO (ComposeMaybe (Constant (IORef (ChildReadyState k))) a)
@@ -1010,6 +1015,7 @@ hoistTraverseWithKeyWithAdjust :: forall (k :: * -> *) v v' t m p.
1010 -> Event t (p k v)
1015 -> Event t (p k v)
1011 -> HydrationDomBuilderT t m (DMap k v', Event t (p k v'))
1016 -> HydrationDomBuilderT t m (DMap k v', Event t (p k v'))
1012hoistTraverseWithKeyWithAdjust base mapPatch updateChildUnreadiness applyDomUpdate_ (f :: forall a. k a -> v a -> HydrationDomBuilderT t m (v' a)) (dm0 :: DMap k v) dm' = do
1017hoistTraverseWithKeyWithAdjust base mapPatch updateChildUnreadiness applyDomUpdate_ (f :: forall a. k a -> v a -> HydrationDomBuilderT t m (v' a)) (dm0 :: DMap k v) dm' = do
1018+ (_, key) <- skipToReplaceStart
1013 initialEnv <- HydrationDomBuilderT ask
1019 initialEnv <- HydrationDomBuilderT ask
1014 let parentUnreadyChildren = _hydrationDomBuilderEnv_unreadyChildren initialEnv
1020 let parentUnreadyChildren = _hydrationDomBuilderEnv_unreadyChildren initialEnv
1015 pendingChange :: IORef (DMap k (Constant (IORef (ChildReadyState k))), p k (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v')) <- liftIO $ newIORef mempty
1021 pendingChange :: IORef (DMap k (Constant (IORef (ChildReadyState k))), p k (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v')) <- liftIO $ newIORef mempty
@@ -1044,7 +1050,9 @@ hoistTraverseWithKeyWithAdjust base mapPatch updateChildUnreadiness applyDomUpda
1044 liftIO $ writeIORef pendingChange (newUnready, p)
1050 liftIO $ writeIORef pendingChange (newUnready, p)
1045 when (DMap.null newUnready) $ do
1051 when (DMap.null newUnready) $ do
1046 applyDomUpdate p
1052 applyDomUpdate p
1053+ stateRef <- liftIO . newIORef =<< HydrationDomBuilderT get
1047− (children0, children') <- HydrationDomBuilderT $ lift $ lift $ base (\k v -> drawChildUpdate initialEnv markChildReady $ f k v) dm0 dm'
1054+ (children0, children') <- HydrationDomBuilderT $ lift $ lift $ base (\k v -> drawChildUpdate stateRef initialEnv markChildReady $ f k v) dm0 dm'
1055+ HydrationDomBuilderT . put =<< liftIO (readIORef stateRef)
1048 let processChild k (Compose (_, _, sRef, _)) = ComposeMaybe <$> do
1056 let processChild k (Compose (_, _, sRef, _)) = ComposeMaybe <$> do
1049 readIORef sRef >>= \case
1057 readIORef sRef >>= \case
1050 ChildReadyState_Ready -> return Nothing
1058 ChildReadyState_Ready -> return Nothing
@@ -1061,8 +1069,10 @@ hoistTraverseWithKeyWithAdjust base mapPatch updateChildUnreadiness applyDomUpda
1061 placeholders0 = weakenDMapWith (\(Compose (_, ph, _, _)) -> ph) children0
1069 placeholders0 = weakenDMapWith (\(Compose (_, ph, _, _)) -> ph) children0
1062 result' = ffor children' $ mapPatch $ \(Compose (_, _, _, r)) -> r
1070 result' = ffor children' $ mapPatch $ \(Compose (_, _, _, r)) -> r
1063 liftIO $ writeIORef placeholders $! placeholders0
1071 liftIO $ writeIORef placeholders $! placeholders0
1072+ getHydrationMode >>= \case
1064− _ <- DMap.traverseWithKey (\_ (Compose (df, _, _, _)) -> Constant () <$ append (toNode df)) children0
1073+ HydrationMode_Immediate -> void $ DMap.traverseWithKey (\_ (Compose (df, _, _, _)) -> Constant () <$ append (toNode df)) children0
1065− liftIO . writeIORef lastPlaceholderRef =<< textNodeInternal ("" :: Text)
1075+ liftIO . writeIORef lastPlaceholderRef =<< skipToReplaceEnd key
1066 requestDomAction_ $ ffor children' $ \p -> do
1076 requestDomAction_ $ ffor children' $ \p -> do
1067 (oldUnready, oldP) <- liftIO $ readIORef pendingChange
1077 (oldUnready, oldP) <- liftIO $ readIORef pendingChange
1068 newUnready <- liftIO $ updateChildUnreadiness p oldUnready
1078 newUnready <- liftIO $ updateChildUnreadiness p oldUnready
@@ -1074,22 +1084,39 @@ hoistTraverseWithKeyWithAdjust base mapPatch updateChildUnreadiness applyDomUpda
1075{-# INLINABLE drawChildUpdate #-}
1085{-# INLINABLE drawChildUpdate #-}
1076drawChildUpdate :: (MonadIO m, MonadJSM m)
1086drawChildUpdate :: (MonadIO m, MonadJSM m)
1087+ => IORef (HydrationState t m)
1077− => HydrationDomBuilderEnv t m
1088+ -> HydrationDomBuilderEnv t m
1078 -> (IORef (ChildReadyState k) -> JSM ()) -- This will NOT be called if the child is ready at initialization time; instead, the ChildReadyState return value will be ChildReadyState_Ready
1089 -> (IORef (ChildReadyState k) -> JSM ()) -- This will NOT be called if the child is ready at initialization time; instead, the ChildReadyState return value will be ChildReadyState_Ready
1079 -> HydrationDomBuilderT t m (v' a)
1090 -> HydrationDomBuilderT t m (v' a)
1080 -> RequesterT t JSM Identity (TriggerEventT t m) (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v' a)
1091 -> RequesterT t JSM Identity (TriggerEventT t m) (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v' a)
1081−drawChildUpdate initialEnv markReady child = do
1092+drawChildUpdate stateRef initialEnv markReady child = do
1082 childReadyState <- liftIO $ newIORef $ ChildReadyState_Unready Nothing
1093 childReadyState <- liftIO $ newIORef $ ChildReadyState_Unready Nothing
1094+ let doc = _hydrationDomBuilderEnv_document initialEnv
1083 unreadyChildren <- liftIO $ newIORef 0
1095 unreadyChildren <- liftIO $ newIORef 0
1084− df <- createDocumentFragment $ _hydrationDomBuilderEnv_document initialEnv
1096+ hydrationMode <- liftIO $ readIORef $ _hydrationDomBuilderEnv_hydrationMode initialEnv
1085− (placeholder, result) <- flip evalStateT (HydrationState [] Nothing) $ runReaderT (unHydrationDomBuilderT $ (,) <$> textNodeInternal ("" :: Text) <*> child) $ initialEnv
1097+ initialState <- liftIO $ readIORef stateRef
1098+ placeholder <- createTextNode doc ("" :: Text)
1099+ p <- case hydrationMode of
1100+ HydrationMode_Hydrating -> do
1101+ let p = _hydrationDomBuilderEnv_parent initialEnv
1102+ case _hydrationState_previousNode initialState of
1103+ Nothing -> Node.appendChild_ p placeholder
1104+ Just pn -> Node.getNextSibling pn >>= Node.insertBefore_ p placeholder
1106+ HydrationMode_Immediate -> do
1107+ df <- createDocumentFragment doc
1108+ Node.appendChild_ df placeholder
1110+ let env = initialEnv
1086− { _hydrationDomBuilderEnv_parent = toNode df
1111+ { _hydrationDomBuilderEnv_parent = either id toNode p
1087− , _hydrationDomBuilderEnv_unreadyChildren = unreadyChildren
1112+ , _hydrationDomBuilderEnv_unreadyChildren = unreadyChildren
1088− , _hydrationDomBuilderEnv_commitAction = markReady childReadyState
1113+ , _hydrationDomBuilderEnv_commitAction = markReady childReadyState
1115+ (result, finalState) <- runStateT (runReaderT (unHydrationDomBuilderT child) env) (initialState { _hydrationState_previousNode = Just $ toNode placeholder })
1116+ liftIO $ writeIORef stateRef finalState
1090 u <- liftIO $ readIORef unreadyChildren
1117 u <- liftIO $ readIORef unreadyChildren
1091 when (u == 0) $ liftIO $ writeIORef childReadyState ChildReadyState_Ready
1118 when (u == 0) $ liftIO $ writeIORef childReadyState ChildReadyState_Ready
1092− return $ Compose (df, placeholder, childReadyState, result)
1119+ return (Compose (either (const $ error "Tried to use document fragment in hydration mode") id p, placeholder, childReadyState, result))
1094{-# INLINABLE drawChildUpdateInt #-}
1121{-# INLINABLE drawChildUpdateInt #-}
1095drawChildUpdateInt :: (MonadIO m, MonadJSM m)
1122drawChildUpdateInt :: (MonadIO m, MonadJSM m)