// Embedded project templates from templates/.
///|
let _embed_main_mbt : String =
#|using @html {a, button, div, h1, h2, li, text, ul}
#|using @rabbita {type Val, type Html}
#|
#|enum Msg {
#| Clicked
#|}
#|
#|fn app() -> Val[Html] {
#| let (count, emit) = @rabbita.create_pure_state(0, update=fn(count, msg) {
#| match msg {
#| Clicked => count + 1
#| }
#| })
#|
#| count.view(count => {
#| div(class="app") <| [
#| h1(class="title", "Hello Rabbita"),
#| div(class="lead", "You built it successfully!"),
#| button(
#| class="click-btn",
#| on_click=emit(Clicked),
#| "You clicked \{count} times",
#| ),
#| div(class="next") <| [
#| h2(class="next-title", "What's next"),
#| ul(class="next-list") <| [
#| li(
#| "Edit a MoonBit file while the dev server runs for instant refresh.",
#| ),
#| li <| [
#| text("Explore "),
#| a(
#| class="inline-link",
#| target=Blank,
#| href="https://github.com/moonbit-community/rabbita",
#| "tutorials and examples",
#| ),
#| ],
#| ],
#| ],
#| ]
#| })
#|}
#|
#|fn main {
#| @rabbita.new(app).mount("app")
#|}
#|
///|
let _embed_moon_pkg : String =
#|import {
#| "moonbit-community/rabbita",
#| "moonbit-community/rabbita/html",
#|}
#|
#|supported_targets = "js"
#|
#|pkgtype(kind: "executable")
#|
///|
let _embed_index_html : String =
#|
#|
#|
#|
#|
#| __WARREN_PROJECT_NAME__
#|
#|
#|
#|
#|
#|
#|
///|
let _embed_styles_css : String =
#|@import url("https://fonts.googleapis.com/css2?family=Manrope:wght@500;700;800&display=swap");
#|
#|* {
#| box-sizing: border-box;
#|}
#|
#|body {
#| margin: 0;
#| min-height: 100vh;
#| color: #171717;
#| font-family: "Manrope", "Avenir Next", "Trebuchet MS", sans-serif;
#| background:
#| radial-gradient(980px 460px at 8% -10%, rgba(255, 143, 184, 0.22), transparent 72%),
#| radial-gradient(1060px 560px at 100% -14%, rgba(255, 184, 219, 0.18), transparent 70%),
#| #f7f9ff;
#|}
#|
#|#app {
#| padding: 112px 20px 68px;
#|}
#|
#|.app {
#| max-width: 700px;
#| margin: 0 auto;
#| text-align: center;
#|}
#|
#|.title {
#| margin: 0;
#| font-size: clamp(2.15rem, 6vw, 3.2rem);
#| line-height: 1.03;
#|}
#|
#|.lead {
#| margin: 12px 0 0;
#| color: #6b7280;
#| font-size: 1.02rem;
#|}
#|
#|.click-btn {
#| display: block;
#| width: fit-content;
#| margin: 24px auto 0;
#| padding: 12px 18px;
#| border: 1px solid #0f0f0f;
#| border-radius: 999px;
#| color: #fff;
#| background: #111;
#| font: inherit;
#| font-weight: 700;
#| cursor: pointer;
#| transition: transform 120ms ease, opacity 120ms ease;
#|}
#|
#|.click-btn:hover {
#| transform: translateY(-1px);
#| opacity: 0.95;
#|}
#|
#|.next {
#| max-width: 560px;
#| margin: 140px auto 0;
#| color: #6b7280;
#| font-size: 0.95rem;
#|}
#|
#|.next-title {
#| margin: 0;
#| font-size: 1.25rem;
#|}
#|
#|.next-list {
#| display: inline-block;
#| margin: 12px auto 0;
#| padding-left: 20px;
#| line-height: 1.65;
#| text-align: left;
#|}
#|
#|.inline-link {
#| color: inherit;
#| text-decoration-color: #9ca3af;
#| text-underline-offset: 3px;
#|}
#|
#|@media (max-width: 640px) {
#| #app {
#| padding-top: 28px;
#| }
#|}
#|
///|
let _embed_moon_mod : String =
#|name = "local/__WARREN_PROJECT_NAME__"
#|
#|version = "0.1.0"
#|
#|import {
#| "moonbit-community/rabbita@__RABBITA_VERSION__",
#|}
#|
#|readme = "README.md"
#|
#|repository = ""
#|
#|license = "Apache-2.0"
#|
#|keywords = [ ]
#|
#|description = "A Rabbita app generated by Warren."
#|
#|preferred_target = "js"
#|
///|
let _embed_readme_md : String =
#|# __WARREN_PROJECT_NAME__
#|
#|## Run in development
#|
#|In this directory:
#|
#|```sh
#|warren dev --browser-entry main
#|```
#|
#|Then open the local URL shown by warren.
#|
///|
let _embed_main_mbt_2 : String =
#|using @rabbita { type Val, type Html }
#|using @html { button, div, h1 }
#|
#|enum Msg {
#| Inc
#| Dec
#|}
#|
#|fn app() -> Val[Html] {
#| let (model, emit) = @rabbita.create_pure_state(
#| 0,
#| update=fn(model, msg) {
#| match msg {
#| Inc => model + 1
#| Dec => model - 1
#| }
#| },
#| )
#|
#| model.view(model => div(class="app") <| [
#| h1("\{model}"),
#| div(class="actions") <| [
#| button(on_click=emit(Dec), "-"),
#| button(on_click=emit(Inc), "+"),
#| ],
#| ])
#|}
#|
#|fn main {
#| @rabbita.new(app).mount("app")
#|}
#|
///|
let _embed_moon_mod_2 : String =
#|name = "local/__WARREN_PROJECT_NAME__"
#|
#|version = "0.1.0"
#|
#|import {
#| "moonbit-community/rabbita@__RABBITA_VERSION__",
#|}
#|
#|readme = "README.md"
#|
#|repository = ""
#|
#|license = "Apache-2.0"
#|
#|keywords = [ ]
#|
#|description = "A Rabbita app generated by Warren."
#|
#|preferred_target = "js"
#|
///|
let _embed_moon_pkg_2 : String =
#|import {
#| "moonbit-community/rabbita",
#| "moonbit-community/rabbita/html",
#|}
#|
#|supported_targets = "js"
#|
#|pkgtype(kind: "executable")
#|
///|
pub struct TemplatesFixture {
default : DefaultFixture
minimized : MinimizedFixture
server : ServerFixture
}
///|
pub struct DefaultFixture {
main : MainFixture
public : PublicFixture
moon_mod : String
readme_md : String
}
///|
pub struct MainFixture {
main_mbt : String
moon_pkg : String
}
///|
pub struct PublicFixture {
index_html : String
styles_css : String
}
///|
pub struct MinimizedFixture {
main_mbt : String
moon_mod : String
moon_pkg : String
}
///|
pub let templates : TemplatesFixture = {
server: {
browser_main_mbt: _embed_server_browser_main_mbt,
moon_mod: _embed_server_moon_mod,
readme_md: _embed_server_readme_md,
gitignore: _embed_server_gitignore,
moon_pkg: _embed_server_moon_pkg,
main_mbt: _embed_server_main_mbt,
warren_assets_mbt: _embed_server_warren_assets_mbt,
},
default: {
main: {
main_mbt: _embed_main_mbt,
moon_pkg: _embed_moon_pkg,
},
public: {
index_html: _embed_index_html,
styles_css: _embed_styles_css,
},
moon_mod: _embed_moon_mod,
readme_md: _embed_readme_md,
},
minimized: {
main_mbt: _embed_main_mbt_2,
moon_mod: _embed_moon_mod_2,
moon_pkg: _embed_moon_pkg_2,
},
}
///|
pub struct ServerFixture {
browser_main_mbt : String
moon_mod : String
readme_md : String
gitignore : String
moon_pkg : String
main_mbt : String
warren_assets_mbt : String
}
///|
let _embed_server_moon_mod : String =
#|name = "local/__WARREN_PROJECT_NAME__"
#|
#|version = "0.1.0"
#|
#|import {
#| "moonbit-community/rabbita@__RABBITA_VERSION__",
#| "moonbitlang/async@0.22.4",
#| "moonbitlang/moonback@0.8.4",
#| "moonbitlang/x@0.5.1",
#|}
#|
#|readme = "README.md"
#|
#|repository = ""
#|
#|license = "Apache-2.0"
#|
#|keywords = [ ]
#|
#|description = "A Rabbita app with a Moonback server generated by Warren."
#|
#|preferred_target = "js"
#|
///|
let _embed_server_readme_md : String =
#|# __WARREN_PROJECT_NAME__
#|
#|Start the app with live reload:
#|
#|```sh
#|warren dev --server-target native
#|```
#|
#|Build the frontend and server into `dist/`:
#|
#|```sh
#|warren build --server-target native
#|```
#|
#|Build a single executable containing the frontend and all `public/` files:
#|
#|```sh
#|warren build --bundle
#|```
#|
#|Run the executable emitted in `dist/`. The server defaults to
#|`http://127.0.0.1:4300/`; `WARREN_HOST` and `WARREN_PORT` override its address.
#|The example API is available at `/api/hello`.
#|
#|Edit `cmd/browser/main.mbt` for the frontend and `cmd/server/main.mbt` for
#|server routes. The resource integration is already wired up; no extra bundle
#|setup is needed. Keep `cmd/server/warren_assets.mbt` in version control.
#|
#|Direct `moon build --target native` also works. To serve frontend files when
#|running the server from Moon's build directory, set `WARREN_DIST` to a directory
#|containing the built frontend. Warren sets this automatically in development.
#|
///|
let _embed_server_gitignore : String =
#|_build/
#|.mooncakes/
#|dist/
#|
///|
let _embed_server_moon_pkg : String =
#|import {
#| "moonbitlang/async",
#| "moonbitlang/async/fs",
#| "moonbitlang/core/env",
#| "moonbitlang/core/string",
#| "moonbitlang/moonback",
#| "moonbitlang/moonback/middlewares/unstable_static" @static,
#| "moonbitlang/x/path",
#|}
#|
#|supported_targets = "native"
#|
#|pkgtype(kind: "executable")
#|
///|
let _embed_server_main_mbt : String =
#|///|
#|async fn main {
#| let host = @env.get_env_var("WARREN_HOST").unwrap_or("127.0.0.1")
#| let port = @string.parse_uint(
#| @env.get_env_var("WARREN_PORT").unwrap_or("4300"),
#| )
#| guard port > 0 && port <= 65535 else { fail("Invalid WARREN_PORT") }
#| let dist = @env.get_env_var("WARREN_DIST").unwrap_or(
#| @path.Path(@env.args()[0]).resolve().dirname().to_string(),
#| )
#| let assets = warren_assets()
#| let dev = @env.get_env_var("WARREN_MODE") == Some("DEV")
#| let client = if dev { @env.get_env_var("WARREN_CLIENT") } else { None }
#| let resources = if dev || assets.is_empty() {
#| @static.new(root=dist, rewrite_trailing_slash_index=true)
#| } else {
#| @static.from_assets(assets, rewrite_trailing_slash_index=true)
#| }
#| let app = @moonback.App(ctx => {
#| ctx.add_middleware(
#| @moonback.Middleware(next => {
#| let serve = (resources.0)(next)
#| (req, res) => {
#| if client is Some(_) && req.path == "/" {
#| next(req, res)
#| } else {
#| serve(req, res)
#| }
#| }
#| }),
#| )
#| if client is Some(client) {
#| ctx.get("/", (_req, res) => {
#| let html = @fs.read_file(
#| @path.Path(dist).join("index.html").to_string(),
#| ).text()
#| let (head, tail) = html
#| .split_once("")
#| .map_or((html, ""), parts => (parts.0.to_owned(), "\{parts.1}"))
#| res.send_html(
#| @moonback.Html(b => {
#| b <+ "\{@moonback.Html::raw(head)}"
#| b <+ ""
#| b <+ "\{@moonback.Html::raw(tail)}"
#| }),
#| )
#| })
#| }
#| ctx.get("/api/hello", (_req, res) => res.send_text("Hello from Moonback"))
#| })
#| defer app.close()
#| let listener = @moonback.listen(host~, port=port.to_uint16(), reuse_addr=true)
#| println("Server is running on http://\{host}:\{port}")
#| app.serve(listener)
#|}
#|
///|
let _embed_server_warren_assets_mbt : String =
#|///|
#|// Warren supplies embedded resources in bundle builds. Keep this file for
#|// ordinary Moon builds and development, which serve resources from disk.
#|fn warren_assets() -> Map[String, Bytes] {
#| {}
#|}
#|
///|
let _embed_server_browser_main_mbt : String =
#|///|
#|enum Msg {
#| Clicked
#|}
#|
#|///|
#|fn app() -> @rabbita.Val[@rabbita.Html] {
#| let (count, emit) = @rabbita.create_pure_state(0, update=(count, msg) => {
#| match msg {
#| Clicked => count + 1
#| }
#| })
#| count.view(count => {
#| @html.div(class="app", [
#| @html.h1(class="title", "Hello Rabbita"),
#| @html.button(
#| class="click-btn",
#| on_click=emit(Clicked),
#| "You clicked \{count} times",
#| ),
#| ])
#| })
#|}
#|
#|///|
#|fn main {
#| @rabbita.new(app).mount("app")
#|}
#|