on develop help sign in
Faster HydrationDomBuilderT
32f4b45Tom Smalley
reflex-dom-core/src/Reflex/Dom/Builder/Hydration.hs+166−126
@@ -55,18 +55,25 @@ module Reflex.Dom.Builder.Hydration
55 , hydrateNode
55 , hydrateNode
56 , getPreviousNode, setPreviousNode
56 , getPreviousNode, setPreviousNode
57 , runHydrationDomBuilderT
57 , runHydrationDomBuilderT
58− , askParent
59 , askEvents
58 , askEvents
60− , append
61− , textNodeInternal
62 , SupportsHydrationDomBuilder
59 , SupportsHydrationDomBuilder
63− , wrap
60+ -- Exported for specialization
61+ , HydrationDomSpace
64 , makeElement
62 , makeElement
65 , drawChildUpdate
63 , drawChildUpdate
66− -- * Internal
64+ , drawChildUpdateInt
67− , traverseDMapWithKeyWithAdjust'
65+ , ChildReadyState
68− , hoistTraverseWithKeyWithAdjust
66+ , DomRenderHookT
67+ , TraverseChild
68+ , append
69+ , wrap
70+ , triggerBody
71+ , WrapArg
72+ , EventTrigger
69 , traverseIntMapWithKeyWithAdjust'
73 , traverseIntMapWithKeyWithAdjust'
74+ , hoistTraverseIntMapWithKeyWithAdjust
75+ , makeNodeInternal
76+ , runDomRenderHookT
70 ) where
77 ) where
71
78
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 (..))
144
151
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'
147
155
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'
150
159
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'
153#endif
163#endif
154
164
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 ()))
168 }
179 }
169
180
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
176#endif
187#endif
177 )
188 )
178
189
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)
181
193
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)
186
199
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
192
205
193instance MonadTrans (HydrationRunnerT t) where
206instance MonadTrans (HydrationRunnerT t) where
207+ {-# INLINE lift #-}
194 lift = HydrationRunnerT . lift . lift . lift
208 lift = HydrationRunnerT . lift . lift . lift
195
209
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
198
213
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
207− --s <- lift setup
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)
210
225
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)
214
232
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
230
248
231instance MonadTrans (HydrationDomBuilderT t) where
249instance MonadTrans (HydrationDomBuilderT t) where
250+ {-# INLINE lift #-}
232− lift = HydrationDomBuilderT . lift . lift . lift
251+ lift = HydrationDomBuilderT . lift . lift
233
252
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
239#endif
258#endif
240 )
259 )
241
260
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
258
277
259instance MonadTrans (DomRenderHookT t) where
278instance MonadTrans (DomRenderHookT t) where
279+ {-# INLINE lift #-}
260 lift = DomRenderHookT . lift . lift
280 lift = DomRenderHookT . lift . lift
261
281
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_
269
289
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_
274
294
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_
279
299
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
289 )
309 )
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)
295
315
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
299
319
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
303
323
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)
315
335
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
319
339
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
323
343
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
327
347
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)
331
351
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
335
355
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
339
359
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)
343
363
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
347
367
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
355 return n
375 return n
356
376
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))
379
399
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 #-}
382wrap
402wrap
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
406
426
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
436
456
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)
440 => Text
460 => Text
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
448
468
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 ()
497+ let env' = env
478− let env' = env { _hydrationDomBuilderEnv_parent = parent }
498+ { _hydrationDomBuilderEnv_parent = Right parent
499+ , _hydrationDomBuilderEnv_delayed = childDelayedRef
500+ }
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
491
514
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
511
534
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')
514
537
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
558
581
559
582
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
572
595
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)
577 => Text
601 => Text
@@ -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)
617
641
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 "")
620
645
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
623
649
@@ -664,18 +690,18 @@ instance DomSpace HydrationDomSpace where
664
690
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 ()
681
707
@@ -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
700
726
@@ -767,7 +793,7 @@ instance (SupportsHydrationDomBuilder t m) => DomBuilder t (HydrationDomBuilderT
767 , _inputElement_files = files
793 , _inputElement_files = files
768 }
794 }
769
795
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 ()
773
799
@@ -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
788
814
@@ -827,7 +853,7 @@ instance (SupportsHydrationDomBuilder t m) => DomBuilder t (HydrationDomBuilderT
827 , _textAreaElement_raw = ()
853 , _textAreaElement_raw = ()
828 }
854 }
829
855
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
833
859
@@ -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
848
874
@@ -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
938
963
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) =>
971 a <- a0
995 a <- a0
972 insertBefore p' =<< liftIO (readIORef after)
996 insertBefore p' =<< liftIO (readIORef after)
973 pure a
997 pure a
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
978 }
1006 }
1007+ dom <- case h of
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
1006 }
1040 }
1041+ dom <- case h of
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')
1022
1059
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
1086
1123
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
1132
1169
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
1189
1226
1190−{-# INLINABLE hoistTraverseWithKeyWithAdjust #-}
1227+{-# INLINE hoistTraverseWithKeyWithAdjust #-}
1191hoistTraverseWithKeyWithAdjust
1228hoistTraverseWithKeyWithAdjust
1192 ::
1229 ::
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')
1298
1335
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')
1406
1443
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))
1413 }
1450 }
1414
1451
1415newtype TraverseChildHydration t m = TraverseChildHydration
1452newtype TraverseChildHydration t m = TraverseChildHydration
@@ -1418,13 +1455,13 @@ newtype TraverseChildHydration t m = TraverseChildHydration
1418 }
1455 }
1419
1456
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
1424
1461
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
1438 }
1477 }
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
1459 }
1498 }
@@ -1468,8 +1507,9 @@ drawChildUpdate initialEnv markReady child = do
1468 }
1507 }
1469 }
1508 }
1470
1509
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
1477
1517
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
1484
1524
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
1488
1528
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
1494
1534
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
1502
1542
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
1510
1550
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
1514
1554
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
1523
1563
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
1527
1567
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
1531
1571
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
1535
1575
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
1547
1587
reflex-dom-core/src/Reflex/Dom/Core.hs+1−1
@@ -2,7 +2,7 @@ module Reflex.Dom.Core (module X) where
2
2
3import Reflex as X hiding (askEvents)
3import Reflex as X hiding (askEvents)
4import Reflex.Dom.Builder.Class as X
4import Reflex.Dom.Builder.Class as X
5−import Reflex.Dom.Builder.Hydration as X hiding (askParent, askEvents, append, textNodeInternal, wrap, makeElement, drawChildUpdate, traverseDMapWithKeyWithAdjust', hoistTraverseWithKeyWithAdjust, traverseIntMapWithKeyWithAdjust')
5+import Reflex.Dom.Builder.Hydration as X hiding (askEvents, makeElement, ChildReadyState, drawChildUpdate, append, wrap, traverseIntMapWithKeyWithAdjust', hoistTraverseIntMapWithKeyWithAdjust)
6import Reflex.Dom.Builder.Immediate as X
6import Reflex.Dom.Builder.Immediate as X
7import Reflex.Dom.Builder.InputDisabled as X
7import Reflex.Dom.Builder.InputDisabled as X
8import Reflex.Dom.Builder.Static as X
8import Reflex.Dom.Builder.Static as X
reflex-dom-core/src/Reflex/Dom/Main.hs+25−35
@@ -85,13 +85,13 @@ attachHydrationWidget
85 -> IORef HydrationMode
85 -> IORef HydrationMode
86 -> IORef [(Node, HydrationRunnerT DomTimeline (PostBuildT DomTimeline (WithJSContextSingleton () (PerformEventT DomTimeline DomHost))) ())]
86 -> IORef [(Node, HydrationRunnerT DomTimeline (PostBuildT DomTimeline (WithJSContextSingleton () (PerformEventT DomTimeline DomHost))) ())]
87 -> JSContextSingleton ()
87 -> JSContextSingleton ()
88− -> (EventChannel -> Event DomTimeline () -> PerformEventT DomTimeline DomHost (IORef (Maybe (EventTrigger DomTimeline ()))))
88+ -> (EventChannel -> Event DomTimeline () -> PerformEventT DomTimeline DomHost (a, IORef (Maybe (EventTrigger DomTimeline ()))))
89− -> IO ()
89+ -> IO (a, FireCommand DomTimeline DomHost)
90attachHydrationWidget switchoverAction hydrationMode rootNodesRef jsSing w = do
90attachHydrationWidget switchoverAction hydrationMode rootNodesRef jsSing w = do
91 events <- newChan
91 events <- newChan
92 runDomHost $ flip runTriggerEventT events $ mdo
92 runDomHost $ flip runTriggerEventT events $ mdo
93 (syncEvent, fireSync) <- newTriggerEvent
93 (syncEvent, fireSync) <- newTriggerEvent
94− (postBuildTriggerRef, fc@(FireCommand fire)) <- lift $ hostPerformEventT $ do
94+ ((result, postBuildTriggerRef), fc@(FireCommand fire)) <- lift $ hostPerformEventT $ do
95 a <- w events syncEvent
95 a <- w events syncEvent
96 _ <- runWithReplace (return ()) $ delayedAction <$ syncEvent
96 _ <- runWithReplace (return ()) $ delayedAction <$ syncEvent
97 pure a
97 pure a
@@ -99,13 +99,12 @@ attachHydrationWidget switchoverAction hydrationMode rootNodesRef jsSing w = do
99 lift $ forM_ mPostBuildTrigger $ \postBuildTrigger -> fire [postBuildTrigger :=> Identity ()] $ return ()
99 lift $ forM_ mPostBuildTrigger $ \postBuildTrigger -> fire [postBuildTrigger :=> Identity ()] $ return ()
100 liftIO $ fireSync ()
100 liftIO $ fireSync ()
101 rootNodes <- liftIO $ readIORef rootNodesRef
101 rootNodes <- liftIO $ readIORef rootNodesRef
102− -- TODO: DomHost is SpiderHost Global only if we're not in profiling mode
103 let delayedAction = do
102 let delayedAction = do
104 for_ (reverse rootNodes) $ \(rootNode, runner) -> do
103 for_ (reverse rootNodes) $ \(rootNode, runner) -> do
105 void $ runWithJSContextSingleton (runPostBuildT (runHydrationRunnerT runner Nothing rootNode events) never) jsSing
104 void $ runWithJSContextSingleton (runPostBuildT (runHydrationRunnerT runner Nothing rootNode events) never) jsSing
106 liftIO $ writeIORef hydrationMode HydrationMode_Immediate
105 liftIO $ writeIORef hydrationMode HydrationMode_Immediate
107 liftIO $ switchoverAction
106 liftIO $ switchoverAction
108− liftIO $ processAsyncEvents events fc
107+ pure (result, fc)
109
108
110type HydrationWidget x a = HydrationDomBuilderT DomTimeline (DomCoreWidget x) a
109type HydrationWidget x a = HydrationDomBuilderT DomTimeline (DomCoreWidget x) a
111
110
@@ -114,6 +113,7 @@ type FloatingWidget x = TriggerEventT DomTimeline (DomCoreWidget x)
114
113
115type DomCoreWidget x = PostBuildT DomTimeline (WithJSContextSingleton x (PerformEventT DomTimeline DomHost))
114type DomCoreWidget x = PostBuildT DomTimeline (WithJSContextSingleton x (PerformEventT DomTimeline DomHost))
116
115
116+{-# INLINABLE runHydrationWidgetWithHeadAndBody #-}
117runHydrationWidgetWithHeadAndBody
117runHydrationWidgetWithHeadAndBody
118 :: IO ()
118 :: IO ()
119 -> ( (forall c. HydrationWidget () c -> FloatingWidget () c) -- "Append to head"
119 -> ( (forall c. HydrationWidget () c -> FloatingWidget () c) -- "Append to head"
@@ -128,81 +128,71 @@ runHydrationWidgetWithHeadAndBody switchoverAction app = withJSContextSingletonM
128 unreadyChildren <- liftIO $ newIORef 0
128 unreadyChildren <- liftIO $ newIORef 0
129 hydrationMode <- liftIO $ newIORef HydrationMode_Hydrating
129 hydrationMode <- liftIO $ newIORef HydrationMode_Hydrating
130 hydrationResult <- liftIO $ newIORef []
130 hydrationResult <- liftIO $ newIORef []
131− liftIO $ attachHydrationWidget switchoverAction hydrationMode hydrationResult jsSing $ \events switchover -> flip runWithJSContextSingleton jsSing $ do
131+ (events, fc) <- liftIO . attachHydrationWidget switchoverAction hydrationMode hydrationResult jsSing $ \events switchover -> do
132 (postBuild, postBuildTriggerRef) <- newEventWithTriggerRef
132 (postBuild, postBuildTriggerRef) <- newEventWithTriggerRef
133 let hydrateDom :: DOM.Node -> HydrationWidget () c -> FloatingWidget () c
133 let hydrateDom :: DOM.Node -> HydrationWidget () c -> FloatingWidget () c
134 hydrateDom n w = do
134 hydrateDom n w = do
135 events' <- TriggerEvent.askEvents
135 events' <- TriggerEvent.askEvents
136− parent <- liftIO $ newIORef $ toNode n
136+ delayed <- liftIO $ newIORef $ pure ()
137 lift $ do
137 lift $ do
138 let builderEnv = HydrationDomBuilderEnv
138 let builderEnv = HydrationDomBuilderEnv
139 { _hydrationDomBuilderEnv_document = globalDoc
139 { _hydrationDomBuilderEnv_document = globalDoc
140− , _hydrationDomBuilderEnv_parent = parent
140+ , _hydrationDomBuilderEnv_parent = Left $ toNode n
141 , _hydrationDomBuilderEnv_unreadyChildren = unreadyChildren
141 , _hydrationDomBuilderEnv_unreadyChildren = unreadyChildren
142 , _hydrationDomBuilderEnv_commitAction = pure ()
142 , _hydrationDomBuilderEnv_commitAction = pure ()
143 , _hydrationDomBuilderEnv_hydrationMode = hydrationMode
143 , _hydrationDomBuilderEnv_hydrationMode = hydrationMode
144 , _hydrationDomBuilderEnv_switchover = switchover
144 , _hydrationDomBuilderEnv_switchover = switchover
145+ , _hydrationDomBuilderEnv_delayed = delayed
145 }
146 }
146− (a, res) <- runHydrationDomBuilderT w builderEnv events'
147+ a <- runHydrationDomBuilderT w builderEnv events'
148+ res <- liftIO $ readIORef delayed
147 liftIO $ modifyIORef' hydrationResult ((n, res) :)
149 liftIO $ modifyIORef' hydrationResult ((n, res) :)
148 pure a
150 pure a
149− flip runPostBuildT postBuild $ flip runTriggerEventT events $ app (hydrateDom $ toNode headElement) (hydrateDom $ toNode bodyElement)
151+ runWithJSContextSingleton (runPostBuildT (runTriggerEventT (app (hydrateDom $ toNode headElement) (hydrateDom $ toNode bodyElement)) events) postBuild) jsSing
150− return postBuildTriggerRef
152+ return (events, postBuildTriggerRef)
153+ liftIO $ processAsyncEvents events fc
151
154
152{-# INLINABLE mainHydrationWidgetWithHeadImmediate #-}
155{-# INLINABLE mainHydrationWidgetWithHeadImmediate #-}
153-- | Warning: `mainHydrationWidgetWithHeadImmediate` is provided only as performance tweak. It is expected to disappear in future releases.
156-- | Warning: `mainHydrationWidgetWithHeadImmediate` is provided only as performance tweak. It is expected to disappear in future releases.
154mainHydrationWidgetWithHeadImmediate :: HydrationWidget () () -> HydrationWidget () () -> JSM ()
157mainHydrationWidgetWithHeadImmediate :: HydrationWidget () () -> HydrationWidget () () -> JSM ()
155mainHydrationWidgetWithHeadImmediate head' body = do
158mainHydrationWidgetWithHeadImmediate head' body = do
156− runHydrationWidgetWithHeadAndBodyImmediate (pure ()) $ \appendHead appendBody -> do
159+ runHydrationWidgetWithHeadAndBodyImmediate $ \appendHead appendBody -> do
157 appendHead head'
160 appendHead head'
158 appendBody body
161 appendBody body
159
162
160−{-# INLINABLE attachHydrationWidgetImmediate #-}
161−attachHydrationWidgetImmediate
162− :: JSContextSingleton ()
163− -> (EventChannel -> PerformEventT DomTimeline DomHost (IORef (Maybe (EventTrigger DomTimeline ()))))
164− -> IO ()
165−attachHydrationWidgetImmediate jsSing w = do
166− events <- newChan
167− runDomHost $ flip runTriggerEventT events $ mdo
168− (postBuildTriggerRef, fc@(FireCommand fire)) <- lift $ hostPerformEventT $ w events
169− mPostBuildTrigger <- readRef postBuildTriggerRef
170− lift $ forM_ mPostBuildTrigger $ \postBuildTrigger -> fire [postBuildTrigger :=> Identity ()] $ return ()
171− liftIO $ processAsyncEvents events fc
172−
173{-# INLINABLE runHydrationWidgetWithHeadAndBodyImmediate #-}
163{-# INLINABLE runHydrationWidgetWithHeadAndBodyImmediate #-}
174runHydrationWidgetWithHeadAndBodyImmediate
164runHydrationWidgetWithHeadAndBodyImmediate
175− :: IO ()
176− -> ( (forall c. HydrationWidget () c -> FloatingWidget () c) -- "Append to head"
165+ :: ( (forall c. HydrationWidget () c -> FloatingWidget () c) -- "Append to head"
177 -> (forall c. HydrationWidget () c -> FloatingWidget () c) -- "Append to body"
166 -> (forall c. HydrationWidget () c -> FloatingWidget () c) -- "Append to body"
178 -> FloatingWidget () ()
167 -> FloatingWidget () ()
179 )
168 )
180 -> JSM ()
169 -> JSM ()
181−runHydrationWidgetWithHeadAndBodyImmediate switchoverAction app = withJSContextSingletonMono $ \jsSing -> do
170+runHydrationWidgetWithHeadAndBodyImmediate app = withJSContextSingletonMono $ \jsSing -> do
182 globalDoc <- currentDocumentUnchecked
171 globalDoc <- currentDocumentUnchecked
183 headElement <- getHeadUnchecked globalDoc
172 headElement <- getHeadUnchecked globalDoc
184 bodyElement <- getBodyUnchecked globalDoc
173 bodyElement <- getBodyUnchecked globalDoc
185 unreadyChildren <- liftIO $ newIORef 0
174 unreadyChildren <- liftIO $ newIORef 0
186 hydrationMode <- liftIO $ newIORef HydrationMode_Immediate
175 hydrationMode <- liftIO $ newIORef HydrationMode_Immediate
187− liftIO $ attachHydrationWidgetImmediate jsSing $ \events -> flip runWithJSContextSingleton jsSing $ do
176+ (events, fc) <- liftIO . attachWidget'' $ \events -> do
188 (postBuild, postBuildTriggerRef) <- newEventWithTriggerRef
177 (postBuild, postBuildTriggerRef) <- newEventWithTriggerRef
189 let hydrateDom :: DOM.Node -> HydrationWidget () c -> FloatingWidget () c
178 let hydrateDom :: DOM.Node -> HydrationWidget () c -> FloatingWidget () c
190 hydrateDom n w = do
179 hydrateDom n w = do
191 events' <- TriggerEvent.askEvents
180 events' <- TriggerEvent.askEvents
192− parent <- liftIO $ newIORef $ toNode n
181+ delayed <- liftIO $ newIORef $ pure ()
193 lift $ do
182 lift $ do
194 let builderEnv = HydrationDomBuilderEnv
183 let builderEnv = HydrationDomBuilderEnv
195 { _hydrationDomBuilderEnv_document = globalDoc
184 { _hydrationDomBuilderEnv_document = globalDoc
196− , _hydrationDomBuilderEnv_parent = parent
185+ , _hydrationDomBuilderEnv_parent = Left $ toNode n
197 , _hydrationDomBuilderEnv_unreadyChildren = unreadyChildren
186 , _hydrationDomBuilderEnv_unreadyChildren = unreadyChildren
198 , _hydrationDomBuilderEnv_commitAction = pure ()
187 , _hydrationDomBuilderEnv_commitAction = pure ()
199 , _hydrationDomBuilderEnv_hydrationMode = hydrationMode
188 , _hydrationDomBuilderEnv_hydrationMode = hydrationMode
200 , _hydrationDomBuilderEnv_switchover = never
189 , _hydrationDomBuilderEnv_switchover = never
190+ , _hydrationDomBuilderEnv_delayed = delayed
201 }
191 }
202− (a, _res) <- runHydrationDomBuilderT w builderEnv events'
192+ runHydrationDomBuilderT w builderEnv events'
203− pure a
204− flip runPostBuildT postBuild $ flip runTriggerEventT events $ app (hydrateDom $ toNode headElement) (hydrateDom $ toNode bodyElement)
193+ runWithJSContextSingleton (runPostBuildT (runTriggerEventT (app (hydrateDom $ toNode headElement) (hydrateDom $ toNode bodyElement)) events) postBuild) jsSing
205− return postBuildTriggerRef
194+ return (events, postBuildTriggerRef)
195+ liftIO $ processAsyncEvents events fc
206
196
207{-# INLINE mainWidget #-}
197{-# INLINE mainWidget #-}
208mainWidget :: (forall x. Widget x ()) -> JSM ()
198mainWidget :: (forall x. Widget x ()) -> JSM ()
reflex-dom-core/src/Reflex/Dom/Prerender.hs+2−1
@@ -115,7 +115,8 @@ instance (Adjustable t m, PrerenderBaseConstraints t m, ReflexHost t) => Prerend
115 , _immediateDomBuilderEnv_unreadyChildren = unreadyChildren
115 , _immediateDomBuilderEnv_unreadyChildren = unreadyChildren
116 , _immediateDomBuilderEnv_commitAction = pure ()
116 , _immediateDomBuilderEnv_commitAction = pure ()
117 }
117 }
118+ delayed <- liftIO $ newIORef $ pure ()
118− ((a, b0), _) <- lift $ runHydrationDomBuilderT server env events
119+ (a, b0) <- lift $ runHydrationDomBuilderT server (env { _hydrationDomBuilderEnv_delayed = delayed }) events
119 (b', trigger) <- newTriggerEvent
120 (b', trigger) <- newTriggerEvent
120 getHydrationMode >>= \case
121 getHydrationMode >>= \case
121 HydrationMode_Immediate -> do
122 HydrationMode_Immediate -> do
reflex-dom-core/src/Reflex/Dom/Specializations.hs+115−1
@@ -1,9 +1,14 @@
1{-# LANGUAGE FlexibleContexts #-}
1{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE GADTs #-}
2{-# LANGUAGE GADTs #-}
3+{-# LANGUAGE PolyKinds #-}
3{-# LANGUAGE Rank2Types #-}
4{-# LANGUAGE Rank2Types #-}
4{-# LANGUAGE ScopedTypeVariables #-}
5{-# LANGUAGE ScopedTypeVariables #-}
5−module Reflex.Dom.Specializations where
6+module Reflex.Dom.Specializations () where
6
7
8+import Control.Concurrent.Chan (Chan)
9+import Data.Dependent.Sum (DSum)
10+import Data.Dependent.Map (DMap)
11+import Data.Some (Some)
7import Data.Text (Text)
12import Data.Text (Text)
8import Reflex.Spider
13import Reflex.Spider
9import Reflex.Class
14import Reflex.Class
@@ -14,6 +19,7 @@ import Reflex.Requester.Base
14import Reflex.TriggerEvent.Base
19import Reflex.TriggerEvent.Base
15import Reflex.Dom.Builder.Class
20import Reflex.Dom.Builder.Class
16import Reflex.Dom.Builder.Immediate
21import Reflex.Dom.Builder.Immediate
22+import qualified Reflex.Dom.Builder.Hydration as H
17import Data.Functor.Identity
23import Data.Functor.Identity
18import Data.Functor.Compose
24import Data.Functor.Compose
19import Data.IORef
25import Data.IORef
@@ -59,3 +65,111 @@ import qualified GHCJS.DOM.Types as DOM
59 -> Event (SpiderTimeline Global) (PatchIntMap v)
65 -> Event (SpiderTimeline Global) (PatchIntMap v)
60 -> ImmediateDomBuilderT (SpiderTimeline Global) (WithJSContextSingleton () (PerformEventT Spider (SpiderHost Global))) (IntMap v', Event (SpiderTimeline Global) (PatchIntMap v'))
66 -> ImmediateDomBuilderT (SpiderTimeline Global) (WithJSContextSingleton () (PerformEventT Spider (SpiderHost Global))) (IntMap v', Event (SpiderTimeline Global) (PatchIntMap v'))
61 #-}
67 #-}
68+
69+-- Hydration stuff
70+
71+type HydrationM = WithJSContextSingleton () (PerformEventT Spider (SpiderHost Global))
72+
73+{-# SPECIALIZE H.makeElement
74+ :: Text
75+ -> ElementConfig er Spider H.HydrationDomSpace
76+ -> H.HydrationDomBuilderT Spider HydrationM a
77+ -> H.HydrationDomBuilderT Spider HydrationM
78+ ((Element er H.HydrationDomSpace Spider, a), Either DOM.Element (IORef DOM.Element))
79+ #-}
80+
81+{-# SPECIALIZE H.makeNodeInternal
82+ :: H.HydrationDomBuilderT Spider HydrationM DOM.Element
83+ -> H.HydrationDomBuilderT Spider HydrationM DOM.Element
84+ #-}
85+{-# SPECIALIZE H.makeNodeInternal
86+ :: H.HydrationDomBuilderT Spider HydrationM DOM.Text
87+ -> H.HydrationDomBuilderT Spider HydrationM DOM.Text
88+ #-}
89+
90+{-# SPECIALIZE H.makeNodeInternal
91+ :: H.HydrationDomBuilderT Spider HydrationM DOM.Comment
92+ -> H.HydrationDomBuilderT Spider HydrationM DOM.Comment
93+ #-}
94+
95+{-# SPECIALIZE H.drawChildUpdate
96+ :: H.HydrationDomBuilderEnv Spider HydrationM
97+ -> (IORef (H.ChildReadyState Int) -> JSM ())
98+ -> H.HydrationDomBuilderT Spider HydrationM (Identity a)
99+ -> H.DomRenderHookT Spider HydrationM (Compose (H.TraverseChild Spider HydrationM Int) Identity a)
100+ #-}
101+
102+{-# SPECIALIZE H.drawChildUpdate
103+ :: H.HydrationDomBuilderEnv Spider HydrationM
104+ -> (IORef (H.ChildReadyState (Some k)) -> JSM ())
105+ -> H.HydrationDomBuilderT Spider HydrationM (f a)
106+ -> H.DomRenderHookT Spider HydrationM (Compose (H.TraverseChild Spider HydrationM (Some k)) f a)
107+ #-}
108+
109+{-# SPECIALIZE H.drawChildUpdateInt
110+ :: H.HydrationDomBuilderEnv Spider HydrationM
111+ -> (IORef (H.ChildReadyState k) -> JSM ())
112+ -> H.HydrationDomBuilderT Spider HydrationM v
113+ -> H.DomRenderHookT Spider HydrationM (H.TraverseChild Spider HydrationM k v)
114+ #-}
115+
116+{-# SPECIALIZE H.append
117+ :: DOM.Node
118+ -> H.HydrationDomBuilderT Spider HydrationM ()
119+ #-}
120+
121+{-# SPECIALIZE H.wrap
122+ :: Chan [DSum (EventTriggerRef Spider) TriggerInvocation]
123+ -> DOM.Element
124+ -> RawElementConfig er Spider H.HydrationDomSpace
125+ -> H.HydrationDomBuilderT Spider HydrationM (DMap EventName (EventFilterTriggerRef Spider er))
126+ #-}
127+
128+{-# SPECIALIZE H.triggerBody
129+ :: DOM.JSContextRef
130+ -> ElementConfig er Spider H.HydrationDomSpace
131+ -> Chan [DSum (EventTriggerRef Spider) TriggerInvocation]
132+ -> DMap EventName (EventFilterTriggerRef Spider er)
133+ -> DOM.Element
134+ -> H.WrapArg er EventName x
135+ -> H.EventTrigger Spider x
136+ -> IO (IO ())
137+ #-}
138+
139+{-# SPECIALIZE H.traverseIntMapWithKeyWithAdjust'
140+ :: (IntMap.Key -> v -> H.HydrationDomBuilderT Spider HydrationM v')
141+ -> IntMap v
142+ -> Event Spider (PatchIntMap v)
143+ -> H.HydrationDomBuilderT Spider HydrationM (IntMap v', Event Spider (PatchIntMap v'))
144+ #-}
145+
146+{-# SPECIALIZE H.hoistTraverseIntMapWithKeyWithAdjust
147+ :: ((IntMap.Key -> v -> H.DomRenderHookT Spider HydrationM (H.TraverseChild Spider HydrationM Int v'))
148+ -> IntMap v
149+ -> Event Spider (PatchIntMap v)
150+ -> H.DomRenderHookT Spider HydrationM (IntMap (H.TraverseChild Spider HydrationM Int v'), Event Spider (PatchIntMap (H.TraverseChild Spider HydrationM Int v'))))
151+ -> (PatchIntMap (H.TraverseChild Spider HydrationM Int v')
152+ -> IntMap (IORef (H.ChildReadyState Int))
153+ -> IO (IntMap (IORef (H.ChildReadyState Int))))
154+ -> (IORef (IntMap DOM.Text)
155+ -> DOM.Text
156+ -> PatchIntMap (H.TraverseChild Spider HydrationM Int v')
157+ -> JSM ())
158+ -> (IntMap.Key -> v -> H.HydrationDomBuilderT Spider HydrationM v')
159+ -> IntMap v
160+ -> Event Spider (PatchIntMap v)
161+ -> H.HydrationDomBuilderT Spider HydrationM (IntMap v', Event Spider (PatchIntMap v'))
162+ #-}
163+
164+{-# SPECIALIZE H.runHydrationDomBuilderT
165+ :: H.HydrationDomBuilderT Spider HydrationM a
166+ -> H.HydrationDomBuilderEnv Spider HydrationM
167+ -> Chan [DSum (EventTriggerRef Spider) TriggerInvocation]
168+ -> HydrationM a
169+ #-}
170+
171+{-# SPECIALIZE H.runDomRenderHookT
172+ :: H.DomRenderHookT Spider HydrationM a
173+ -> Chan [DSum (EventTriggerRef Spider) TriggerInvocation]
174+ -> HydrationM a
175+ #-}
reflex-dom-core/test/hydration.hs+2−2
@@ -1352,7 +1352,7 @@ testWidget' beforeJS afterSwitchover bodyWidget = maybe (error "test timed out")
1352 waitUntilSwitchover <- liftIO newEmptyMVar -- Empty until switchover
1352 waitUntilSwitchover <- liftIO newEmptyMVar -- Empty until switchover
1353 let entryPoint = do
1353 let entryPoint = do
1354 liftIO $ takeMVar waitBeforeJS
1354 liftIO $ takeMVar waitBeforeJS
1355− mainHydrationWidgetWithSwitchoverAction (putMVar waitUntilSwitchover ()) (pure ()) $ bodyWidget
1355+ mainHydrationWidgetWithSwitchoverAction (putMVar waitUntilSwitchover ()) (pure ()) bodyWidget
1356 syncPoint
1356 syncPoint
1357 application <- liftIO $ jsaddleOr defaultConnectionOptions entryPoint $ \_ sendResponse ->
1357 application <- liftIO $ jsaddleOr defaultConnectionOptions entryPoint $ \_ sendResponse ->
1358 sendResponse $ responseLBS status200 [] $ "<!doctype html>\n" <> LBS.fromStrict html
1358 sendResponse $ responseLBS status200 [] $ "<!doctype html>\n" <> LBS.fromStrict html
@@ -1397,7 +1397,7 @@ testWidgetDebug bodyWidget = liftIO $ do
1397 el "script" $ text $ TE.decodeUtf8 $ LBS.toStrict $ jsaddleJs False
1397 el "script" $ text $ TE.decodeUtf8 $ LBS.toStrict $ jsaddleJs False
1398 ((), html) <- renderStatic staticApp
1398 ((), html) <- renderStatic staticApp
1399 let entryPoint = do
1399 let entryPoint = do
1400− mainHydrationWidgetWithSwitchoverAction (pure ()) (pure ()) $ bodyWidget
1400+ mainHydrationWidgetWithSwitchoverAction (pure ()) (pure ()) bodyWidget
1401 syncPoint
1401 syncPoint
1402 application <- jsaddleOr defaultConnectionOptions entryPoint $ \_ sendResponse -> sendResponse $ responseLBS status200 [] $ "<!doctype html>\n" <> LBS.fromStrict html
1402 application <- jsaddleOr defaultConnectionOptions entryPoint $ \_ sendResponse -> sendResponse $ responseLBS status200 [] $ "<!doctype html>\n" <> LBS.fromStrict html
1403 Warp.runSettings (Warp.setPort 3911 Warp.defaultSettings) application
1403 Warp.runSettings (Warp.setPort 3911 Warp.defaultSettings) application
reflex-dom/benchmarks/krausest.hs+2−1
@@ -26,7 +26,8 @@ type TableDiff = PatchIntMap Row
26main :: IO ()
26main :: IO ()
27main = do
27main = do
28 seed <- randomIO
28 seed <- randomIO
29+-- mainWidgetWithHead' (\_ -> headW, \_ -> bodyW seed) -- Immediate builder
29− mainWidgetWithHead {-mainHydrationWidgetWithHeadImmediate-} headW (bodyW seed)
30+ mainHydrationWidgetWithHeadImmediate headW (bodyW seed) -- Hydration builder
30
31
31titleW :: DomBuilder t m => m ()
32titleW :: DomBuilder t m => m ()
32titleW = text "Reflex-dom keyed"
33titleW = text "Reflex-dom keyed"