@@ -2,19 +2,19 @@ module Test.Main where
22
33import Prelude
44
5- import Data.Exists ( Exists , mkExists )
5+ import Data.Bifunctor ( bimap )
66import Data.Foldable (for_ , traverse_ )
77import Data.Function.Uncurried as Fn
88import Data.Maybe (Maybe (..), isNothing )
9- import Data.Newtype (wrap )
9+ import Data.Newtype (class Newtype , un , wrap )
1010import Data.Tuple (Tuple (..))
1111import Effect (Effect )
1212import Effect.Ref as Ref
1313import Effect.Timer as Timer
1414import Effect.Uncurried as EFn
1515import Halogen.VDom as V
1616import Halogen.VDom.DOM.Prop (Prop (..), propFromString , buildProp )
17- import Halogen.VDom.Util ( refEq )
17+ import Halogen.VDom.Thunk ( Thunk , thunk1 , buildThunk )
1818import Unsafe.Coerce (unsafeCoerce )
1919import Web.DOM.Document (Document ) as DOM
2020import Web.DOM.Element (toNode ) as DOM
@@ -29,9 +29,12 @@ infixr 1 prop as :=
2929prop ∷ ∀ a . String → String → Prop a
3030prop key val = Property key (propFromString val)
3131
32- type VDom = V.VDom (Array (Prop Void )) (Exists Thunk )
32+ newtype VDom a = VDom ( V.VDom (Array (Prop a )) (Thunk VDom a ) )
3333
34- data Thunk b = Thunk b (b → VDom )
34+ instance functorHtml ∷ Functor VDom where
35+ map f (VDom vdom) = VDom (bimap (map (map f)) (map f) vdom)
36+
37+ derive instance newtypeVDom ∷ Newtype (VDom a ) _
3538
3639type State = Array Database
3740
@@ -55,19 +58,19 @@ type DBQuery =
5558initialState ∷ State
5659initialState = []
5760
58- elem ∷ ∀ a w . String → a → Array (V. VDom a w ) → V. VDom a w
59- elem n a = V.Elem Nothing (V.ElemName n) a
61+ elem ∷ ∀ a . String → Array ( Prop a ) → Array (VDom a ) → VDom a
62+ elem n a c = VDom $ V.Elem Nothing (V.ElemName n) a (unsafeCoerce c)
6063
61- keyed ∷ ∀ a w . String → a → Array (Tuple String (V. VDom a w )) → V. VDom a w
62- keyed n a = V.Keyed Nothing (V.ElemName n) a
64+ keyed ∷ ∀ a . String → Array ( Prop a ) → Array (Tuple String (VDom a )) → VDom a
65+ keyed n a c = VDom $ V.Keyed Nothing (V.ElemName n) a (unsafeCoerce c)
6366
64- text ∷ ∀ a w . String → V. VDom a w
65- text = V.Text
67+ text ∷ ∀ a . String → VDom a
68+ text a = VDom $ V.Text a
6669
67- thunk ∷ ∀ a . (a → VDom ) → a → VDom
68- thunk render val = V.Widget (mkExists ( Thunk val render))
70+ thunk ∷ ∀ a b . (a → VDom b ) → a → VDom b
71+ thunk render val = VDom $ V.Widget $ Fn .runFn2 thunk1 render val
6972
70- renderData ∷ State → VDom
73+ renderData ∷ State → VDom Void
7174renderData st =
7275 elem " div" []
7376 [ elem " table"
@@ -108,41 +111,11 @@ renderData st =
108111 ]
109112 ]
110113
111- type WidgetState a w =
112- { t :: Exists Thunk
113- , step :: V.Step a w
114- }
115-
116- buildWidget
117- ∷ V.VDomSpec (Array (Prop Void )) (Exists Thunk )
118- → V.Machine (Exists Thunk ) DOM.Node
119- buildWidget spec = render
120- where
121- render = EFn .mkEffectFn1 \t → case unsafeCoerce t of
122- Thunk a render' → do
123- step ← EFn .runEffectFn1 (V .buildVDom spec) (render' a)
124- let state = { t, step }
125- pure (V .mkStep (V.Step (V .extract step) state patch done))
126-
127- patch = EFn .mkEffectFn2 \state t →
128- case unsafeCoerce state.t, unsafeCoerce t of
129- Thunk a render1, Thunk b render2 →
130- if Fn .runFn2 refEq a b && Fn .runFn2 refEq render1 render2
131- then
132- pure (V .mkStep (V.Step (V .extract state.step) state patch done))
133- else do
134- step ← EFn .runEffectFn2 V .step state.step (render2 b)
135- let nextState = { t, step }
136- pure (V .mkStep (V.Step (V .extract step) nextState patch done))
137-
138- done = EFn .mkEffectFn1 \state → do
139- EFn .runEffectFn1 V .halt state.step
140-
141114mkSpec
142115 ∷ DOM.Document
143- → V.VDomSpec (Array (Prop Void )) (Exists Thunk )
116+ → V.VDomSpec (Array (Prop Void )) (Thunk VDom Void )
144117mkSpec document = V.VDomSpec
145- { buildWidget
118+ { buildWidget: buildThunk (un VDom )
146119 , buildAttributes: buildProp (const (pure unit))
147120 , document
148121 }
@@ -157,13 +130,13 @@ foreign import requestAnimationFrame ∷ Effect Unit → Effect Unit
157130
158131mkRenderQueue
159132 ∷ ∀ a
160- . V.VDomSpec (Array (Prop Void )) (Exists Thunk )
133+ . V.VDomSpec (Array (Prop Void )) (Thunk VDom Void )
161134 → DOM.Node
162- → (a → VDom )
135+ → (a → VDom Void )
163136 → a
164137 → Effect (a → Effect Unit )
165138mkRenderQueue spec parent render initialValue = do
166- initMachine ← EFn .runEffectFn1 (V .buildVDom spec) (render initialValue)
139+ initMachine ← EFn .runEffectFn1 (V .buildVDom spec) (un VDom ( render initialValue) )
167140 _ ← DOM .appendChild (V .extract initMachine) parent
168141 ref ← Ref .new initMachine
169142 val ← Ref .new Nothing
@@ -173,24 +146,24 @@ mkRenderQueue spec parent render initialValue = do
173146 when (isNothing v) $ requestAnimationFrame do
174147 machine ← Ref .read ref
175148 Ref .read val >>= traverse_ \v' → do
176- res ← EFn .runEffectFn2 V .step machine (render v')
149+ res ← EFn .runEffectFn2 V .step machine (un VDom ( render v') )
177150 Ref .write res ref
178151 Ref .write Nothing val
179152
180153mkRenderQueue'
181154 ∷ ∀ a
182- . V.VDomSpec (Array (Prop Void )) (Exists Thunk )
155+ . V.VDomSpec (Array (Prop Void )) (Thunk VDom Void )
183156 → DOM.Node
184- → (a → VDom )
157+ → (a → VDom Void )
185158 → a
186159 → Effect (a → Effect Unit )
187160mkRenderQueue' spec parent render initialValue = do
188- initMachine ← EFn .runEffectFn1 (V .buildVDom spec) (render initialValue)
161+ initMachine ← EFn .runEffectFn1 (V .buildVDom spec) (un VDom ( render initialValue) )
189162 _ ← DOM .appendChild (V .extract initMachine) parent
190163 ref ← Ref .new initMachine
191164 pure \v → do
192165 machine ← Ref .read ref
193- res ← EFn .runEffectFn2 V .step machine (render v)
166+ res ← EFn .runEffectFn2 V .step machine (un VDom ( render v) )
194167 Ref .write res ref
195168
196169main ∷ Effect Unit
0 commit comments