Skip to content

Commit 71911b6

Browse files
committed
.
1 parent b303771 commit 71911b6

13 files changed

+105
-75
lines changed

plugin/package.mill

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import mill.util.BuildInfo. millBinPlatform
44
import mill._, scalalib._, publish._
55
import mill.util.VcsVersion
66
import build.V
7+
import build.FormatFixPublish
78

8-
object `package` extends ScalaModule with PublishModule:
9+
object `package` extends ScalaModule with FormatFixPublish:
910
def platformSuffix = s"_mill$millBinPlatform"
1011

1112
def scalaVersion = build.V.scalaVersion

plugin/src/refresh_plugin.scala

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,15 @@
1-
package io.github.quafadas.RefreshPlugin
1+
package io.github.quafadas
22

33
import io.github.quafadas.sjsls.LiveServerConfig
44
import mill.*
55
import mill.scalalib.*
66
import mill.scalajslib.*
7-
import os.Path
7+
88
import mill.api.Task.Simple
99
import fs2.concurrent.Topic
1010
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.*
2411
import cats.effect.unsafe.implicits.global
2512
import io.github.quafadas.sjsls.LiveServerConfig
26-
import cats.effect.ExitCode
27-
import scala.util.{Try, Success, Failure}
28-
import scala.concurrent.Future
2913
import mill.api.BuildCtx
3014
import mill.scalajslib.api.Report
3115
implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global
@@ -36,17 +20,17 @@ trait ScalaJsRefreshModule extends ScalaJSModule:
3620

3721

3822
def indexHtml = Task{
39-
os.write.over(Task.dest / "index.html", io.github.quafadas.sjsls.vanillaTemplate)
23+
os.write.over(Task.dest / "index.html", io.github.quafadas.sjsls.vanillaTemplate(withStyles()))
4024
PathRef(Task.dest / "index.html")
4125
}
4226

43-
def assetsDir = Task{
44-
"assets"
45-
}
27+
def assetsDir =
28+
super.moduleDir / "assets"
4629

47-
def assets = Task{
48-
os.write.over(Task.dest / "style.css", io.github.quafadas.sjsls.lessStyle(true).render)
49-
PathRef(Task.dest / assetsDir())
30+
def withStyles = Task{ true}
31+
32+
def assets = Task.Source{
33+
assetsDir
5034
}
5135

5236
def port = Task {
@@ -66,33 +50,35 @@ trait ScalaJsRefreshModule extends ScalaJSModule:
6650
}
6751

6852
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())
53+
val assets_ = assets()
54+
val path = fastLinkJS().dest.path
55+
os.copy.over(indexHtml().path, Task.dest / "index.html")
56+
os.copy(assets_.path, Task.dest, mergeFolders = true)
57+
updateServer.publish1(println("publish update")).unsafeRunSync()
58+
(Task.dest.toString(), assets_.path.toString(), path.toString())
59+
7560
}
7661

7762
def lcs = Task.Worker{
78-
val (assets, js) = siteGen()
63+
val (site, assets, js) = siteGen()
64+
println("Gen lsc")
7965
LiveServerConfig(
8066
baseDir = None,
8167
outDir = Some(js),
8268
port = com.comcast.ip4s.Port.fromInt(port()).getOrElse(throw new IllegalArgumentException(s"invalid port: ${port()}")),
83-
indexHtmlTemplate = Some(assets),
69+
indexHtmlTemplate = Some(site),
8470
buildTool = io.github.quafadas.sjsls.NoBuildTool(), // Here we are a slave to the build tool
8571
openBrowserAt = "/index.html",
8672
preventBrowserOpen = !openBrowser(),
8773
dezombify = dezombify(),
88-
logLevel = logLevel()
74+
logLevel = logLevel(),
75+
customRefresh = Some(updateServer)
8976
)
9077
}
9178

9279
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()
9580

81+
println(lcs())
9682
BuildCtx.withFilesystemCheckerDisabled {
9783
new RefreshServer(lcs())
9884
}

sjsls/src/buildRunner.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ def buildRunner(
5252
invokeVia,
5353
extraBuildArgs
5454
)(logger)
55-
case n: NoBuildTool => logger.info("No build tool specified, skipping build").toResource
55+
case n: NoBuildTool =>
56+
logger.info("No build tool specified, skipping build").toResource
5657
end match
5758
end buildRunner
5859

sjsls/src/htmlGen.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,10 @@ private def makeInternalPreloads(ref: Ref[IO, Map[String, String]]) =
152152

153153
end makeInternalPreloads
154154

155-
def vanillaTemplate: String =
155+
def vanillaTemplate(styles: Boolean): String =
156156
val r = Ref.of[IO, Map[String, String]](Map.empty)
157157
r.flatMap( rf =>
158-
vanillaTemplate(true, rf, false).map(_.render)
158+
vanillaTemplate(styles, rf, false).map(_.render)
159159
).unsafeRunSync()(using cats.effect.unsafe.implicits.global)
160160

