### Tyrian Initialization Source: https://tyrian.indigoengine.io/documentation/guides/guided-tour Initializes the Tyrian application's model and command. This function sets the starting value of the model (0 in this case) and returns no initial commands. It requires Tyrian and cats-effect imports. ```scala import tyrian.* import tyrian.Html.* import cats.effect.IO type Model = Int def init(flags: Map[String, String]): (Model, Cmd[IO, Msg]) = (0, Cmd.None) ``` -------------------------------- ### Quick Project Setup with Giter8 Source: https://tyrian.indigoengine.io/documentation/installation/quickstart This command uses the giter8 template engine to quickly create a new Tyrian project. It requires giter8 to be installed and assumes you have sbt and npm/yarn available. The command initiates a new project based on the specified template. ```bash sbt new PurpleKingdomGames/tyrian.g8 ``` -------------------------------- ### Quick Start: Set up Tyrian Flowbite Project with SBT Source: https://tyrian.indigoengine.io/documentation/installation/tyrian-flowbite-template This snippet demonstrates the command to quickly set up a new Tyrian project utilizing Flowbite components. It requires the sbt build tool to be installed and configured. ```shell sbt new linux-root/tyrian-flowbite.g8 ``` -------------------------------- ### Tyrian SPA Counter Example Source: https://tyrian.indigoengine.io/documentation/guides/guided-tour This Scala code defines a minimal Tyrian SPA for a counter. It extends TyrianIOApp, defining the model, message types, initialization, update logic, and view. It requires Tyrian, cats-effect, and Scala.js. ```scala import tyrian.Html.* import tyrian.* import cats.effect.IO import scala.scalajs.js.annotation.* // @JSExportTopLevel("TyrianApp") // Commented out to appease mdoc.. object Main extends TyrianIOApp[Msg, Model]: def router: Location => Msg = Routing.none(Msg.NoOp) def init(flags: Map[String, String]): (Model, Cmd[IO, Msg]) = (0, Cmd.None) def update(model: Model): Msg => (Model, Cmd[IO, Msg]) = case Msg.Increment => (model + 1, Cmd.None) case Msg.Decrement => (model - 1, Cmd.None) case Msg.NoOp => (model, Cmd.None) def view(model: Model): Html[Msg] = div()( button(onClick(Msg.Decrement))("-"), div()(model.toString), button(onClick(Msg.Increment))("+") ) def subscriptions(model: Model): Sub[IO, Msg] = Sub.None type Model = Int enum Msg: case Increment, Decrement, NoOp ``` -------------------------------- ### Tyrian Model Definition Source: https://tyrian.indigoengine.io/documentation/guides/guided-tour Defines the data model for a Tyrian application. In this simple counter example, the model is an Int, aliased as 'Model' for clarity. This requires basic Tyrian imports. ```scala type Model = Int ``` -------------------------------- ### Install Sass and Bootstrap Source: https://tyrian.indigoengine.io/documentation/guides/styles Installs the necessary packages, Sass and Bootstrap, using npm. These are essential for compiling custom SCSS files and utilizing Bootstrap's styling framework. ```bash npm install sass npm install bootstrap ``` -------------------------------- ### Render Page View with Basic HTML Structure Source: https://tyrian.indigoengine.io/documentation/guides/guided-tour Defines the 'view' function in Tyrian to render a basic HTML structure. It takes a 'Model' as input and returns 'Html[Msg]'. This function creates a div containing two buttons and a div to display the model's string representation. ```scala def view(model: Model): Html[Msg] = div( button("-"), div(model.toString), button("+") ) ``` -------------------------------- ### Simple Server-Side Rendering with Tyrian Source: https://tyrian.indigoengine.io/documentation/guides/ssr Demonstrates a basic example of server-side rendering using Tyrian in Scala. It shows how to create HTML fragments with styles and text content, which can then be rendered to a String. ```scala import tyrian.* import tyrian.Html.* val styles = style(CSS.`font-family`("Arial, Helvetica, sans-serif")) val topLine = p(b(text("HTML fragment rendered by Tyrian on the server."))) val output: String = div(styles)( topLine, p("Hello, world!") ).render ``` -------------------------------- ### Import Tyrian HTML Utilities Source: https://tyrian.indigoengine.io/documentation/guides/ssr Import the necessary classes from the Tyrian library to start using its HTML tag syntax for generating HTML on the server-side. ```scala import tyrian.* import tyrian.Html.* ``` -------------------------------- ### Render Page View with Click Event Handlers Source: https://tyrian.indigoengine.io/documentation/guides/guided-tour Enhances the 'view' function to include click event handlers on the buttons. When the '-' button is clicked, 'Msg.Decrement' is emitted; when the '+' button is clicked, 'Msg.Increment' is emitted. The return type is 'Html[Msg]' to handle these messages. ```scala def view(model: Model): Html[Msg] = div( button(onClick(Msg.Decrement))("-"), div(model.toString), button(onClick(Msg.Increment))("+") ) ``` -------------------------------- ### Basic HTML Rendering in Tyrian (Scala) Source: https://tyrian.indigoengine.io/documentation/guides/html Demonstrates the fundamental syntax for creating HTML structures in Tyrian using Scala. It shows how to define elements, apply basic styles, and include interactive buttons. This example requires the tyrian library. ```Scala import tyrian.* import tyrian.Html.* import tyrian.CSS enum Msg: case Greet val myStyles = style(CSS.`font-family`("Arial, Helvetica, sans-serif")) val topLine = p(b(text("This is some HTML in bold."))) div(id := "my-container")( div(myStyles)( topLine, p("Hello, world!"), button(onClick(Msg.Greet))("Say hello!") ) ) ``` -------------------------------- ### Manage Local Storage with Tyrian LocalStorage Cmd Source: https://tyrian.indigoengine.io/documentation/guides/goodies The LocalStorage command provides a set of commands that mirror the browser's local storage interface. It allows for setting, getting, removing, and clearing items, as well as retrieving items by index and the total length. It handles success and various error conditions. ```scala import tyrian.cmds.* val cmd: Cmd[IO, Msg] = Cmd.Batch[IO, Msg]( LocalStorage.setItem("key", "value") { case LocalStorage.Result.Success => Msg.NoOp case e => Msg.Error(e.toString) }, LocalStorage.getItem("key") { case Right(LocalStorage.Result.Found(value)) => Msg.Read(value) case Left(LocalStorage.Result.NotFound(e)) => Msg.Error(e.toString) }, LocalStorage.removeItem("key") { case LocalStorage.Result.Success => Msg.NoOp case e => Msg.Error(e.toString) }, LocalStorage.clear { case LocalStorage.Result.Success => Msg.NoOp case e => Msg.Error(e.toString) }, LocalStorage.key(0) { case LocalStorage.Result.Key(keyAtIndex0) => Msg.Read(keyAtIndex0) case LocalStorage.Result.NotFound(e) => Msg.Error(e.toString) case e => Msg.Error(e.toString) }, LocalStorage.length { case LocalStorage.Result.Length(value) => Msg.Read(value.toString) } ) ``` -------------------------------- ### Define Message Enum for UI Actions Source: https://tyrian.indigoengine.io/documentation/guides/guided-tour Declares an enumeration 'Msg' to represent distinct messages or events that can be triggered by user interactions within the UI. This example defines two possible messages: 'Increment' and 'Decrement'. ```scala enum Msg: case Increment, Decrement ``` -------------------------------- ### Render Page View with HTML ID Attribute Source: https://tyrian.indigoengine.io/documentation/guides/guided-tour Demonstrates how to add an HTML attribute, specifically an 'id', to an element in Tyrian's 'view' function. The 'id' attribute is set to 'my container' for the main div. ```scala def view(model: Model): Html[Msg] = div(id := "my container")( button("-"), div(model.toString), button("+") ) ``` -------------------------------- ### HTTP - Fetch Random GIF Source: https://tyrian.indigoengine.io/documentation/guides/networking Demonstrates how to fetch a random GIF using the built-in `tyrian.http.Http` command. This example includes setting up model and message types, a JSON decoder, and an HTTP helper to send the request. ```APIDOC ## POST /api/users ### Description This endpoint allows for the creation of a new user in the system. It requires user details in the request body. ### Method POST ### Endpoint /api/users ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **username** (string) - Required - The desired username for the new user. - **email** (string) - Required - The email address of the new user. - **password** (string) - Required - The password for the new user. ### Request Example ```json { "username": "johndoe", "email": "john.doe@example.com", "password": "securepassword123" } ``` ### Response #### Success Response (201 Created) - **id** (string) - The unique identifier for the newly created user. - **username** (string) - The username of the created user. - **email** (string) - The email address of the created user. #### Response Example ```json { "id": "a1b2c3d4-e5f6-7890-1234-567890abcdef", "username": "johndoe", "email": "john.doe@example.com" } ``` ``` -------------------------------- ### Combine Mouse Movement and Periodic Ticks Subscriptions (Scala) Source: https://tyrian.indigoengine.io/documentation/guides/subs This example shows how to combine multiple subscriptions into a single one using `Sub.Batch`. It includes a subscription for mouse movement and another for periodic ticks every second, mapping the tick event to `Msg.CurrentSeconds`. ```scala import scala.concurrent.duration._ import org.scalajs.dom.document import org.scalajs.dom.MouseEvent import tyrian.* enum Msg: case MouseMove(x: Double, y: Double) case CurrentSeconds(seconds: Double) val mousePosition: Sub[IO, Msg] = Sub.fromEvent("mousemove", document) { case e: MouseEvent => Option(Msg.MouseMove(e.pageX, e.pageY)) } val tick = Sub.every[IO](1.second, "tick") .map(date => Msg.CurrentSeconds(date.getSeconds())) def subscriptions(model: Model): Sub[IO, Msg] = Sub.Batch[IO, Msg]( mousePosition, tick ) ``` -------------------------------- ### Scala.js Main Method for scalajs-bundler Source: https://tyrian.indigoengine.io/documentation/guides/bundling This code snippet demonstrates how to define a `main` method in Scala.js when using scalajs-bundler. This is necessary because scalajs-bundler requires Scala.js to run from the `main` method, unlike Parcel.js examples where `TyrianApp.launch` is called directly from JavaScript. The `main` method simply calls one of the underlying `launch` methods on the `TyrianApp` trait. ```scala def main(args: Array[String]): Unit = launch("myapp") ``` -------------------------------- ### Tyrian: Creating Custom HTML Elements (Scala) Source: https://tyrian.indigoengine.io/documentation/guides/html Provides examples of how to manually define custom HTML tags, attributes, properties, styles, and event handlers in Tyrian. This is useful when Tyrian's built-in definitions are insufficient or missing. ```Scala // A 'canvas' tag tag("canvas", List(id := "an-id"), Nil) // An attribute attribute("my-attribute", "its-value") // A property property("my-property", "its-value") // Styles style("width", "100px") styles("width" -> "100px", "height" -> "50px") // An event-type attribute onEvent("click", (evt: Tyrian.Event) => Msg.Greet) ``` -------------------------------- ### sbt Plugin and Dependency Configuration for Tyrian Source: https://tyrian.indigoengine.io/documentation/installation/quickstart This snippet shows how to configure sbt to use Tyrian. It involves adding the Scala.js plugin and then including the Tyrian library (either the core or ZIO version) and optionally the Tyrian/Indigo Bridge library in your project's dependencies. It also configures the Scala.js linker to output CommonJS modules. ```scala addSbtPlugin("org.scala-js" % "sbt-scalajs" % "@SCALAJS_VERSION@") ``` ```scala enablePlugins(ScalaJSPlugin) libraryDependencies ++= Seq( "io.indigoengine" %%% "tyrian-io" % "@VERSION@" // OR "io.indigoengine" %%% "tyrian-zio" % "@VERSION@" ) scalaJSLinkerConfig ~= { _.withModuleKind(ModuleKind.CommonJSModule) } ``` ```scala libraryDependencies ++= Seq( ..., "io.indigoengine" %%% "tyrian-indigo-bridge" % "@VERSION@" ) ``` -------------------------------- ### Mill Build Configuration for Tyrian with Scala.js Source: https://tyrian.indigoengine.io/documentation/installation/quickstart This Mill build script sets up a Scala.js module for a Tyrian project. It includes dependencies for Tyrian and optionally the Tyrian/Indigo Bridge, along with MUnit for testing. The configuration specifies the Scala and Scala.js versions and sets the module kind to CommonJSModule. ```scala import $ivy.`com.lihaoyi::mill-contrib-bloop:$MILL_VERSION` import mill._ import mill.scalalib._ import mill.scalalib.api._ import mill.scalajslib._ import mill.scalajslib.api._ object counter extends ScalaJSModule { def scalaVersion = "@SCALA_VERSION@" def scalaJSVersion = "@SCALAJS_VERSION@" def ivyDeps = Agg(ivy"io.indigoengine::tyrian::@VERSION@") override def moduleKind = T(mill.scalajslib.api.ModuleKind.CommonJSModule) object test extends Tests { def ivyDeps = Agg(ivy"org.scalameta::munit::0.7.29") def testFramework = "munit.Framework" override def moduleKind = T(mill.scalajslib.api.ModuleKind.CommonJSModule) } } ``` ```scala def ivyDeps = Agg( ivy"io.indigoengine::tyrian::@VERSION@", ivy"io.indigoengine::tyrian-indigo-bridge::@VERSION@" ) ``` -------------------------------- ### Generate Random Double with Tyrian Command Source: https://tyrian.indigoengine.io/documentation/guides/cmd This example shows how to use Tyrian's `Random.double` command to generate a random double value. It illustrates the need to map the command's result to a specific message type (`MyMsg.MyRandom`) using `.map`. ```Scala enum MyMsg: case MyRandom(d: Double) extends MyMsg Random.double[IO].map(next => MyMsg.MyRandom(next.value)) ``` -------------------------------- ### Configure Scala.js to Use Main Module Initializer Source: https://tyrian.indigoengine.io/documentation/guides/bundling This setting in `build.sbt` tells Scala.js to use the `main` method as the entry point for your application when using `scalajs-bundler`. This is a key difference from configurations that rely on direct JavaScript calls to launch the application. ```scala scalaJSUseMainModuleInitializer := true ``` -------------------------------- ### Update Counter Value Based on Messages Source: https://tyrian.indigoengine.io/documentation/guides/guided-tour Implements the 'update' function in Tyrian, which reacts to messages emitted from the view. It takes the current 'Model' and a 'Msg', returning a new 'Model' and a 'Cmd'. This function increments or decrements the model (an Int) based on 'Msg.Increment' or 'Msg.Decrement', respectively, with no associated commands. ```scala def update(model: Model): Msg => (Model, Cmd[IO, Msg]) = case Msg.Increment => (model + 1, Cmd.None) case Msg.Decrement => (model - 1, Cmd.None) ``` -------------------------------- ### ImageLoader Commands Source: https://tyrian.indigoengine.io/documentation/guides/goodies Load images from a given path and receive an `HTMLImageElement` for use in your application. ```APIDOC ## ImageLoader Commands ### Description Load an image from a specified URL or path. The loaded image is returned as an `HTMLImageElement`. ### Method `Cmd.apply` ### Endpoint N/A (Internal command) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```scala import tyrian.cmds.* val cmd: Cmd[IO, Msg] = ImageLoader.load("path/to/img.png") { case ImageLoader.Result.ImageLoadError(msg, path) => Msg.Error(msg) case ImageLoader.Result.Image(imageElement) => Msg.UseImage(imageElement) } ``` ### Response #### Success Response (200) N/A (Commands do not return HTTP responses) #### Response Example N/A ### Error Handling Handles `ImageLoader.Result.ImageLoadError` if the image fails to load. ``` -------------------------------- ### Embed HTMX JavaScript in HTML Source: https://tyrian.indigoengine.io/documentation/guides/ssr Include the HTMX JavaScript library and its extensions in your HTML structure to enable HTMX functionality on the client-side. This example shows how to embed it using Tyrian's syntax. ```scala html( head( script(src := "https://unpkg.com/htmx.org@1.9.10")(), script(src := "https://unpkg.com/htmx.org/dist/ext/ws.js")() ) ) ``` -------------------------------- ### HotReload Bootstrap Command Source: https://tyrian.indigoengine.io/documentation/guides/goodies Initializes the HotReload functionality by providing a save key, a decoding function for the model, and handlers for potential errors or successful model restoration. This command is typically added to the init function of an application. ```scala HotReload.bootstrap("my-save-data", Model.decode) { case Left(msg) => Msg.Log("Error during hot-reload!: " + msg) case Right(model) => Msg.OverwriteModel(model) } ``` -------------------------------- ### Http Commands Source: https://tyrian.indigoengine.io/documentation/guides/goodies Make HTTP requests and receive their responses as messages. Refer to the Networking section for detailed usage. ```APIDOC ## Http Commands ### Description Perform HTTP requests (GET, POST, etc.) and handle the responses within your Tyrian application's message system. ### Method `Cmd.apply` ### Endpoint N/A (Internal command, requires URL configuration) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example Refer to the "Networking" section for detailed examples. ### Response #### Success Response (200) N/A (Commands do not return HTTP responses) #### Response Example N/A ``` -------------------------------- ### Dom Commands Source: https://tyrian.indigoengine.io/documentation/guides/goodies Interact with the Document Object Model (DOM) using `focus` and `blur` commands, similar to Elm's Browser.Dom package. ```APIDOC ## Dom Commands ### Description Manipulate the DOM, such as focusing or blurring elements, with methods inspired by Elm's Browser.Dom package. ### Method `Cmd.apply` ### Endpoint N/A (Internal command) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```scala import cats.effect.IO import tyrian.* import tyrian.cmds.* val cmd: Cmd[IO, Msg] = Dom.focus("my-id") { case Left(Dom.NotFound(id)) => Msg.Error(s"ID $id not found") case Right(_) => Msg.Empty } ``` ### Response #### Success Response (200) N/A (Commands do not return HTTP responses) #### Response Example N/A ### Error Handling Handles `Dom.NotFound` for elements that do not exist. ``` -------------------------------- ### LocalStorage Commands Source: https://tyrian.indigoengine.io/documentation/guides/goodies Interact with the browser's local storage for saving, retrieving, removing, and clearing key-value pairs. ```APIDOC ## LocalStorage Commands ### Description Provides commands to interact with the browser's `localStorage` API, allowing you to store, retrieve, and manage data. ### Method `Cmd.apply` ### Endpoint N/A (Internal command) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```scala import tyrian.cmds.* val cmd: Cmd[IO, Msg] = Cmd.Batch[IO, Msg]( LocalStorage.setItem("key", "value") { case LocalStorage.Result.Success => Msg.NoOp case e => Msg.Error(e.toString) }, LocalStorage.getItem("key") { case Right(LocalStorage.Result.Found(value)) => Msg.Read(value) case Left(LocalStorage.Result.NotFound(e)) => Msg.Error(e.toString) }, LocalStorage.removeItem("key") { case LocalStorage.Result.Success => Msg.NoOp case e => Msg.Error(e.toString) }, LocalStorage.clear { case LocalStorage.Result.Success => Msg.NoOp case e => Msg.Error(e.toString) }, LocalStorage.key(0) { case LocalStorage.Result.Key(keyAtIndex0) => Msg.Read(keyAtIndex0) case LocalStorage.Result.NotFound(e) => Msg.Error(e.toString) case e => Msg.Error(e.toString) }, LocalStorage.length { case LocalStorage.Result.Length(value) => Msg.Read(value.toString) } ) ``` ### Response #### Success Response (200) N/A (Commands do not return HTTP responses) #### Response Example N/A ### Error Handling Handles various `LocalStorage.Result` cases, including `Success`, `NotFound`, and general errors. ``` -------------------------------- ### Load Image with Tyrian ImageLoader Cmd Source: https://tyrian.indigoengine.io/documentation/guides/goodies The ImageLoader command loads an image from a given path and returns an HTMLImageElement. It's useful for pre-loading images in your application. It includes error handling for cases where the image fails to load. ```scala import tyrian.cmds.* val cmd: Cmd[IO, Msg] = ImageLoader.load("path/to/img.png") { case ImageLoader.Result.ImageLoadError(msg, path) => Msg.Error(msg) case ImageLoader.Result.Image(imageElement) => Msg.UseImage(imageElement) } ``` -------------------------------- ### Integrate SCSS in HTML Source: https://tyrian.indigoengine.io/documentation/guides/styles Demonstrates how to link a custom SCSS file to an HTML page. This is a common step in build pipelines to ensure the compiled CSS is loaded by the browser. ```html ``` -------------------------------- ### Observe Mouse Movement with Subscriptions (Scala) Source: https://tyrian.indigoengine.io/documentation/guides/subs This snippet demonstrates how to create a subscription to observe mouse movements. It uses `Sub.fromEvent` to listen for 'mousemove' events on the document and maps the `MouseEvent` to a `Msg.MouseMove` message. ```scala import org.scalajs.dom.document import org.scalajs.dom.MouseEvent import cats.effect.IO import tyrian.* type Model = Int enum Msg: case MouseMove(x: Double, y: Double) val mousePosition: Sub[IO, Msg] = Sub.fromEvent("mousemove", document) { case e: MouseEvent => Option(Msg.MouseMove(e.pageX, e.pageY)) } def subscriptions(model: Model): Sub[IO, Msg] = mousePosition ``` -------------------------------- ### Import Tyrian HTMX Utilities Source: https://tyrian.indigoengine.io/documentation/guides/ssr Import the specific HTMX-related classes from the Tyrian library to utilize HTMX-specific syntax and features for building hypermedia applications. ```scala import tyrian.htmx.* import tyrian.htmx.Html.* ``` -------------------------------- ### Scala HTML with Bootstrap Classes Source: https://tyrian.indigoengine.io/documentation/guides/styles Shows how to apply Bootstrap's grid system and utility classes within Scala-based HTML generation for Tyrian applications. This allows for responsive and styled layouts. ```scala def view(model: Model): Html[Msg] = div(`class` := "container")( div(`class` := "row")( div(`class` := "col bodyText", styles("text-align" -> "right"))( button(onClick(Msg.Decrement))(text("-")) ), div(`class` := "col bodyText", styles("text-align" -> "center"))( text(model.toString) ), div(`class` := "col bodyText", styles("text-align" -> "left"))( button(onClick(Msg.Increment))(text("+")) ) ) ) ``` -------------------------------- ### Built-in Cmd Goodies Overview Source: https://tyrian.indigoengine.io/documentation/guides/goodies Tyrian provides a set of built-in commands that simplify common tasks. These include utilities for interacting with the DOM, reading files, making HTTP requests, managing local storage, logging, and generating random values. ```APIDOC ## Built-in Cmd Goodies These nuggets of functionality are used as commands. * `Dom` - A few methods such as `focus` and `blur` to manipulate the DOM. Inspired by the Elm Browser.Dom package. * `FileReader` - Given the id of a file input field that has had a file selected, this Cmd will read either raw bytes, an image or text file to return a `IArray[Byte]` or an `HTMLImageElement` or `String` respectively. * `Http` - Make HTTP requests that return their responses as a message. * `ImageLoader` - Given a path, this cmd will load an image and return an `HTMLImageElement` for you to make use of. * `LocalStorage` - Allows you to save and load to/from your browsers local storage. * `Logger` - A simple logger that logs to the Browsers console with a few standard headers and the log message. * `Random` - A Cmd to generate random values. ``` -------------------------------- ### Read File Contents with Tyrian FileReader Cmd Source: https://tyrian.indigoengine.io/documentation/guides/goodies The FileReader command enables reading file data, with built-in support for text and images. It takes the ID of a file input field and can return the file's contents as a String, or an HTMLImageElement for images. Error handling is included. ```scala import tyrian.cmds.* val cmd: Cmd[IO, Msg] = FileReader.readText("my-file-input-field-id") { case FileReader.Result.Error(msg) => Msg.Error(msg) case FileReader.Result.File(name, path, contents) => Msg.Read(contents) } ``` -------------------------------- ### FileReader Commands Source: https://tyrian.indigoengine.io/documentation/guides/goodies Read file data from an input field, with built-in support for text and images. ```APIDOC ## FileReader Commands ### Description Read the contents of a file selected in an input field. Supports reading as text, raw bytes, or an image element. ### Method `Cmd.apply` ### Endpoint N/A (Internal command) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```scala import tyrian.cmds.* val cmd: Cmd[IO, Msg] = FileReader.readText("my-file-input-field-id") { case FileReader.Result.Error(msg) => Msg.Error(msg) case FileReader.Result.File(name, path, contents) => Msg.Read(contents) } ``` ### Response #### Success Response (200) N/A (Commands do not return HTTP responses) #### Response Example N/A ### Error Handling Handles `FileReader.Result.Error` for issues during file reading. ``` -------------------------------- ### Enable ScalaJS Bundler Plugin in build.sbt Source: https://tyrian.indigoengine.io/documentation/guides/bundling This code snippet illustrates how to enable the `ScalaJSBundlerPlugin` within your `build.sbt` file. This step is crucial after adding the plugin dependency in `project/plugins.sbt` to activate the bundler's functionality for your Scala.js project. ```scala enablePlugins(ScalaJSBundlerPlugin) ``` -------------------------------- ### Tyrian WebSocket API Source: https://tyrian.indigoengine.io/documentation/guides/networking Illustrates the basic structure and methods of Tyrian's WebSocket implementation. It includes commands for connecting, publishing, subscribing, and disconnecting. This is a high-level overview of the API. ```scala final class WebSocket[F[_]: Async](liveSocket: LiveSocket[F]): def disconnect[Msg]: Cmd[F, Msg] def publish[Msg](message: String): Cmd[F, Msg] def subscribe[Msg](f: WebSocketEvent => Msg): Sub[F, Msg] /** The running instance of the WebSocket */ final class LiveSocket[F[_]: Async](val socket: dom.WebSocket, val subs: Sub[F, WebSocketEvent]) object WebSocket: def connect[F[_]: Async, Msg]( address: String, onOpenMessage: String, keepAliveSettings: KeepAliveSettings )( resultToMessage: WebSocketConnect[F] => Msg ): Cmd[F, Msg] ``` -------------------------------- ### Simplified Console Log Command Implementation Source: https://tyrian.indigoengine.io/documentation/guides/cmd A simplified implementation of a console logging command in Tyrian. This `consoleLog` function creates a `Cmd.SideEffect` that captures a zero-argument function (thunk) to execute `println`. ```Scala def consoleLog(msg: String): Cmd[IO, Nothing] = Cmd.SideEffect { println(msg) } ``` -------------------------------- ### Tyrian: Applying Inline Styles (Scala) Source: https://tyrian.indigoengine.io/documentation/guides/html Shows how to apply inline CSS styles to HTML elements in Tyrian using the `style` function and the `CSS` object. This allows for direct styling of elements within the Scala code. ```Scala p(style(CSS.`font-weight`("bold")))("Hello") ``` -------------------------------- ### Logger Commands Source: https://tyrian.indigoengine.io/documentation/guides/goodies Log messages to the browser's console using different log levels (info, debug, etc.). Includes 'once' versions to log a message only the first time. ```APIDOC ## Logger Commands ### Description Log messages to the browser's JavaScript console. Supports standard log levels and provides 'once' versions to ensure a message is logged only a single time. ### Method `Cmd.apply` ### Endpoint N/A (Internal command) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```scala import tyrian.cmds.* // Standard logging val cmd: Cmd[IO, Msg] = Logger.info("Log this!") // Log only once val cmdOnce: Cmd[IO, Msg] = Logger.debugOnce("Log this exact message only once!") ``` ### Response #### Success Response (200) N/A (Commands do not return HTTP responses) #### Response Example N/A ``` -------------------------------- ### Fetch Random GIF via HTTP using Tyrian Source: https://tyrian.indigoengine.io/documentation/guides/networking Demonstrates fetching a random GIF using Tyrian's Http command. It defines data models, message types, and a decoder for JSON responses. This snippet requires cats-effect, circe, and Tyrian libraries. ```scala import cats.effect.IO import cats.syntax.either._ import io.circe.HCursor import io.circe.parser._ import tyrian.* import tyrian.cmds.* import tyrian.http.* import tyrian.Html.* final case class Model1(topic: String, gifUrl: String) enum Msg1: case MorePlease extends Msg1 case NewGif(result: String) extends Msg1 case GifError(error: String) extends Msg1 object Msg1: def jsonDecode(hcursor: HCursor) = hcursor .downField("data") .downField("images") .downField("downsized_medium") .get[String]("url") .toOption .toRight("wrong json format") private val onResponse: Response => Msg1 = { response => parse(response.body) .leftMap(_.message) .flatMap(j => jsonDecode(j.hcursor)) .fold(Msg1.GifError(_), Msg1.NewGif(_)) } private val onError: HttpError => Msg1 = e => Msg1.GifError(e.toString) def fromHttpResponse: Decoder[Msg1] = Decoder[Msg1](onResponse, onError) object HttpHelper: def url(topic: String) = s"https://api.giphy.com/v1/gifs/random?api_key=dc6zaTOxFJmzC&tag=$topic" def getRandomGif(topic: String): Cmd[IO, Msg1] = Http.send(Request.get(url(topic)), Msg1.fromHttpResponse) object HttpMain: def init(flags: Map[String, String]): (Model1, Cmd[IO, Msg1]) = (Model1("cats", "waiting.gif"), HttpHelper.getRandomGif("cats")) def update(model: Model1): Msg1 => (Model1, Cmd[IO, Msg1]) = case Msg1.MorePlease => (model, HttpHelper.getRandomGif(model.topic)) case Msg1.NewGif(newUrl) => (model.copy(gifUrl = newUrl), Cmd.None) case Msg1.GifError(_) => (model, Cmd.None) ``` -------------------------------- ### Advanced Frontend Routing with Tyrian Case Matching Source: https://tyrian.indigoengine.io/documentation/guides/routing Implements a router function using case matching for detailed route handling. This allows for specific navigation to different pages based on the `Location.Internal.pathName` or navigates to external URLs. It handles both internal and external locations. ```Elm def router: Location => Msg = case loc: Location.Internal => loc.pathName match case "/" => Msg.NavigateTo(Page.Page1) case "/page1" => Msg.NavigateTo(Page.Page1) case "/page2" => Msg.NavigateTo(Page.Page2) case "/page3" => Msg.NavigateTo(Page.Page3) case "/page4" => Msg.NavigateTo(Page.Page4) case "/page5" => Msg.NavigateTo(Page.Page5) case "/page6" => Msg.NavigateTo(Page.Page6) case _ => Msg.NoOp case loc: Location.External => Msg.NavigateToUrl(loc.href) ``` -------------------------------- ### HotReload Subscription Source: https://tyrian.indigoengine.io/documentation/guides/goodies Sets up a recurring subscription to trigger the saving of the application's state. It uses `Sub.every` to periodically send a `Msg.TakeSnapshot` message, which in turn prompts the HotReload command to save the model. ```scala Sub.every[IO](1.second, hotReloadKey).map(_ => Msg.TakeSnapshot) ``` -------------------------------- ### HotReload Snapshot Command Source: https://tyrian.indigoengine.io/documentation/guides/goodies Triggers the saving of the current application model to local storage using the HotReload functionality. This command is typically invoked in response to a specific message, such as Msg.TakeSnapshot. ```scala case Msg.TakeSnapshot => (model, HotReload.snapshot(hotReloadKey, model, Model.encode)) ``` -------------------------------- ### Fetch Random GIF via HTTP using http4s-dom and Tyrian Source: https://tyrian.indigoengine.io/documentation/guides/networking Shows how to integrate http4s-dom with Tyrian for HTTP requests. This replaces the default HttpHelper with an implementation using FetchClientBuilder. It requires http4s-dom, circe, and Tyrian. ```scala import io.circe.{ Decoder as JsonDecoder, DecodingFailure } import org.http4s.circe.CirceEntityCodec.* import org.http4s.dom.FetchClientBuilder object Http4sDomHelper: private val client = FetchClientBuilder[IO].create given JsonDecoder[Msg1] = JsonDecoder.instance { c => Msg1.jsonDecode(c).map(Msg1.NewGif(_)).leftMap(e => DecodingFailure(e, c.history)) } def getRandomGif(topic: String): Cmd[IO, Msg1] = val fetchGif: IO[Msg1] = client .expect[Msg1](HttpHelper.url(topic)) .handleError(e => Msg1.GifError(e.getMessage)) Cmd.Run(fetchGif) ``` -------------------------------- ### Tyrian: Using Span with Attributes and Children (Scala) Source: https://tyrian.indigoengine.io/documentation/guides/html Illustrates how to create a `span` HTML element in Tyrian with a class attribute and a child `p` element. This showcases the standard syntax for defining tags, attributes, and nested content. ```Scala span(`class` := "green-box")( p("This is some text.") ) ``` -------------------------------- ### Manipulate DOM with Tyrian Cmd Source: https://tyrian.indigoengine.io/documentation/guides/goodies The Dom command allows for DOM manipulation, inspired by Elm's Browser.Dom package. It provides methods like `focus` and `blur` to interact with HTML elements. It handles cases where the target element is not found. ```scala import cats.effect.IO import tyrian.* import tyrian.cmds.* val cmd: Cmd[IO, Msg] = Dom.focus("my-id") { case Left(Dom.NotFound(id)) => Msg.Error(s"ID $id not found") case Right(_) => Msg.Empty } ``` -------------------------------- ### Basic Frontend Routing with Tyrian Routing Module Source: https://tyrian.indigoengine.io/documentation/guides/routing Implements a basic router function using the `Routing` module. This approach forwards internal and external links as custom `Msg` types. Ensure you provide suitable `Msg` types for `FollowInternalLink` and `FollowExternalLink`. ```Elm def router: Location => Msg = Routing.basic(Msg.FollowInternalLink(_), Msg.FollowExternalLink(_)) ``` -------------------------------- ### Tyrian: Optional Tag Rendering with `orEmpty` (Scala) Source: https://tyrian.indigoengine.io/documentation/guides/html Demonstrates how to conditionally render an HTML element in Tyrian using the `orEmpty` extension method on `Option`. This requires importing `tyrian.syntax`. It's useful for displaying elements only when certain conditions are met. ```Scala import tyrian.syntax.* Option(p("Show this!")).orEmpty ``` -------------------------------- ### Random Commands Source: https://tyrian.indigoengine.io/documentation/guides/goodies Generate random values, including integers, shuffled lists, and alphanumeric strings. Random commands require mapping to convert the result into a message. ```APIDOC ## Random Commands ### Description Generate various types of random values, such as integers, shuffled lists, and alphanumeric strings. Unlike other commands, `Random` commands require explicit mapping to convert their results into application messages. ### Method `Cmd.apply` ### Endpoint N/A (Internal command) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```scala import tyrian.cmds.* val toMessage = (v: String) => Msg.RandomValue(v) val cmd: Cmd[IO, Msg] = Cmd.Batch( Random.int[IO].map(i => toMessage(i.value.toString)), Random.shuffle[IO, Int](List(1, 2, 3)).map(l => toMessage(l.value.toString)), Random.Seeded(12l).alphaNumeric[IO](5).map(a => toMessage(a.value.mkString)) ) ``` ### Response #### Success Response (200) N/A (Commands do not return HTTP responses) #### Response Example N/A ``` -------------------------------- ### Tyrian: Importing CSS Definitions (Scala) Source: https://tyrian.indigoengine.io/documentation/guides/html Details the import statement required to access predefined CSS terms within Tyrian. This facilitates the use of standard CSS properties and values in a type-safe manner. ```Scala import tyrian.CSS.* ``` -------------------------------- ### Custom SCSS with Bootstrap Import Source: https://tyrian.indigoengine.io/documentation/guides/styles Defines a custom SCSS file that imports Bootstrap's core styles and allows for variable overrides. This enables the use of Bootstrap's utility classes and theming capabilities in your project. ```scss @import "../node_modules/bootstrap/scss/bootstrap"; $font-stack: Helvetica, sans-serif; $primary-color: #333; body { font: 3em $font-stack; color: $primary-color; } ``` -------------------------------- ### Tyrian: Defining HTML Attributes (Scala) Source: https://tyrian.indigoengine.io/documentation/guides/html Demonstrates the syntax for defining HTML attributes in Tyrian using the `:=` operator. This is the standard way to associate key-value pairs with HTML elements, such as setting an element's ID. ```Scala id := "my-container" ```