Skip to content

Commit 38e5b6a

Browse files
committed
enable wasm
1 parent 92593d9 commit 38e5b6a

File tree

7 files changed

+74
-46
lines changed

7 files changed

+74
-46
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ testDir
66
.bsp
77
out
88
.bloop
9-
.DS_Store
9+
.DS_Store
10+
.vscode/mcp.json

.mill-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.12.8
1+
0.12.10

routes/src/app.route.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ def appRoute[F[_]: Files](stringPath: String)(using f: Async[F]): HttpRoutes[F]
1919
.fromPath(fs2.io.file.Path(stringPath) / req.uri.path.renderString, Some(req))
2020
.getOrElseF(f.pure(Response[F](Status.NotFound)))
2121

22+
case req @ GET -> Root / fName ~ "wasm" =>
23+
StaticFile
24+
.fromPath(fs2.io.file.Path(stringPath) / req.uri.path.renderString, Some(req))
25+
.getOrElseF(f.pure(Response[F](Status.NotFound)))
26+
2227
case req @ GET -> Root / fName ~ "map" =>
2328
StaticFile
2429
.fromPath(fs2.io.file.Path(stringPath) / req.uri.path.renderString, Some(req))

site/docs/_docs/config.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,18 +145,18 @@ cs launch io.github.quafadas::sjsls:{{projectVersion}} -- \
145145

