con t msg = {Html : source xbody,
             Notify : msg -> transaction {}}

con action = fn state => {Re_render : option xbody,
                          Change_state : option state}

fun create [state] [msg] (handler : state -> msg -> action state) (init_state : state) (init_html : xbody) =
    state <- source init_state;
    html <- source init_html;
    return {Html = html,
            Notify = fn msg =>
                        st <- get state;
                        act <- return (handler st msg);
                        (case act.Re_render of
                             None => return ()
                           | Some htm => set html htm);
                        (case act.Change_state of
                             None => return ()
                           | Some st => set state st)}

fun render [msg] (t : t msg) = <xml><dyn signal={signal t.Html}/></xml>

fun notify [msg] (t : t msg) (m : msg) = t.Notify m