Skip to content

Commit 6f5e118

Browse files
committed
.
1 parent 69a5955 commit 6f5e118

22 files changed

+616
-222
lines changed

build.mill

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
//| mill-jvm-version: 21
2-
//| mill-version: 1.0.3
2+
//| mill-version: 1.0.4
33
//| mvnDeps:
44
//| - com.lihaoyi::mill-contrib-buildinfo:$MILL_VERSION
55
//| - com.goyeau::mill-scalafix::0.6.0
6-
7-
8-
package build
6+
//| - io.github.quafadas:millSite_mill1_3.7:0.0.50
97

108
import os.copy.over
119
// import io.github.quafadas.millSite._
1210
import mill._, scalalib._, publish._, scalanativelib._
1311
import mill.scalalib.scalafmt.ScalafmtModule
1412
import mill.util.*
13+
import mill.util.BuildInfo.millVersion
1514

1615
import com.goyeau.mill.scalafix.ScalafixModule
1716
import java.text.Format
18-
// import io.github.quafadas.millSite.SiteModule
17+
import io.github.quafadas.millSite.SiteModule
18+
import mill.util.VcsVersion
1919

2020

2121
object V{
@@ -27,6 +27,8 @@ object V{
2727
val laminar = "17.2.1"
2828
val scalaJsDom = "2.8.1"
2929
val scalaJs = "1.19.0"
30+
val fs2 = "3.11.0"
31+
val millLibs = mvn"com.lihaoyi::mill-libs:$millVersion"
3032
}
3133

3234
trait FormatFix extends ScalafmtModule with ScalafixModule with ScalaModule
@@ -67,19 +69,6 @@ trait Testy extends TestModule.Munit with FormatFix {
6769
}
6870

6971

70-
// object site extends SiteModule {
71-
72-
// def scalaVersion = V.scalaVersion
73-
// def unidocDeps = Seq(build.sjsls, build.routes)
74-
// override def unidocTitle = "Scala JS Live Server API"
75-
76-
// override def repoLink = "https://github.com/Quafadas/live-server-scala-cli-js"
77-
78-
// override def latestVersion = "0.2.11"
79-
80-
81-
// }
82-
8372
// SN deps which aren't yet there.
8473
/**
8574
1 targets failed

plugin/package.mill

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package build.plugin
2+
3+
import mill.util.BuildInfo. millBinPlatform
4+
import mill._, scalalib._, publish._
5+
import mill.util.VcsVersion
6+
import build.V
7+
8+
object `package` extends ScalaModule with PublishModule:
9+
def platformSuffix = s"_mill$millBinPlatform"
10+
11+
def scalaVersion = build.V.scalaVersion
12+
13+
def scalaArtefactVersion: Task[String] =
14+
scalaVersion.map(_.split("\\.").take(2).mkString("."))
15+
16+
override def artifactName = "sjsls_plugin"
17+
18+
def mvnDeps = Task{
19+
super.mvnDeps() ++
20+
Seq(
21+
V.millLibs,
22+
mvn"co.fs2:fs2-io_3:${V.fs2}"
23+
)
24+
}
25+
26+
def moduleDeps = Seq(build.sjsls)
27+
28+
def artifactSuffix = s"${platformSuffix()}_${scalaArtefactVersion()}"
29+
30+
def publishVersion = VcsVersion.vcsState().format()
31+
// def publishVersion = "DONTUSEME"
32+
33+
override def pomSettings = Task {
34+
PomSettings(
35+
description = "Mill plugin for mdoc, static site generation",
36+
organization = "io.github.quafadas",
37+
url = "https://github.com/Quafadas/millSite",
38+
licenses = Seq(License.`Apache-2.0`),
39+
versionControl = VersionControl.github("quafadas", "millSite"),
40+
developers = Seq(
41+
Developer("quafadas", "Simon Parten", "https://github.com/quafadas")
42+
)
43+
)
44+
}

plugin/src/refresh_plugin.scala

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package io.github.quafadas.RefreshPlugin
2+
3+
import io.github.quafadas.sjsls.LiveServerConfig
4+
import mill.*
5+
import mill.scalalib.*
6+
import mill.scalajslib.*
7+
import os.Path
8+
import mill.api.Task.Simple
9+
import fs2.concurrent.Topic
10+
import cats.effect.IO
11+
// import mill.scalajslib.*
12+
// import coursier.maven.MavenRepository
13+
// import mill.api.Result
14+
// import mill.util.Jvm.createJar
15+
// import mill.define.PathRef
16+
// import mill.scalalib.api.CompilationResult
17+
// // import de.tobiasroeser.mill.vcs.version.VcsVersion
18+
// import scala.util.Try
19+
// import mill.scalalib.publish.PomSettings
20+
// import mill.scalalib.publish.License
21+
// import mill.scalalib.publish.VersionControl
22+
// import os.SubPath
23+
// import ClasspathHelp.*
24+
import cats.effect.unsafe.implicits.global
25+
import io.github.quafadas.sjsls.LiveServerConfig
26+
import cats.effect.ExitCode
27+
import scala.util.{Try, Success, Failure}
28+
import scala.concurrent.Future
29+
import mill.api.BuildCtx
30+
import mill.scalajslib.api.Report
31+
implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global
32+
33+
trait ScalaJsRefreshModule extends ScalaJSModule:
34+
35+
lazy val updateServer = Topic[IO, Unit].unsafeRunSync()
36+
37+
38+
def indexHtml = Task{
39+
os.write.over(Task.dest / "index.html", io.github.quafadas.sjsls.vanillaTemplate)
40+
PathRef(Task.dest / "index.html")
41+
}
42+
43+
def assetsDir = Task{
44+
"assets"
45+
}
46+
47+
def assets = Task{
48+
os.write.over(Task.dest / "style.css", io.github.quafadas.sjsls.lessStyle(true).render)
49+
PathRef(Task.dest / assetsDir())
50+
}
51+
52+
def port = Task {
53+
8080
54+
}
55+
56+
def openBrowser= Task {
57+
true
58+
}
59+
60+
def logLevel = Task {
61+
"warn"
62+
}
63+
64+
def dezombify = Task {
65+
true
66+
}
67+
68+
def siteGen = Task{
69+
val assets_ = assets()
70+
val path = fastLinkJS().dest
71+
os.copy.over(Task.dest / "index.html", indexHtml().path)
72+
os.copy.over(Task.dest / assetsDir(), assets_.path)
73+
updateServer.publish1(println("publishing update"))
74+
(assets_.path.toString(), path.path.toString())
75+
}
76+
77+
def lcs = Task.Worker{
78+
val (assets, js) = siteGen()
79+
LiveServerConfig(
80+
baseDir = None,
81+
outDir = Some(js),
82+
port = com.comcast.ip4s.Port.fromInt(port()).getOrElse(throw new IllegalArgumentException(s"invalid port: ${port()}")),
83+
indexHtmlTemplate = Some(assets),
84+
buildTool = io.github.quafadas.sjsls.NoBuildTool(), // Here we are a slave to the build tool
85+
openBrowserAt = "/index.html",
86+
preventBrowserOpen = !openBrowser(),
87+
dezombify = dezombify(),
88+
logLevel = logLevel()
89+
)
90+
}
91+
92+
def serve = Task.Worker{
93+
// Let's kill off anything that is a zombie on the port we want to use
94+
val p = port()
95+
96+
BuildCtx.withFilesystemCheckerDisabled {
97+
new RefreshServer(lcs())
98+
}
99+
}
100+
101+
class RefreshServer(lcs: LiveServerConfig) extends AutoCloseable {
102+
val server = io.github.quafadas.sjsls.LiveServer.main(lcs).allocated
103+
104+
server.map(_._1).unsafeRunSync()
105+
106+
override def close(): Unit = {
107+
// This is the shutdown hook for http4s
108+
println("Shutting down server...")
109+
server.map(_._2).flatten.unsafeRunSync()
110+
}
111+
}
112+

site/docs/Configuration/config.md

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Config
22

3-
The server is a CLI. It has a number of flags that can be used to configure it. Here is the current list of flags and what they do. You can see these flags by running ` --help` in your terminal.
3+
The CLI launches an http server. It has a number of flags that can be used to configure it. Here is the current list of flags and what they do. You can see these flags by running ` --help` in your terminal.
44

5-
```
6-
cs launch io.github.quafadas::sjsls:{{projectVersion}} -- --help
5+
```sh
6+
cs launch io.github.quafadas::sjsls:latest.version -- --help
77

88
```
99

@@ -56,7 +56,7 @@ Fire up a terminal in projectDir
5656
```
5757

5858
```sh
59-
cs launch io.github.quafadas::sjsls:{{projectVersion}}
59+
cs launch io.github.quafadas::sjsls:latest.version
6060
```
6161
This is the classic [viteless](https://github.com/Quafadas/viteless/tree/main) example
6262

@@ -73,7 +73,7 @@ With styles.
7373
Run
7474

7575
```sh
76-
cs launch io.github.quafadas::sjsls:{{projectVersion}} -- --styles-dir --fully/qualified/dir/to/styles
76+
cs launch io.github.quafadas::sjsls:latest.version -- --styles-dir --fully/qualified/dir/to/styles
7777
```
7878

7979
## Did I mention I want a full blown SPA?
@@ -89,7 +89,7 @@ With client side routing under `/app`?
8989
Run
9090

9191
```sh
92-
cs launch io.github.quafadas::sjsls:{{projectVersion}} -- --client-routes-prefix app
92+
cs launch io.github.quafadas::sjsls:latest.version -- --client-routes-prefix app
9393
```
9494

9595
## Stop generating my HTML. I want to bring my own.
@@ -105,7 +105,7 @@ Okay.
105105
```
106106
With
107107
```sh
108-
cs launch io.github.quafadas::sjsls:{{projectVersion}} -- --path-to-index-html fully/qualified/path/to/assets
108+
cs launch io.github.quafadas::sjsls:latest.version -- --path-to-index-html fully/qualified/path/to/assets
109109
```
110110

111111
Note: if you're brining your own html, drop the `--styles` flag - reference `index.less` from your html and read [docs](https://lesscss.org) to get it working in browser.
@@ -134,7 +134,7 @@ With a backend running on `8080` and a frontend on `3000`, it is configured that
134134
Also, we're now using mill. We need to tell the cli the frontend module name and the directory the compiles JS ends up in.
135135

136136
```sh
137-
cs launch io.github.quafadas::sjsls:{{projectVersion}} -- \
137+
cs launch io.github.quafadas::sjsls:latest.version -- \
138138
--path-to-index-html /Users/simon/Code/mill-full-stack/frontend/ui \
139139
--build-tool mill \
140140
--mill-module-name frontend \
@@ -153,7 +153,6 @@ This would serve the static site build with the `docJar` tool.
153153
C:\temp\live-server-scala-cli-js> cs launch io.github.quafadas::sjsls:0.2.0 -- --path-to-index-html C:\\temp\\live-server-scala-cli-js\\out\\site\\live.dest\\site --build-tool none --browse-on-open-at /docs/index.html
154154
```
155155

156-
***
157156
You need to include this javascript script tag in the body html - otherwise no page refresh.
158157

159158
```html
@@ -167,5 +166,4 @@ You need to include this javascript script tag in the body html - otherwise no p
167166
if ("PageRefresh" in msg) location.reload();
168167
});
169168
</script>
170-
```
171-
***
169+
```

site/docs/Configuration/library.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Library
2+
3+
The LiveServerConfig can also accept an `fs2.Topic` as a parameter. This allows any tool which can instantiate an `fs2.Topic` to emit a pulse, which will refresh the client. Have a look at the mill plugin code for details.

site/docs/advantages.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Here are the key advantages of this approach:
88

99
- Because there's no seperate ecosystem or NPM to configure, configuring build and CI is a lot easier. No `node_modules` to worry about. I found that this simplicity infected everything around it.
1010

11-
- In terms of performance; NPM dependancies are loaded out the CDN. This is slow the first time - but seriously - check the network browser tools when you refresh the page. The second time they are all served out of browser cache - it takes 0ms. Even better, that cache _survives application redeployment!_. If you pre-load the (fat) "internal-" xxx dependancies scalaJS produces, this combination crushes page load times.
11+
- In terms of performance; NPM dependancies are loaded out the CDN. This is slow the first time, but check the network browser tools when you refresh the page. The second time they are all served out of browser cache - it takes 0ms. Even better, that cache _survives application redeployment!_.
1212

1313
- You can use the same build tool for both backend and frontend, and share code between them.
1414

site/docs/caveats.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ It is usually possible to work around such limitations, but it is not pain free.
1212

1313
I strongly suspect though that as time marches formward ESModules will become the norm, and this limitation will become irrelevant.
1414

15-
# Scale
15+
## Support
1616

17-
This project is not backed by anyone making money from it. Support is therefore ad hoc and limited.
17+
This project is not backed by any power larger than my curiosity.

site/docs/deployment.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
title: Deployment
1+
Deployment
22
---
33

44
This project targets the dev loop. When comes to deploy however, I always hit the same problem. From discord;

site/docs/index.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,15 @@
44
55
Paste this into your terminal and hit enter.
66

7-
${version.latest}
8-
97
```sh
108
scala-cli --version && \
119
cs version && \
1210
git clone https://github.com/Quafadas/viteless.git && \
1311
cd viteless && \
14-
cs launch io.github.quafadas::sjsls:${{version.latest}}
12+
cs launch io.github.quafadas::sjsls:latest.release
1513
```
1614

17-
Note that to work, you need the following directives in scala-cli:
15+
Note that to work, you need cs and scala-cli to be on your path.
1816

1917

2018
## It worked... okay... I have 20 more seconds
@@ -26,11 +24,10 @@ Edit `hello.scala` and save the change. You should see the change refreshed in y
2624

2725
## Aw shoot - errors
2826

29-
The command above assumes you have coursier (as cs) and scala-cli installed and available on your path.
27+
The command above assumes you have coursier (as cs) and scala-cli and git installed and available on your path.
3028

3129
If you don't have those, consider visiting their respective websites and setting up those tools - they are both excellent and fundamental to the scala ecosystem, you'll need them at some point ...
3230

3331
- [coursier](https://get-coursier.io/docs/cli-installation)
3432
- [scala-cli](https://scala-cli.virtuslab.org)
3533

36-
Once installed, give it another go.

site/docs/motivation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
I'm a big scala JS fan. However, the reliance on vite for the dev loop / deployment complexified my build piplines to the point where full stack wasn't fun for me anymore. I found maintaining _both_ a JVM setup and a node setup was annoying locally.
44

5-
And then I had do it again in CI. So, intead of giving up on scala JS and going to write typescript, I figured it would be way more fun to simply try and go 100% scala.
5+
And then I had do it again in CI. So, intead of giving up on scala JS and going to write typescript, I figured it would be way more fun to simply try and go 100% scala - zero friction save, link, refresh.
66

77
I wanted to break the dependance on node / npm completely whilst retaining a sane developer experience for browser based scala-js development.

0 commit comments

Comments
 (0)