///|
pub using @cmd {type Cmd, type Command}

///|
pub using @cmd {none, batch, task, perform, attempt}

///|
using @html {type Html}

///|
/// Start the application.
/// 
/// - `model` is the state of your application.
/// - `view` is a way to turn your model into HTML.
/// - `update` a way to update your state based on messages.
/// 
/// These three are the core of the TEA. Rabbit-TEA is highly unstable at this time, 
/// but it follows the same pattern as Elm. You can visit https://guide.elm-lang.org/ 
/// to get more intuition!
/// 
/// To start the application with router, you can use the `application` function.
pub fn[Model, Message] new(
  model~ : Model,
  update~ : (Message, Model) -> (Cmd[Message], Model),
  view~ : (Model) -> Html[Message],
  mount? : String = "app",
) -> App[Message, Model] {
  @dom.document()
  .get_element_by_id(mount)
  .unwrap()
  .set_inner_html("
") let mut sandbox = None let mut curr_dom = @vdom.node("div", [], []) fn after_update(html : @html.Html[Message]) { guard sandbox is Some(sandbox) let new_dom = html.to_virtual_dom() new_dom.patch(curr_dom, sandbox, mount~) curr_dom = new_dom } let sb = @browser.Sandbox::new(model, update, view, after_update~) sandbox = Some(sb) sb.refresh() App::{ sandbox: sb } } ///| /// Start the application. /// /// - `model` is the state of your application. /// - `view` is a way to turn your model into HTML. /// - `update` a way to update your state based on messages. /// /// These three are the core of the TEA. Rabbit-TEA is highly unstable at this time, /// but it follows the same pattern as Elm. You can visit https://guide.elm-lang.org/ /// to get more intuition! /// /// To start the application with router, you can use the `application` function. pub fn[Model, Message] startup( model~ : Model, update~ : (Message, Model) -> (Cmd[Message], Model), view~ : (Model) -> Html[Message], mount? : String = "app", ) -> Unit { ignore(new(model~, update~, view~, mount~)) } ///| struct App[Msg, Model] { sandbox : @browser.Sandbox[Msg, Model, @html.Html[Msg]] } ///| /// run the update function of the application. pub fn[Msg, Model] App::dispatch(self : App[Msg, Model], msg : Msg) -> Unit { self.sandbox.update(msg) } ///| pub fn[Model, Msg] new_with_route( initialize~ : (@url.Url) -> (Cmd[Msg], Model), update~ : (Msg, Model) -> (Cmd[Msg], Model), view~ : (Model) -> @html.Html[Msg], url_changed? : (@url.Url) -> Msg, url_request? : (@url.UrlRequest) -> Msg, mount? : String = "app", ) -> App[Msg, Model] { @dom.document() .get_element_by_id(mount) .unwrap() .set_inner_html("
") let mut sandbox_ref = None let mut curr_dom = @vdom.node("div", [], []) fn after_update(html : @html.Html[Msg]) { guard sandbox_ref is Some(sandbox) let new_dom = html.to_virtual_dom() new_dom.patch(curr_dom, sandbox, mount~) curr_dom = new_dom } guard (try? @url.parse(@dom.window().current_url())) is Ok(url) let (cmd, model) = initialize(url) let sandbox = @browser.Sandbox::new( model, update, view, after_update~, url_request?, url_changed?, ) sandbox_ref = Some(sandbox) sandbox..launch(cmd)..refresh() App::{ sandbox, } } ///| /// Start the application with initial URL. /// /// - `url_changed` is a message that will be passed when the URL is changed by the navigation API in the `@browser` package. /// - `url_request` is a message that will be passed when an `` tag is clicked. /// - `initialize` will be called when the application is started. /// pub fn[Model, Msg] application( initialize~ : (@url.Url) -> (Cmd[Msg], Model), update~ : (Msg, Model) -> (Cmd[Msg], Model), view~ : (Model) -> @html.Html[Msg], url_changed? : (@url.Url) -> Msg, url_request? : (@url.UrlRequest) -> Msg, mount? : String = "app", ) -> Unit { ignore( new_with_route( initialize~, update~, view~, url_changed?, url_request?, mount~, ), ) }