Skip to content

Commit 60d5b39

Browse files
authored
Merge pull request #117 from http4s/integration/0.2-main-20220319
Merge 0.2 -> main
2 parents f074c01 + e36b21f commit 60d5b39

File tree

15 files changed

+444
-142
lines changed

15 files changed

+444
-142
lines changed

.github/workflows/ci.yml

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ on:
1717
env:
1818
PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}
1919
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
20+
SONATYPE_CREDENTIAL_HOST: ${{ secrets.SONATYPE_CREDENTIAL_HOST }}
2021
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
2122
PGP_SECRET: ${{ secrets.PGP_SECRET }}
2223
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -41,12 +42,21 @@ jobs:
4142
with:
4243
fetch-depth: 0
4344

45+
- name: Download Java (temurin@8)
46+
id: download-java-temurin-8
47+
if: matrix.java == 'temurin@8'
48+
uses: typelevel/download-java@v1
49+
with:
50+
distribution: temurin
51+
java-version: 8
52+
4453
- name: Setup Java (temurin@8)
4554
if: matrix.java == 'temurin@8'
4655
uses: actions/setup-java@v2
4756
with:
48-
distribution: temurin
57+
distribution: jdkfile
4958
java-version: 8
59+
jdkFile: ${{ steps.download-java-temurin-8.outputs.jdkFile }}
5060

5161
- name: Cache sbt
5262
uses: actions/cache@v2
@@ -113,12 +123,21 @@ jobs:
113123
with:
114124
fetch-depth: 0
115125

126+
- name: Download Java (temurin@8)
127+
id: download-java-temurin-8
128+
if: matrix.java == 'temurin@8'
129+
uses: typelevel/download-java@v1
130+
with:
131+
distribution: temurin
132+
java-version: 8
133+
116134
- name: Setup Java (temurin@8)
117135
if: matrix.java == 'temurin@8'
118136
uses: actions/setup-java@v2
119137
with:
120-
distribution: temurin
138+
distribution: jdkfile
121139
java-version: 8
140+
jdkFile: ${{ steps.download-java-temurin-8.outputs.jdkFile }}
122141

123142
- name: Cache sbt
124143
uses: actions/cache@v2
@@ -154,12 +173,12 @@ jobs:
154173
155174
- name: Import signing key
156175
if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE == ''
157-
run: echo $PGP_SECRET | base64 -d | gpg --import
176+
run: echo $PGP_SECRET | base64 -di | gpg --import
158177

159178
- name: Import signing key and strip passphrase
160179
if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE != ''
161180
run: |
162-
echo "$PGP_SECRET" | base64 -d > /tmp/signing-key.gpg
181+
echo "$PGP_SECRET" | base64 -di > /tmp/signing-key.gpg
163182
echo "$PGP_PASSPHRASE" | gpg --pinentry-mode loopback --passphrase-fd 0 --import /tmp/signing-key.gpg
164183
(echo "$PGP_PASSPHRASE"; echo; echo) | gpg --command-fd 0 --pinentry-mode loopback --change-passphrase $(gpg --list-secret-keys --with-colons 2> /dev/null | grep '^sec:' | cut --delimiter ':' --fields 5 | tail -n 1)
165184
@@ -180,12 +199,21 @@ jobs:
180199
with:
181200
fetch-depth: 0
182201

202+
- name: Download Java (temurin@8)
203+
id: download-java-temurin-8
204+
if: matrix.java == 'temurin@8'
205+
uses: typelevel/download-java@v1
206+
with:
207+
distribution: temurin
208+
java-version: 8
209+
183210
- name: Setup Java (temurin@8)
184211
if: matrix.java == 'temurin@8'
185212
uses: actions/setup-java@v2
186213
with:
187-
distribution: temurin
214+
distribution: jdkfile
188215
java-version: 8
216+
jdkFile: ${{ steps.download-java-temurin-8.outputs.jdkFile }}
189217

190218
- name: Cache sbt
191219
uses: actions/cache@v2
@@ -208,4 +236,4 @@ jobs:
208236
with:
209237
github_token: ${{ secrets.GITHUB_TOKEN }}
210238
publish_dir: site/target/docs/site
211-
publish_branch: gh-pages
239+
keep_files: true

.scalafmt.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version = 3.4.0
1+
version = 3.4.3
22

33
runner.dialect = Scala213Source3
44

README.md

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