146146
```
147147

148-
## Static site, no build tool.
148+
## Static site, no build tool.
149149

150-
This would serve the static site build with the `docJar` tool.
150+
This would serve the static site build with the `docJar` tool.
151151

152-
```sh
152+
```sh
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

156156
***
157157
You need to include this javascript script tag in the body html - otherwise no page refresh.
158158

159-
```
159+
```html
160160
<script>
161161
const sse = new EventSource("/refresh/v1/sse");
162162
sse.addEventListener("message", (e) => {

sjsls/src/middleware/ETagMiddleware.scala

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,39 +19,42 @@ import cats.syntax.all.*
1919

2020
object ETagMiddleware:
2121

22+
private def respondWithEtag(mr: Ref[IO, Map[String, String]], req: Request[IO], resp: Response[IO])(
23+
logger: Scribe[IO]
24+
) =
25+
mr.get
26+
.flatMap {
27+
map =>
28+
// logger.trace(s"Responding with ETag at path: ${req.uri.path}") >>
29+
map.get(req.uri.path.toString.drop(1)) match
30+
case Some(hash) =>
31+
logger.debug(s"Found ETag: $hash in map for ${req.uri.path}") >>
32+
IO(
33+
resp.putHeaders(
34+
Header.Raw(ci"ETag", hash),
35+
Header.Raw(ci"Cache-control", "Must-Revalidate"),
36+
Header.Raw(ci"Cache-control", "No-cache"),
37+
Header.Raw(ci"Cache-control", "max-age=0"),
38+
Header.Raw(ci"Cache-control", "public")
39+
)
40+
)
41+
case None =>
42+
logger.debug("No hash found in map at path :" + req.uri.toString) >>
43+
IO(
44+
resp.putHeaders(
45+
Header.Raw(ci"Cache-control", "Must-Revalidate"),
46+
Header.Raw(ci"Cache-control", "No-cache"),
47+
Header.Raw(ci"Cache-control", "max-age=0"),
48+
Header.Raw(ci"Cache-control", "public")
49+
)
50+
)
51+
end match
52+
}
53+
end respondWithEtag
54+
2255
def apply(service: HttpRoutes[IO], mr: Ref[IO, Map[String, String]])(logger: Scribe[IO]): HttpRoutes[IO] = Kleisli {
2356
(req: Request[IO]) =>
2457

25-
def respondWithEtag(resp: Response[IO]) =
26-
mr.get
27-
.flatMap {
28-
map =>
29-
map.get(req.uri.path.toString.drop(1)) match
30-
case Some(hash) =>
31-
logger.debug(req.uri.toString) >>
32-
IO(
33-
resp.putHeaders(
34-
Header.Raw(ci"ETag", hash),
35-
Header.Raw(ci"Cache-control", "Must-Revalidate"),
36-
Header.Raw(ci"Cache-control", "No-cache"),
37-
Header.Raw(ci"Cache-control", "max-age=0"),
38-
Header.Raw(ci"Cache-control", "public")
39-
)
40-
)
41-
case None =>
42-
logger.debug(req.uri.toString) >>
43-
IO(
44-
resp.putHeaders(
45-
Header.Raw(ci"Cache-control", "Must-Revalidate"),
46-
Header.Raw(ci"Cache-control", "No-cache"),
47-
Header.Raw(ci"Cache-control", "max-age=0"),
48-
Header.Raw(ci"Cache-control", "public")
49-
)
50-
)
51-
end match
52-
}
53-
end respondWithEtag
54-
5558
req.headers.get(ci"If-None-Match") match
5659
case Some(header) =>
5760
val etag = header.head.value
@@ -65,23 +68,24 @@ object ETagMiddleware:
6568
map.get(req.uri.path.toString.drop(1)) match
6669
case Some(foundEt) =>
6770
if etag == foundEt then
68-
logger.debug("ETag matches, returning 304") >>
71+
logger.debug(s"ETag $etag found in cache at path ${req.uri.path}, returning 304") >>
6972
IO(Response[IO](Status.NotModified))
7073
else
71-
logger.debug(etag) >>
72-
logger.debug("ETag doesn't match, returning 200") >>
73-
respondWithEtag(resp)
74+
logger.debug(s"$etag not found in cache at path ${req.uri.path} returning 200") >>
75+
respondWithEtag(mr, req, resp)(logger)
7476
end if
7577
case None =>
76-
respondWithEtag(resp)
78+
logger.debug(s"No path found in cache at path ${req.uri.path}") >>
79+
respondWithEtag(mr, req, resp)(logger)
7780
}
7881
}
7982
case _ =>
80-
OptionT.liftF(logger.debug("No ETag header in query, service it")) >>
83+
OptionT.liftF(logger.debug("No If-None-Match ETag header in request")) >>
84+
OptionT.liftF(logger.debug(s"Headers are : ${req.headers.headers.mkString(", ")} at ${req.uri.path}")) >>
8185
service(req).semiflatMap {
8286
resp =>
83-
logger.trace(resp.toString) >>
84-
respondWithEtag(resp)
87+
logger.debug(resp.toString) >>
88+
respondWithEtag(mr, req, resp)(logger)
8589
}
8690
end match
8791
}

sjsls/src/static.watcher.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ def updateMapRef(stringPath: fs2.io.file.Path, mr: Ref[IO, Map[String, String]])
8787
.walk(stringPath)
8888
.evalFilter(Files[IO].isRegularFile)
8989
.parEvalMap(maxConcurrent = 8)(path => fileHash(path).map(path -> _))
90+
// .evalTap {
91+
// case (path, hash) =>
92+
// logger.debug(s"File $path has hash $hash")
93+
// }
9094
.compile
9195
.toVector
9296
.flatMap(

sjsls/test/src/RoutesSpec.scala

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class RoutesSuite extends CatsEffectSuite:
3434
val testStr = "const hi = 'Hello, world'"
3535
val simpleCss = "h1 {color: red;}"
3636
val testHash = md.digest(testStr.getBytes()).map("%02x".format(_)).mkString
37+
val testBinary = os.read.bytes(os.resource / "cat.webp")
3738
given filesInstance: Files[IO] = Files.forAsync[IO]
3839

3940
val files = FunFixture[os.Path](
@@ -45,6 +46,7 @@ class RoutesSuite extends CatsEffectSuite:
4546
os.write(tempFile, testStr)
4647
os.write(tempDir / "test2.js", testStr)
4748
os.write(tempDir / "test3.js", testStr)
49+
os.write(tempDir / "test.wasm", testBinary)
4850
tempDir
4951
,
5052
teardown = tempDir =>
@@ -148,6 +150,7 @@ class RoutesSuite extends CatsEffectSuite:
148150

149151
files.test(
150152
"That the routes serve files on first call with a 200, that the eTag is set, and on second call with a 304, that index.html is served from SPA"
153+
.only
151154
) {
152155
tempDir =>
153156

@@ -156,7 +159,7 @@ class RoutesSuite extends CatsEffectSuite:
156159
.root
157160
.clearHandlers()
158161
.clearModifiers()
159-
.withHandler(minimumLevel = Some(Level.get("error").get))
162+
.withHandler(minimumLevel = Some(Level.get("debug").get))
160163
.replace()
161164

162165
val aLogger = scribe.cats[IO]
@@ -208,6 +211,17 @@ class RoutesSuite extends CatsEffectSuite:
208211
org.http4s.Headers.of(org.http4s.Header.Raw(ci"If-None-Match", testHash))
209212
)
210213

214+
val requestWasm = org.http4s.Request[IO](uri = org.http4s.Uri.unsafeFromString("/test.wasm"))
215+
216+
val checkWasm = client
217+
.run(requestWasm)
218+
.use {
219+
resp =>
220+
assertEquals(resp.status.code, 200)
221+
assertEquals(resp.headers.get(ci"ETag").isDefined, true)
222+
IO.unit
223+
}
224+
211225
val checkResp2 = client
212226
.run(request2)
213227
.use {
@@ -237,7 +251,7 @@ class RoutesSuite extends CatsEffectSuite:
237251
assertEquals(respH.headers.get(ci"ETag").isDefined, true)
238252
IO.unit
239253
}
240-
checkResp1 >> checkResp2 >> checkRespSpa >> checkRespHtml
254+
checkResp1 >> checkResp2 >> checkWasm >> checkRespSpa >> checkRespHtml
241255

242256
}
243257
}

0 commit comments

Comments
 (0)