@@ -55,18 +55,25 @@ module Reflex.Dom.Builder.Hydration
55 , hydrateNode
55 , hydrateNode
56 , getPreviousNode, setPreviousNode
56 , getPreviousNode, setPreviousNode
57 , runHydrationDomBuilderT
57 , runHydrationDomBuilderT
59 , askEvents
58 , askEvents
62 , SupportsHydrationDomBuilder
59 , SupportsHydrationDomBuilder
63− , wrap
60+ -- Exported for specialization
64 , makeElement
62 , makeElement
65 , drawChildUpdate
63 , drawChildUpdate
66− -- * Internal
64+ , drawChildUpdateInt
67− , traverseDMapWithKeyWithAdjust'
65+ , ChildReadyState
68− , hoistTraverseWithKeyWithAdjust
66+ , DomRenderHookT
69 , traverseIntMapWithKeyWithAdjust'
73 , traverseIntMapWithKeyWithAdjust'
74+ , hoistTraverseIntMapWithKeyWithAdjust
72import Control.Concurrent
79import Control.Concurrent
@@ -143,19 +150,22 @@ import Data.Functor.Contravariant (phantom)
143import GHCJS.DOM.Types (MonadJSM (..))
150import GHCJS.DOM.Types (MonadJSM (..))
145instance MonadJSM m => MonadJSM (HydrationRunnerT t m) where
152instance MonadJSM m => MonadJSM (HydrationRunnerT t m) where
153+ {-# INLINE liftJSM' #-}
146− liftJSM' = lift . liftJSM'
154+ liftJSM' = lift . liftJSM'
148instance MonadJSM m => MonadJSM (HydrationDomBuilderT t m) where
156instance MonadJSM m => MonadJSM (HydrationDomBuilderT t m) where
157+ {-# INLINE liftJSM' #-}
149− liftJSM' = lift . liftJSM'
158+ liftJSM' = lift . liftJSM'
151instance MonadJSM m => MonadJSM (DomRenderHookT t m) where
160instance MonadJSM m => MonadJSM (DomRenderHookT t m) where
161+ {-# INLINE liftJSM' #-}
152− liftJSM' = lift . liftJSM'
162+ liftJSM' = lift . liftJSM'
155−data HydrationDomBuilderEnv t = HydrationDomBuilderEnv
165+data HydrationDomBuilderEnv t m = HydrationDomBuilderEnv
156 { _hydrationDomBuilderEnv_document :: {-# UNPACK #-} !Document
166 { _hydrationDomBuilderEnv_document :: {-# UNPACK #-} !Document
157 -- ^ Reference to the document
167 -- ^ Reference to the document
158− , _hydrationDomBuilderEnv_parent :: {-# UNPACK #-} !(IORef Node)
168+ , _hydrationDomBuilderEnv_parent :: !(Either Node (IORef Node))
159 -- ^ This is in an IORef because in the time up to hydration we can't actually know what the
169 -- ^ This is in an IORef because in the time up to hydration we can't actually know what the
160 -- parent is - we populate this reference during the DOM traversal at hydration time
170 -- parent is - we populate this reference during the DOM traversal at hydration time
161 , _hydrationDomBuilderEnv_unreadyChildren :: {-# UNPACK #-} !(IORef Word)
171 , _hydrationDomBuilderEnv_unreadyChildren :: {-# UNPACK #-} !(IORef Word)
@@ -165,6 +175,7 @@ data HydrationDomBuilderEnv t = HydrationDomBuilderEnv
165 , _hydrationDomBuilderEnv_hydrationMode :: {-# UNPACK #-} !(IORef HydrationMode)
175 , _hydrationDomBuilderEnv_hydrationMode :: {-# UNPACK #-} !(IORef HydrationMode)
166 -- ^ In hydration mode? Should be switched to `HydrationMode_Immediate` after hydration is finished
176 -- ^ In hydration mode? Should be switched to `HydrationMode_Immediate` after hydration is finished
167 , _hydrationDomBuilderEnv_switchover :: !(Event t ())
177 , _hydrationDomBuilderEnv_switchover :: !(Event t ())
178+ , _hydrationDomBuilderEnv_delayed :: {-# UNPACK #-} !(IORef (HydrationRunnerT t m ()))
170-- | The monad which performs the delayed actions to reuse prerendered nodes and set up events.
181-- | The monad which performs the delayed actions to reuse prerendered nodes and set up events.
@@ -176,48 +187,55 @@ newtype HydrationRunnerT t m a = HydrationRunnerT { unHydrationRunnerT :: StateT
190+{-# INLINE localRunner #-}
179localRunner :: (MonadJSM m, Monad m) => HydrationRunnerT t m a -> Maybe Node -> Node -> HydrationRunnerT t m a
191localRunner :: (MonadJSM m, Monad m) => HydrationRunnerT t m a -> Maybe Node -> Node -> HydrationRunnerT t m a
180localRunner (HydrationRunnerT m) s parent = HydrationRunnerT . lift $ local (\_ -> parent) (evalStateT m s)
192localRunner (HydrationRunnerT m) s parent = HydrationRunnerT . lift $ local (\_ -> parent) (evalStateT m s)
194+{-# INLINE runHydrationRunnerT #-}
182runHydrationRunnerT
195runHydrationRunnerT
183 :: (MonadRef m, Ref m ~ IORef, Monad m, PerformEvent t m, MonadFix m, MonadReflexCreateTrigger t m, MonadJSM m, MonadJSM (Performable m))
196 :: (MonadRef m, Ref m ~ IORef, Monad m, PerformEvent t m, MonadFix m, MonadReflexCreateTrigger t m, MonadJSM m, MonadJSM (Performable m))
184 => HydrationRunnerT t m a -> Maybe Node -> Node -> Chan [DSum (EventTriggerRef t) TriggerInvocation] -> m a
197 => HydrationRunnerT t m a -> Maybe Node -> Node -> Chan [DSum (EventTriggerRef t) TriggerInvocation] -> m a
185runHydrationRunnerT (HydrationRunnerT m) s parent = runDomRenderHookT (runReaderT (evalStateT m s) parent)
198runHydrationRunnerT (HydrationRunnerT m) s parent = runDomRenderHookT (runReaderT (evalStateT m s) parent)
187instance MonadReflexCreateTrigger t m => MonadReflexCreateTrigger t (HydrationRunnerT t m) where
200instance MonadReflexCreateTrigger t m => MonadReflexCreateTrigger t (HydrationRunnerT t m) where
188− {-# INLINABLE newEventWithTrigger #-}
201+ {-# INLINE newEventWithTrigger #-}
189 newEventWithTrigger = lift . newEventWithTrigger
202 newEventWithTrigger = lift . newEventWithTrigger
190− {-# INLINABLE newFanEventWithTrigger #-}
203+ {-# INLINE newFanEventWithTrigger #-}
191 newFanEventWithTrigger f = lift $ newFanEventWithTrigger f
204 newFanEventWithTrigger f = lift $ newFanEventWithTrigger f
193instance MonadTrans (HydrationRunnerT t) where
206instance MonadTrans (HydrationRunnerT t) where
194 lift = HydrationRunnerT . lift . lift . lift
208 lift = HydrationRunnerT . lift . lift . lift
196instance MonadSample t m => MonadSample t (HydrationRunnerT t m) where
210instance MonadSample t m => MonadSample t (HydrationRunnerT t m) where
211+ {-# INLINE sample #-}
197 sample = lift . sample
212 sample = lift . sample
199-- | Add a hydration step which depends on some computation that should only be
214-- | Add a hydration step which depends on some computation that should only be
200-- done *before* the switchover to immediate mode - this is most likely some
215-- done *before* the switchover to immediate mode - this is most likely some
201-- form of 'hold' which we want to remove after hydration is done
216-- form of 'hold' which we want to remove after hydration is done
217+{-# INLINE addHydrationStepWithSetup #-}
202addHydrationStepWithSetup :: (Adjustable t m, MonadIO m) => m a -> (a -> HydrationRunnerT t m ()) -> HydrationDomBuilderT t m ()
218addHydrationStepWithSetup :: (Adjustable t m, MonadIO m) => m a -> (a -> HydrationRunnerT t m ()) -> HydrationDomBuilderT t m ()
203addHydrationStepWithSetup setup f = getHydrationMode >>= \case
219addHydrationStepWithSetup setup f = getHydrationMode >>= \case
204 HydrationMode_Immediate -> pure ()
220 HydrationMode_Immediate -> pure ()
205 HydrationMode_Hydrating -> do
221 HydrationMode_Hydrating -> do
206 switchover <- HydrationDomBuilderT $ asks _hydrationDomBuilderEnv_switchover
222 switchover <- HydrationDomBuilderT $ asks _hydrationDomBuilderEnv_switchover
208 (s, _) <- lift $ runWithReplace setup $ return () <$ switchover -- 4% more memory than above
223 (s, _) <- lift $ runWithReplace setup $ return () <$ switchover -- 4% more memory than above
209− HydrationDomBuilderT $ modify' (>> f s)
224+ addHydrationStep (f s)
211-- | Add a hydration step
226-- | Add a hydration step
227+{-# INLINE addHydrationStep #-}
212−addHydrationStep :: Monad m => HydrationRunnerT t m () -> HydrationDomBuilderT t m ()
228+addHydrationStep :: MonadIO m => HydrationRunnerT t m () -> HydrationDomBuilderT t m ()
213−addHydrationStep m = HydrationDomBuilderT $ modify' (>> m)
229+addHydrationStep m = do
230+ delayedRef <- HydrationDomBuilderT $ asks _hydrationDomBuilderEnv_delayed
231+ liftIO $ modifyIORef' delayedRef (>> m)
215-- | A monad for DomBuilder which just gets the results of children and pushes
233-- | A monad for DomBuilder which just gets the results of children and pushes
216-- work into an action that is delayed until after postBuild (to match the
234-- work into an action that is delayed until after postBuild (to match the
217-- static builder). The action runs in 'HydrationRunnerT', which performs the
235-- static builder). The action runs in 'HydrationRunnerT', which performs the
218-- DOM takeover and sets up the events, after which point this monad will
236-- DOM takeover and sets up the events, after which point this monad will
219-- continue in the vein of 'ImmediateDomBuilderT'.
237-- continue in the vein of 'ImmediateDomBuilderT'.
220−newtype HydrationDomBuilderT t m a = HydrationDomBuilderT { unHydrationDomBuilderT :: ReaderT (HydrationDomBuilderEnv t) (StateT (HydrationRunnerT t m ()) (DomRenderHookT t m)) a }
238+newtype HydrationDomBuilderT t m a = HydrationDomBuilderT { unHydrationDomBuilderT :: ReaderT (HydrationDomBuilderEnv t m) (DomRenderHookT t m) a }
221 deriving (Functor, Applicative, Monad, MonadFix, MonadIO, MonadException
239 deriving (Functor, Applicative, Monad, MonadFix, MonadIO, MonadException
222#if MIN_VERSION_base(4,9,1)
240#if MIN_VERSION_base(4,9,1)
223 , MonadAsyncException
241 , MonadAsyncException
@@ -229,7 +247,8 @@ instance PrimMonad m => PrimMonad (HydrationDomBuilderT x m) where
229 primitive = lift . primitive
247 primitive = lift . primitive
231instance MonadTrans (HydrationDomBuilderT t) where
249instance MonadTrans (HydrationDomBuilderT t) where
232− lift = HydrationDomBuilderT . lift . lift . lift
251+ lift = HydrationDomBuilderT . lift . lift
234-- | Shared behavior for HydrationDomBuilderT and HydrationRunnerT
253-- | Shared behavior for HydrationDomBuilderT and HydrationRunnerT
235newtype DomRenderHookT t m a = DomRenderHookT { unDomRenderHookT :: RequesterT t JSM Identity (TriggerEventT t m) a }
254newtype DomRenderHookT t m a = DomRenderHookT { unDomRenderHookT :: RequesterT t JSM Identity (TriggerEventT t m) a }
@@ -239,7 +258,7 @@ newtype DomRenderHookT t m a = DomRenderHookT { unDomRenderHookT :: RequesterT t
242−{-# INLINABLE runDomRenderHookT #-}
261+{-# INLINE runDomRenderHookT #-}
243runDomRenderHookT
262runDomRenderHookT
244 :: (MonadFix m, PerformEvent t m, MonadReflexCreateTrigger t m, MonadJSM m, MonadJSM (Performable m), MonadRef m, Ref m ~ IORef)
263 :: (MonadFix m, PerformEvent t m, MonadReflexCreateTrigger t m, MonadJSM m, MonadJSM (Performable m), MonadRef m, Ref m ~ IORef)
245 => DomRenderHookT t m a
264 => DomRenderHookT t m a
@@ -257,6 +276,7 @@ runDomRenderHookT (DomRenderHookT a) events = do
257 void . liftIO $ f v
276 void . liftIO $ f v
259instance MonadTrans (DomRenderHookT t) where
278instance MonadTrans (DomRenderHookT t) where
260 lift = DomRenderHookT . lift . lift
280 lift = DomRenderHookT . lift . lift
262instance (Reflex t, MonadFix m) => DomRenderHook t (DomRenderHookT t m) where
282instance (Reflex t, MonadFix m) => DomRenderHook t (DomRenderHookT t m) where
@@ -268,16 +288,16 @@ instance (Reflex t, MonadFix m) => DomRenderHook t (DomRenderHookT t m) where
268 requestDomAction_ = DomRenderHookT . requesting_
288 requestDomAction_ = DomRenderHookT . requesting_
270instance (Reflex t, MonadFix m) => DomRenderHook t (HydrationDomBuilderT t m) where
290instance (Reflex t, MonadFix m) => DomRenderHook t (HydrationDomBuilderT t m) where
271− withRenderHook hook = HydrationDomBuilderT . mapReaderT (mapStateT (withRenderHook hook)) . unHydrationDomBuilderT
291+ withRenderHook hook = HydrationDomBuilderT . mapReaderT (withRenderHook hook) . unHydrationDomBuilderT
272− requestDomAction = HydrationDomBuilderT . lift . lift . requestDomAction
292+ requestDomAction = HydrationDomBuilderT . lift . requestDomAction
273− requestDomAction_ = HydrationDomBuilderT . lift . lift . requestDomAction_
293+ requestDomAction_ = HydrationDomBuilderT . lift . requestDomAction_
275instance (Reflex t, MonadFix m) => DomRenderHook t (HydrationRunnerT t m) where
295instance (Reflex t, MonadFix m) => DomRenderHook t (HydrationRunnerT t m) where
276 withRenderHook hook = HydrationRunnerT . mapStateT (mapReaderT (withRenderHook hook)) . unHydrationRunnerT
296 withRenderHook hook = HydrationRunnerT . mapStateT (mapReaderT (withRenderHook hook)) . unHydrationRunnerT
277 requestDomAction = HydrationRunnerT . lift . lift . requestDomAction
297 requestDomAction = HydrationRunnerT . lift . lift . requestDomAction
278 requestDomAction_ = HydrationRunnerT . lift . lift . requestDomAction_
298 requestDomAction_ = HydrationRunnerT . lift . lift . requestDomAction_
280−{-# INLINABLE runHydrationDomBuilderT #-}
300+{-# INLINE runHydrationDomBuilderT #-}
281runHydrationDomBuilderT
301runHydrationDomBuilderT
282 :: ( MonadFix m
302 :: ( MonadFix m
283 , PerformEvent t m
303 , PerformEvent t m
@@ -288,20 +308,20 @@ runHydrationDomBuilderT
288 , Ref m ~ IORef
308 , Ref m ~ IORef
290 => HydrationDomBuilderT t m a
310 => HydrationDomBuilderT t m a
291− -> HydrationDomBuilderEnv t
311+ -> HydrationDomBuilderEnv t m
292 -> Chan [DSum (EventTriggerRef t) TriggerInvocation]
312 -> Chan [DSum (EventTriggerRef t) TriggerInvocation]
293− -> m (a, HydrationRunnerT t m ())
313+ -> m a
294−runHydrationDomBuilderT (HydrationDomBuilderT a) env = runDomRenderHookT (runStateT (runReaderT a env) (pure ()))
314+runHydrationDomBuilderT (HydrationDomBuilderT a) env = runDomRenderHookT (runReaderT a env)
296instance Monad m => HasDocument (HydrationDomBuilderT t m) where
316instance Monad m => HasDocument (HydrationDomBuilderT t m) where
297− {-# INLINABLE askDocument #-}
317+ {-# INLINE askDocument #-}
298 askDocument = HydrationDomBuilderT $ asks _hydrationDomBuilderEnv_document
318 askDocument = HydrationDomBuilderT $ asks _hydrationDomBuilderEnv_document
300−{-# INLINABLE localEnv #-}
320+{-# INLINE localEnv #-}
301−localEnv :: Monad m => (HydrationDomBuilderEnv t -> HydrationDomBuilderEnv t) -> HydrationDomBuilderT t m a -> HydrationDomBuilderT t m a
321+localEnv :: Monad m => (HydrationDomBuilderEnv t m -> HydrationDomBuilderEnv t m) -> HydrationDomBuilderT t m a -> HydrationDomBuilderT t m a
302−localEnv f = HydrationDomBuilderT . local f . unHydrationDomBuilderT
322+localEnv f = HydrationDomBuilderT . local (f $!) . unHydrationDomBuilderT
304−{-# INLINABLE append #-}
324+{-# INLINE append #-}
305append :: MonadJSM m => DOM.Node -> HydrationDomBuilderT t m ()
325append :: MonadJSM m => DOM.Node -> HydrationDomBuilderT t m ()
306append n = do
326append n = do
307 p <- getParent
327 p <- getParent
@@ -313,39 +333,39 @@ data HydrationMode
313 | HydrationMode_Immediate
333 | HydrationMode_Immediate
314 deriving (Eq, Ord, Show)
334 deriving (Eq, Ord, Show)
316−{-# INLINABLE askParent #-}
336+{-# INLINE askParent #-}
317askParent :: Monad m => HydrationRunnerT t m DOM.Node
337askParent :: Monad m => HydrationRunnerT t m DOM.Node
318askParent = HydrationRunnerT ask
338askParent = HydrationRunnerT ask
320−{-# INLINABLE getPreviousNode #-}
340+{-# INLINE getPreviousNode #-}
321getPreviousNode :: Monad m => HydrationRunnerT t m (Maybe DOM.Node)
341getPreviousNode :: Monad m => HydrationRunnerT t m (Maybe DOM.Node)
322getPreviousNode = HydrationRunnerT get
342getPreviousNode = HydrationRunnerT get
324−{-# INLINABLE setPreviousNode #-}
344+{-# INLINE setPreviousNode #-}
325setPreviousNode :: Monad m => Maybe DOM.Node -> HydrationRunnerT t m ()
345setPreviousNode :: Monad m => Maybe DOM.Node -> HydrationRunnerT t m ()
326setPreviousNode = HydrationRunnerT . put
346setPreviousNode = HydrationRunnerT . put
328−{-# INLINABLE getParent #-}
348+{-# INLINE getParent #-}
329getParent :: MonadIO m => HydrationDomBuilderT t m DOM.Node
349getParent :: MonadIO m => HydrationDomBuilderT t m DOM.Node
330−getParent = liftIO . readIORef =<< HydrationDomBuilderT (asks _hydrationDomBuilderEnv_parent)
350+getParent = either pure (liftIO . readIORef) =<< HydrationDomBuilderT (asks _hydrationDomBuilderEnv_parent)
332−{-# INLINABLE askUnreadyChildren #-}
352+{-# INLINE askUnreadyChildren #-}
333askUnreadyChildren :: Monad m => HydrationDomBuilderT t m (IORef Word)
353askUnreadyChildren :: Monad m => HydrationDomBuilderT t m (IORef Word)
334askUnreadyChildren = HydrationDomBuilderT $ asks _hydrationDomBuilderEnv_unreadyChildren
354askUnreadyChildren = HydrationDomBuilderT $ asks _hydrationDomBuilderEnv_unreadyChildren
336−{-# INLINABLE askCommitAction #-}
356+{-# INLINE askCommitAction #-}
337askCommitAction :: Monad m => HydrationDomBuilderT t m (JSM ())
357askCommitAction :: Monad m => HydrationDomBuilderT t m (JSM ())
338askCommitAction = HydrationDomBuilderT $ asks _hydrationDomBuilderEnv_commitAction
358askCommitAction = HydrationDomBuilderT $ asks _hydrationDomBuilderEnv_commitAction
340−{-# INLINABLE getHydrationMode #-}
360+{-# INLINE getHydrationMode #-}
341getHydrationMode :: MonadIO m => HydrationDomBuilderT t m HydrationMode
361getHydrationMode :: MonadIO m => HydrationDomBuilderT t m HydrationMode
342getHydrationMode = liftIO . readIORef =<< HydrationDomBuilderT (asks _hydrationDomBuilderEnv_hydrationMode)
362getHydrationMode = liftIO . readIORef =<< HydrationDomBuilderT (asks _hydrationDomBuilderEnv_hydrationMode)
344−{-# INLINABLE askEvents #-}
364+{-# INLINE askEvents #-}
345askEvents :: Monad m => HydrationDomBuilderT t m (Chan [DSum (EventTriggerRef t) TriggerInvocation])
365askEvents :: Monad m => HydrationDomBuilderT t m (Chan [DSum (EventTriggerRef t) TriggerInvocation])
346−askEvents = HydrationDomBuilderT . lift . lift . DomRenderHookT . lift $ TriggerEventT.askEvents
366+askEvents = HydrationDomBuilderT . lift . DomRenderHookT . lift $ TriggerEventT.askEvents
348−{-# INLINABLE makeNodeInternal #-}
368+{-# INLINE makeNodeInternal #-}
349makeNodeInternal
369makeNodeInternal
350 :: forall node t m. (MonadJSM m, IsNode node, Typeable node)
370 :: forall node t m. (MonadJSM m, IsNode node, Typeable node)
351 => HydrationDomBuilderT t m node -> HydrationDomBuilderT t m node
371 => HydrationDomBuilderT t m node -> HydrationDomBuilderT t m node
@@ -354,7 +374,7 @@ makeNodeInternal mkNode = do
354 append $ toNode n
374 append $ toNode n
357−{-# INLINABLE hydrateNode #-}
377+{-# INLINE hydrateNode #-}
358-- | This function expects the existing DOM at the current hydration node to be
378-- | This function expects the existing DOM at the current hydration node to be
359-- correct. It skips any nodes that are the wrong type, or that fail the
379-- correct. It skips any nodes that are the wrong type, or that fail the
360-- @check@. The previous node reference is also updated.
380-- @check@. The previous node reference is also updated.
@@ -378,7 +398,7 @@ hydrateNode check constructor = do
378type SupportsHydrationDomBuilder t m = (Reflex t, MonadJSM m, MonadHold t m, MonadFix m, MonadReflexCreateTrigger t m, MonadRef m, Ref m ~ Ref JSM, Adjustable t m, PrimMonad m, PerformEvent t m, MonadJSM (Performable m))
398type SupportsHydrationDomBuilder t m = (Reflex t, MonadJSM m, MonadHold t m, MonadFix m, MonadReflexCreateTrigger t m, MonadRef m, Ref m ~ Ref JSM, Adjustable t m, PrimMonad m, PerformEvent t m, MonadJSM (Performable m))
380-- | This 'wrap' is only partial: it doesn't create the 'EventSelector' itself
400-- | This 'wrap' is only partial: it doesn't create the 'EventSelector' itself
381−{-# INLINABLE wrap #-}
401+{-# INLINE wrap #-}
383 :: forall m er t. (Reflex t, MonadJSM m, MonadReflexCreateTrigger t m, DomRenderHook t m)
403 :: forall m er t. (Reflex t, MonadJSM m, MonadReflexCreateTrigger t m, DomRenderHook t m)
384 => Chan [DSum (EventTriggerRef t) TriggerInvocation]
404 => Chan [DSum (EventTriggerRef t) TriggerInvocation]
@@ -404,7 +424,7 @@ wrap events e cfg = do
404 return $ en :=> EventFilterTriggerRef triggerRef
424 return $ en :=> EventFilterTriggerRef triggerRef
405 return eventTriggerRefs
425 return eventTriggerRefs
407−{-# INLINABLE triggerBody #-}
427+{-# INLINE triggerBody #-}
408triggerBody
428triggerBody
409 :: forall er t x. DOM.JSContextRef
429 :: forall er t x. DOM.JSContextRef
410 -> ElementConfig er t HydrationDomSpace
430 -> ElementConfig er t HydrationDomSpace
@@ -434,19 +454,19 @@ triggerBody ctx cfg events eventTriggerRefs e (WrapArg en) t = case DMap.lookup
434 handler :: GhcjsEventHandler er
454 handler :: GhcjsEventHandler er
435 !handler = _ghcjsEventSpec_handler $ _rawElementConfig_eventSpec $ extractRawElementConfig cfg
455 !handler = _ghcjsEventSpec_handler $ _rawElementConfig_eventSpec $ extractRawElementConfig cfg
437−{-# INLINABLE makeElement #-}
457+{-# INLINE makeElement #-}
438makeElement
458makeElement
439 :: forall er t m a. (MonadJSM m, MonadHold t m, MonadFix m, MonadReflexCreateTrigger t m, Adjustable t m, Ref m ~ IORef, PerformEvent t m, MonadJSM (Performable m), MonadRef m)
459 :: forall er t m a. (MonadJSM m, MonadHold t m, MonadFix m, MonadReflexCreateTrigger t m, Adjustable t m, Ref m ~ IORef, PerformEvent t m, MonadJSM (Performable m), MonadRef m)
441 -> ElementConfig er t HydrationDomSpace
461 -> ElementConfig er t HydrationDomSpace
442 -> HydrationDomBuilderT t m a
462 -> HydrationDomBuilderT t m a
443− -> HydrationDomBuilderT t m ((Element er HydrationDomSpace t, a), IORef DOM.Element)
463+ -> HydrationDomBuilderT t m ((Element er HydrationDomSpace t, a), Either DOM.Element (IORef DOM.Element))
444makeElement elementTag cfg child = do
464makeElement elementTag cfg child = do
445 doc <- askDocument
465 doc <- askDocument
446 ctx <- askJSM
466 ctx <- askJSM
447 events <- askEvents
467 events <- askEvents
449− let buildElement :: MonadJSM n => n DOM.Element
469+ let buildElement :: JSM DOM.Element
450 buildElement = do
470 buildElement = do
451 e <- uncheckedCastTo DOM.Element <$> case cfg ^. namespace of
471 e <- uncheckedCastTo DOM.Element <$> case cfg ^. namespace of
452 Nothing -> createElement doc elementTag
472 Nothing -> createElement doc elementTag
@@ -462,21 +482,23 @@ makeElement elementTag cfg child = do
462 Just ns -> hasAttributeNS e (Just ns) ssrAttr <* removeAttributeNS e (Just ns) ssrAttr
482 Just ns -> hasAttributeNS e (Just ns) ssrAttr <* removeAttributeNS e (Just ns) ssrAttr
463 getHydrationMode >>= \case
483 getHydrationMode >>= \case
464 HydrationMode_Immediate -> do
484 HydrationMode_Immediate -> do
465− e <- makeNodeInternal buildElement
485+ e <- makeNodeInternal $ liftJSM buildElement
466− p <- liftIO $ newIORef $ toNode e
467 -- Run the child builder with updated parent and previous sibling references
486 -- Run the child builder with updated parent and previous sibling references
468− result <- localEnv (\env -> env { _hydrationDomBuilderEnv_parent = p }) child
487+ result <- localEnv (\env -> env { _hydrationDomBuilderEnv_parent = Left $ toNode e }) child
469 eventTriggerRefs <- wrap events e $ extractRawElementConfig cfg
488 eventTriggerRefs <- wrap events e $ extractRawElementConfig cfg
470 es <- newFanEventWithTrigger $ triggerBody ctx cfg events eventTriggerRefs e
489 es <- newFanEventWithTrigger $ triggerBody ctx cfg events eventTriggerRefs e
471− e' <- liftIO $ newIORef e
472− return ((Element es (), result), e')
490+ return ((Element es (), result), Left e)
473 HydrationMode_Hydrating -> do
491 HydrationMode_Hydrating -> do
474 -- Schedule everything for after postBuild, except for getting the result itself
492 -- Schedule everything for after postBuild, except for getting the result itself
475 parent <- liftIO $ newIORef $ error "Parent not yet initialized"
493 parent <- liftIO $ newIORef $ error "Parent not yet initialized"
476 e' <- liftIO $ newIORef $ error "makeElement: Element not yet initialized"
494 e' <- liftIO $ newIORef $ error "makeElement: Element not yet initialized"
477 env <- HydrationDomBuilderT ask
495 env <- HydrationDomBuilderT ask
496+ childDelayedRef <- liftIO $ newIORef $ pure ()
478− let env' = env { _hydrationDomBuilderEnv_parent = parent }
498+ { _hydrationDomBuilderEnv_parent = Right parent
499+ , _hydrationDomBuilderEnv_delayed = childDelayedRef
479− (result, childDom) <- HydrationDomBuilderT $ lift $ lift $ runStateT (runReaderT (unHydrationDomBuilderT child) env') (pure ())
501+ result <- HydrationDomBuilderT $ lift $ runReaderT (unHydrationDomBuilderT child) env'
480 wrapResult <- liftIO newEmptyMVar
502 wrapResult <- liftIO newEmptyMVar
481 let activateElement = do
503 let activateElement = do
482 e <- hydrateNode hasSSRAttribute DOM.Element
504 e <- hydrateNode hasSSRAttribute DOM.Element
@@ -487,6 +509,7 @@ makeElement elementTag cfg child = do
487 refs <- wrap events e $ extractRawElementConfig cfg
509 refs <- wrap events e $ extractRawElementConfig cfg
488 liftIO $ putMVar wrapResult (e, refs)
510 liftIO $ putMVar wrapResult (e, refs)
489 pure $ toNode e
511 pure $ toNode e
512+ childDom <- liftIO $ readIORef childDelayedRef
490 addHydrationStep $ activateElement >>= localRunner childDom Nothing
513 addHydrationStep $ activateElement >>= localRunner childDom Nothing
492 -- We need the EventSelector to switch to the real event handler after activation
515 -- We need the EventSelector to switch to the real event handler after activation
@@ -510,9 +533,9 @@ makeElement elementTag cfg child = do
510 Just c -> c
533 Just c -> c
512 let dummyElement = error "makeElement: DOM.Element"
535 let dummyElement = error "makeElement: DOM.Element"
513− return ((Element es dummyElement, result), e')
536+ return ((Element es dummyElement, result), Right e')
515−{-# INLINABLE textNodeInternal #-}
538+{-# INLINE textNodeInternal #-}
516textNodeInternal :: (Adjustable t m, MonadHold t m, MonadJSM m, MonadFix m, Reflex t) => Text -> Maybe (Event t Text) -> HydrationDomBuilderT t m DOM.Text
539textNodeInternal :: (Adjustable t m, MonadHold t m, MonadJSM m, MonadFix m, Reflex t) => Text -> Maybe (Event t Text) -> HydrationDomBuilderT t m DOM.Text
517textNodeInternal !t mSetContents = getHydrationMode >>= \case
540textNodeInternal !t mSetContents = getHydrationMode >>= \case
518 HydrationMode_Immediate -> do
541 HydrationMode_Immediate -> do
@@ -529,7 +552,7 @@ textNodeInternal !t mSetContents = getHydrationMode >>= \case
529-- text content of each node we come to, comparing it to the content we
552-- text content of each node we come to, comparing it to the content we
530-- expect. We also have a special case for empty text nodes - we always create
553-- expect. We also have a special case for empty text nodes - we always create
531-- the and add them after the previous node reference.
554-- the and add them after the previous node reference.
532−{-# INLINABLE hydrateTextNode #-}
555+{-# INLINE hydrateTextNode #-}
533hydrateTextNode :: MonadJSM m => Text -> HydrationRunnerT t m DOM.Text
556hydrateTextNode :: MonadJSM m => Text -> HydrationRunnerT t m DOM.Text
534hydrateTextNode t@"" = do
557hydrateTextNode t@"" = do
535 doc <- Node.getOwnerDocumentUnchecked =<< askParent
558 doc <- Node.getOwnerDocumentUnchecked =<< askParent
@@ -557,7 +580,7 @@ hydrateTextNode t = do
557 Nothing -> go parent $ Just $ toNode originalNode
580 Nothing -> go parent $ Just $ toNode originalNode
560−{-# INLINABLE commentNodeInternal #-}
583+{-# INLINE commentNodeInternal #-}
561commentNodeInternal :: (Ref m ~ IORef, MonadRef m, PerformEvent t m, MonadReflexCreateTrigger t m, MonadJSM (Performable m), MonadJSM m, MonadFix m, ToDOMString contents, Reflex t, Adjustable t m) => contents -> Maybe (Event t contents) -> HydrationDomBuilderT t m DOM.Comment
584commentNodeInternal :: (Ref m ~ IORef, MonadRef m, PerformEvent t m, MonadReflexCreateTrigger t m, MonadJSM (Performable m), MonadJSM m, MonadFix m, ToDOMString contents, Reflex t, Adjustable t m) => contents -> Maybe (Event t contents) -> HydrationDomBuilderT t m DOM.Comment
562commentNodeInternal !t mSetContents = getHydrationMode >>= \case
585commentNodeInternal !t mSetContents = getHydrationMode >>= \case
563 HydrationMode_Immediate -> do
586 HydrationMode_Immediate -> do
@@ -572,6 +595,7 @@ commentNodeInternal !t mSetContents = getHydrationMode >>= \case
573-- | We leave markers in the static builder as comments, and rip these comments
596-- | We leave markers in the static builder as comments, and rip these comments
574-- out at hydration time, replacing them with empty text nodes.
597-- out at hydration time, replacing them with empty text nodes.
598+{-# INLINE skipToAndReplaceComment #-}
575skipToAndReplaceComment
599skipToAndReplaceComment
576 :: (MonadJSM m, Reflex t, MonadFix m, Adjustable t m, MonadHold t m)
600 :: (MonadJSM m, Reflex t, MonadFix m, Adjustable t m, MonadHold t m)
@@ -615,9 +639,11 @@ skipToAndReplaceComment prefix key0Ref = getHydrationMode >>= \case
615 writeIORef keyRef key
639 writeIORef keyRef key
616 pure (switchComment, textNodeRef, keyRef)
640 pure (switchComment, textNodeRef, keyRef)
642+{-# INLINE skipToReplaceStart #-}
618skipToReplaceStart :: (MonadJSM m, Reflex t, MonadFix m, Adjustable t m, MonadHold t m) => HydrationDomBuilderT t m (HydrationRunnerT t m (), IORef DOM.Text, IORef Text)
643skipToReplaceStart :: (MonadJSM m, Reflex t, MonadFix m, Adjustable t m, MonadHold t m) => HydrationDomBuilderT t m (HydrationRunnerT t m (), IORef DOM.Text, IORef Text)
619skipToReplaceStart = skipToAndReplaceComment "replace-start" =<< liftIO (newIORef "")
644skipToReplaceStart = skipToAndReplaceComment "replace-start" =<< liftIO (newIORef "")
646+{-# INLINE skipToReplaceEnd #-}
621skipToReplaceEnd :: (MonadJSM m, Reflex t, MonadFix m, Adjustable t m, MonadHold t m) => IORef Text -> HydrationDomBuilderT t m (HydrationRunnerT t m (), IORef DOM.Text)
647skipToReplaceEnd :: (MonadJSM m, Reflex t, MonadFix m, Adjustable t m, MonadHold t m) => IORef Text -> HydrationDomBuilderT t m (HydrationRunnerT t m (), IORef DOM.Text)
622skipToReplaceEnd key = fmap (\(m,e,_) -> (m,e)) $ skipToAndReplaceComment "replace-end" key
648skipToReplaceEnd key = fmap (\(m,e,_) -> (m,e)) $ skipToAndReplaceComment "replace-end" key
@@ -664,18 +690,18 @@ instance DomSpace HydrationDomSpace where
665instance (SupportsHydrationDomBuilder t m) => DomBuilder t (HydrationDomBuilderT t m) where
691instance (SupportsHydrationDomBuilder t m) => DomBuilder t (HydrationDomBuilderT t m) where
666 type DomBuilderSpace (HydrationDomBuilderT t m) = HydrationDomSpace
692 type DomBuilderSpace (HydrationDomBuilderT t m) = HydrationDomSpace
667− {-# INLINABLE textNode #-}
693+ {-# INLINE textNode #-}
668 textNode (TextNodeConfig initialContents mSetContents) = do
694 textNode (TextNodeConfig initialContents mSetContents) = do
669 _ <- textNodeInternal initialContents mSetContents
695 _ <- textNodeInternal initialContents mSetContents
670 return $ TextNode ()
696 return $ TextNode ()
671− {-# INLINABLE commentNode #-}
697+ {-# INLINE commentNode #-}
672 commentNode (CommentNodeConfig initialContents mSetContents) = do
698 commentNode (CommentNodeConfig initialContents mSetContents) = do
673 _ <- commentNodeInternal initialContents mSetContents
699 _ <- commentNodeInternal initialContents mSetContents
674 return $ CommentNode ()
700 return $ CommentNode ()
675− {-# INLINABLE element #-}
701+ {-# INLINE element #-}
676 element elementTag cfg child = do
702 element elementTag cfg child = do
677 fst <$> makeElement elementTag cfg child
703 fst <$> makeElement elementTag cfg child
678− {-# INLINABLE inputElement #-}
704+ {-# INLINE inputElement #-}
679 inputElement cfg = do
705 inputElement cfg = do
680 ((e, _), domElementRef) <- makeElement "input" (cfg ^. inputElementConfig_elementConfig) $ return ()
706 ((e, _), domElementRef) <- makeElement "input" (cfg ^. inputElementConfig_elementConfig) $ return ()
@@ -694,7 +720,7 @@ instance (SupportsHydrationDomBuilder t m) => DomBuilder t (HydrationDomBuilderT
694 let v0 = _inputElementConfig_initialValue cfg
720 let v0 = _inputElementConfig_initialValue cfg
695 impl :: (DomRenderHook t n, MonadJSM n) => n ()
721 impl :: (DomRenderHook t n, MonadJSM n) => n ()
696 impl = do
722 impl = do
697− domElement <- liftIO $ readIORef domElementRef
723+ domElement <- either pure (liftIO . readIORef) domElementRef
698 let domInputElement = uncheckedCastTo DOM.HTMLInputElement domElement
724 let domInputElement = uncheckedCastTo DOM.HTMLInputElement domElement
699 getValue = Input.getValue domInputElement
725 getValue = Input.getValue domInputElement
@@ -767,7 +793,7 @@ instance (SupportsHydrationDomBuilder t m) => DomBuilder t (HydrationDomBuilderT
767 , _inputElement_files = files
793 , _inputElement_files = files
770− {-# INLINABLE textAreaElement #-}
796+ {-# INLINE textAreaElement #-}
771 textAreaElement cfg = do
797 textAreaElement cfg = do
772 ((e, _), domElementRef) <- makeElement "textarea" (cfg ^. textAreaElementConfig_elementConfig) $ return ()
798 ((e, _), domElementRef) <- makeElement "textarea" (cfg ^. textAreaElementConfig_elementConfig) $ return ()
@@ -782,7 +808,7 @@ instance (SupportsHydrationDomBuilder t m) => DomBuilder t (HydrationDomBuilderT
782 let v0 = _textAreaElementConfig_initialValue cfg
808 let v0 = _textAreaElementConfig_initialValue cfg
783 impl :: (DomRenderHook t n, MonadJSM n) => n ()
809 impl :: (DomRenderHook t n, MonadJSM n) => n ()
784 impl = do
810 impl = do
785− domElement <- liftIO $ readIORef domElementRef
811+ domElement <- either pure (liftIO . readIORef) domElementRef
786 let domTextAreaElement = uncheckedCastTo DOM.HTMLTextAreaElement domElement
812 let domTextAreaElement = uncheckedCastTo DOM.HTMLTextAreaElement domElement
787 getValue = TextArea.getValue domTextAreaElement
813 getValue = TextArea.getValue domTextAreaElement
@@ -827,7 +853,7 @@ instance (SupportsHydrationDomBuilder t m) => DomBuilder t (HydrationDomBuilderT
827 , _textAreaElement_raw = ()
853 , _textAreaElement_raw = ()
830− {-# INLINABLE selectElement #-}
856+ {-# INLINE selectElement #-}
831 selectElement cfg child = do
857 selectElement cfg child = do
832 ((e, result), domElementRef) <- makeElement "select" (cfg ^. selectElementConfig_elementConfig) child
858 ((e, result), domElementRef) <- makeElement "select" (cfg ^. selectElementConfig_elementConfig) child
@@ -842,7 +868,7 @@ instance (SupportsHydrationDomBuilder t m) => DomBuilder t (HydrationDomBuilderT
842 let v0 = _selectElementConfig_initialValue cfg
868 let v0 = _selectElementConfig_initialValue cfg
843 impl :: (DomRenderHook t n, MonadJSM n) => n ()
869 impl :: (DomRenderHook t n, MonadJSM n) => n ()
844 impl = do
870 impl = do
845− domElement <- liftIO $ readIORef domElementRef
871+ domElement <- either pure (liftIO . readIORef) domElementRef
846 let domSelectElement = uncheckedCastTo DOM.HTMLSelectElement domElement
872 let domSelectElement = uncheckedCastTo DOM.HTMLSelectElement domElement
847 getValue = Select.getValue domSelectElement
873 getValue = Select.getValue domSelectElement
@@ -912,8 +938,7 @@ instance SupportsHydrationDomBuilder t m => MountableDomBuilder t (HydrationDomB
912 type DomFragment (HydrationDomBuilderT t m) = HydrationDomFragment
938 type DomFragment (HydrationDomBuilderT t m) = HydrationDomFragment
913 buildDomFragment w = do
939 buildDomFragment w = do
914 df <- createDocumentFragment =<< askDocument
940 df <- createDocumentFragment =<< askDocument
915− p <- liftIO $ newIORef $ toNode df
916− result <- localEnv (\env -> env { _hydrationDomBuilderEnv_parent = p }) w
941+ result <- localEnv (\env -> env { _hydrationDomBuilderEnv_parent = Left $ toNode df }) w
917 s <- liftIO $ newIORef FragmentState_Unmounted
942 s <- liftIO $ newIORef FragmentState_Unmounted
918 return (HydrationDomFragment df s, result)
943 return (HydrationDomFragment df s, result)
919 mountDomFragment fragment setFragment = do
944 mountDomFragment fragment setFragment = do
@@ -937,7 +962,7 @@ instance (Reflex t, Monad m, Adjustable t m, MonadHold t m, MonadFix m) => Adjus
937 traverseDMapWithKeyWithAdjustWithMove f m = DomRenderHookT . traverseDMapWithKeyWithAdjustWithMove (\k -> unDomRenderHookT . f k) m
962 traverseDMapWithKeyWithAdjustWithMove f m = DomRenderHookT . traverseDMapWithKeyWithAdjustWithMove (\k -> unDomRenderHookT . f k) m
939instance (Adjustable t m, MonadJSM m, MonadHold t m, MonadFix m, PrimMonad m) => Adjustable t (HydrationDomBuilderT t m) where
964instance (Adjustable t m, MonadJSM m, MonadHold t m, MonadFix m, PrimMonad m) => Adjustable t (HydrationDomBuilderT t m) where
940− {-# INLINABLE runWithReplace #-}
965+ {-# INLINE runWithReplace #-}
941 runWithReplace a0 a' = do
966 runWithReplace a0 a' = do
942 initialEnv <- HydrationDomBuilderT ask
967 initialEnv <- HydrationDomBuilderT ask
943 let hydrating = _hydrationDomBuilderEnv_hydrationMode initialEnv
968 let hydrating = _hydrationDomBuilderEnv_hydrationMode initialEnv
@@ -963,7 +988,6 @@ instance (Adjustable t m, MonadJSM m, MonadHold t m, MonadFix m, PrimMonad m) =>
963 p' <- case h of
988 p' <- case h of
964 HydrationMode_Hydrating -> pure parent
989 HydrationMode_Hydrating -> pure parent
965 HydrationMode_Immediate -> toNode <$> createDocumentFragment doc
990 HydrationMode_Immediate -> toNode <$> createDocumentFragment doc
966− p <- liftIO $ newIORef p'
967 unreadyChildren <- liftIO $ newIORef 0
991 unreadyChildren <- liftIO $ newIORef 0
968 let a0' = case h of
992 let a0' = case h of
969 HydrationMode_Hydrating -> a0
993 HydrationMode_Hydrating -> a0
@@ -971,22 +995,28 @@ instance (Adjustable t m, MonadJSM m, MonadHold t m, MonadFix m, PrimMonad m) =>
972 insertBefore p' =<< liftIO (readIORef after)
996 insertBefore p' =<< liftIO (readIORef after)
998+ delayed <- case h of
999+ HydrationMode_Hydrating -> liftIO $ newIORef $ pure ()
1000+ HydrationMode_Immediate -> pure $ _hydrationDomBuilderEnv_delayed initialEnv
974− (result, dom) <- flip runStateT (pure ()) $ runReaderT (unHydrationDomBuilderT a0') initialEnv
1001+ result <- runReaderT (unHydrationDomBuilderT a0') initialEnv
975 { _hydrationDomBuilderEnv_unreadyChildren = unreadyChildren
1002 { _hydrationDomBuilderEnv_unreadyChildren = unreadyChildren
976 , _hydrationDomBuilderEnv_commitAction = myCommitAction
1003 , _hydrationDomBuilderEnv_commitAction = myCommitAction
977− , _hydrationDomBuilderEnv_parent = p
1004+ , _hydrationDomBuilderEnv_parent = Left p'
1005+ , _hydrationDomBuilderEnv_delayed = delayed
1008+ HydrationMode_Hydrating -> liftIO $ readIORef delayed
1009+ HydrationMode_Immediate -> pure $ pure ()
979 liftIO $ readIORef unreadyChildren >>= \case
1010 liftIO $ readIORef unreadyChildren >>= \case
980 0 -> writeIORef haveEverBeenReady True
1011 0 -> writeIORef haveEverBeenReady True
981 _ -> modifyIORef' parentUnreadyChildren succ
1012 _ -> modifyIORef' parentUnreadyChildren succ
982 return (dom, result)
1013 return (dom, result)
983 a'' <- numberOccurrences a'
1014 a'' <- numberOccurrences a'
984− ((hydrate0, result0), child') <- HydrationDomBuilderT $ lift $ lift $ runWithReplace drawInitialChild $ ffor a'' $ \(cohortId, child) -> do
1015+ ((hydrate0, result0), child') <- HydrationDomBuilderT $ lift $ runWithReplace drawInitialChild $ ffor a'' $ \(cohortId, child) -> do
985 h <- liftIO $ readIORef hydrating
1016 h <- liftIO $ readIORef hydrating
986 p' <- case h of
1017 p' <- case h of
987 HydrationMode_Hydrating -> pure parent
1018 HydrationMode_Hydrating -> pure parent
988 HydrationMode_Immediate -> toNode <$> createDocumentFragment doc
1019 HydrationMode_Immediate -> toNode <$> createDocumentFragment doc
989− p <- liftIO $ newIORef p'
990 unreadyChildren <- liftIO $ newIORef 0
1020 unreadyChildren <- liftIO $ newIORef 0
991 let commitAction = do
1021 let commitAction = do
992 c <- liftIO $ readIORef currentCohort
1022 c <- liftIO $ readIORef currentCohort
@@ -997,13 +1027,20 @@ instance (Adjustable t m, MonadJSM m, MonadHold t m, MonadFix m, PrimMonad m) =>
997 insertBefore p' after'
1027 insertBefore p' after'
998 liftIO $ writeIORef currentCohort cohortId
1028 liftIO $ writeIORef currentCohort cohortId
999 myCommitAction
1029 myCommitAction
1030+ delayed <- case h of
1031+ HydrationMode_Hydrating -> liftIO $ newIORef $ pure ()
1032+ HydrationMode_Immediate -> pure $ _hydrationDomBuilderEnv_delayed initialEnv
1000− (result, dom) <- flip runStateT (pure ()) $ runReaderT (unHydrationDomBuilderT child) $ initialEnv
1033+ result <- runReaderT (unHydrationDomBuilderT child) $ initialEnv
1001 { _hydrationDomBuilderEnv_unreadyChildren = unreadyChildren
1034 { _hydrationDomBuilderEnv_unreadyChildren = unreadyChildren
1002 , _hydrationDomBuilderEnv_commitAction = case h of
1035 , _hydrationDomBuilderEnv_commitAction = case h of
1003 HydrationMode_Hydrating -> myCommitAction
1036 HydrationMode_Hydrating -> myCommitAction
1004 HydrationMode_Immediate -> commitAction
1037 HydrationMode_Immediate -> commitAction
1005− , _hydrationDomBuilderEnv_parent = p
1038+ , _hydrationDomBuilderEnv_parent = Left p'
1039+ , _hydrationDomBuilderEnv_delayed = delayed
1042+ HydrationMode_Hydrating -> liftIO $ readIORef delayed
1043+ HydrationMode_Immediate -> pure $ pure ()
1007 uc <- liftIO $ readIORef unreadyChildren
1044 uc <- liftIO $ readIORef unreadyChildren
1008 let commitActionToRunNow = if uc == 0
1045 let commitActionToRunNow = if uc == 0
1009 then Just $ commitAction
1046 then Just $ commitAction
@@ -1020,11 +1057,11 @@ instance (Adjustable t m, MonadJSM m, MonadHold t m, MonadFix m, PrimMonad m) =>
1020 requestDomAction_ $ fmapMaybe id commitAction
1057 requestDomAction_ $ fmapMaybe id commitAction
1021 return (result0, snd <$> child')
1058 return (result0, snd <$> child')
1023− {-# INLINABLE traverseIntMapWithKeyWithAdjust #-}
1060+ {-# INLINE traverseIntMapWithKeyWithAdjust #-}
1024 traverseIntMapWithKeyWithAdjust = traverseIntMapWithKeyWithAdjust'
1061 traverseIntMapWithKeyWithAdjust = traverseIntMapWithKeyWithAdjust'
1025− {-# INLINABLE traverseDMapWithKeyWithAdjust #-}
1062+ {-# INLINE traverseDMapWithKeyWithAdjust #-}
1026 traverseDMapWithKeyWithAdjust = traverseDMapWithKeyWithAdjust'
1063 traverseDMapWithKeyWithAdjust = traverseDMapWithKeyWithAdjust'
1027− {-# INLINABLE traverseDMapWithKeyWithAdjustWithMove #-}
1064+ {-# INLINE traverseDMapWithKeyWithAdjustWithMove #-}
1028 traverseDMapWithKeyWithAdjustWithMove = do
1065 traverseDMapWithKeyWithAdjustWithMove = do
1029 let updateChildUnreadiness (p :: PatchDMapWithMove k (Compose (TraverseChild t m (Some k)) v')) old = do
1066 let updateChildUnreadiness (p :: PatchDMapWithMove k (Compose (TraverseChild t m (Some k)) v')) old = do
1030 let new :: forall a. k a -> PatchDMapWithMove.NodeInfo k (Compose (TraverseChild t m (Some k)) v') a -> IO (PatchDMapWithMove.NodeInfo k (Constant (IORef (ChildReadyState (Some k)))) a)
1067 let new :: forall a. k a -> PatchDMapWithMove.NodeInfo k (Compose (TraverseChild t m (Some k)) v') a -> IO (PatchDMapWithMove.NodeInfo k (Constant (IORef (ChildReadyState (Some k)))) a)
@@ -1084,7 +1121,7 @@ instance (Adjustable t m, MonadJSM m, MonadHold t m, MonadFix m, PrimMonad m) =>
1084 mapM_ (\(k :=> v) -> void $ placeFragment k v) $ DMap.toDescList p -- We need to go in reverse order here, to make sure the placeholders are in the right spot at the right time
1121 mapM_ (\(k :=> v) -> void $ placeFragment k v) $ DMap.toDescList p -- We need to go in reverse order here, to make sure the placeholders are in the right spot at the right time
1085 liftIO $ writeIORef placeholders $! phsAfter
1122 liftIO $ writeIORef placeholders $! phsAfter
1087−{-# INLINABLE traverseDMapWithKeyWithAdjust' #-}
1124+{-# INLINE traverseDMapWithKeyWithAdjust' #-}
1088traverseDMapWithKeyWithAdjust'
1125traverseDMapWithKeyWithAdjust'
1089 :: forall t m (k :: * -> *) v v'. (Adjustable t m, MonadHold t m, MonadFix m, MonadJSM m, PrimMonad m, DMap.GCompare k)
1126 :: forall t m (k :: * -> *) v v'. (Adjustable t m, MonadHold t m, MonadFix m, MonadJSM m, PrimMonad m, DMap.GCompare k)
1090 => (forall a. k a -> v a -> HydrationDomBuilderT t m (v' a))
1127 => (forall a. k a -> v a -> HydrationDomBuilderT t m (v' a))
@@ -1130,7 +1167,7 @@ traverseDMapWithKeyWithAdjust' = do
1130 Just (Right immediate) -> Just $ Just $ _traverseChildImmediate_placeholder immediate
1167 Just (Right immediate) -> Just $ Just $ _traverseChildImmediate_placeholder immediate
1131 liftIO $ writeIORef placeholders $! fromMaybe phs $ apply filtered phs
1168 liftIO $ writeIORef placeholders $! fromMaybe phs $ apply filtered phs
1133−{-# INLINABLE traverseIntMapWithKeyWithAdjust' #-}
1170+{-# INLINE traverseIntMapWithKeyWithAdjust' #-}
1134traverseIntMapWithKeyWithAdjust'
1171traverseIntMapWithKeyWithAdjust'
1135 :: forall t m v v'. (Adjustable t m, MonadJSM m, MonadFix m, PrimMonad m, MonadHold t m)
1172 :: forall t m v v'. (Adjustable t m, MonadJSM m, MonadFix m, PrimMonad m, MonadHold t m)
1136 => (IntMap.Key -> v -> HydrationDomBuilderT t m v')
1173 => (IntMap.Key -> v -> HydrationDomBuilderT t m v')
@@ -1187,7 +1224,7 @@ insertAfterPreviousNode node = do
1187 Node.insertBefore_ parent node nextNode
1224 Node.insertBefore_ parent node nextNode
1188 setPreviousNode $ Just $ toNode node
1225 setPreviousNode $ Just $ toNode node
1190−{-# INLINABLE hoistTraverseWithKeyWithAdjust #-}
1227+{-# INLINE hoistTraverseWithKeyWithAdjust #-}
1191hoistTraverseWithKeyWithAdjust
1228hoistTraverseWithKeyWithAdjust
1193 ( Adjustable t m
1230 ( Adjustable t m
@@ -1257,7 +1294,7 @@ hoistTraverseWithKeyWithAdjust base mapPatch updateChildUnreadiness applyDomUpda
1257 when (DMap.null newUnready) $ do
1294 when (DMap.null newUnready) $ do
1258 applyDomUpdate p
1295 applyDomUpdate p
1259 (children0 :: DMap k (Compose (TraverseChild t m (Some k)) v'), children' :: Event t (p k (Compose (TraverseChild t m (Some k)) v')))
1296 (children0 :: DMap k (Compose (TraverseChild t m (Some k)) v'), children' :: Event t (p k (Compose (TraverseChild t m (Some k)) v')))
1260− <- HydrationDomBuilderT $ lift $ lift $ base (\k v -> drawChildUpdate initialEnv markChildReady $ f k v) dm0 dm'
1297+ <- HydrationDomBuilderT $ lift $ base (\k v -> drawChildUpdate initialEnv markChildReady $ f k v) dm0 dm'
1261 let processChild k (Compose (TraverseChild e _)) = case e of
1298 let processChild k (Compose (TraverseChild e _)) = case e of
1262 Left _ -> pure $ ComposeMaybe Nothing
1299 Left _ -> pure $ ComposeMaybe Nothing
1263 Right immediate -> ComposeMaybe <$> do
1300 Right immediate -> ComposeMaybe <$> do
@@ -1296,7 +1333,7 @@ hoistTraverseWithKeyWithAdjust base mapPatch updateChildUnreadiness applyDomUpda
1296 result' = ffor children' $ mapPatch $ _traverseChild_result . getCompose
1333 result' = ffor children' $ mapPatch $ _traverseChild_result . getCompose
1297 return (result0, result')
1334 return (result0, result')
1299−{-# INLINABLE hoistTraverseIntMapWithKeyWithAdjust #-}
1336+{-# INLINE hoistTraverseIntMapWithKeyWithAdjust #-}
1300hoistTraverseIntMapWithKeyWithAdjust ::
1337hoistTraverseIntMapWithKeyWithAdjust ::
1301 ( Adjustable t m
1338 ( Adjustable t m
1302 , MonadHold t m
1339 , MonadHold t m
@@ -1365,7 +1402,7 @@ hoistTraverseIntMapWithKeyWithAdjust base updateChildUnreadiness applyDomUpdate_
1365 when (IntMap.null newUnready) $ do
1402 when (IntMap.null newUnready) $ do
1366 applyDomUpdate p
1403 applyDomUpdate p
1367 (children0 :: IntMap (TraverseChild t m Int v'), children' :: Event t (p (TraverseChild t m Int v')))
1404 (children0 :: IntMap (TraverseChild t m Int v'), children' :: Event t (p (TraverseChild t m Int v')))
1368− <- HydrationDomBuilderT $ lift $ lift $ base (\k v -> drawChildUpdateInt initialEnv markChildReady $ f k v) dm0 dm'
1405+ <- HydrationDomBuilderT $ lift $ base (\k v -> drawChildUpdateInt initialEnv markChildReady $ f k v) dm0 dm'
1369 let processChild k (TraverseChild e _) = case e of
1406 let processChild k (TraverseChild e _) = case e of
1370 Left _ -> pure Nothing
1407 Left _ -> pure Nothing
1371 Right immediate -> do
1408 Right immediate -> do
@@ -1405,11 +1442,11 @@ hoistTraverseIntMapWithKeyWithAdjust base updateChildUnreadiness applyDomUpdate_
1405 return (result0, result')
1442 return (result0, result')
1407data TraverseChildImmediate k = TraverseChildImmediate
1444data TraverseChildImmediate k = TraverseChildImmediate
1408− { _traverseChildImmediate_fragment :: DOM.DocumentFragment
1445+ { _traverseChildImmediate_fragment :: {-# UNPACK #-} !DOM.DocumentFragment
1409 -- ^ Child is appended to this fragment
1446 -- ^ Child is appended to this fragment
1410− , _traverseChildImmediate_placeholder :: DOM.Text
1447+ , _traverseChildImmediate_placeholder :: {-# UNPACK #-} !DOM.Text
1411 -- ^ Placeholder reference
1448 -- ^ Placeholder reference
1412− , _traverseChildImmediate_childReadyState :: IORef (ChildReadyState k)
1449+ , _traverseChildImmediate_childReadyState :: {-# UNPACK #-} !(IORef (ChildReadyState k))
1415newtype TraverseChildHydration t m = TraverseChildHydration
1452newtype TraverseChildHydration t m = TraverseChildHydration
@@ -1418,13 +1455,13 @@ newtype TraverseChildHydration t m = TraverseChildHydration
1420data TraverseChild t m k a = TraverseChild
1457data TraverseChild t m k a = TraverseChild
1421− { _traverseChild_mode :: Either (TraverseChildHydration t m) (TraverseChildImmediate k)
1458+ { _traverseChild_mode :: !(Either (TraverseChildHydration t m) (TraverseChildImmediate k))
1422− , _traverseChild_result :: a
1459+ , _traverseChild_result :: !a
1423 } deriving Functor
1460 } deriving Functor
1425−{-# INLINABLE drawChildUpdate #-}
1462+{-# INLINE drawChildUpdate #-}
1426−drawChildUpdate :: (MonadIO m, MonadJSM m, Reflex t)
1463+drawChildUpdate :: (MonadJSM m, Reflex t)
1427− => HydrationDomBuilderEnv t
1464+ => HydrationDomBuilderEnv t m
1428 -> (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
1465 -> (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
1429 -> HydrationDomBuilderT t m (f a)
1466 -> HydrationDomBuilderT t m (f a)
1430 -> DomRenderHookT t m (Compose (TraverseChild t m k) f a)
1467 -> DomRenderHookT t m (Compose (TraverseChild t m k) f a)
@@ -1433,9 +1470,12 @@ drawChildUpdate initialEnv markReady child = do
1433 unreadyChildren <- liftIO $ newIORef 0
1470 unreadyChildren <- liftIO $ newIORef 0
1434 liftIO (readIORef $ _hydrationDomBuilderEnv_hydrationMode initialEnv) >>= \case
1471 liftIO (readIORef $ _hydrationDomBuilderEnv_hydrationMode initialEnv) >>= \case
1435 HydrationMode_Hydrating -> do
1472 HydrationMode_Hydrating -> do
1473+ childDelayedRef <- liftIO $ newIORef $ pure ()
1436− (result, childDelayed) <- flip runStateT (pure ()) $ runReaderT (unHydrationDomBuilderT child) initialEnv
1474+ result <- runReaderT (unHydrationDomBuilderT child) initialEnv
1437 { _hydrationDomBuilderEnv_unreadyChildren = unreadyChildren
1475 { _hydrationDomBuilderEnv_unreadyChildren = unreadyChildren
1476+ , _hydrationDomBuilderEnv_delayed = childDelayedRef
1478+ childDelayed <- liftIO $ readIORef childDelayedRef
1439 return $ Compose $ TraverseChild
1479 return $ Compose $ TraverseChild
1440 { _traverseChild_result = result
1480 { _traverseChild_result = result
1441 , _traverseChild_mode = Left TraverseChildHydration
1481 , _traverseChild_mode = Left TraverseChildHydration
@@ -1451,9 +1491,8 @@ drawChildUpdate initialEnv markReady child = do
1451 df <- createDocumentFragment doc
1491 df <- createDocumentFragment doc
1452 placeholder <- createTextNode doc ("" :: Text)
1492 placeholder <- createTextNode doc ("" :: Text)
1453 Node.appendChild_ df placeholder
1493 Node.appendChild_ df placeholder
1454− parentRef <- liftIO . newIORef $ toNode df
1455− (result, _s) <- flip runStateT (pure ()) $ runReaderT (unHydrationDomBuilderT child) initialEnv
1494+ result <- runReaderT (unHydrationDomBuilderT child) initialEnv
1456− { _hydrationDomBuilderEnv_parent = parentRef
1495+ { _hydrationDomBuilderEnv_parent = Left $ toNode df
1457 , _hydrationDomBuilderEnv_unreadyChildren = unreadyChildren
1496 , _hydrationDomBuilderEnv_unreadyChildren = unreadyChildren
1458 , _hydrationDomBuilderEnv_commitAction = markReady childReadyState
1497 , _hydrationDomBuilderEnv_commitAction = markReady childReadyState
@@ -1468,8 +1507,9 @@ drawChildUpdate initialEnv markReady child = do
1510+{-# INLINE drawChildUpdateInt #-}
1471drawChildUpdateInt :: (MonadIO m, MonadJSM m, Reflex t)
1511drawChildUpdateInt :: (MonadIO m, MonadJSM m, Reflex t)
1472− => HydrationDomBuilderEnv t
1512+ => HydrationDomBuilderEnv t m
1473 -> (IORef (ChildReadyState k) -> JSM ())
1513 -> (IORef (ChildReadyState k) -> JSM ())
1474 -> HydrationDomBuilderT t m v
1514 -> HydrationDomBuilderT t m v
1475 -> DomRenderHookT t m (TraverseChild t m k v)
1515 -> DomRenderHookT t m (TraverseChild t m k v)
@@ -1477,35 +1517,35 @@ drawChildUpdateInt env mark m = fmap runIdentity . getCompose <$> drawChildUpdat
1478instance PerformEvent t m => PerformEvent t (HydrationDomBuilderT t m) where
1518instance PerformEvent t m => PerformEvent t (HydrationDomBuilderT t m) where
1479 type Performable (HydrationDomBuilderT t m) = Performable m
1519 type Performable (HydrationDomBuilderT t m) = Performable m
1480− {-# INLINABLE performEvent_ #-}
1520+ {-# INLINE performEvent_ #-}
1481 performEvent_ e = lift $ performEvent_ e
1521 performEvent_ e = lift $ performEvent_ e
1482− {-# INLINABLE performEvent #-}
1522+ {-# INLINE performEvent #-}
1483 performEvent e = lift $ performEvent e
1523 performEvent e = lift $ performEvent e
1485instance PostBuild t m => PostBuild t (HydrationDomBuilderT t m) where
1525instance PostBuild t m => PostBuild t (HydrationDomBuilderT t m) where
1486− {-# INLINABLE getPostBuild #-}
1526+ {-# INLINE getPostBuild #-}
1487 getPostBuild = lift getPostBuild
1527 getPostBuild = lift getPostBuild
1489instance MonadReflexCreateTrigger t m => MonadReflexCreateTrigger t (HydrationDomBuilderT t m) where
1529instance MonadReflexCreateTrigger t m => MonadReflexCreateTrigger t (HydrationDomBuilderT t m) where
1490− {-# INLINABLE newEventWithTrigger #-}
1530+ {-# INLINE newEventWithTrigger #-}
1491 newEventWithTrigger = lift . newEventWithTrigger
1531 newEventWithTrigger = lift . newEventWithTrigger
1492− {-# INLINABLE newFanEventWithTrigger #-}
1532+ {-# INLINE newFanEventWithTrigger #-}
1493 newFanEventWithTrigger f = lift $ newFanEventWithTrigger f
1533 newFanEventWithTrigger f = lift $ newFanEventWithTrigger f
1495instance (Monad m, MonadRef m, Ref m ~ Ref IO, MonadReflexCreateTrigger t m) => TriggerEvent t (HydrationDomBuilderT t m) where
1535instance (Monad m, MonadRef m, Ref m ~ Ref IO, MonadReflexCreateTrigger t m) => TriggerEvent t (HydrationDomBuilderT t m) where
1496− {-# INLINABLE newTriggerEvent #-}
1536+ {-# INLINE newTriggerEvent #-}
1497− newTriggerEvent = HydrationDomBuilderT . lift . lift $ newTriggerEvent
1537+ newTriggerEvent = HydrationDomBuilderT . lift $ newTriggerEvent
1498− {-# INLINABLE newTriggerEventWithOnComplete #-}
1538+ {-# INLINE newTriggerEventWithOnComplete #-}
1499− newTriggerEventWithOnComplete = HydrationDomBuilderT . lift . lift $ newTriggerEventWithOnComplete
1539+ newTriggerEventWithOnComplete = HydrationDomBuilderT . lift $ newTriggerEventWithOnComplete
1500− {-# INLINABLE newEventWithLazyTriggerWithOnComplete #-}
1540+ {-# INLINE newEventWithLazyTriggerWithOnComplete #-}
1501− newEventWithLazyTriggerWithOnComplete f = HydrationDomBuilderT . lift . lift $ newEventWithLazyTriggerWithOnComplete f
1541+ newEventWithLazyTriggerWithOnComplete f = HydrationDomBuilderT . lift $ newEventWithLazyTriggerWithOnComplete f
1503instance (Monad m, MonadRef m, Ref m ~ Ref IO, MonadReflexCreateTrigger t m) => TriggerEvent t (DomRenderHookT t m) where
1543instance (Monad m, MonadRef m, Ref m ~ Ref IO, MonadReflexCreateTrigger t m) => TriggerEvent t (DomRenderHookT t m) where
1504− {-# INLINABLE newTriggerEvent #-}
1544+ {-# INLINE newTriggerEvent #-}
1505 newTriggerEvent = DomRenderHookT . lift $ newTriggerEvent
1545 newTriggerEvent = DomRenderHookT . lift $ newTriggerEvent
1506− {-# INLINABLE newTriggerEventWithOnComplete #-}
1546+ {-# INLINE newTriggerEventWithOnComplete #-}
1507 newTriggerEventWithOnComplete = DomRenderHookT . lift $ newTriggerEventWithOnComplete
1547 newTriggerEventWithOnComplete = DomRenderHookT . lift $ newTriggerEventWithOnComplete
1508− {-# INLINABLE newEventWithLazyTriggerWithOnComplete #-}
1548+ {-# INLINE newEventWithLazyTriggerWithOnComplete #-}
1509 newEventWithLazyTriggerWithOnComplete f = DomRenderHookT . lift $ newEventWithLazyTriggerWithOnComplete f
1549 newEventWithLazyTriggerWithOnComplete f = DomRenderHookT . lift $ newEventWithLazyTriggerWithOnComplete f
1511instance HasJSContext m => HasJSContext (HydrationDomBuilderT t m) where
1551instance HasJSContext m => HasJSContext (HydrationDomBuilderT t m) where
@@ -1514,15 +1554,15 @@ instance HasJSContext m => HasJSContext (HydrationDomBuilderT t m) where
1515instance MonadRef m => MonadRef (HydrationDomBuilderT t m) where
1555instance MonadRef m => MonadRef (HydrationDomBuilderT t m) where
1516 type Ref (HydrationDomBuilderT t m) = Ref m
1556 type Ref (HydrationDomBuilderT t m) = Ref m
1517− {-# INLINABLE newRef #-}
1557+ {-# INLINE newRef #-}
1518 newRef = lift . newRef
1558 newRef = lift . newRef
1519− {-# INLINABLE readRef #-}
1559+ {-# INLINE readRef #-}
1520 readRef = lift . readRef
1560 readRef = lift . readRef
1521− {-# INLINABLE writeRef #-}
1561+ {-# INLINE writeRef #-}
1522 writeRef r = lift . writeRef r
1562 writeRef r = lift . writeRef r
1524instance MonadAtomicRef m => MonadAtomicRef (HydrationDomBuilderT t m) where
1564instance MonadAtomicRef m => MonadAtomicRef (HydrationDomBuilderT t m) where
1525− {-# INLINABLE atomicModifyRef #-}
1565+ {-# INLINE atomicModifyRef #-}
1526 atomicModifyRef r = lift . atomicModifyRef r
1566 atomicModifyRef r = lift . atomicModifyRef r
1528instance (HasJS x m, ReflexHost t) => HasJS x (HydrationDomBuilderT t m) where
1568instance (HasJS x m, ReflexHost t) => HasJS x (HydrationDomBuilderT t m) where
@@ -1530,18 +1570,18 @@ instance (HasJS x m, ReflexHost t) => HasJS x (HydrationDomBuilderT t m) where
1530 liftJS = lift . liftJS
1570 liftJS = lift . liftJS
1532instance MonadSample t m => MonadSample t (HydrationDomBuilderT t m) where
1572instance MonadSample t m => MonadSample t (HydrationDomBuilderT t m) where
1533− {-# INLINABLE sample #-}
1573+ {-# INLINE sample #-}
1534 sample = lift . sample
1574 sample = lift . sample
1536instance MonadHold t m => MonadHold t (HydrationDomBuilderT t m) where
1576instance MonadHold t m => MonadHold t (HydrationDomBuilderT t m) where
1537− {-# INLINABLE hold #-}
1577+ {-# INLINE hold #-}
1538 hold v0 v' = lift $ hold v0 v'
1578 hold v0 v' = lift $ hold v0 v'
1539− {-# INLINABLE holdDyn #-}
1579+ {-# INLINE holdDyn #-}
1540 holdDyn v0 v' = lift $ holdDyn v0 v'
1580 holdDyn v0 v' = lift $ holdDyn v0 v'
1541− {-# INLINABLE holdIncremental #-}
1581+ {-# INLINE holdIncremental #-}
1542 holdIncremental v0 v' = lift $ holdIncremental v0 v'
1582 holdIncremental v0 v' = lift $ holdIncremental v0 v'
1543− {-# INLINABLE buildDynamic #-}
1583+ {-# INLINE buildDynamic #-}
1544 buildDynamic a0 = lift . buildDynamic a0
1584 buildDynamic a0 = lift . buildDynamic a0
1545− {-# INLINABLE headE #-}
1585+ {-# INLINE headE #-}
1546 headE = lift . headE
1586 headE = lift . headE