From d5a0205d1c4543fe2927e7c35fecf2974b6bc502 Mon Sep 17 00:00:00 2001 From: CCH <31771180+Chingles2404@users.noreply.github.com> Date: Thu, 13 Jun 2024 22:25:21 +0800 Subject: [PATCH 1/8] Initial draft for IOVercel --- .../main/scala/feral/vercel/IOVercel.scala | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala diff --git a/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala b/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala new file mode 100644 index 00000000..d8662ec0 --- /dev/null +++ b/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala @@ -0,0 +1,61 @@ +/* + * Copyright 2021 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + package feral.vercel + +import cats.effect.IO +import cats.effect.kernel.Resource +import cats.effect.unsafe.IORuntime +import cats.effect.std.Dispatcher +import cats.syntax.all._ + +import scala.scalajs.js + +import org.http4s.nodejs.IncomingMessage +import org.http4s.nodejs.ServerResponse +import org.http4s.HttpApp + +private[vercel] abstract class IOVercel { + + final def main(args: Array[String]): Unit = + js.Dynamic.global.exports.updateDynamic(handlerName)(handlerFn) + + protected def handlerName: String = getClass.getSimpleName.init + + protected def runtime: IORuntime = IORuntime.global + + def handler: Resource[IO, HttpApp[IO]] + + private[vercel] lazy val handlerFn + : js.Function2[IncomingMessage, ServerResponse, Unit] = { + val dispatcherHandle = { + Dispatcher + .parallel[IO](await = false) + .product(handler) + .allocated + .map(_._1) // drop unused finalizer + .unsafeToPromise()(runtime) + } + + (request: IncomingMessage, response: ServerResponse) => + dispatcherHandle.`then`[Unit] { + case (dispatcher, handle) => + dispatcher.unsafeRunAndForget( + request.toRequest.flatMap(handle(_)).flatMap(response.writeResponse[IO]) + ) + } + } +} \ No newline at end of file From 3e3de1c40cb215934a431ae5234540f5774dbcc6 Mon Sep 17 00:00:00 2001 From: CCH <31771180+Chingles2404@users.noreply.github.com> Date: Fri, 14 Jun 2024 01:10:59 +0800 Subject: [PATCH 2/8] Fixed the error in line 56 --- .../main/scala/feral/vercel/IOVercel.scala | 121 +++++++++--------- 1 file changed, 60 insertions(+), 61 deletions(-) diff --git a/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala b/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala index d8662ec0..2cdb78f5 100644 --- a/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala +++ b/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala @@ -1,61 +1,60 @@ -/* - * Copyright 2021 Typelevel - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - package feral.vercel - -import cats.effect.IO -import cats.effect.kernel.Resource -import cats.effect.unsafe.IORuntime -import cats.effect.std.Dispatcher -import cats.syntax.all._ - -import scala.scalajs.js - -import org.http4s.nodejs.IncomingMessage -import org.http4s.nodejs.ServerResponse -import org.http4s.HttpApp - -private[vercel] abstract class IOVercel { - - final def main(args: Array[String]): Unit = - js.Dynamic.global.exports.updateDynamic(handlerName)(handlerFn) - - protected def handlerName: String = getClass.getSimpleName.init - - protected def runtime: IORuntime = IORuntime.global - - def handler: Resource[IO, HttpApp[IO]] - - private[vercel] lazy val handlerFn - : js.Function2[IncomingMessage, ServerResponse, Unit] = { - val dispatcherHandle = { - Dispatcher - .parallel[IO](await = false) - .product(handler) - .allocated - .map(_._1) // drop unused finalizer - .unsafeToPromise()(runtime) - } - - (request: IncomingMessage, response: ServerResponse) => - dispatcherHandle.`then`[Unit] { - case (dispatcher, handle) => - dispatcher.unsafeRunAndForget( - request.toRequest.flatMap(handle(_)).flatMap(response.writeResponse[IO]) - ) - } - } -} \ No newline at end of file +/* + * Copyright 2021 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package feral.vercel + +import cats.effect.IO +import cats.effect.kernel.Resource +import cats.effect.unsafe.IORuntime +import cats.effect.std.Dispatcher +import cats.syntax.all._ + +import scala.scalajs.js + +import org.http4s.nodejs.IncomingMessage +import org.http4s.nodejs.ServerResponse +import org.http4s.HttpApp + +private[vercel] abstract class IOVercel { + + final def main(args: Array[String]): Unit = + js.Dynamic.global.exports.updateDynamic(handlerName)(handlerFn) + + protected def handlerName: String = getClass.getSimpleName.init + + protected def runtime: IORuntime = IORuntime.global + + def handler: Resource[IO, HttpApp[IO]] + + private[vercel] lazy val handlerFn: js.Function2[IncomingMessage, ServerResponse, Unit] = { + val dispatcherHandle = { + Dispatcher + .parallel[IO](await = false) + .product(handler) + .allocated + .map(_._1) // drop unused finalizer + .unsafeToPromise()(runtime) + } + + (request: IncomingMessage, response: ServerResponse) => + dispatcherHandle.`then`[Unit] { + case (dispatcher, handle) => + dispatcher.unsafeRunAndForget( + request.toRequest[IO].flatMap(handle(_)).flatMap(response.writeResponse[IO]) + ) + } + } +} From 7e8fe500c6e60389abadd1ee8ced72d8288bdb6c Mon Sep 17 00:00:00 2001 From: CCH <31771180+Chingles2404@users.noreply.github.com> Date: Fri, 14 Jun 2024 23:31:23 +0800 Subject: [PATCH 3/8] Ran scalafix --- vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala b/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala index 2cdb78f5..71eef288 100644 --- a/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala +++ b/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala @@ -18,15 +18,14 @@ package feral.vercel import cats.effect.IO import cats.effect.kernel.Resource -import cats.effect.unsafe.IORuntime import cats.effect.std.Dispatcher +import cats.effect.unsafe.IORuntime import cats.syntax.all._ - -import scala.scalajs.js - +import org.http4s.HttpApp import org.http4s.nodejs.IncomingMessage import org.http4s.nodejs.ServerResponse -import org.http4s.HttpApp + +import scala.scalajs.js private[vercel] abstract class IOVercel { From d37670d921d5a0915972c79b4911361ebaaf100a Mon Sep 17 00:00:00 2001 From: CCH <31771180+Chingles2404@users.noreply.github.com> Date: Mon, 17 Jun 2024 03:23:35 +0800 Subject: [PATCH 4/8] Suppressed warning about discarded value --- vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala b/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala index 71eef288..2f509a47 100644 --- a/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala +++ b/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala @@ -49,7 +49,7 @@ private[vercel] abstract class IOVercel { } (request: IncomingMessage, response: ServerResponse) => - dispatcherHandle.`then`[Unit] { + val _ = dispatcherHandle.`then`[Unit] { case (dispatcher, handle) => dispatcher.unsafeRunAndForget( request.toRequest[IO].flatMap(handle(_)).flatMap(response.writeResponse[IO]) From 4b52398b6d3b77cb6197890ccb591c37336d26b5 Mon Sep 17 00:00:00 2001 From: CCH <31771180+Chingles2404@users.noreply.github.com> Date: Tue, 18 Jun 2024 19:33:28 +0800 Subject: [PATCH 5/8] Removed Vercel from docs --- build.sbt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 5163e312..8254470c 100644 --- a/build.sbt +++ b/build.sbt @@ -212,8 +212,7 @@ lazy val unidocs = project inProjects( lambda.jvm, lambdaHttp4s.jvm, - lambdaCloudFormationCustomResource.jvm, - vercelNodeJS + lambdaCloudFormationCustomResource.jvm ) } ) From 6cd40c7753c16c9d2b75d5fea3250cadb3c73e2d Mon Sep 17 00:00:00 2001 From: CCH <31771180+Chingles2404@users.noreply.github.com> Date: Sun, 7 Jul 2024 05:16:09 +0800 Subject: [PATCH 6/8] Updated Vercel support, added Vercel example --- build.sbt | 8 ++++- .../scala/feral/examples/VercelNodejs.scala | 36 +++++++++++++++++++ .../scala/feral/examples/Http4sLambda.scala | 0 .../scala/feral/examples/KinesisLambda.scala | 0 .../main/scala/feral/vercel/IOVercel.scala | 6 ++-- 5 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 examples/js/src/main/scala/feral/examples/VercelNodejs.scala rename examples/{ => shared}/src/main/scala/feral/examples/Http4sLambda.scala (100%) rename examples/{ => shared}/src/main/scala/feral/examples/KinesisLambda.scala (100%) diff --git a/build.sbt b/build.sbt index 8254470c..6a5de6eb 100644 --- a/build.sbt +++ b/build.sbt @@ -184,8 +184,8 @@ lazy val vercelNodeJS = project tlVersionIntroduced := List("2.13", "3").map(_ -> "0.3.1").toMap ) + lazy val examples = crossProject(JSPlatform, JVMPlatform) - .crossType(CrossType.Pure) .in(file("examples")) .settings( libraryDependencies ++= Seq( @@ -198,6 +198,12 @@ lazy val examples = crossProject(JSPlatform, JVMPlatform) ) .settings(commonSettings) .dependsOn(lambda, lambdaHttp4s) + .jsConfigure(_.dependsOn(vercelNodeJS)) + .jsSettings( + scalaJSUseMainModuleInitializer := true, + Compile / mainClass := Some("feral.examples.vercelNodejsHandler"), + scalaJSLinkerConfig ~= { _.withModuleKind(ModuleKind.CommonJSModule) } + ) .enablePlugins(NoPublishPlugin) lazy val unidocs = project diff --git a/examples/js/src/main/scala/feral/examples/VercelNodejs.scala b/examples/js/src/main/scala/feral/examples/VercelNodejs.scala new file mode 100644 index 00000000..aaa25095 --- /dev/null +++ b/examples/js/src/main/scala/feral/examples/VercelNodejs.scala @@ -0,0 +1,36 @@ +/* + * Copyright 2021 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package feral.examples + +import cats.effect._ +import feral.vercel._ +import org.http4s._ +import org.http4s.dsl.io._ + +object vercelNodejsHandler extends IOVercel { + def handler = { + val app = HttpRoutes.of[IO] { + case GET -> Root / "hello" / name => + Ok(s"Hello, $name.") + }.orNotFound + + Resource.pure(app) + + /*Resource.pure(HttpApp.pure(Response[IO](Status.Ok)))*/ + } + +} diff --git a/examples/src/main/scala/feral/examples/Http4sLambda.scala b/examples/shared/src/main/scala/feral/examples/Http4sLambda.scala similarity index 100% rename from examples/src/main/scala/feral/examples/Http4sLambda.scala rename to examples/shared/src/main/scala/feral/examples/Http4sLambda.scala diff --git a/examples/src/main/scala/feral/examples/KinesisLambda.scala b/examples/shared/src/main/scala/feral/examples/KinesisLambda.scala similarity index 100% rename from examples/src/main/scala/feral/examples/KinesisLambda.scala rename to examples/shared/src/main/scala/feral/examples/KinesisLambda.scala diff --git a/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala b/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala index 2f509a47..3a3c23ac 100644 --- a/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala +++ b/vercel-nodejs/src/main/scala/feral/vercel/IOVercel.scala @@ -27,12 +27,10 @@ import org.http4s.nodejs.ServerResponse import scala.scalajs.js -private[vercel] abstract class IOVercel { +abstract class IOVercel { final def main(args: Array[String]): Unit = - js.Dynamic.global.exports.updateDynamic(handlerName)(handlerFn) - - protected def handlerName: String = getClass.getSimpleName.init + js.Dynamic.global.module.exports = handlerFn protected def runtime: IORuntime = IORuntime.global From bfc38bf262290d1581ff067585b49c35a854698c Mon Sep 17 00:00:00 2001 From: CCH <31771180+Chingles2404@users.noreply.github.com> Date: Sun, 7 Jul 2024 05:19:22 +0800 Subject: [PATCH 7/8] Ran scalafix --- .../src/main/scala/feral/examples/VercelNodejs.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/js/src/main/scala/feral/examples/VercelNodejs.scala b/examples/js/src/main/scala/feral/examples/VercelNodejs.scala index aaa25095..45b7d54f 100644 --- a/examples/js/src/main/scala/feral/examples/VercelNodejs.scala +++ b/examples/js/src/main/scala/feral/examples/VercelNodejs.scala @@ -23,10 +23,12 @@ import org.http4s.dsl.io._ object vercelNodejsHandler extends IOVercel { def handler = { - val app = HttpRoutes.of[IO] { - case GET -> Root / "hello" / name => - Ok(s"Hello, $name.") - }.orNotFound + val app = HttpRoutes + .of[IO] { + case GET -> Root / "hello" / name => + Ok(s"Hello, $name.") + } + .orNotFound Resource.pure(app) From 5bb619eee70bd854da8310f0ab33ef9dec5ead4a Mon Sep 17 00:00:00 2001 From: CCH <31771180+Chingles2404@users.noreply.github.com> Date: Sun, 7 Jul 2024 05:22:15 +0800 Subject: [PATCH 8/8] Ran scalafmtSbt --- build.sbt | 1 - 1 file changed, 1 deletion(-) diff --git a/build.sbt b/build.sbt index 6a5de6eb..19a880ed 100644 --- a/build.sbt +++ b/build.sbt @@ -184,7 +184,6 @@ lazy val vercelNodeJS = project tlVersionIntroduced := List("2.13", "3").map(_ -> "0.3.1").toMap ) - lazy val examples = crossProject(JSPlatform, JVMPlatform) .in(file("examples")) .settings(