From 97667859761f76e9a4e53edc2b47a7f2f922b17b Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Sun, 17 Oct 2021 13:19:17 -0700 Subject: [PATCH 1/2] Remove unused dependency to scalajs-dom --- build.sbt | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sbt b/build.sbt index 5842721cd2..5f479e2515 100644 --- a/build.sbt +++ b/build.sbt @@ -247,6 +247,7 @@ lazy val node = crossProject(JSPlatform) stOutputPackage := "fs2.internal.jsdeps", stPrivateWithin := Some("fs2"), stStdlib := List("es2020"), + stUseScalaJsDom := false, stIncludeDev := true ) From 06e22523da2c7790aa4c6e673c2ed2ed8cd06020 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Sun, 17 Oct 2021 21:16:49 +0000 Subject: [PATCH 2/2] Use Node types instead of SJS std lib --- .../scala/fs2/io/internal/ByteChunkOps.scala | 4 ++- .../scala/fs2/io/internal/ThrowableOps.scala | 32 +++++++++++++++++++ io/js/src/main/scala/fs2/io/ioplatform.scala | 16 ++++++---- .../io/net/DatagramSocketGroupPlatform.scala | 3 +- .../fs2/io/net/DatagramSocketPlatform.scala | 7 ++-- .../fs2/io/net/SocketGroupPlatform.scala | 5 +-- .../scala/fs2/io/net/tls/TLSParameters.scala | 15 +++++---- .../fs2/io/net/tls/TLSSocketPlatform.scala | 3 +- .../net/unixsocket/UnixSocketsPlatform.scala | 3 +- .../scala/fs2/io/NodeJSCompressionSuite.scala | 4 +-- 10 files changed, 67 insertions(+), 25 deletions(-) create mode 100644 io/js/src/main/scala/fs2/io/internal/ThrowableOps.scala diff --git a/io/js/src/main/scala/fs2/io/internal/ByteChunkOps.scala b/io/js/src/main/scala/fs2/io/internal/ByteChunkOps.scala index 8852c30f57..659c9bbb69 100644 --- a/io/js/src/main/scala/fs2/io/internal/ByteChunkOps.scala +++ b/io/js/src/main/scala/fs2/io/internal/ByteChunkOps.scala @@ -23,6 +23,7 @@ package fs2.io.internal import fs2.Chunk import fs2.internal.jsdeps.node.bufferMod +import fs2.internal.jsdeps.std import scala.scalajs.js.typedarray.{ArrayBuffer, TypedArrayBuffer} @@ -31,7 +32,8 @@ private[fs2] object ByteChunkOps { implicit def toBufferOps(buffer: bufferMod.global.Buffer): BufferOps = new BufferOps(buffer) private[fs2] final class ByteChunkOps(val chunk: Chunk[Byte]) extends AnyVal { - def toBuffer: bufferMod.global.Buffer = bufferMod.Buffer.from(chunk.toUint8Array) + def toBuffer: bufferMod.global.Buffer = bufferMod.Buffer.from(toNodeUint8Array) + def toNodeUint8Array: std.Uint8Array = chunk.toUint8Array.asInstanceOf[std.Uint8Array] } private[fs2] final class BufferOps(val buffer: bufferMod.global.Buffer) extends AnyVal { diff --git a/io/js/src/main/scala/fs2/io/internal/ThrowableOps.scala b/io/js/src/main/scala/fs2/io/internal/ThrowableOps.scala new file mode 100644 index 0000000000..0176370df1 --- /dev/null +++ b/io/js/src/main/scala/fs2/io/internal/ThrowableOps.scala @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2013 Functional Streams for Scala + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package fs2.io.internal + +import fs2.internal.jsdeps.std + +private[fs2] object ThrowableOps { + implicit def toThrowableOps(t: Throwable): ThrowableOps = new ThrowableOps(t) + + private[fs2] final class ThrowableOps(t: Throwable) { + def toJSError: std.Error = std.Error(t.getMessage(), t.getClass.getSimpleName) + } +} diff --git a/io/js/src/main/scala/fs2/io/ioplatform.scala b/io/js/src/main/scala/fs2/io/ioplatform.scala index 72bd0ac90a..57b2df3f15 100644 --- a/io/js/src/main/scala/fs2/io/ioplatform.scala +++ b/io/js/src/main/scala/fs2/io/ioplatform.scala @@ -29,11 +29,13 @@ import cats.effect.std.Dispatcher import cats.effect.std.Queue import cats.effect.syntax.all._ import cats.syntax.all._ +import fs2.internal.jsdeps.std import fs2.internal.jsdeps.node.bufferMod import fs2.internal.jsdeps.node.nodeStrings import fs2.internal.jsdeps.node.streamMod import fs2.io.internal.ByteChunkOps._ import fs2.io.internal.EventEmitterOps._ +import fs2.io.internal.ThrowableOps._ import scala.annotation.nowarn import scala.scalajs.js @@ -78,7 +80,7 @@ private[fs2] trait ioplatform { readable.destroy() } case (readable, Resource.ExitCase.Errored(ex)) => - SyncIO(readable.destroy(js.Error(ex.getMessage()))) + SyncIO(readable.destroy(ex.toJSError)) case (readable, Resource.ExitCase.Canceled) => if (destroyIfCanceled) SyncIO(readable.destroy()) @@ -94,7 +96,7 @@ private[fs2] trait ioplatform { _ <- registerListener0(readable, nodeStrings.close)(_.on_close(_, _)) { () => dispatcher.unsafeRunAndForget(queue.offer(None)) }(SyncIO.syncForSyncIO) - _ <- registerListener[js.Error](readable, nodeStrings.error)(_.on_error(_, _)) { e => + _ <- registerListener[std.Error](readable, nodeStrings.error)(_.on_error(_, _)) { e => dispatcher.unsafeRunAndForget(error.complete(js.JavaScriptException(e))) }(SyncIO.syncForSyncIO) } yield readable @@ -172,7 +174,7 @@ private[fs2] trait ioplatform { } go(in).stream.handleErrorWith { ex => - Stream.eval(F.delay(writable.destroy(js.Error(ex.getMessage)))) + Stream.eval(F.delay(writable.destroy(ex.toJSError))) }.drain } .adaptError { case IOException(ex) => ex } @@ -212,7 +214,7 @@ private[fs2] trait ioplatform { dispatcher.unsafeRunAndForget( readQueue.take.attempt.flatMap { case Left(ex) => - F.delay(readable.destroy(js.Error(ex.getMessage))) + F.delay(readable.destroy(ex.toJSError)) case Right(chunk) => F.delay(readable.push(chunk.map(_.toUint8Array).orNull)).void } @@ -227,7 +229,7 @@ private[fs2] trait ioplatform { F.delay( cb( e.left.toOption - .fold[js.Error | Null](null)(e => js.Error(e.getMessage())) + .fold[std.Error | Null](null)(_.toJSError) ) ) ) @@ -242,7 +244,7 @@ private[fs2] trait ioplatform { F.delay( cb( e.left.toOption - .fold[js.Error | Null](null)(e => js.Error(e.getMessage())) + .fold[std.Error | Null](null)(_.toJSError) ) ) ) @@ -260,7 +262,7 @@ private[fs2] trait ioplatform { F.delay( cb( e.left.toOption - .fold[js.Error | Null](null)(e => js.Error(e.getMessage())) + .fold[std.Error | Null](null)(_.toJSError) ) ) ) diff --git a/io/js/src/main/scala/fs2/io/net/DatagramSocketGroupPlatform.scala b/io/js/src/main/scala/fs2/io/net/DatagramSocketGroupPlatform.scala index df61c3f617..cad9b7c3ca 100644 --- a/io/js/src/main/scala/fs2/io/net/DatagramSocketGroupPlatform.scala +++ b/io/js/src/main/scala/fs2/io/net/DatagramSocketGroupPlatform.scala @@ -32,6 +32,7 @@ import com.comcast.ip4s.Port import fs2.internal.jsdeps.node.dgramMod import fs2.internal.jsdeps.node.eventsMod import fs2.internal.jsdeps.node.nodeStrings +import fs2.internal.jsdeps.std import scala.scalajs.js @@ -62,7 +63,7 @@ private[net] trait DatagramSocketGroupCompanionPlatform { socket <- DatagramSocket.forAsync[F](sock) _ <- F .async_[Unit] { cb => - val errorListener: js.Function1[js.Error, Unit] = { error => + val errorListener: js.Function1[std.Error, Unit] = { error => cb(Left(js.JavaScriptException(error))) } sock.once_error(nodeStrings.error, errorListener) diff --git a/io/js/src/main/scala/fs2/io/net/DatagramSocketPlatform.scala b/io/js/src/main/scala/fs2/io/net/DatagramSocketPlatform.scala index 6a541878ac..6e4de9f3f6 100644 --- a/io/js/src/main/scala/fs2/io/net/DatagramSocketPlatform.scala +++ b/io/js/src/main/scala/fs2/io/net/DatagramSocketPlatform.scala @@ -42,6 +42,7 @@ import fs2.io.internal.EventEmitterOps._ import fs2.internal.jsdeps.node.bufferMod import fs2.internal.jsdeps.node.dgramMod import fs2.internal.jsdeps.node.nodeStrings +import fs2.internal.jsdeps.std import scala.scalajs.js @@ -77,7 +78,7 @@ private[net] trait DatagramSocketCompanionPlatform { ) ) } - _ <- registerListener[js.Error](sock, nodeStrings.error)(_.on_error(_, _)) { e => + _ <- registerListener[std.Error](sock, nodeStrings.error)(_.on_error(_, _)) { e => dispatcher.unsafeRunAndForget(error.complete(js.JavaScriptException(e))) } socket <- Resource.make(F.pure(new AsyncDatagramSocket(sock, queue, error)))(_ => @@ -103,11 +104,11 @@ private[net] trait DatagramSocketCompanionPlatform { override def write(datagram: Datagram): F[Unit] = F.async_ { cb => sock.send( - datagram.bytes.toUint8Array, + datagram.bytes.toNodeUint8Array, datagram.remote.port.value.toDouble, datagram.remote.host.toString, (err, _) => - Option(err.asInstanceOf[js.Error]).fold(cb(Right(())))(err => + Option(err.asInstanceOf[std.Error]).fold(cb(Right(())))(err => cb(Left(js.JavaScriptException(err))) ) ) diff --git a/io/js/src/main/scala/fs2/io/net/SocketGroupPlatform.scala b/io/js/src/main/scala/fs2/io/net/SocketGroupPlatform.scala index c2d1c0593f..6f0c0a1656 100644 --- a/io/js/src/main/scala/fs2/io/net/SocketGroupPlatform.scala +++ b/io/js/src/main/scala/fs2/io/net/SocketGroupPlatform.scala @@ -35,6 +35,7 @@ import com.comcast.ip4s.Port import com.comcast.ip4s.SocketAddress import fs2.internal.jsdeps.node.netMod import fs2.internal.jsdeps.node.nodeStrings +import fs2.internal.jsdeps.std import fs2.io.internal.EventEmitterOps._ import scala.scalajs.js @@ -63,7 +64,7 @@ private[net] trait SocketGroupCompanionPlatform { self: SocketGroup.type => socket <- Socket.forAsync(sock) _ <- F .async[Unit] { cb => - registerListener[js.Error](sock, nodeStrings.error)(_.once_error(_, _)) { error => + registerListener[std.Error](sock, nodeStrings.error)(_.once_error(_, _)) { error => cb(Left(js.JavaScriptException(error))) }.evalTap(_ => F.delay(sock.connect(to.port.value.toDouble, to.host.toString, () => cb(Right(())))) @@ -98,7 +99,7 @@ private[net] trait SocketGroupCompanionPlatform { self: SocketGroup.type => cb(Right(())) } ) - _ <- registerListener[js.Error](server, nodeStrings.error)(_.once_error(_, _)) { e => + _ <- registerListener[std.Error](server, nodeStrings.error)(_.once_error(_, _)) { e => dispatcher.unsafeRunAndForget(error.complete(js.JavaScriptException(e))) } _ <- error.get diff --git a/io/js/src/main/scala/fs2/io/net/tls/TLSParameters.scala b/io/js/src/main/scala/fs2/io/net/tls/TLSParameters.scala index 5560baa737..08631ccae7 100644 --- a/io/js/src/main/scala/fs2/io/net/tls/TLSParameters.scala +++ b/io/js/src/main/scala/fs2/io/net/tls/TLSParameters.scala @@ -25,11 +25,12 @@ package net package tls import fs2.io.internal.ByteChunkOps._ +import fs2.io.internal.ThrowableOps._ import fs2.internal.jsdeps.node.tlsMod +import fs2.internal.jsdeps.std import scala.scalajs.js.JSConverters._ import scala.scalajs.js import scala.scalajs.js.| -import scala.scalajs.js.typedarray.Uint8Array import cats.syntax.all._ import cats.effect.kernel.Async import cats.effect.std.Dispatcher @@ -81,7 +82,7 @@ sealed trait TLSParameters { requestCert.foreach(options.setRequestCert(_)) rejectUnauthorized.foreach(options.setRejectUnauthorized(_)) alpnProtocols - .map(_.map(x => x: String | Uint8Array).toJSArray) + .map(_.map(x => x: String | std.Uint8Array).toJSArray) .foreach(options.setALPNProtocols(_)) sniCallback.map(_.toJS(dispatcher)).foreach(options.setSNICallback(_)) } @@ -131,13 +132,13 @@ object TLSParameters { def apply[F[_]: Async](servername: String): F[Either[Throwable, Option[SecureContext]]] private[TLSParameters] def toJS[F[_]](dispatcher: Dispatcher[F])(implicit F: Async[F] - ): js.Function2[String, js.Function2[js.Error | Null, js.UndefOr[ + ): js.Function2[String, js.Function2[std.Error | Null, js.UndefOr[ tlsMod.SecureContext ], Unit], Unit] = { (servername, cb) => dispatcher.unsafeRunAndForget { import SecureContext.ops apply(servername).flatMap { - case Left(ex) => F.delay(cb(js.Error(ex.getMessage), null)) + case Left(ex) => F.delay(cb(ex.toJSError, null)) case Right(Some(ctx)) => F.delay(cb(null, ctx.toJS)) case Right(None) => F.delay(cb(null, null)) } @@ -155,17 +156,17 @@ object TLSParameters { } final case class PSKCallbackNegotation(psk: Chunk[Byte], identity: String) { - private[TLSParameters] def toJS = tlsMod.PSKCallbackNegotation(identity, psk.toUint8Array) + private[TLSParameters] def toJS = tlsMod.PSKCallbackNegotation(identity, psk.toNodeUint8Array) } trait CheckServerIdentity { def apply(servername: String, cert: Chunk[Byte]): Either[Throwable, Unit] private[TLSParameters] def toJS - : js.Function2[String, tlsMod.PeerCertificate, js.UndefOr[js.Error]] = { + : js.Function2[String, tlsMod.PeerCertificate, js.UndefOr[std.Error]] = { (servername, cert) => apply(servername, cert.raw.toChunk) match { - case Left(ex) => js.Error(ex.getMessage) + case Left(ex) => ex.toJSError case _ => () } } diff --git a/io/js/src/main/scala/fs2/io/net/tls/TLSSocketPlatform.scala b/io/js/src/main/scala/fs2/io/net/tls/TLSSocketPlatform.scala index 7b973c8d57..9f48376973 100644 --- a/io/js/src/main/scala/fs2/io/net/tls/TLSSocketPlatform.scala +++ b/io/js/src/main/scala/fs2/io/net/tls/TLSSocketPlatform.scala @@ -36,6 +36,7 @@ import fs2.internal.jsdeps.node.netMod import fs2.internal.jsdeps.node.nodeStrings import fs2.internal.jsdeps.node.streamMod import fs2.internal.jsdeps.node.tlsMod +import fs2.internal.jsdeps.std import fs2.io.internal.ByteChunkOps._ import fs2.io.internal.SuspendedStream @@ -66,7 +67,7 @@ private[tls] trait TLSSocketCompanionPlatform { self: TLSSocket.type => dispatcher.unsafeRunAndForget( errorDef.complete(IOException.unapply(ex).getOrElse(ex)) ) - }: js.Function1[js.Error, Unit] + }: js.Function1[std.Error, Unit] tlsSockReadable <- suspendReadableAndRead( destroyIfNotEnded = false, destroyIfCanceled = false diff --git a/io/js/src/main/scala/fs2/io/net/unixsocket/UnixSocketsPlatform.scala b/io/js/src/main/scala/fs2/io/net/unixsocket/UnixSocketsPlatform.scala index ad137ec65a..e69917cb79 100644 --- a/io/js/src/main/scala/fs2/io/net/unixsocket/UnixSocketsPlatform.scala +++ b/io/js/src/main/scala/fs2/io/net/unixsocket/UnixSocketsPlatform.scala @@ -26,6 +26,7 @@ import cats.effect.kernel.Async import cats.effect.kernel.Resource import fs2.io.net.Socket import fs2.internal.jsdeps.node.netMod +import fs2.internal.jsdeps.std import cats.syntax.all._ import scala.scalajs.js import cats.effect.std.Dispatcher @@ -78,7 +79,7 @@ private[unixsocket] trait UnixSocketsCompanionPlatform { ) _ <- Stream .resource( - registerListener[js.Error](server, nodeStrings.error)(_.once_error(_, _)) { e => + registerListener[std.Error](server, nodeStrings.error)(_.once_error(_, _)) { e => dispatcher.unsafeRunAndForget(errored.complete(js.JavaScriptException(e))) } ) diff --git a/io/js/src/test/scala/fs2/io/NodeJSCompressionSuite.scala b/io/js/src/test/scala/fs2/io/NodeJSCompressionSuite.scala index 56b04eeae4..415d64b442 100644 --- a/io/js/src/test/scala/fs2/io/NodeJSCompressionSuite.scala +++ b/io/js/src/test/scala/fs2/io/NodeJSCompressionSuite.scala @@ -35,7 +35,7 @@ class NodeJSCompressionSuite extends CompressionSuite { strategy: Int, nowrap: Boolean ): Array[Byte] = { - val in = Chunk.array(b).toUint8Array + val in = Chunk.array(b).toNodeUint8Array val options = zlibMod .ZlibOptions() .setLevel(level.toDouble) @@ -49,7 +49,7 @@ class NodeJSCompressionSuite extends CompressionSuite { } override def inflateStream(b: Array[Byte], nowrap: Boolean): Array[Byte] = { - val in = Chunk.array(b).toUint8Array + val in = Chunk.array(b).toNodeUint8Array val options = zlibMod.ZlibOptions() val out = if (nowrap)