diff --git a/build.sbt b/build.sbt index cf750aa9..6ba2cc8b 100644 --- a/build.sbt +++ b/build.sbt @@ -120,8 +120,9 @@ lazy val tyrianProject = logoSettings(version) ) .aggregate( + tyrianTags.js, + tyrianTags.jvm, tyrian.js, - tyrian.jvm, tyrianIO.js, tyrianZIO.js, sandbox.js, @@ -134,16 +135,32 @@ lazy val tyrianProject = sandboxSSR.jvm ) -lazy val tyrian = +lazy val tyrianTags = crossProject(JSPlatform, JVMPlatform) .crossType(CrossType.Full) + .in(file("tyrian-tags")) .settings( - name := "tyrian", + name := "tyrian-tags", commonSettings ++ publishSettings, Compile / sourceGenerators += codeGen("tyrian", TagGen.gen).taskValue, Compile / sourceGenerators += codeGen("tyrian", AttributeGen.gen).taskValue, Compile / sourceGenerators += codeGen("CSS", "tyrian", CSSGen.gen).taskValue ) + .jsSettings( + commonJsSettings, + libraryDependencies ++= Seq( + "org.scala-js" %%% "scalajs-dom" % Dependencies.scalajsDomVersion + ) + ) + +lazy val tyrian = + crossProject(JSPlatform) + .crossType(CrossType.Pure) + .withoutSuffixFor(JSPlatform) + .settings( + name := "tyrian", + commonSettings ++ publishSettings + ) .jsSettings( commonJsSettings, libraryDependencies ++= Seq( @@ -152,6 +169,7 @@ lazy val tyrian = "io.github.buntec" %%% "scala-js-snabbdom" % Dependencies.scalajsSnabbdom ) ) + .dependsOn(tyrianTags) lazy val tyrianIO = crossProject(JSPlatform) @@ -223,7 +241,7 @@ lazy val sandboxZIO = lazy val sandboxSSR = crossProject(JVMPlatform) .crossType(CrossType.Pure) - .dependsOn(tyrian, tyrianHtmx) + .dependsOn(tyrianTags, tyrianHtmx) .in(file("sandbox-ssr")) .settings( neverPublish, @@ -244,7 +262,6 @@ lazy val unidocs = name := "Tyrian", neverPublish, ScalaUnidoc / unidoc / unidocProjectFilter := inAnyProject -- inProjects( - tyrian.jvm, sandboxZIO.js, sandbox.js, docs, @@ -344,7 +361,7 @@ lazy val tyrianHtmx = .jsSettings( commonJsSettings ) - .dependsOn(tyrian) + .dependsOn(tyrianTags) addCommandAlias( "sandboxBuild", diff --git a/tyrian/js/src/main/scala/tyrian/LocationPlatform.scala b/tyrian-tags/js/src/main/scala/tyrian/LocationPlatform.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/LocationPlatform.scala rename to tyrian-tags/js/src/main/scala/tyrian/LocationPlatform.scala diff --git a/tyrian-tags/js/src/main/scala/tyrian/Tyrian.scala b/tyrian-tags/js/src/main/scala/tyrian/Tyrian.scala new file mode 100644 index 00000000..df7b853d --- /dev/null +++ b/tyrian-tags/js/src/main/scala/tyrian/Tyrian.scala @@ -0,0 +1,8 @@ +package tyrian + +object Tyrian: + + type Event = org.scalajs.dom.Event + type KeyboardEvent = org.scalajs.dom.KeyboardEvent + type MouseEvent = org.scalajs.dom.MouseEvent + type HTMLInputElement = org.scalajs.dom.HTMLInputElement diff --git a/tyrian-tags/js/src/main/scala/tyrian/syntax.scala b/tyrian-tags/js/src/main/scala/tyrian/syntax.scala new file mode 100644 index 00000000..e28f85f1 --- /dev/null +++ b/tyrian-tags/js/src/main/scala/tyrian/syntax.scala @@ -0,0 +1,5 @@ +package tyrian + +object syntax: + + extension [M](oa: Option[Elem[M]]) def orEmpty: Elem[M] = oa.getOrElse(tyrian.Empty) diff --git a/tyrian/jvm/src/main/scala/tyrian/LocationPlatform.scala b/tyrian-tags/jvm/src/main/scala/tyrian/LocationPlatform.scala similarity index 97% rename from tyrian/jvm/src/main/scala/tyrian/LocationPlatform.scala rename to tyrian-tags/jvm/src/main/scala/tyrian/LocationPlatform.scala index 6c48724c..7c4a03a6 100644 --- a/tyrian/jvm/src/main/scala/tyrian/LocationPlatform.scala +++ b/tyrian-tags/jvm/src/main/scala/tyrian/LocationPlatform.scala @@ -1,3 +1,4 @@ package tyrian trait LocationPlatform + diff --git a/tyrian/jvm/src/main/scala/tyrian/Tyrian.scala b/tyrian-tags/jvm/src/main/scala/tyrian/Tyrian.scala similarity index 100% rename from tyrian/jvm/src/main/scala/tyrian/Tyrian.scala rename to tyrian-tags/jvm/src/main/scala/tyrian/Tyrian.scala diff --git a/tyrian/shared/src/main/scala/tyrian/Attr.scala b/tyrian-tags/shared/src/main/scala/tyrian/Attr.scala similarity index 100% rename from tyrian/shared/src/main/scala/tyrian/Attr.scala rename to tyrian-tags/shared/src/main/scala/tyrian/Attr.scala diff --git a/tyrian/shared/src/main/scala/tyrian/HTMLRendering.scala b/tyrian-tags/shared/src/main/scala/tyrian/HTMLRendering.scala similarity index 100% rename from tyrian/shared/src/main/scala/tyrian/HTMLRendering.scala rename to tyrian-tags/shared/src/main/scala/tyrian/HTMLRendering.scala diff --git a/tyrian/shared/src/main/scala/tyrian/Html.scala b/tyrian-tags/shared/src/main/scala/tyrian/Html.scala similarity index 100% rename from tyrian/shared/src/main/scala/tyrian/Html.scala rename to tyrian-tags/shared/src/main/scala/tyrian/Html.scala diff --git a/tyrian/shared/src/main/scala/tyrian/Location.scala b/tyrian-tags/shared/src/main/scala/tyrian/Location.scala similarity index 100% rename from tyrian/shared/src/main/scala/tyrian/Location.scala rename to tyrian-tags/shared/src/main/scala/tyrian/Location.scala diff --git a/tyrian/shared/src/main/scala/tyrian/LocationDetails.scala b/tyrian-tags/shared/src/main/scala/tyrian/LocationDetails.scala similarity index 100% rename from tyrian/shared/src/main/scala/tyrian/LocationDetails.scala rename to tyrian-tags/shared/src/main/scala/tyrian/LocationDetails.scala diff --git a/tyrian/shared/src/main/scala/tyrian/Style.scala b/tyrian-tags/shared/src/main/scala/tyrian/Style.scala similarity index 100% rename from tyrian/shared/src/main/scala/tyrian/Style.scala rename to tyrian-tags/shared/src/main/scala/tyrian/Style.scala diff --git a/tyrian/js/src/test/scala/tyrian/AttrTests.scala b/tyrian-tags/shared/src/test/scala/tyrian/AttrTests.scala similarity index 100% rename from tyrian/js/src/test/scala/tyrian/AttrTests.scala rename to tyrian-tags/shared/src/test/scala/tyrian/AttrTests.scala diff --git a/tyrian/shared/src/test/scala/tyrian/HTMLRenderingTests.scala b/tyrian-tags/shared/src/test/scala/tyrian/HTMLRenderingTests.scala similarity index 100% rename from tyrian/shared/src/test/scala/tyrian/HTMLRenderingTests.scala rename to tyrian-tags/shared/src/test/scala/tyrian/HTMLRenderingTests.scala diff --git a/tyrian/js/src/test/scala/tyrian/HtmlTests.scala b/tyrian-tags/shared/src/test/scala/tyrian/HtmlTests.scala similarity index 100% rename from tyrian/js/src/test/scala/tyrian/HtmlTests.scala rename to tyrian-tags/shared/src/test/scala/tyrian/HtmlTests.scala diff --git a/tyrian/js/src/test/scala/tyrian/LocationDetailsTests.scala b/tyrian-tags/shared/src/test/scala/tyrian/LocationDetailsTests.scala similarity index 100% rename from tyrian/js/src/test/scala/tyrian/LocationDetailsTests.scala rename to tyrian-tags/shared/src/test/scala/tyrian/LocationDetailsTests.scala diff --git a/tyrian/js/src/test/scala/tyrian/LocationTests.scala b/tyrian-tags/shared/src/test/scala/tyrian/LocationTests.scala similarity index 100% rename from tyrian/js/src/test/scala/tyrian/LocationTests.scala rename to tyrian-tags/shared/src/test/scala/tyrian/LocationTests.scala diff --git a/tyrian/shared/src/test/scala/tyrian/StyleTests.scala b/tyrian-tags/shared/src/test/scala/tyrian/StyleTests.scala similarity index 100% rename from tyrian/shared/src/test/scala/tyrian/StyleTests.scala rename to tyrian-tags/shared/src/test/scala/tyrian/StyleTests.scala diff --git a/tyrian/js/src/main/scala/tyrian/Tyrian.scala b/tyrian/js/src/main/scala/tyrian/Tyrian.scala deleted file mode 100644 index 9ea1b6a1..00000000 --- a/tyrian/js/src/main/scala/tyrian/Tyrian.scala +++ /dev/null @@ -1,44 +0,0 @@ -package tyrian - -import cats.effect.kernel.Async -import org.scalajs.dom.Element -import tyrian.runtime.TyrianRuntime - -object Tyrian: - - type Event = org.scalajs.dom.Event - type KeyboardEvent = org.scalajs.dom.KeyboardEvent - type MouseEvent = org.scalajs.dom.MouseEvent - type HTMLInputElement = org.scalajs.dom.HTMLInputElement - - /** Directly starts the app. Computes the initial state of the given application, renders it on the given DOM element, - * and listens to user actions - * @param init - * initial state - * @param update - * state transition function - * @param view - * view function - * @param subscriptions - * subscriptions function - * @param node - * the DOM element to mount the app to - * @param runner - * the function that runs the program. Has a type of `F[Option[Msg]] => (Either[Throwable, Option[Msg]] => Unit) => - * Unit`, essentially: `task.unsafeRunAsync(callback)` - * @tparam F - * The effect type to use, e.g. `IO` - * @tparam Model - * Type of model - * @tparam Msg - * Type of messages - */ - def start[F[_]: Async, Model, Msg]( - node: Element, - router: Location => Msg, - init: (Model, Cmd[F, Msg]), - update: Model => Msg => (Model, Cmd[F, Msg]), - view: Model => Html[Msg], - subscriptions: Model => Sub[F, Msg] - ): F[Nothing] = - TyrianRuntime[F, Model, Msg](router, node, init._1, init._2, update, view, subscriptions) diff --git a/tyrian/js/src/main/scala/tyrian/Cmd.scala b/tyrian/src/main/scala/tyrian/Cmd.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/Cmd.scala rename to tyrian/src/main/scala/tyrian/Cmd.scala diff --git a/tyrian/js/src/main/scala/tyrian/HotReload.scala b/tyrian/src/main/scala/tyrian/HotReload.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/HotReload.scala rename to tyrian/src/main/scala/tyrian/HotReload.scala diff --git a/tyrian/js/src/main/scala/tyrian/Nav.scala b/tyrian/src/main/scala/tyrian/Nav.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/Nav.scala rename to tyrian/src/main/scala/tyrian/Nav.scala diff --git a/tyrian/js/src/main/scala/tyrian/Routing.scala b/tyrian/src/main/scala/tyrian/Routing.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/Routing.scala rename to tyrian/src/main/scala/tyrian/Routing.scala diff --git a/tyrian/js/src/main/scala/tyrian/Sub.scala b/tyrian/src/main/scala/tyrian/Sub.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/Sub.scala rename to tyrian/src/main/scala/tyrian/Sub.scala diff --git a/tyrian/js/src/main/scala/tyrian/TyrianAppF.scala b/tyrian/src/main/scala/tyrian/TyrianAppF.scala similarity index 83% rename from tyrian/js/src/main/scala/tyrian/TyrianAppF.scala rename to tyrian/src/main/scala/tyrian/TyrianAppF.scala index 6a6d0a25..dc6ca3c9 100644 --- a/tyrian/js/src/main/scala/tyrian/TyrianAppF.scala +++ b/tyrian/src/main/scala/tyrian/TyrianAppF.scala @@ -6,6 +6,7 @@ import org.scalajs.dom.Element import org.scalajs.dom.HTMLElement import org.scalajs.dom.document import org.scalajs.dom.window +import tyrian.runtime.TyrianRuntime import scala.annotation.nowarn import scala.scalajs.js.Promise @@ -110,7 +111,7 @@ trait TyrianAppF[F[_]: Async, Msg, Model]: def ready(node: Element, flags: Map[String, String]): Unit = run( - Tyrian.start[F, Model, Msg]( + TyrianAppF.start[F, Model, Msg]( node, router, _init(flags), @@ -165,3 +166,35 @@ object TyrianAppF: case (dataAttr, attrValue) if dataAttr.startsWith("tyrianFlag") => dataAttr.replaceFirst("^tyrianFlag", "") -> attrValue }.toMap + + /** Directly starts the app. Computes the initial state of the given application, renders it on the given DOM element, + * and listens to user actions + * @param init + * initial state + * @param update + * state transition function + * @param view + * view function + * @param subscriptions + * subscriptions function + * @param node + * the DOM element to mount the app to + * @param runner + * the function that runs the program. Has a type of `F[Option[Msg]] => (Either[Throwable, Option[Msg]] => Unit) => + * Unit`, essentially: `task.unsafeRunAsync(callback)` + * @tparam F + * The effect type to use, e.g. `IO` + * @tparam Model + * Type of model + * @tparam Msg + * Type of messages + */ + def start[F[_]: Async, Model, Msg]( + node: Element, + router: Location => Msg, + init: (Model, Cmd[F, Msg]), + update: Model => Msg => (Model, Cmd[F, Msg]), + view: Model => Html[Msg], + subscriptions: Model => Sub[F, Msg] + ): F[Nothing] = + TyrianRuntime[F, Model, Msg](router, node, init._1, init._2, update, view, subscriptions) diff --git a/tyrian/js/src/main/scala/tyrian/cmds/Dom.scala b/tyrian/src/main/scala/tyrian/cmds/Dom.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/cmds/Dom.scala rename to tyrian/src/main/scala/tyrian/cmds/Dom.scala diff --git a/tyrian/js/src/main/scala/tyrian/cmds/Download.scala b/tyrian/src/main/scala/tyrian/cmds/Download.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/cmds/Download.scala rename to tyrian/src/main/scala/tyrian/cmds/Download.scala diff --git a/tyrian/js/src/main/scala/tyrian/cmds/File.scala b/tyrian/src/main/scala/tyrian/cmds/File.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/cmds/File.scala rename to tyrian/src/main/scala/tyrian/cmds/File.scala diff --git a/tyrian/js/src/main/scala/tyrian/cmds/FileReader.scala b/tyrian/src/main/scala/tyrian/cmds/FileReader.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/cmds/FileReader.scala rename to tyrian/src/main/scala/tyrian/cmds/FileReader.scala diff --git a/tyrian/js/src/main/scala/tyrian/cmds/ImageLoader.scala b/tyrian/src/main/scala/tyrian/cmds/ImageLoader.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/cmds/ImageLoader.scala rename to tyrian/src/main/scala/tyrian/cmds/ImageLoader.scala diff --git a/tyrian/js/src/main/scala/tyrian/cmds/LocalStorage.scala b/tyrian/src/main/scala/tyrian/cmds/LocalStorage.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/cmds/LocalStorage.scala rename to tyrian/src/main/scala/tyrian/cmds/LocalStorage.scala diff --git a/tyrian/js/src/main/scala/tyrian/cmds/Logger.scala b/tyrian/src/main/scala/tyrian/cmds/Logger.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/cmds/Logger.scala rename to tyrian/src/main/scala/tyrian/cmds/Logger.scala diff --git a/tyrian/js/src/main/scala/tyrian/cmds/Random.scala b/tyrian/src/main/scala/tyrian/cmds/Random.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/cmds/Random.scala rename to tyrian/src/main/scala/tyrian/cmds/Random.scala diff --git a/tyrian/js/src/main/scala/tyrian/http/Decoder.scala b/tyrian/src/main/scala/tyrian/http/Decoder.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/http/Decoder.scala rename to tyrian/src/main/scala/tyrian/http/Decoder.scala diff --git a/tyrian/js/src/main/scala/tyrian/http/Http.scala b/tyrian/src/main/scala/tyrian/http/Http.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/http/Http.scala rename to tyrian/src/main/scala/tyrian/http/Http.scala diff --git a/tyrian/js/src/main/scala/tyrian/http/Models.scala b/tyrian/src/main/scala/tyrian/http/Models.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/http/Models.scala rename to tyrian/src/main/scala/tyrian/http/Models.scala diff --git a/tyrian/js/src/main/scala/tyrian/http/Request.scala b/tyrian/src/main/scala/tyrian/http/Request.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/http/Request.scala rename to tyrian/src/main/scala/tyrian/http/Request.scala diff --git a/tyrian/js/src/main/scala/tyrian/runtime/CmdHelper.scala b/tyrian/src/main/scala/tyrian/runtime/CmdHelper.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/runtime/CmdHelper.scala rename to tyrian/src/main/scala/tyrian/runtime/CmdHelper.scala diff --git a/tyrian/js/src/main/scala/tyrian/runtime/Renderer.scala b/tyrian/src/main/scala/tyrian/runtime/Renderer.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/runtime/Renderer.scala rename to tyrian/src/main/scala/tyrian/runtime/Renderer.scala diff --git a/tyrian/js/src/main/scala/tyrian/runtime/RendererState.scala b/tyrian/src/main/scala/tyrian/runtime/RendererState.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/runtime/RendererState.scala rename to tyrian/src/main/scala/tyrian/runtime/RendererState.scala diff --git a/tyrian/js/src/main/scala/tyrian/runtime/Rendering.scala b/tyrian/src/main/scala/tyrian/runtime/Rendering.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/runtime/Rendering.scala rename to tyrian/src/main/scala/tyrian/runtime/Rendering.scala diff --git a/tyrian/js/src/main/scala/tyrian/runtime/SubHelper.scala b/tyrian/src/main/scala/tyrian/runtime/SubHelper.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/runtime/SubHelper.scala rename to tyrian/src/main/scala/tyrian/runtime/SubHelper.scala diff --git a/tyrian/js/src/main/scala/tyrian/runtime/TyrianRuntime.scala b/tyrian/src/main/scala/tyrian/runtime/TyrianRuntime.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/runtime/TyrianRuntime.scala rename to tyrian/src/main/scala/tyrian/runtime/TyrianRuntime.scala diff --git a/tyrian/js/src/main/scala/tyrian/syntax.scala b/tyrian/src/main/scala/tyrian/syntax.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/syntax.scala rename to tyrian/src/main/scala/tyrian/syntax.scala diff --git a/tyrian/js/src/main/scala/tyrian/websocket/WebSocket.scala b/tyrian/src/main/scala/tyrian/websocket/WebSocket.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/websocket/WebSocket.scala rename to tyrian/src/main/scala/tyrian/websocket/WebSocket.scala diff --git a/tyrian/js/src/main/scala/tyrian/websocket/WebSocketEvent.scala b/tyrian/src/main/scala/tyrian/websocket/WebSocketEvent.scala similarity index 100% rename from tyrian/js/src/main/scala/tyrian/websocket/WebSocketEvent.scala rename to tyrian/src/main/scala/tyrian/websocket/WebSocketEvent.scala diff --git a/tyrian/js/src/main/scala/util/Functions.scala b/tyrian/src/main/scala/util/Functions.scala similarity index 100% rename from tyrian/js/src/main/scala/util/Functions.scala rename to tyrian/src/main/scala/util/Functions.scala diff --git a/tyrian/js/src/test/scala/tyrian/CmdLawsTest.scala b/tyrian/src/test/scala/tyrian/CmdLawsTest.scala similarity index 100% rename from tyrian/js/src/test/scala/tyrian/CmdLawsTest.scala rename to tyrian/src/test/scala/tyrian/CmdLawsTest.scala diff --git a/tyrian/js/src/test/scala/tyrian/CmdSubUtils.scala b/tyrian/src/test/scala/tyrian/CmdSubUtils.scala similarity index 100% rename from tyrian/js/src/test/scala/tyrian/CmdSubUtils.scala rename to tyrian/src/test/scala/tyrian/CmdSubUtils.scala diff --git a/tyrian/js/src/test/scala/tyrian/CmdTests.scala b/tyrian/src/test/scala/tyrian/CmdTests.scala similarity index 100% rename from tyrian/js/src/test/scala/tyrian/CmdTests.scala rename to tyrian/src/test/scala/tyrian/CmdTests.scala diff --git a/tyrian/js/src/test/scala/tyrian/SubLawsTest.scala b/tyrian/src/test/scala/tyrian/SubLawsTest.scala similarity index 100% rename from tyrian/js/src/test/scala/tyrian/SubLawsTest.scala rename to tyrian/src/test/scala/tyrian/SubLawsTest.scala diff --git a/tyrian/js/src/test/scala/tyrian/SubTests.scala b/tyrian/src/test/scala/tyrian/SubTests.scala similarity index 100% rename from tyrian/js/src/test/scala/tyrian/SubTests.scala rename to tyrian/src/test/scala/tyrian/SubTests.scala diff --git a/tyrian/js/src/test/scala/tyrian/cmds/RandomTests.scala b/tyrian/src/test/scala/tyrian/cmds/RandomTests.scala similarity index 100% rename from tyrian/js/src/test/scala/tyrian/cmds/RandomTests.scala rename to tyrian/src/test/scala/tyrian/cmds/RandomTests.scala