161161
def vanillaTemplate(withStyles: Boolean, ref: Ref[IO, Map[String, String]], attemptPreload: Boolean): IO[TypedTag[String]] =

sjsls/src/liveServer.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ object LiveServer extends IOApp:
8282
scribe.cats[IO].debug(s"Assuming port ${lsc.port} is free").toResource
8383
)
8484
fileToHashRef <- Ref[IO].of(Map.empty[String, String]).toResource
85-
refreshTopic <- lsc.customRefresh.fold(Topic[IO, Unit])(IO(_)).toResource
85+
refreshTopic <- lsc.customRefresh.fold(Topic[IO, Unit])(
86+
scribe.cats[IO].debug(s"Custom refresh topic supplied") >>
87+
IO(_)
88+
).toResource
8689
linkingTopic <- Topic[IO, Unit].toResource
8790
client <- EmberClientBuilder.default[IO].build
8891
baseDirPath <- lsc.baseDir.fold(Files[IO].currentWorkingDirectory.toResource)(toDirectoryPath)
@@ -136,7 +139,8 @@ object LiveServer extends IOApp:
136139
proxyRoutes,
137140
fileToHashRef,
138141
lsc.clientRoutingPrefix,
139-
lsc.injectPreloads
142+
lsc.injectPreloads,
143+
lsc.buildTool
140144
)(logger)
141145

142146
_ <- updateMapRef(outDirPath, fileToHashRef)(logger).toResource