3-
Use http4s in your browser with Scala.js! Check out the [live example](https://http4s.github.io/http4s-dom/) in the docs.
4-
3+
Use http4s in your browser with Scala.js! Check out the [interactive examples](https://http4s.github.io/http4s-dom/) in the docs.
54

65
Features:
76

8-
* A [`Client` implementation](https://www.javadoc.io/doc/org.http4s/http4s-dom_sjs1_2.13/latest/org/http4s/dom/FetchClientBuilder.html) backed by [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
9-
* A [`Service Worker` integration](https://www.javadoc.io/doc/org.http4s/http4s-dom_sjs1_2.13/latest/org/http4s/dom/ServiceWorker$.html) to install your `HttpRoutes` as a [`FetchEvent` handler](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/onfetch)
7+
* A [`Client` implementation](fetch.md) backed by [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
8+
* A [`WSClient` implementation](websocket.md) backed by [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket$.html)
9+
* A [`Service Worker` integration](serviceworker.md) to install your `HttpRoutes` as a [`FetchEvent` handler](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/onfetch)
1010
* Encoders for [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File), [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) and [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)
1111

1212
Notably, http4s-dom can also be used to create _serverless_ apps with [Cloudflare Workers](https://workers.cloudflare.com) which have adopted the same APIs used in the browser!
@@ -16,9 +16,6 @@ Notably, http4s-dom can also be used to create _serverless_ apps with [Cloudflar
1616
[![http4s-dom Scala version support](https://index.scala-lang.org/http4s/http4s-dom/http4s-dom/latest.svg)](https://index.scala-lang.org/http4s/http4s-dom/http4s-dom)
1717

1818
```scala
19-
// Supports http4s 0.23.x and scala-js-dom 2.x
20-
libraryDependencies += "org.http4s" %%% "http4s-dom" % "0.2.0"
21-
22-
// Or, for compatibility with scala-js-dom 1.x
23-
libraryDependencies += "org.http4s" %%% "http4s-dom" % "0.1.0"
19+
// Supports http4s 0.23.x
20+
libraryDependencies += "org.http4s" %%% "http4s-dom" % "0.2.1"
2421
```

build.sbt

Lines changed: 27 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -53,29 +53,35 @@ Global / fileServicePort := {
5353
import cats.data.Kleisli
5454
import cats.effect.IO
5555
import cats.effect.unsafe.implicits.global
56-
import com.comcast.ip4s.Port
57-
import org.http4s.ember.server.EmberServerBuilder
56+
import org.http4s._
57+
import org.http4s.dsl.io._
58+
import org.http4s.blaze.server.BlazeServerBuilder
5859
import org.http4s.server.staticcontent._
60+
import java.net.InetSocketAddress
5961

6062
(for {
6163
deferredPort <- IO.deferred[Int]
62-
_ <- EmberServerBuilder
63-
.default[IO]
64-
.withPort(Port.fromInt(0).get)
65-
.withHttpApp {
66-
Kleisli { req =>
67-
fileService[IO](FileService.Config(".")).orNotFound.run(req).map { res =>
68-
// TODO find out why mime type is not auto-inferred
69-
if (req.uri.renderString.endsWith(".js"))
70-
res.withHeaders(
71-
"Service-Worker-Allowed" -> "/",
72-
"Content-Type" -> "text/javascript"
73-
)
74-
else res
64+
_ <- BlazeServerBuilder[IO]
65+
.bindSocketAddress(new InetSocketAddress("localhost", 0))
66+
.withHttpWebSocketApp { wsb =>
67+
HttpRoutes
68+
.of[IO] {
69+
case Method.GET -> Root / "ws" =>
70+
wsb.build(identity)
71+
case req =>
72+
fileService[IO](FileService.Config(".")).orNotFound.run(req).map { res =>
73+
// TODO find out why mime type is not auto-inferred
74+
if (req.uri.renderString.endsWith(".js"))
75+
res.withHeaders(
76+
"Service-Worker-Allowed" -> "/",
77+
"Content-Type" -> "text/javascript"
78+
)
79+
else res
80+
}
7581
}
76-
}
82+
.orNotFound
7783
}
78-
.build
84+
.resource
7985
.map(_.address.getPort)
8086
.evalTap(deferredPort.complete(_))
8187
.useForever
@@ -103,9 +109,9 @@ ThisBuild / Test / jsEnv := {
103109
}
104110
}
105111

106-
val catsEffectVersion = "3.3.5"
107-
val fs2Version = "3.2.4"
108-
val http4sVersion = "1.0.0-M31"
112+
val catsEffectVersion = "3.3.8"
113+
val fs2Version = "3.2.5"
114+
val http4sVersion = "1.0.0-M32"
109115
val scalaJSDomVersion = "2.1.0"
110116
val circeVersion = "0.15.0-M1"
111117
val munitVersion = "0.7.29"
@@ -133,7 +139,7 @@ lazy val tests = project
133139
.settings(
134140
scalaJSUseMainModuleInitializer := true,
135141
(Test / test) := (Test / test).dependsOn(Compile / fastOptJS).value,
136-
buildInfoKeys := Seq[BuildInfoKey](scalaVersion),
142+
buildInfoKeys := Seq[BuildInfoKey](scalaVersion, fileServicePort),
137143
buildInfoPackage := "org.http4s.dom",
138144
libraryDependencies ++= Seq(
139145
"org.scalameta" %%% "munit" % munitVersion % Test,
@@ -155,48 +161,16 @@ lazy val jsdocs =
155161
)
156162
.enablePlugins(ScalaJSPlugin)
157163

158-
import laika.ast.Path.Root
159-
import laika.ast._
160-
import laika.ast.LengthUnit._
161-
import laika.helium.Helium
162-
import laika.helium.config.{
163-
Favicon,
164-
HeliumIcon,
165-
IconLink,
166-
ImageLink,
167-
ReleaseInfo,
168-
Teaser,
169-
TextLink
170-
}
171-
import laika.theme.config.Color
172-
173-
Global / excludeLintKeys += laikaDescribe
174-
175164
lazy val docs = project
176165
.in(file("site"))
177166
.settings(
178-
libraryDependencies += "org.scala-js" %% "scalajs-linker" % scalaJSVersion,
179-
libraryDependencies += {
180-
scalaBinaryVersion.value match {
181-
// keep these pinned to mdoc.js Scala versions
182-
// scala-steward:off
183-
case "2.12" =>
184-
("org.scala-js" %% "scalajs-compiler" % scalaJSVersion).cross(
185-
CrossVersion.constant("2.12.15"))
186-
case "2.13" | "3" =>
187-
("org.scala-js" %% "scalajs-compiler" % scalaJSVersion).cross(
188-
CrossVersion.constant("2.13.6"))
189-
// scala-steward:on
190-
}
191-
},
192167
tlFatalWarningsInCi := false,
193168
mdocJS := Some(jsdocs),
194169
mdocVariables ++= Map(
195170
"js-opt" -> "fast",
196171
"HTTP4S_VERSION" -> http4sVersion,
197172
"CIRCE_VERSION" -> circeVersion
198173
),
199-
laikaDescribe := "<disabled>",
200174
laikaConfig ~= { _.withRawContent },
201175
tlSiteHeliumConfig ~= {
202176
// Actually, this *disables* auto-linking, to avoid duplicates with mdoc

docs/README.md

Lines changed: 0 additions & 66 deletions
This file was deleted.

docs/directory.conf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
laika.navigationOrder = [
2+
index.md
3+
fetch.md
4+
websocket.md
5+
serviceworker.md
6+
]

docs/fetch.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Fetch Client
2+
3+
The [`FetchClientBuilder`](https://www.javadoc.io/doc/org.http4s/http4s-dom_sjs1_2.13/latest/org/http4s/dom/FetchClientBuilder.html) creates a standard http4s [`Client`](https://http4s.org/v0.23/api/org/http4s/client/client) that is described in the [http4s documentation](https://http4s.org/v0.23/client/).
4+
5+
## Example
6+
7+
```scala mdoc:js
8+
<div style="text-align:center">
9+
<h3 style="padding:10px">
10+
I'm bored.
11+
</h3>
12+
<button id="button">Fetch Activity</button>
13+
<p style="padding:10px" id="activity"></p>
14+
</div>
15+
---
16+
import cats.effect._
17+
import cats.effect.unsafe.implicits._
18+
import io.circe.generic.auto._
19+
import org.http4s.circe.CirceEntityCodec._
20+
import org.http4s.dom._
21+
import org.scalajs.dom._
22+
23+
val client = FetchClientBuilder[IO].create
24+
25+
val activityElement = document.getElementById("activity")
26+
27+
case class Activity(activity: String)
28+
29+
val fetchActivity: IO[Unit] = for {
30+
_ <- IO(activityElement.innerHTML = "<i>fetching...</i>")
31+
activity <- client.expect[Activity]("https://www.boredapi.com/api/activity")
32+
_ <- IO(activityElement.innerHTML = activity.activity)
33+
} yield ()
34+
35+
val button = document.getElementById("button").asInstanceOf[html.Button]
36+
37+
button.onclick = _ => fetchActivity.unsafeRunAndForget()
38+
```

docs/index.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# http4s-dom
2+
3+
Use http4s in your browser with Scala.js!
4+
Features:
5+
6+
* A [`Client` implementation](fetch.md) backed by [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
7+
* A [`WSClient` implementation](websocket.md) backed by [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket$.html)
8+
* A [`Service Worker` integration](serviceworker.md) to install your `HttpRoutes` as a [`FetchEvent` handler](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/onfetch)
9+
* Encoders for [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File), [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) and [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)
10+
11+
Notably, http4s-dom can also be used to create _serverless_ apps with [Cloudflare Workers](https://workers.cloudflare.com) which have adopted the same APIs used in the browser!
12+
13+
## Installation
14+
15+
[![http4s-dom Scala version support](https://index.scala-lang.org/http4s/http4s-dom/http4s-dom/latest.svg)](https://index.scala-lang.org/http4s/http4s-dom/http4s-dom)
16+
17+
```scala
18+
// Supports http4s 0.23.x and scala-js-dom 2.x
19+
libraryDependencies += "org.http4s" %%% "http4s-dom" % "@VERSION@"
20+
21+
// recommended, brings in the latest client module
22+
libraryDependencies += "org.http4s" %%% "http4s-client" % "@HTTP4S_VERSION@"
23+
24+
// optional, for JSON support
25+
libraryDependencies += "org.http4s" %%% "http4s-circe" % "@HTTP4S_VERSION@"
26+
libraryDependencies += "io.circe" %%% "circe-generic" % "@CIRCE_VERSION@"
27+
```

0 commit comments

Comments
 (0)