sjsls/src/middleware/ETagMiddleware.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ object ETagMiddleware:
2424
) =
2525
mr.get
2626
.flatMap {
27+
2728
map =>
28-
// logger.trace(s"Responding with ETag at path: ${req.uri.path}") >>
2929
map.get(req.uri.path.toString.drop(1)) match
3030
case Some(hash) =>
31+
logger.debug("Map") >>
32+
logger.debug(map.toString) >>
3133
logger.debug(s"Found ETag: $hash in map for ${req.uri.path}") >>
3234
IO(
3335
resp.putHeaders(
@@ -69,6 +71,7 @@ object ETagMiddleware:
6971
case Some(foundEt) =>
7072
if etag == foundEt then
7173
logger.debug(s"ETag $etag found in cache at path ${req.uri.path}, returning 304") >>
74+
logger.debug("map is: " + map.toString) >>
7275
IO(Response[IO](Status.NotModified))
7376
else
7477
logger.debug(s"$etag not found in cache at path ${req.uri.path} returning 200") >>

sjsls/src/middleware/staticpathMiddleware.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ inline def cachedFileResponse(epochInstant: Instant, fullPath: Path, req: Reques
5353
val zdt = ZonedDateTime.ofInstant(Instant.ofEpochSecond(lastmod), ZoneId.of("GMT"))
5454
val response =
5555
if parseFromHeader(epochInstant, browserLastModifiedAt) == lastmod then
56-
logger.debug("Time matches, returning 304") >>
56+
logger.debug(s"Time matches, returning 304 for ${req.uri.path}") >>
5757
IO(
5858
respondWithCacheLastModified(Response[IO](Status.NotModified), zdt)
5959
)
6060
else
6161
logger.debug(lastmod.toString()) >>
62-
logger.debug("Last modified doesn't match, returning 200") >>
62+
logger.debug(s"Last modified doesn't match, returning 200 for ${req.uri.path}") >>
6363
IO(
6464
respondWithCacheLastModified(resp, zdt)
6565
)
@@ -70,7 +70,8 @@ inline def cachedFileResponse(epochInstant: Instant, fullPath: Path, req: Reques
7070
response
7171
}
7272
case _ =>
73-
OptionT.liftF(logger.debug("No If-Modified-Since headers in request")) >>
73+
OptionT.liftF(
74+
logger.debug(s"No If-Modified-Since headers in request ${req.uri.path}") ) >>
7475
service(req).map {
7576
resp =>
7677
respondWithCacheLastModified(

sjsls/src/refreshRoute.scala

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,39 @@ import fs2.concurrent.Topic
1111
import cats.effect.IO
1212

1313
import _root_.io.circe.syntax.EncoderOps
14+
import cats.effect.kernel.Ref
15+
import scribe.Scribe
16+
import cats.syntax.all.*
1417

15-
def refreshRoutes(refreshTopic: Topic[IO, Unit]) = HttpRoutes.of[IO] {
16-
case GET -> Root / "refresh" / "v1" / "sse" =>
17-
val keepAlive = fs2.Stream.fixedRate[IO](10.seconds).as(KeepAlive())
18-
Ok(
19-
keepAlive
20-
.merge(refreshTopic.subscribe(10).as(PageRefresh()))
21-
.map(msg => ServerSentEvent(Some(msg.asJson.noSpaces)))
22-
)
18+
19+
def refreshRoutes(refreshTopic: Topic[IO, Unit], buildTool: BuildTool,stringPath: fs2.io.file.Path, mr: Ref[IO, Map[String, String]], logger: Scribe[IO]) = HttpRoutes.of[IO] {
20+
21+
val keepAlive = fs2.Stream.fixedRate[IO](10.seconds).as(KeepAlive())
22+
val refresh = refreshTopic
23+
.subscribe(10)
24+
25+
buildTool match
26+
case _: NoBuildTool =>
27+
case GET -> Root / "refresh" / "v1" / "sse" =>
28+
Ok(
29+
keepAlive
30+
.merge(
31+
refresh
32+
.evalTap(_ =>
33+
// A different tool is responsible for linking, so we hash the files "on the fly" when an update is requested
34+
logger.debug("Updating Map Ref") >>
35+
updateMapRef(stringPath, mr)(logger)
36+
)
37+
.as(PageRefresh())
38+
)
39+
.map(msg => ServerSentEvent(Some(msg.asJson.noSpaces)))
40+
)
41+
case _ =>
42+
case GET -> Root / "refresh" / "v1" / "sse" =>
43+
println("Hit this one")
44+
Ok(
45+
keepAlive
46+
.merge(refresh.as(PageRefresh()))
47+
.map(msg => ServerSentEvent(Some(msg.asJson.noSpaces)))
48+
)
2349
}

sjsls/src/routes.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,26 @@ import cats.MonadThrow
1414
import cats.data.Kleisli
1515
import cats.data.OptionT
1616
import cats.effect.*
17-
import cats.effect.IO
1817
import cats.effect.kernel.Ref
1918
import cats.effect.kernel.Resource
2019
import cats.syntax.all.*
2120

21+
// TODO: Test that the map of hashes is updated, when an external build tool is responsible for refresh pulses
2222
def routes[F[_]: Files: MonadThrow](
2323
stringPath: String,
2424
refreshTopic: Topic[IO, Unit],
2525
indexOpts: Option[IndexHtmlConfig],
2626
proxyRoutes: HttpRoutes[IO],
2727
ref: Ref[IO, Map[String, String]],
2828
clientRoutingPrefix: Option[String],
29-
injectPreloads: Boolean
29+
injectPreloads: Boolean,
30+
buildTool: BuildTool
3031
)(logger: Scribe[IO]): Resource[IO, HttpRoutes[IO]] =
3132

3233
val traceLogger = traceLoggerMiddleware(logger)
3334
val zdt = ZonedDateTime.now()
3435

36+
// val linkedAppWithCaching: HttpRoutes[IO] = appRoute[IO](stringPath)
3537
val linkedAppWithCaching: HttpRoutes[IO] = ETagMiddleware(appRoute[IO](stringPath), ref)(logger)
3638
val spaRoutes = clientRoutingPrefix.map(s => (s, buildSpaRoute(indexOpts, ref, zdt, injectPreloads)(logger)))
3739
val staticRoutes = Some(staticAssetRoutes(indexOpts, ref, zdt, injectPreloads)(logger))
@@ -44,7 +46,7 @@ def routes[F[_]: Files: MonadThrow](
4446
)
4547

4648
val refreshableApp = traceLogger(
47-
refreshRoutes(refreshTopic).combineK(proxyRoutes).combineK(routes)
49+
refreshRoutes(refreshTopic, buildTool, fs2.io.file.Path(stringPath), ref, logger).combineK(proxyRoutes).combineK(routes)
4850
)
4951

5052
IO(refreshableApp).toResource

sjsls/src/staticWatcher.scala

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ import fs2.io.file.Path
2020
import scribe.Scribe
2121

2222
import cats.effect.*
23-
import cats.effect.IO
24-
import cats.effect.OutcomeIO
25-
import cats.effect.ResourceIO
23+
2624
import cats.syntax.all.*
2725

2826
def staticWatcher(
@@ -87,10 +85,10 @@ def updateMapRef(stringPath: fs2.io.file.Path, mr: Ref[IO, Map[String, String]])
8785
.walk(stringPath)
8886
.evalFilter(Files[IO].isRegularFile)
8987
.parEvalMap(maxConcurrent = 8)(path => fileHash(path).map(path -> _))
90-
// .evalTap {
91-
// case (path, hash) =>
92-
// logger.debug(s"File $path has hash $hash")
93-
// }
88+
.evalTap {
89+
case (path, hash) =>
90+
logger.debug(s"File $path has hash $hash")
91+
}
9492
.compile
9593
.toVector
9694
.flatMap(

0 commit comments

Comments
 (0)